diff --git a/go.mod b/go.mod
index cd49716d..e71241b9 100644
--- a/go.mod
+++ b/go.mod
@@ -4,11 +4,11 @@ go 1.12
require (
cwtch.im/cwtch v0.3.16
- git.openprivacy.ca/openprivacy/connectivity v1.2.0
+ git.openprivacy.ca/openprivacy/connectivity v1.1.4
git.openprivacy.ca/openprivacy/log v1.0.1
github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d // indirect
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41
github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41 // indirect
github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41 // indirect
golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 // indirect
-)
\ No newline at end of file
+)
diff --git a/go.sum b/go.sum
index 12bdad00..127c46e7 100644
--- a/go.sum
+++ b/go.sum
@@ -6,6 +6,8 @@ cwtch.im/cwtch v0.3.14 h1:XL8UbCUyIosdFTD5nSlpvhbQQGFLjvFmd81/SmfBSP8=
cwtch.im/cwtch v0.3.14/go.mod h1:wDmgxWBWak/xvZ5GurdYNOJ8b8eha1MwVdiWsCS/pwI=
cwtch.im/cwtch v0.3.15 h1:Z7fFREwXY728q2YmmwgHL357zAobrsWJ2oPkkGwzvo0=
cwtch.im/cwtch v0.3.15/go.mod h1:iI9q4C3njHFBYQkNEbzMdK6QWPS0Vbkc0FigRHZNTvM=
+cwtch.im/cwtch v0.3.16 h1:4M5So2zRDjy5byzd3G8ZrA2ZWObfm/oSIRfMBIFdOuI=
+cwtch.im/cwtch v0.3.16/go.mod h1:iI9q4C3njHFBYQkNEbzMdK6QWPS0Vbkc0FigRHZNTvM=
cwtch.im/tapir v0.1.15 h1:XSCWOvjmNkzMT2IceFgTBXWGKtYfr3a8o+La1s10OhE=
cwtch.im/tapir v0.1.15/go.mod h1:HzezugpEx+nZ3LdyDsl0w6n45IJYnOt8uqldkLWmaqs=
cwtch.im/tapir v0.1.17 h1:2jVZUe1a88tMI4aJPvRTO4Id3NN3PsM62cT5lntEChk=
diff --git a/go/constants/style.go b/go/constants/style.go
deleted file mode 100644
index 75b5bb4c..00000000
--- a/go/constants/style.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package constants
-
-var TIME_FORMAT = "Mon 3:04pm"
diff --git a/go/ui/gcd.go b/go/ui/gcd.go
index e6b4b229..91bca3d4 100644
--- a/go/ui/gcd.go
+++ b/go/ui/gcd.go
@@ -62,14 +62,14 @@ type GrandCentralDispatcher struct {
_ func(handle, key, value string) `signal:"UpdateContactAttribute"`
// messages pane stuff
- _ func(handle, from, displayName, message, image string, mID string, fromMe bool, ts string, ackd bool, error bool) `signal:"AppendMessage"`
- _ func(handle, from, displayName, message, image string, mID string, fromMe bool, ts string, ackd bool, error bool) `signal:"PrependMessage"`
- _ func() `signal:"ClearMessages"`
- _ func() `signal:"ResetMessagePane"`
- _ func(mID string) `signal:"Acknowledged"`
- _ func(title string) `signal:"SetToolbarTitle"`
- _ func(signature string, err string) `signal:"GroupSendError"`
- _ func(loading bool) `signal:"SetLoadingState"`
+ _ func(handle, from, displayName, message, image string, mID string, fromMe bool, ts int64, ackd bool, error bool) `signal:"AppendMessage"`
+ _ func(handle, from, displayName, message, image string, mID string, fromMe bool, ts int64, ackd bool, error bool) `signal:"PrependMessage"`
+ _ func() `signal:"ClearMessages"`
+ _ func() `signal:"ResetMessagePane"`
+ _ func(mID string) `signal:"Acknowledged"`
+ _ func(title string) `signal:"SetToolbarTitle"`
+ _ func(signature string, err string) `signal:"GroupSendError"`
+ _ func(loading bool) `signal:"SetLoadingState"`
// profile-area stuff
_ func(name, onion, image, tag, showBlocked string) `signal:"UpdateMyProfile"`
@@ -113,8 +113,8 @@ type GrandCentralDispatcher struct {
_ func(onion string) `signal:"deleteContact,auto"`
_ func() `signal:"allowUnknownPeers,auto"`
_ func() `signal:"blockUnknownPeers,auto"`
- _ func(onion string) `signal:"storeHistoryForPeer,auto"`
- _ func(onion string) `signal:"deleteHistoryForPeer,auto"`
+ _ func(onion string) `signal:"storeHistoryForPeer,auto"`
+ _ func(onion string) `signal:"deleteHistoryForPeer,auto"`
_ func() `constructor:"init"`
}
@@ -283,7 +283,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
image,
string(tl[i].Signature),
tl[i].PeerID == the.Peer.GetOnion(),
- tl[i].Timestamp.Format(constants.TIME_FORMAT),
+ tl[i].Timestamp.Unix(),
tl[i].Received.Equal(time.Unix(0, 0)) == false, // If the received timestamp is epoch, we have not yet received this message through an active server
false,
)
@@ -322,7 +322,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
image,
string(messages[i].Signature),
fromMe,
- messages[i].Timestamp.Format(constants.TIME_FORMAT),
+ messages[i].Timestamp.Unix(),
messages[i].Acknowledged,
messages[i].Error != "",
)
@@ -351,7 +351,7 @@ func (this *GrandCentralDispatcher) requestPeerSettings() {
//blockunkownpeers, _ := the.Peer.GetAttribute(attr.GetPeerScope(constants.BlockUnknownPeersSetting))
// Whether Cwtch should save the history of the peer
- saveHistory,exists := contact.GetAttribute(event.SaveHistoryKey)
+ saveHistory, exists := contact.GetAttribute(event.SaveHistoryKey)
if !exists {
saveHistory = event.DeleteHistoryDefault
}
diff --git a/go/ui/manager.go b/go/ui/manager.go
index 87d7fd75..b88f70e1 100644
--- a/go/ui/manager.go
+++ b/go/ui/manager.go
@@ -285,10 +285,10 @@ func (this *manager) AddMessage(handle string, from string, message string, from
updateLastReadTime(handle)
// If the message is not from the user then add it, otherwise, just acknowledge.
if !fromMe {
- this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Format(constants.TIME_FORMAT), false, false)
+ this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Unix(), false, false)
} else {
if !Acknowledged {
- this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Format(constants.TIME_FORMAT), false, false)
+ this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Unix(), false, false)
} else {
this.gcd.Acknowledged(messageID)
}
diff --git a/qml/main.qml b/qml/main.qml
index 6b033d8d..cbf56650 100644
--- a/qml/main.qml
+++ b/qml/main.qml
@@ -204,8 +204,13 @@ ApplicationWindow {
Item { anchors.fill: parent } // empty
- OverlayPane { // messagePane
- anchors.fill: parent
+ Rectangle {
+ color: Theme.backgroundMainColor
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ OverlayPane { // messagePane
+ anchors.fill: parent
+ }
}
@@ -242,13 +247,17 @@ ApplicationWindow {
function updateToolbar() {
- toolbar.hideTitle()
- toolbar.rightMenuVisible = false
+
+
if (currentIndex == splashPane) {
+ toolbar.hideTitle()
+ toolbar.rightMenuVisible = false
toolbar.visible = false
} else {
toolbar.visible = true
if (currentIndex == managementPane) {
+ toolbar.hideTitle()
+ toolbar.rightMenuVisible = false
toolbar.color = Theme.backgroundMainColor
toolbar.leftMenuVisible = true
toolbar.backVisible = false
@@ -257,6 +266,8 @@ ApplicationWindow {
toolbar.backVisible = true
if (currentIndex == profilePane && theStack.currentIndex == theStack.emptyPane) {
+ toolbar.hideTitle()
+ toolbar.rightMenuVisible = false
toolbar.color = Theme.backgroundMainColor
} else {
toolbar.color = Theme.backgroundPaneColor
diff --git a/qml/overlays/BulletinOverlay.qml b/qml/overlays/BulletinOverlay.qml
index 4be09d70..90bf89ce 100644
--- a/qml/overlays/BulletinOverlay.qml
+++ b/qml/overlays/BulletinOverlay.qml
@@ -140,7 +140,7 @@ ColumnLayout {
}
Text {
id: texttitle
- text: '' + Utils.htmlEscaped(title) + ' by ' + from + "
" + timestamp
+ text: '' + Utils.htmlEscaped(title) + ' by ' + from + "
" + Qt.formatDateTime(new Date(timestamp*1000), "MMMM d, h:mm ap")
leftPadding: 10
topPadding: 5
bottomPadding:5
diff --git a/qml/overlays/ChatOverlay.qml b/qml/overlays/ChatOverlay.qml
index 2d0f34a2..e3114a03 100644
--- a/qml/overlays/ChatOverlay.qml
+++ b/qml/overlays/ChatOverlay.qml
@@ -42,9 +42,12 @@ Item {
timestamp: _ts
ackd: _ackd
error: _error
+ calendarEvent: _handle == "calendar"
+ // listview doesnt do anchors right
+ // https://stackoverflow.com/questions/31381997/why-does-anchors-fill-does-not-work-in-a-qml-listviews-delegates-subviews-and/31382307
+ width: messagesListView.width
}
-
Connections {
target: gcd
@@ -62,6 +65,28 @@ Item {
}
if (msg.o != 1) return
+ var date = new Date(ts * 1000);
+ if (messagesModel.count != 0) {
+ var prevDate = new Date(messagesModel.get(messagesModel.count-1)["_ts"] * 1000);
+ if (prevDate.getFullYear() != date.getFullYear()
+ || prevDate.getMonth() != date.getMonth()
+ || prevDate.getUTCDate() != date.getUTCDate()) {
+ console.log("DATES DONT MATCH")
+ messagesModel.append({
+ "_handle": "calendar",
+ "_from": "calendar",
+ "_displayName": "calendar",
+ "_message": Qt.formatDateTime(date, "MMMM dd, yyyy"),
+ "_rawMessage": "",
+ "_image": "",
+ "_mid": "",
+ "_fromMe": false,
+ "_ts": ts,
+ "_ackd": true,
+ "_error": "",
+ })
+ }
+ }
messagesModel.append({
"_handle": handle,
@@ -95,6 +120,28 @@ Item {
}
if (msg.o != 1) return
+ var date = new Date(ts * 1000);
+ if (messagesModel.count != 0) {
+ var prevDate = new Date(messagesModel.get(0)["_ts"] * 1000);
+
+ if (prevDate.getFullYear() != date.getFullYear()
+ || prevDate.getMonth() != date.getMonth()
+ || prevDate.getUTCDate() != date.getUTCDate()) {
+ messagesModel.insert(0, {
+ "_handle": "calendar",
+ "_from": "calendar",
+ "_displayName": "calendar",
+ "_message": Qt.formatDateTime(prevDate, "MMMM dd, yyyy"),
+ "_rawMessage": "",
+ "_image": "",
+ "_mid": "",
+ "_fromMe": false,
+ "_ts": ts,
+ "_ackd": true,
+ "_error": "",
+ })
+ }
+ }
messagesModel.insert(0, {
"_handle": handle,
diff --git a/qml/overlays/ListOverlay.qml b/qml/overlays/ListOverlay.qml
index 444f9696..1393050b 100644
--- a/qml/overlays/ListOverlay.qml
+++ b/qml/overlays/ListOverlay.qml
@@ -172,7 +172,7 @@ ColumnLayout {
RowLayout {
Text {
id: texttitle
- text: '' + Utils.htmlEscaped(title) + ' by ' + displayName + "
" + timestamp
+ text: '' + Utils.htmlEscaped(title) + ' by ' + displayName + "
" + Qt.formatDateTime(new Date(timestamp*1000), "MMMM d, h:mm ap")
leftPadding: 10
topPadding: 5
bottomPadding:5
diff --git a/qml/panes/PeerSettingsPane.qml b/qml/panes/PeerSettingsPane.qml
index 9bd3e755..ad7d0494 100644
--- a/qml/panes/PeerSettingsPane.qml
+++ b/qml/panes/PeerSettingsPane.qml
@@ -53,8 +53,7 @@ Opaque.SettingsList { // settingsPane
dropShadowColor: Theme.dropShadowPaneColor
onClicked: {
gcd.savePeerSettings(txtOnion.text, txtDisplayName.text)
- // TODO: broken
- theStack.title = txtDisplayName.text
+ toolbar.setTitle(txtDisplayName.text)
theStack.pane = theStack.messagePane
}
}
diff --git a/qml/panes/SettingsPane.qml b/qml/panes/SettingsPane.qml
index 35342804..ac11c51f 100644
--- a/qml/panes/SettingsPane.qml
+++ b/qml/panes/SettingsPane.qml
@@ -71,7 +71,8 @@ Opaque.SettingsList { // settingsPane
to: gcd.os == "android" ? 4.0 : 1.9
value: gcd.themeScale
live: false
- stepSize: 0.1
+ snapMode: Slider.SnapAlways
+ stepSize: 0.25
onValueChanged: {
gcd.themeScale = zoomSlider.value
diff --git a/qml/widgets/Message.qml b/qml/widgets/Message.qml
index 10ea3911..f20194e4 100644
--- a/qml/widgets/Message.qml
+++ b/qml/widgets/Message.qml
@@ -6,12 +6,12 @@ import QtQuick.Layouts 1.3
import "../opaque" as Opaque
import "../opaque/controls" as Awesome
+import "../opaque/theme"
+import "../opaque/fonts"
-Item {
+Rectangle {
id: root
- anchors.left: fromMe ? undefined : parent.left
- anchors.right: fromMe ? parent.right : undefined
height: Math.max(imgProfile.height, rectMessageBubble.height)
property string message
@@ -22,9 +22,12 @@ Item {
property string messageID
property bool fromMe
property bool ackd
- property alias timestamp: ts.text
+ property int timestamp
property alias image: imgProfile.source
property string error
+ property bool calendarEvent
+
+ property real logscale: 4 * Math.log10(gcd.themeScale + 1)
Connections {
target: gcd
@@ -42,15 +45,20 @@ Item {
}
}
-
Opaque.Portrait {
id: imgProfile
anchors.left: parent.left
- // TODO: currently unused?
- //handle: root.from
- visible: !fromMe
- //showStatus: false
- //highlight: ima.containsMouse
+ anchors.bottom: parent.bottom
+
+ visible: !fromMe && !calendarEvent
+
+
+ size: fromMe || calendarEvent ? 0 : Theme.contactPortraitSize * 0.5
+ badgeVisible: false
+
+
+ portraitBorderColor: Theme.portraitOnlineBorderColor
+ portraitColor: Theme.portraitOnlineBackgroundColor
ToolTip.visible: ima.containsMouse
//: Click to DM
@@ -75,95 +83,112 @@ Item {
Rectangle { // THIS IS JUST A PRETTY MESSAGE-HOLDING RECTANGLE
id: rectMessageBubble
- height: colMessageBubble.height + 8
+ height: (handle.visible ? handle.height : 0) + (10 * gcd.themeScale) + colMessageBubble.height + 8
width: colMessageBubble.width + 6
- color: fromMe ? "#B09CBC" : "#4B3557"
- radius: 5
+ color: fromMe ? Theme.messageFromMeBackgroundColor : (calendarEvent ? Theme.messageFromOtherBackgroundColor : Theme.messageFromOtherBackgroundColor)
+ radius: 15 * logscale
- // the console will complain constantly about me setting these anchors, but qt only allows margins if they've been set to something
- // a kludge to fix this would be to have spacers before/after and set the widths according to the side they're on ^ea
- anchors.left: fromMe ? undefined : imgProfile.right //parent.left
- anchors.right: fromMe ? parent.right : undefined
- anchors.leftMargin: 5
- anchors.rightMargin: 9
+ anchors.left: fromMe ? undefined : (calendarEvent ? undefined : imgProfile.right) //parent.left
+ anchors.right: fromMe ? (calendarEvent ? undefined : parent.right) : undefined
+ anchors.horizontalCenter: calendarEvent ? parent.horizontalCenter : undefined
+
+ anchors.leftMargin: calendarEvent ? 0 : 5
+ anchors.rightMargin: calendarEvent ? 0 : 9
anchors.topMargin: 5
+ // A sharp corner on the side of the "speaker"
+ Rectangle {
+ id: sharpCorner
+ visible: !calendarEvent
+ height: parent.radius
+ width: parent.radius
- ColumnLayout {
+ anchors.bottom: rectMessageBubble.bottom
+ anchors.left: fromMe ? undefined : parent.left
+ anchors.right: fromMe ? parent.right : undefined
+
+ color: parent.color
+ }
+
+ Opaque.EllipsisLabel {
+ id: handle
+ visible: !fromMe && !calendarEvent
+
+ text: displayName
+
+ color: Theme.messageFromOtherTextColor
+ size: Theme.chatSize * gcd.themeScale
+ 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
+ width: Math.max(lbl.width, ts.width + ack.width + 10)
- Column { // combine these into one element or else childrenRect won't play nicely
- TextEdit { // this is used as a helper to calculate the message box width
- id: dummy
- visible: false
- padding: 6
- leftPadding: 10
- font.pixelSize: gcd.themeScale * 12
- wrapMode: TextEdit.NoWrap
- text: lbl.text
- textFormat: Text.RichText
- }
+ anchors.top: fromMe ? parent.top : (calendarEvent ? parent.top : handle.bottom)
+ anchors.topMargin: 10 * gcd.themeScale
- TextEdit { // this is the actual text display
- id: lbl
- text: parse(message, 12, true)
- color: "#FFFFFF"
- padding: 6
- leftPadding: 10
- font.pixelSize: gcd.themeScale * 12
- selectByMouse: gcd.os != "android"
- readOnly: true
- width: Math.min(dummy.width, root.parent.width - (imgProfile.visible ? imgProfile.width : 0) - 40)
- wrapMode: TextEdit.Wrap
- textFormat: Text.RichText
- }
+ TextEdit { // this is used as a helper to calculate the message box width
+ id: dummy
+ visible: false
+ padding: 6 * gcd.themeScale
+ leftPadding: 10 * gcd.themeScale
+ font.pixelSize: gcd.themeScale * Theme.chatSize
+ wrapMode: TextEdit.NoWrap
+ text: lbl.text
+ textFormat: Text.RichText
}
- RowLayout {
+ TextEdit { // this is the actual text display
+ id: lbl
+ text: parse(message, 12, true)
+ color: fromMe ? Theme.messageFromMeTextColor : Theme.messageFromOtherTextColor
+ padding: 6 * gcd.themeScale
+ leftPadding: 10 * gcd.themeScale
+ font.pixelSize: gcd.themeScale * Theme.chatSize
+ selectByMouse: gcd.os != "android"
+ readOnly: true
+ width: Math.min(dummy.width, root.parent.width - (imgProfile.visible ? imgProfile.width : 0) - 40)
+ wrapMode: TextEdit.Wrap
+ textFormat: Text.RichText
+ }
+
+ Row {
id: rowBottom
- anchors.left: parent.left
anchors.right: parent.right
+ visible: !calendarEvent
-
- Label { // TIMESTAMP
+ Opaque.ScalingLabel { // TIMESTAMP
id: ts
- color: "#FFFFFF"
- font.pixelSize: 10 * gcd.themeScale
- anchors.left: parent.left
- leftPadding: 10
- }
-
- Label { // DISPLAY NAME FOR GROUPS
- color: "#FFFFFF"
- font.pixelSize: 10 * gcd.themeScale
- anchors.right: parent.right
- text: displayName.length > 12 ? displayName.substr(0,12) + "..." : displayName
- visible: !fromMe
- ToolTip.text: from
- ToolTip.visible: ma2.containsMouse
- ToolTip.delay: 200
-
- MouseArea {
- id: ma2
- anchors.fill: parent
- hoverEnabled: true
- }
+ text: Qt.formatDateTime(new Date(root.timestamp*1000), "h:mm ap")
+ color: fromMe ? Theme.messageFromMeTextColor : Theme.messageFromOtherTextColor
+ font.pixelSize: Theme.chatMetaTextSize * gcd.themeScale
+ rightPadding: 10
}
Image { // ACKNOWLEDGEMENT ICON
id: ack
- anchors.right: parent.right
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")
- height: 10 * gcd.themeScale
- sourceSize.height: 10 * gcd.themeScale
+ height: Theme.chatMetaTextSize * gcd.themeScale
+ width: Theme.chatMetaTextSize * gcd.themeScale
+ anchors.bottom: parent.bottom
+
+ sourceSize.height: Theme.chatMetaTextSize * gcd.themeScale
visible: fromMe
ToolTip.visible: ma.containsMouse
ToolTip.delay: 200
//: Could not send this message
ToolTip.text: root.error != "" ? qsTr("could-not-send-msg-error") + ":" + root.error : (root.ackd ? qsTr("acknowledged-label") : qsTr("pending-label"))
-
MouseArea {
id: ma
anchors.fill: parent
diff --git a/qml/widgets/MyProfile.qml b/qml/widgets/MyProfile.qml
index 45f6a348..04750c19 100644
--- a/qml/widgets/MyProfile.qml
+++ b/qml/widgets/MyProfile.qml
@@ -31,10 +31,10 @@ Item {
function realignProfile() {
if (dualPane) {
- profile.height = 78 * logscale
+ profile.height = Theme.contactPortraitSize * logscale
- portrait.baseWidth = 78 * logscale
- portrait.height = 78 * logscale
+ portrait.baseWidth = Theme.contactPortraitSize * logscale
+ portrait.height = Theme.contactPortraitSize * logscale
portrait.anchors.horizontalCenter = undefined
portrait.anchors.left = profile.left
@@ -49,10 +49,9 @@ Item {
nameCenter.anchors.horizontalCenter = undefined
nameCenter.anchors.left = nameRow.left
} else {
- profile.height = (150 * logscale)
+ profile.height = (Theme.contactPortraitSize * 2 * logscale)
- portrait.baseWidth = 100 * logscale
- portrait.height = 100 * logscale
+ portrait.size = Theme.contactPortraitSize * 1.5
portrait.anchors.left = undefined
portrait.anchors.leftMargin = undefined