Android Bugfixxing Part 1
the build was successful
Details
the build was successful
Details
- Icons Now Show - Zoom Slider doesn't Crash (2 causes) - One desktop/android crash caused by Ellipsis Label (now replaced) - One android crash caused by ButtonTextField (fixed) - Removed some emoji handling that was unused.
This commit is contained in:
parent
cb932d3ca3
commit
a5c96964e8
|
@ -0,0 +1,82 @@
|
|||
# Notes on Android Debugging
|
||||
|
||||
If you are reading this you are probably interested in developing Cwtch for Android! Awesome.
|
||||
|
||||
The Cwtch UI app is intended to be a single codebase that runs on multiple platforms. This
|
||||
complicates the build process in favour of simplifying the code (so goes the theory).
|
||||
|
||||
We make use of https://github.com/therecipe/qt/ for deploying Go/Qt code to Android. Before you venture into the weeds
|
||||
of this README please take a look at the [Installation](https://github.com/therecipe/qt/wiki/Installation)
|
||||
and [Setup instructions](https://github.com/therecipe/qt/wiki/Deploying-Linux-to-Android) in therecipe/qt.
|
||||
|
||||
## Building
|
||||
|
||||
Check out and follow the instructions at https://github.com/therecipe/qt/wiki/Deploying-Linux-to-Android as they are sufficient,
|
||||
below you will find high-level notes regarding the process.
|
||||
|
||||
You need to run `qtsetup --qt_version=<vesion> full android` for the non-docker setup. You will need to do this
|
||||
for every major version change of therecipe dependencies.
|
||||
|
||||
You will also need the Android 28 SDK (Pie), the NDK, SDK build tools and platform tools, gradle and **JDK 8**
|
||||
|
||||
JAVA_HOME=/path/to/jre8
|
||||
ANDROID_NDK_DIR=/path/to/ndk
|
||||
|
||||
Once all that setup is done you should be able to run:
|
||||
|
||||
qtdeploy build android
|
||||
|
||||
2-4 minutes later an android apk will pop out in `./deploy/android/build-debug.apk`.
|
||||
|
||||
### Build Setup Issues we have seen
|
||||
|
||||
* `Could not determine java version from <blah>` - this is thrown by gradle inside the `androiddeployqt` process when the
|
||||
Java version is *not* JRE8. Ensure that JAVA_HOME is pointed to the correct java installation.
|
||||
* ` readelf <blah> "is not an ordinary file"` - this isn't actually an error that will stop the build, but sometimes
|
||||
because of the very long debug log output you will come across it when trying to find the *actual* error (which is
|
||||
probably a Java version issue). It can be safely ignored.
|
||||
* `could not find QAndroid...` / `CPP build errors` - you will need to run `qtsetup` full android` for the Qt version
|
||||
you are using.
|
||||
* Example: androidextras_android.cpp:9:10: fatal error: 'QAndroidActivityResultReceiver' file not found
|
||||
|
||||
## Testing on a Real Device
|
||||
|
||||
Consult the Android documentation on setting up your device for development.
|
||||
|
||||
You will need an android sdk, setup your device for USB Debugging and then with `adb` you can do:
|
||||
|
||||
adb install -r ./deploy/android/build-debug.apk
|
||||
|
||||
To get the logs you can run
|
||||
|
||||
adb logcat
|
||||
|
||||
Android Studio provides a nice logcat interface for quickly filtering log files that can be very useful when trying to
|
||||
debug complex behavior, but command line tools like `grep` and the built-in [logcat filtering](https://developer.android.com/studio/command-line/logcat)
|
||||
should also suffice.
|
||||
|
||||
*Important*: Cwtch UI technically runs *3* different applications: Cwtch Frontend (application client),
|
||||
Cwtch Backend (application server) and Tor. When filtering logcat you should be aware that some of your messages might
|
||||
be getting logged by a different process.
|
||||
|
||||
(*Ctrl-F Helper: "Why are log messages missing"*)
|
||||
|
||||
# Bundled Libraries
|
||||
|
||||
There seems to be a bug in Qt (https://bugreports.qt.io/browse/QTBUG-84371) that prevents the use of
|
||||
`AndroidExtras` in `ANDROID_MODULES_INCLUDE` so we bundle it in `android/libQt5AndroidExtras.so` along with
|
||||
`libtor` for Tor support.
|
||||
|
||||
## Non-SDK Interfaces
|
||||
|
||||
e.g. java.lang.NoSuchFieldException: No field mPivotX in class Landroid/graphics/drawable/RotateDrawable$RotateState;
|
||||
|
||||
* https://bugreports.qt.io/browse/QTBUG-71590
|
||||
|
||||
## Plugins
|
||||
|
||||
Theoretically speaking it should be possible to use `ANDROID_EXTRA_PLUGINS` to include support for e.g.
|
||||
SVG images on Android. However, we have been unable to make it work. If you would like to try, the following
|
||||
issues might be helpful:
|
||||
|
||||
* https://bugreports.qt.io/browse/QTBUG-60022
|
15
Makefile
15
Makefile
|
@ -1,6 +1,9 @@
|
|||
.PHONY: all clean linux windows android
|
||||
all: clean linux windows android
|
||||
default: linux
|
||||
default: linux
|
||||
|
||||
SHELL := env QT_BUILD_VERSION=$(QT_BUILD_VERSION) $(SHELL)
|
||||
QT_BUILD_VERSION ?= "5.13.4"
|
||||
|
||||
clean:
|
||||
rm -r vendor || true
|
||||
|
@ -18,7 +21,7 @@ android:
|
|||
|
||||
linux_build:
|
||||
date
|
||||
qtdeploy -qt_version "5.13.0" build linux 2>&1 | tee qtdeploy.log | pv
|
||||
qtdeploy -qt_version $(QT_BUILD_VERSION) build linux 2>&1 | tee qtdeploy.log | pv
|
||||
date
|
||||
cp -R assets deploy/linux/
|
||||
$(MAKE) linux_clean
|
||||
|
@ -28,7 +31,7 @@ linux_clean:
|
|||
|
||||
windows_build:
|
||||
date
|
||||
qtdeploy -qt_version "5.13.0" build windows 2>&1 | tee qtdeploy.log | pv
|
||||
qtdeploy -qt_version $(QT_BUILD_VERSION) build windows 2>&1 | tee qtdeploy.log | pv
|
||||
date
|
||||
cp -R assets deploy/windows/
|
||||
$(MAKE) linux_clean
|
||||
|
@ -37,11 +40,11 @@ windows_clean:
|
|||
#ntd
|
||||
|
||||
android_build:
|
||||
mv assets android/
|
||||
cp -R assets android/
|
||||
date
|
||||
qtdeploy -docker build android 2>&1 | tee qtdeploy.log | pv
|
||||
## TODO have this also include AndroidExtras (see ANDROID_DEBUGGING) for full notes.
|
||||
env ANDROID_MODULES_INCLUDE="Core,Gui,Svg,QuickWidgets,Xml" qtdeploy -debug -qt_version $(QT_BUILD_VERSION) build android 2>&1 | tee qtdeploy.log | pv
|
||||
date
|
||||
$(MAKE) android_clean
|
||||
|
||||
android_clean:
|
||||
mv android/assets assets
|
||||
|
|
Binary file not shown.
12
go.sum
12
go.sum
|
@ -49,6 +49,7 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b
|
|||
github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc=
|
||||
github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
|
@ -77,8 +78,19 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
|||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/struCoder/pidusage v0.1.3 h1:pZcSa6asBE38TJtW0Nui6GeCjLTpaT/jAnNP7dUTLSQ=
|
||||
github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI=
|
||||
github.com/therecipe/env_darwin_amd64_513 v0.0.0-20190626001412-d8e92e8db4d0 h1:Txh3Vvzx49BQg6OwSuYqOGNndpCWPYScIpEgK5BcGpc=
|
||||
github.com/therecipe/env_darwin_amd64_513 v0.0.0-20190626001412-d8e92e8db4d0/go.mod h1:mdZdqBBs62KM68t1wD7rjG2NumvwuSNLqmMetEAqI14=
|
||||
github.com/therecipe/env_linux_amd64_513 v0.0.0-20190626000307-e137a3934da6 h1:i0/LROzMqqMuHJ9gPeH2+So1Icle7zSVRqzXR4Z75hw=
|
||||
github.com/therecipe/env_linux_amd64_513 v0.0.0-20190626000307-e137a3934da6/go.mod h1:Cq/lZrZTuGhRckzJgZFONK4WCE67AssWhHYj82U5FFI=
|
||||
github.com/therecipe/env_windows_amd64_513 v0.0.0-20190626000028-79ec8bd06fb2 h1:dpqvgFCZRuxwiJhWVwQZSJ8zDaORf+GiUGxxOGzlQtc=
|
||||
github.com/therecipe/env_windows_amd64_513 v0.0.0-20190626000028-79ec8bd06fb2/go.mod h1:evzb6PHK/MrRdJyhL1kbQXTfbMu4t4JOLl6iz55ywvk=
|
||||
github.com/therecipe/env_windows_amd64_513/Tools v0.0.0-20190626000028-79ec8bd06fb2 h1:hM5KSUn4YbSvPuXAWJyywohkDocI+hSEsL+Msc9/FDA=
|
||||
github.com/therecipe/env_windows_amd64_513/Tools v0.0.0-20190626000028-79ec8bd06fb2/go.mod h1:75GdIZ2clS7WUwhRklktkP02ffFz7+tBx8/Ue8eFexU=
|
||||
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41 h1:yBVcrpbaQYJBdKT2pxTdlL4hBE/eM4UPcyj9YpyvSok=
|
||||
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us=
|
||||
github.com/therecipe/qt v0.0.0-20200904063919-c0c124a5770d h1:T+d8FnaLSvM/1BdlDXhW4d5dr2F07bAbB+LpgzMxx+o=
|
||||
github.com/therecipe/qt v0.0.0-20200904063919-c0c124a5770d/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us=
|
||||
github.com/therecipe/qt/internal/binding/files/docs v0.0.0-20191019224306-1097424d656c h1:/VhcwU7WuFEVgDHZ9V8PIYAyYqQ6KNxFUjBMOf2aFZM=
|
||||
github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41 h1:My9HYsfDI/fJPZGyilw6066buBiZ7pgKRRgAyvKK5lA=
|
||||
github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:7m8PDYDEtEVqfjoUQc2UrFqhG0CDmoVJjRlQxexndFc=
|
||||
github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41 h1:jTzKrQ6EIPvKw1B9/wwoKJLrXF+ManMsXoUzufxAdsg=
|
||||
|
|
|
@ -690,12 +690,6 @@ func (this *GrandCentralDispatcher) setLocaleHelper(locale string) {
|
|||
}
|
||||
|
||||
func (this *GrandCentralDispatcher) themeScaleChanged(newThemeScale float32) {
|
||||
// TODO: solve why themeScale > 2.0 halts app launch - related task - solve all the qml launch warnings around anchors/layouts
|
||||
if this.Os() != "android" {
|
||||
if newThemeScale > 1.99 {
|
||||
this.SetThemeScale(1.99)
|
||||
}
|
||||
}
|
||||
this.GlobalSettings.Zoom = newThemeScale
|
||||
WriteGlobalSettings(this.GlobalSettings)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ type GlobalSettings struct {
|
|||
}
|
||||
|
||||
var DefaultGlobalSettings = GlobalSettings{
|
||||
Zoom: 1.0,
|
||||
Zoom: 1.9,
|
||||
Locale: "en",
|
||||
Theme: "light",
|
||||
PreviousPid: -1,
|
||||
|
@ -68,11 +68,13 @@ func ReadGlobalSettings() *GlobalSettings {
|
|||
return &settings
|
||||
}
|
||||
|
||||
|
||||
err = json.Unmarshal(settingsBytes, &settings)
|
||||
if err != nil {
|
||||
log.Errorf("Could not parse global ui settings: %v\n", err)
|
||||
}
|
||||
log.Debugf("MAP: %v", settings.Experiments)
|
||||
|
||||
log.Debugf("Settings: %v", settings)
|
||||
return &settings
|
||||
}
|
||||
|
||||
|
|
2
main.go
2
main.go
|
@ -44,6 +44,7 @@ func init() {
|
|||
}
|
||||
|
||||
func main() {
|
||||
|
||||
if os.Getenv("CWTCH_FOLDER") != "" {
|
||||
the.CwtchDir = os.Getenv("CWTCH_FOLDER")
|
||||
} else if runtime.GOOS == "android" {
|
||||
|
@ -259,6 +260,7 @@ func loadACN() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// generate a random socks and control port (not real random...these are port numbers...)
|
||||
mrand.Seed(int64(time.Now().Nanosecond()))
|
||||
port := mrand.Intn(1000) + 9600
|
||||
|
|
|
@ -75,8 +75,6 @@ ApplicationWindow {
|
|||
return px * 72 / (Screen.pixelDensity * 25.4)
|
||||
}
|
||||
|
||||
|
||||
|
||||
StackView {
|
||||
id: rootStack
|
||||
|
||||
|
@ -115,6 +113,7 @@ ApplicationWindow {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// The actual app
|
||||
property Item mainLayout: Rectangle {
|
||||
color: Theme.backgroundMainColor
|
||||
|
@ -191,6 +190,7 @@ ApplicationWindow {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
RowLayout { // Profile Pane (contact list + overlays)
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b8d01338786625a41ba430ede6430715f5c82b33
|
||||
Subproject commit 3b9675e25917f667ba4b1cf1db09d44ed328f010
|
|
@ -32,7 +32,7 @@ ColumnLayout {
|
|||
//: ex: "... paste an address here to add a contact ..."
|
||||
placeholderText: qsTr("search-list")
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
icon: gcd.assetPath + "core/search-24px.svg"
|
||||
icon: gcd.assetPath + "core/search-24px.webp"
|
||||
|
||||
|
||||
onTextChanged: {
|
||||
|
@ -47,18 +47,19 @@ ColumnLayout {
|
|||
|
||||
Opaque.Icon {
|
||||
visible:!listpanel.online
|
||||
source: gcd.assetPath + "core/negative_heart_24px.svg"
|
||||
source: gcd.assetPath + "core/negative_heart_24px.webp"
|
||||
iconColor: Theme.mainTextColor
|
||||
backgroundColor: Theme.backgroundPaneColor
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
height: 150
|
||||
width: 150
|
||||
}
|
||||
Opaque.EllipsisLabel {
|
||||
Label {
|
||||
visible:!listpanel.online
|
||||
color: Theme.mainTextColor
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
size: 18 * gcd.themeScale
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: 18 * gcd.themeScale
|
||||
text: qsTr("peer-not-online")
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ Opaque.SettingsList { // groupSettingsPane
|
|||
width: 18
|
||||
Layout.alignment: Qt.AlignRight
|
||||
iconColor: gsp.connected ? Theme.statusbarOnlineFontColor : Theme.statusbarDisconnectedTorFontColor
|
||||
source: gcd.assetPath + (gsp.connected ? "core/signal_cellular_4_bar-24px.svg" : "core/signal_cellular_connected_no_internet_4_bar-24px.svg")
|
||||
source: gcd.assetPath + (gsp.connected ? "core/signal_cellular_4_bar-24px.webp" : "core/signal_cellular_connected_no_internet_4_bar-24px.webp")
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
|
@ -115,7 +115,7 @@ Opaque.SettingsList { // groupSettingsPane
|
|||
width: 18
|
||||
Layout.alignment: Qt.AlignRight
|
||||
iconColor : gsp.synced ? Theme.statusbarOnlineFontColor : Theme.statusbarConnectingFontColor
|
||||
source: gcd.assetPath + (gsp.synced ? "core/syncing-01.svg" : "core/syncing-03.svg")
|
||||
source: gcd.assetPath + (gsp.synced ? "core/syncing-01.webp" : "core/syncing-03.webp")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ Opaque.Flickable {
|
|||
nameLabel.text = ""
|
||||
|
||||
portrait.performTransform = true
|
||||
portrait.source = "core/account_circle-24px_negative_space.svg"
|
||||
portrait.source = "core/account_circle-24px_negative_space.webp"
|
||||
tag = ""
|
||||
confirmDeleteTxt.text = ""
|
||||
radioUsePassword.checked = true
|
||||
|
@ -136,7 +136,7 @@ Opaque.Flickable {
|
|||
|
||||
badgeContent: Image {// Profle Type
|
||||
id: profiletype
|
||||
source: radioUsePassword.checked ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
|
||||
source: radioUsePassword.checked ? gcd.assetPath + "core/lock-24px.webp" : gcd.assetPath + "core/lock-open-24px.webp"
|
||||
height: 40 * gcd.themeScale
|
||||
width: height
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ ColumnLayout {
|
|||
spacing: 20 * gcd.themeScale
|
||||
|
||||
Opaque.ScalingLabel {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
wrapMode: TextEdit.Wrap
|
||||
size: Theme.primaryTextSize
|
||||
|
||||
|
@ -56,16 +56,13 @@ ColumnLayout {
|
|||
|
||||
Opaque.Button {
|
||||
id: "button"
|
||||
//anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
width: 100 * gcd.themeScale
|
||||
height: Theme.primaryTextSize * gcd.themeScale
|
||||
icon: "lock_open-24px"
|
||||
|
||||
//: Unlock
|
||||
text: qsTr("unlock")
|
||||
|
||||
height: Theme.primaryTextSize * gcd.themeScale
|
||||
|
||||
|
||||
onClicked: {
|
||||
gcd.unlockProfiles(txtPassword.text)
|
||||
txtPassword.text = ""
|
||||
|
@ -76,7 +73,7 @@ ColumnLayout {
|
|||
|
||||
Opaque.ScalingLabel {
|
||||
id: error
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
color: Theme.textfieldErrorColor
|
||||
//: 0 profiles loaded with that password
|
||||
text: qsTr("error-0-profiles-loaded-for-password")
|
||||
|
|
|
@ -34,33 +34,40 @@ Opaque.SettingsList { // Add Profile Pane
|
|||
serverAddEditPane.server_messages = server_messages;
|
||||
}
|
||||
|
||||
settings: Column {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 700
|
||||
settings: Column {
|
||||
|
||||
Opaque.ScalingLabel {
|
||||
text: server_name
|
||||
size: 16
|
||||
}
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 700
|
||||
|
||||
Opaque.Setting {
|
||||
label: qsTr("server-availability")
|
||||
Opaque.ScalingLabel {
|
||||
text: server_name
|
||||
size: 16
|
||||
}
|
||||
|
||||
Opaque.Setting {
|
||||
label: qsTr("server-availability")
|
||||
|
||||
|
||||
field: Opaque.ToggleSwitch {
|
||||
anchors.right: parent.right
|
||||
field: Opaque.ToggleSwitch {
|
||||
anchors.right: parent.right
|
||||
|
||||
isToggled: serverAddEditPane.server_available
|
||||
onToggled: function() {
|
||||
serverAddEditPane.server_available = !serverAddEditPane.server_available
|
||||
if (serverAddEditPane.server_available) {
|
||||
gcd.startServer(serverAddEditPane.server_name)
|
||||
} else {
|
||||
gcd.stopServer(serverAddEditPane.server_name)
|
||||
isToggled: serverAddEditPane.server_available
|
||||
onToggled: function() {
|
||||
serverAddEditPane.server_available = !serverAddEditPane.server_available
|
||||
if (serverAddEditPane.server_available) {
|
||||
gcd.startServer(serverAddEditPane.server_name)
|
||||
} else {
|
||||
gcd.stopServer(serverAddEditPane.server_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Opaque.Setting {
|
||||
label: qsTr("server-autostart")
|
||||
|
@ -87,6 +94,7 @@ Opaque.SettingsList { // Add Profile Pane
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Opaque.Setting {
|
||||
inline: false
|
||||
label: qsTr("server-key-bundle")
|
||||
|
|
|
@ -20,7 +20,7 @@ Opaque.SettingsList { // settingsPane
|
|||
|
||||
settings: Column {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 700
|
||||
width: parent.width - 20
|
||||
|
||||
Opaque.Setting {
|
||||
//: Language
|
||||
|
@ -70,8 +70,7 @@ Opaque.SettingsList { // settingsPane
|
|||
Opaque.Slider {
|
||||
id: zoomSlider
|
||||
from: 0.5
|
||||
// TODO: find out why > 2.0 halts desktop app on load - task: fix all the qml anchor/layout warnings on load
|
||||
to: gcd.os == "android" ? 4.0 : 1.9
|
||||
to: 4.0
|
||||
value: gcd.themeScale
|
||||
live: false
|
||||
snapMode: Slider.SnapAlways
|
||||
|
@ -158,8 +157,6 @@ Opaque.SettingsList { // settingsPane
|
|||
target: gcd
|
||||
|
||||
onSupplySettings: function(locale, zoom, theme) {
|
||||
if (zoom != "") zoomSlider.value = zoom
|
||||
|
||||
for (var i=0; i < cbLangItems.count; i++) {
|
||||
var item = cbLangItems.get(i)
|
||||
if (item["value"] == locale) {
|
||||
|
|
|
@ -56,7 +56,7 @@ ColumnLayout {
|
|||
//: ex: "... paste an address here to add a contact ..."
|
||||
//placeholderText: qsTr("paste-address-to-add-contact")
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
icon: gcd.assetPath + "core/search-24px.svg"
|
||||
icon: gcd.assetPath + "core/search-24px.webp"
|
||||
|
||||
|
||||
onTextChanged: {
|
||||
|
|
|
@ -76,7 +76,7 @@ Opaque.PortraitRow {
|
|||
spacing: 16 * gcd.themeScale
|
||||
|
||||
Opaque.Icon {
|
||||
source: gcd.assetPath + "core/favorite-24px.svg"
|
||||
source: gcd.assetPath + "core/favorite-24px.webp"
|
||||
iconColor: Theme.toolbarIconColor
|
||||
backgroundColor: rowColor
|
||||
height: 18 * gcd.themeScale
|
||||
|
@ -86,7 +86,7 @@ Opaque.PortraitRow {
|
|||
}
|
||||
|
||||
Opaque.Icon {
|
||||
source: gcd.assetPath + "core/delete-24px.svg"
|
||||
source: gcd.assetPath + "core/delete-24px.webp"
|
||||
iconColor: Theme.toolbarIconColor
|
||||
backgroundColor: rowColor
|
||||
height: 18 * gcd.themeScale
|
||||
|
|
|
@ -109,25 +109,23 @@ Rectangle {
|
|||
color: parent.color
|
||||
}
|
||||
|
||||
Opaque.EllipsisLabel {
|
||||
Label {
|
||||
id: handle
|
||||
visible: !fromMe && !calendarEvent
|
||||
|
||||
text: displayName
|
||||
|
||||
color: Theme.messageFromOtherTextColor
|
||||
size: Theme.chatSize * gcd.themeScale
|
||||
weight: Font.Bold
|
||||
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: Theme.chatSize * gcd.themeScale
|
||||
font.weight: Font.Bold
|
||||
font.family: Fonts.applicationFontBold.name
|
||||
font.styleName: "Bold"
|
||||
leftPadding: 10 * gcd.themeScale
|
||||
topPadding: 10 * gcd.themeScale
|
||||
|
||||
container: lbl
|
||||
}
|
||||
|
||||
onWidthChanged: { handle.textResize() }
|
||||
|
||||
Column {
|
||||
id: colMessageBubble
|
||||
|
||||
|
@ -176,7 +174,7 @@ Rectangle {
|
|||
|
||||
Image { // ACKNOWLEDGEMENT ICON
|
||||
id: ack
|
||||
source: root.error != "" ? gcd.assetPath + "fontawesome/regular/window-close.svg" : (root.ackd ? gcd.assetPath + "fontawesome/regular/check-circle.svg" : gcd.assetPath + "fontawesome/regular/hourglass.svg")
|
||||
source: root.error != "" ? gcd.assetPath + "core/fontawesome/regular/window-close.webp" : (root.ackd ? gcd.assetPath + "core/fontawesome/regular/check-circle.svg" : gcd.assetPath + "core/fontawesome/regular/hourglass.svg")
|
||||
height: Theme.chatMetaTextSize * gcd.themeScale
|
||||
width: Theme.chatMetaTextSize * gcd.themeScale
|
||||
anchors.bottom: parent.bottom
|
||||
|
|
|
@ -111,7 +111,7 @@ ColumnLayout {
|
|||
text: ""
|
||||
padding: 6 * gcd.themeScale
|
||||
wrapMode: TextEdit.Wrap
|
||||
textFormat: Text.RichText
|
||||
textFormat: Text.PlainText
|
||||
width: rectMessage.width
|
||||
color: Theme.mainTextColor
|
||||
|
||||
|
@ -208,7 +208,7 @@ ColumnLayout {
|
|||
|
||||
Opaque.Icon { // SEND MESSAGE BUTTON
|
||||
id: btnSend
|
||||
source: gcd.assetPath + "core/send-24px.svg"
|
||||
source: gcd.assetPath + "core/send-24px.webp"
|
||||
width: colRight.width
|
||||
height: 50 * gcd.themeScale
|
||||
size: 36 * gcd.themeScale
|
||||
|
@ -219,24 +219,10 @@ ColumnLayout {
|
|||
|
||||
property int nextMessageID: 1
|
||||
|
||||
TextEdit {
|
||||
id: txtHidden
|
||||
visible: false
|
||||
textFormat: Text.RichText
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
// Cannot use .text b/c in rich text mode it is always full of html
|
||||
if (txtMessage.length != 0) {
|
||||
txtHidden.text = restoreEmoji(txtMessage.text)
|
||||
txtHidden.text = txtHidden.text.replace(/<br \/>/g,"[:newline:]");
|
||||
|
||||
var txt = txtHidden.text.trim()
|
||||
if (txt.length > 0) {
|
||||
var rawText = txtHidden.getText(0, txtHidden.text.length)
|
||||
|
||||
root.sendClicked(rawText)
|
||||
}
|
||||
var txt = txtMessage.text.trim()
|
||||
if (txt.length > 0) {
|
||||
root.sendClicked(txt)
|
||||
}
|
||||
txtMessage.text = ""
|
||||
}
|
||||
|
@ -248,7 +234,7 @@ ColumnLayout {
|
|||
|
||||
Opaque.Icon { // EMOJI DRAWER BUTTON
|
||||
id: btnEmoji
|
||||
source: gcd.assetPath + "core/mood-24px.svg"
|
||||
source: gcd.assetPath + "core/mood-24px.webp"
|
||||
|
||||
size: 25
|
||||
height: 36 * gcd.themeScale
|
||||
|
@ -263,7 +249,7 @@ ColumnLayout {
|
|||
|
||||
Opaque.Icon {
|
||||
id: btnAttach
|
||||
source: gcd.assetPath + "core/attach_file-24px.svg"
|
||||
source: gcd.assetPath + "core/attach_file-24px.webp"
|
||||
|
||||
size: 25
|
||||
height: 36 * gcd.themeScale
|
||||
|
|
|
@ -31,6 +31,7 @@ Item {
|
|||
onDualPaneChanged: { realignProfile() }
|
||||
|
||||
function realignProfile() {
|
||||
|
||||
if (dualPane) {
|
||||
profile.height = Theme.contactPortraitSize * logscale
|
||||
|
||||
|
@ -89,7 +90,7 @@ Item {
|
|||
|
||||
badgeContent: Image {// Profle Type
|
||||
id: profiletype
|
||||
source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
|
||||
source: tag == "v1-userPassword" ? gcd.assetPath + "core/lock-24px.webp" : gcd.assetPath + "core/lock_open-24px.webp"
|
||||
height: Theme.badgeTextSize * gcd.themeScale
|
||||
width: height
|
||||
}
|
||||
|
@ -105,17 +106,16 @@ Item {
|
|||
id: nameCenter
|
||||
width: name.width + addBtn.width
|
||||
|
||||
Opaque.EllipsisLabel {
|
||||
Label {
|
||||
id: name
|
||||
|
||||
color: Theme.portraitOnlineTextColor
|
||||
size: Theme.usernameSize * gcd.themeScale
|
||||
weight: Font.Bold
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: Theme.usernameSize * gcd.themeScale
|
||||
font.weight: Font.Bold
|
||||
font.family: Fonts.applicationFontExtraBold.name
|
||||
font.styleName: "ExtraBold"
|
||||
text: nick
|
||||
extraPadding: addBtn.width + 30
|
||||
container: nameRow
|
||||
}
|
||||
|
||||
Opaque.Button { // Add Button
|
||||
|
@ -124,7 +124,7 @@ Item {
|
|||
anchors.left: name.right
|
||||
anchors.top: name.top
|
||||
|
||||
icon: "solid/plus"
|
||||
icon: "fontawesome/solid/plus"
|
||||
|
||||
height: name.height
|
||||
width: height
|
||||
|
|
|
@ -93,6 +93,17 @@ ColumnLayout {
|
|||
image: _image
|
||||
tag: _tag
|
||||
Layout.fillWidth: true
|
||||
rowClicked: function(handle) {
|
||||
gcd.broadcast("ResetMessagePane");
|
||||
gcd.broadcast("ResetProfile");
|
||||
gcd.selectedProfile = handle;
|
||||
gcd.loadProfile(handle);
|
||||
parentStack.pane = parentStack.profilePane;
|
||||
}
|
||||
editClicked: function(handle, displayName, tag, image) {
|
||||
profileAddEditPane.load(handle, displayName, tag, image);
|
||||
parentStack.pane = parentStack.addEditProfilePane;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +112,7 @@ ColumnLayout {
|
|||
handle: ""
|
||||
displayName: qsTr("add-new-profile-btn")
|
||||
nameColor: Theme.mainTextColor
|
||||
image: "/core/account_circle-24px_negative_space.svg" //"/fontawesome/regular/user.svg"
|
||||
image: "/core/account_circle-24px_negative_space.webp"
|
||||
tag: ""
|
||||
portraitBorderColor: Theme.defaultButtonColor
|
||||
portraitColor: Theme.defaultButtonColor
|
||||
|
@ -109,7 +120,7 @@ ColumnLayout {
|
|||
portraitPerformTransform: true
|
||||
badgeVisible: true
|
||||
badgeContent: Image {
|
||||
source: gcd.assetPath + "/fontawesome/solid/plus.svg"
|
||||
source: gcd.assetPath + "core/fontawesome/solid/plus.webp"
|
||||
height: Theme.badgeTextSize * gcd.themeScale
|
||||
width: height
|
||||
}
|
||||
|
|
|
@ -11,55 +11,53 @@ import "../opaque" as Opaque
|
|||
import "../opaque/styles"
|
||||
import "../opaque/theme"
|
||||
|
||||
Opaque.PortraitRow {
|
||||
RowLayout {
|
||||
id: root
|
||||
badgeColor: Theme.portraitProfileBadgeColor
|
||||
property alias handle: prow.handle
|
||||
property alias displayName: prow.displayName
|
||||
property alias image: prow.image
|
||||
property alias tag: prow.tag
|
||||
property alias badgeColor: prow.badgeColor
|
||||
property var rowClicked: {}
|
||||
property var editClicked: {}
|
||||
|
||||
portraitBorderColor: Theme.portraitOnlineBorderColor
|
||||
portraitColor: Theme.portraitOnlineBackgroundColor
|
||||
nameColor: Theme.portraitOnlineTextColor
|
||||
onionColor: Theme.portraitOnlineTextColor
|
||||
Opaque.PortraitRow {
|
||||
id: prow
|
||||
badgeColor: Theme.portraitProfileBadgeColor
|
||||
Layout.fillWidth: true
|
||||
portraitBorderColor: Theme.portraitOnlineBorderColor
|
||||
portraitColor: Theme.portraitOnlineBackgroundColor
|
||||
nameColor: Theme.portraitOnlineTextColor
|
||||
onionColor: Theme.portraitOnlineTextColor
|
||||
|
||||
badgeContent: Image {// Profle Type
|
||||
id: profiletype
|
||||
source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
|
||||
height: Theme.badgeTextSize * gcd.themeScale
|
||||
width: height
|
||||
badgeContent: Image {// Profle Type
|
||||
id: profiletype
|
||||
source: tag == "v1-userPassword" ? gcd.assetPath + "core/lock-24px.webp" : gcd.assetPath + "core/lock_open-24px.webp"
|
||||
height: Theme.badgeTextSize * gcd.themeScale
|
||||
width: height
|
||||
}
|
||||
|
||||
onClicked: rowClicked(handle)
|
||||
}
|
||||
|
||||
Opaque.Icon {// Edit BUTTON
|
||||
id: btnEdit
|
||||
source: gcd.assetPath + "core/edit-24px.svg"
|
||||
|
||||
backgroundColor: root.color
|
||||
source: gcd.assetPath + "core/edit-24px.webp"
|
||||
Layout.minimumWidth: 80
|
||||
Layout.fillHeight: true
|
||||
backgroundColor: Theme.backgroundMainColor
|
||||
hilightBackgroundColor: Theme.backgroundHilightElementColor
|
||||
iconColor: Theme.altTextColor
|
||||
|
||||
anchors.right: parent.right
|
||||
|
||||
//rectUnread.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: 1 * gcd.themeScale
|
||||
anchors.rightMargin: 20 * gcd.themeScale
|
||||
// Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
height: parent.height * 0.5
|
||||
width: parent.height * 0.5
|
||||
size: parent.height * 0.5
|
||||
|
||||
onClicked: {
|
||||
profileAddEditPane.load(handle, displayName, tag, image)
|
||||
parentStack.pane = parentStack.addEditProfilePane
|
||||
}
|
||||
height: root.height / 2
|
||||
width: root.height / 2
|
||||
size: root.height / 2
|
||||
|
||||
onHover: function (hover) {
|
||||
root.isHover = hover
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: function openClick(handle) {
|
||||
gcd.broadcast("ResetMessagePane");
|
||||
gcd.broadcast("ResetProfile");
|
||||
gcd.selectedProfile = handle
|
||||
gcd.loadProfile(handle)
|
||||
parentStack.pane = parentStack.profilePane
|
||||
onClicked: editClicked(handle, displayName, tag, image)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,14 @@ ColumnLayout {
|
|||
autostart: _autostart
|
||||
messages: _messages
|
||||
Layout.fillWidth: true
|
||||
rowClicked: function(handle) {
|
||||
|
||||
}
|
||||
editClicked: function(handle, displayName, tag, image) {
|
||||
gcd.checkServer(handle)
|
||||
serverAddEditPane.load(handle, displayName, status, _autostart, _messages, _bundle)
|
||||
parentStack.pane = parentStack.addEditServerPane
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,13 +109,13 @@ ColumnLayout {
|
|||
handle: ""
|
||||
displayName: qsTr("add-new-profile-btn")
|
||||
nameColor: Theme.mainTextColor
|
||||
image: "/fontawesome/regular/user.svg"
|
||||
image: "core/fontawesome/regular/user.webp"
|
||||
tag: ""
|
||||
portraitBorderColor: Theme.portraitOnlineBorderColor
|
||||
portraitColor: Theme.portraitOnlineBackgroundColor
|
||||
badgeVisible: true
|
||||
badgeContent: Image {
|
||||
source: gcd.assetPath + "/fontawesome/solid/plus.svg"
|
||||
source: gcd.assetPath + "core/fontawesome/solid/plus.webp"
|
||||
height: Theme.badgeTextSize * gcd.themeScale
|
||||
width: height
|
||||
}
|
||||
|
|
|
@ -11,55 +11,13 @@ import "../opaque" as Opaque
|
|||
import "../opaque/styles"
|
||||
import "../opaque/theme"
|
||||
|
||||
Opaque.PortraitRow {
|
||||
ProfileRow {
|
||||
id: root
|
||||
property int status;
|
||||
property string bundle;
|
||||
property bool autostart;
|
||||
property int messages;
|
||||
|
||||
portraitBorderColor: Theme.portraitOnlineBorderColor
|
||||
portraitColor: Theme.portraitOnlineBackgroundColor
|
||||
nameColor: Theme.portraitOnlineTextColor
|
||||
onionColor: Theme.portraitOnlineTextColor
|
||||
property int status
|
||||
property string bundle
|
||||
property bool autostart
|
||||
property int messages
|
||||
|
||||
badgeColor: status == 1 ? Theme.portraitOnlineBadgeColor : Theme.portraitOfflineBadgeColor
|
||||
badgeVisible: true
|
||||
|
||||
Opaque.Icon {// Edit BUTTON
|
||||
id: btnEdit
|
||||
source: gcd.assetPath + "core/edit-24px.svg"
|
||||
|
||||
backgroundColor: root.color
|
||||
iconColor: Theme.altTextColor
|
||||
|
||||
anchors.right: parent.right
|
||||
|
||||
//rectUnread.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: 1 * gcd.themeScale
|
||||
anchors.rightMargin: 20 * gcd.themeScale
|
||||
|
||||
height: parent.height * 0.5
|
||||
width: parent.height * 0.5
|
||||
size: parent.height * 0.5
|
||||
|
||||
onClicked: {
|
||||
gcd.checkServer(handle)
|
||||
serverAddEditPane.load(handle, displayName, status, autostart, messages, bundle)
|
||||
parentStack.pane = parentStack.addEditServerPane
|
||||
}
|
||||
|
||||
onHover: function (hover) {
|
||||
root.isHover = hover
|
||||
gcd.checkServer(handle)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onClicked: function openClick(handle) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO Badge Images
|
||||
}
|
||||
|
|
|
@ -63,9 +63,9 @@ Rectangle {
|
|||
statusbar.color = Theme.statusbarDisconnectedInternetColor
|
||||
statusMessage.color = Theme.statusbarDisconnectedInternetFontColor
|
||||
networkStatus.iconColor = Theme.statusbarDisconnectedInternetFontColor
|
||||
networkStatus.source = gcd.assetPath + "core/signal_cellular_off-24px.svg"
|
||||
networkStatus.source = gcd.assetPath + "core/signal_cellular_off-24px.webp"
|
||||
connectionStatus.iconColor = Theme.statusbarDisconnectedInternetFontColor
|
||||
connectionStatus.source = gcd.assetPath + "core/syncing-03.svg"
|
||||
connectionStatus.source = gcd.assetPath + "core/syncing-03.webp"
|
||||
//: Disconnected from the internet, check your connection
|
||||
statusMessage.text = qsTr("network-status-disconnected")
|
||||
show()
|
||||
|
@ -73,9 +73,9 @@ Rectangle {
|
|||
statusbar.color = Theme.statusbarDisconnectedTorColor
|
||||
statusMessage.color = Theme.statusbarDisconnectedTorFontColor
|
||||
networkStatus.iconColor = Theme.statusbarDisconnectedTorFontColor
|
||||
networkStatus.source = gcd.assetPath + "core/signal_cellular_connected_no_internet_4_bar-24px.svg"
|
||||
networkStatus.source = gcd.assetPath + "core/signal_cellular_connected_no_internet_4_bar-24px.webp"
|
||||
connectionStatus.iconColor = Theme.statusbarDisconnectedTorFontColor
|
||||
connectionStatus.source = gcd.assetPath + "core/syncing-03.svg"
|
||||
connectionStatus.source = gcd.assetPath + "core/syncing-03.webp"
|
||||
//: Attempting to connect to Tor network
|
||||
statusMessage.text = qsTr("network-status-attempting-tor")
|
||||
show()
|
||||
|
@ -83,9 +83,9 @@ Rectangle {
|
|||
statusbar.color = Theme.statusbarConnectingColor
|
||||
statusMessage.color = Theme.statusbarConnectingFontColor
|
||||
networkStatus.iconColor = Theme.statusbarConnectingFontColor
|
||||
networkStatus.source = gcd.assetPath + "core/signal_cellular_connected_no_internet_4_bar-24px.svg"
|
||||
networkStatus.source = gcd.assetPath + "core/signal_cellular_connected_no_internet_4_bar-24px.webp"
|
||||
connectionStatus.iconColor = Theme.statusbarConnectingFontColor
|
||||
connectionStatus.source = gcd.assetPath + "core/syncing-02.svg"
|
||||
connectionStatus.source = gcd.assetPath + "core/syncing-02.webp"
|
||||
//: Connecting...
|
||||
statusMessage.text = qsTr("network-status-connecting")
|
||||
show()
|
||||
|
@ -93,9 +93,9 @@ Rectangle {
|
|||
statusbar.color = Theme.statusbarOnlineColor
|
||||
statusMessage.color = Theme.statusbarOnlineFontColor
|
||||
networkStatus.iconColor = Theme.statusbarOnlineFontColor
|
||||
networkStatus.source = gcd.assetPath + "core/signal_cellular_4_bar-24px.svg"
|
||||
networkStatus.source = gcd.assetPath + "core/signal_cellular_4_bar-24px.webp"
|
||||
connectionStatus.iconColor = Theme.statusbarOnlineFontColor
|
||||
connectionStatus.source = gcd.assetPath + "core/syncing-01.svg"
|
||||
connectionStatus.source = gcd.assetPath + "core/syncing-01.webp"
|
||||
//: Online
|
||||
statusMessage.text = qsTr("network-status-online")
|
||||
hide()
|
||||
|
|
Reference in New Issue