From db315f8de16a4c20aa9470913ba09f9d76e92192 Mon Sep 17 00:00:00 2001 From: erinn Date: Fri, 9 Oct 2020 11:09:43 -0700 Subject: [PATCH 1/6] message model take one --- Makefile | 2 +- go.mod | 8 +- go.sum | 207 ----------------------------------- go/handlers/peerHandler.go | 7 +- go/the/globals.go | 2 +- go/ui/gcd.go | 30 ++--- go/ui/manager.go | 40 ++++--- main.go | 15 +++ qml/overlays/ChatOverlay.qml | 38 ++++--- qml/widgets/ContactRow.qml | 1 + 10 files changed, 95 insertions(+), 255 deletions(-) delete mode 100644 go.sum diff --git a/Makefile b/Makefile index 6a66eee2..10ca2f16 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ android: linux_build: date - qtdeploy -qt_version "5.13.0" build linux 2>&1 | tee qtdeploy.log | pv + qtdeploy -docker -qt_version "5.13.0" build linux 2>&1 | tee qtdeploy.log | pv date cp -R assets deploy/linux/ $(MAKE) linux_clean diff --git a/go.mod b/go.mod index d66e0dda..72323dbf 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,16 @@ module cwtch.im/ui go 1.12 require ( - cwtch.im/cwtch v0.4.2 + cwtch.im/cwtch v0.4.3 git.openprivacy.ca/openprivacy/connectivity v1.3.1 git.openprivacy.ca/openprivacy/log v1.0.1 + github.com/c-bata/go-prompt v0.2.3 // indirect + github.com/google/go-cmp v0.4.0 // indirect github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d // indirect + github.com/mattn/go-colorable v0.1.6 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-tty v0.0.3 // indirect + github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 // 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 diff --git a/go.sum b/go.sum deleted file mode 100644 index 21f9ac85..00000000 --- a/go.sum +++ /dev/null @@ -1,207 +0,0 @@ -cwtch.im/cwtch v0.3.10 h1:akrIwsc1KnLbT3K6ZIFkhmA7kI62L03EWna7Ul1vszU= -cwtch.im/cwtch v0.3.10/go.mod h1:tmYeI2v0IEeBMbqzhcndXWZ2oyflhK4Afcf27+49rKU= -cwtch.im/cwtch v0.3.11 h1:2+W2w9HDQowKwEGx4oRLywmn0NzQ0Sg9JEyBdR/V1mA= -cwtch.im/cwtch v0.3.11/go.mod h1:PnMJb9CyzdrdbYjmL99pl6Nu34s6+lmeENVnGaY0hzk= -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/cwtch v0.4.0 h1:lhGQiYRBqSF0Pif9QttYVL4B1Oy1vc0v3cZejL7c7x4= -cwtch.im/cwtch v0.4.0/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI= -cwtch.im/cwtch v0.4.1 h1:wjf/3Vw5fDByEwwnXqWrPtpKsXTLk0oz0PqNGYcR+MQ= -cwtch.im/cwtch v0.4.1/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI= -cwtch.im/cwtch v0.4.2 h1:qIjTOwKkBf1tIsat27gXPriXSZXtKcTJ8Sf7E/2+GXc= -cwtch.im/cwtch v0.4.2/go.mod h1:10gBkMSqAH95Pz4jTx5mpIHE+dkn+4kRC4BFTxWuQK8= -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= -cwtch.im/tapir v0.1.17/go.mod h1:HzezugpEx+nZ3LdyDsl0w6n45IJYnOt8uqldkLWmaqs= -cwtch.im/tapir v0.1.18 h1:Fs/jL9ZRyel/A1D/BYzIPEVQau8y5BJg44yA+GQDbSM= -cwtch.im/tapir v0.1.18/go.mod h1:/IrAI6CBHfgzsfgRT8WHVb1P9fCCz7+45hfsdkKn8Zg= -cwtch.im/tapir v0.2.0 h1:7MkoR5+uEuPW34/O0GZRidnIjq/01Cfm8nl5IRuqpGc= -cwtch.im/tapir v0.2.0/go.mod h1:xzzZ28adyUXNkYL1YodcHsAiTt3IJ8Loc29YVn9mIEQ= -git.openprivacy.ca/openprivacy/bine v0.0.3 h1:PSHUmNqaW7BZUX8n2eTDeNbjsuRe+t5Ae0Og+P+jDM0= -git.openprivacy.ca/openprivacy/bine v0.0.3/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLyqtXc46XBcnuXm/mU= -git.openprivacy.ca/openprivacy/connectivity v1.1.0/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= -git.openprivacy.ca/openprivacy/connectivity v1.1.1 h1:hKxBOmxP7Jdu3K1BJ93mRtKNiWUoP6YHt/o2snE2Z0w= -git.openprivacy.ca/openprivacy/connectivity v1.1.1/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= -git.openprivacy.ca/openprivacy/connectivity v1.1.2 h1:Bk8ul3+4/awpQGvskfLpp7/K3Lj8OAxBwlmQqeZy3Ok= -git.openprivacy.ca/openprivacy/connectivity v1.1.2/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= -git.openprivacy.ca/openprivacy/connectivity v1.1.3 h1:iRGHS8RB4SZ9cjYK/yXt4R8PqQDVwwYJZ3iqe+w3IPE= -git.openprivacy.ca/openprivacy/connectivity v1.1.3/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= -git.openprivacy.ca/openprivacy/connectivity v1.1.4 h1:/I9epvNNjM8rR/q5y9Y63D9/aPXpBFvngwNGLD8mvUk= -git.openprivacy.ca/openprivacy/connectivity v1.1.4/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= -git.openprivacy.ca/openprivacy/connectivity v1.2.0 h1:dbZ5CRl11vg3BNHdzRKSlDP8OUtDB+mf6FkxMVf73qw= -git.openprivacy.ca/openprivacy/connectivity v1.2.0/go.mod h1:B7vzuVmChJtSKoh0ezph5vu6DQ0gIk0zHUNG6IgXCcA= -git.openprivacy.ca/openprivacy/connectivity v1.2.1 h1:oRL56TR9ZQnKkGkTIQ9wYbJ2IkOOsi/zLYExYiAS+sE= -git.openprivacy.ca/openprivacy/connectivity v1.2.1/go.mod h1:B7vzuVmChJtSKoh0ezph5vu6DQ0gIk0zHUNG6IgXCcA= -git.openprivacy.ca/openprivacy/connectivity v1.2.2 h1:CeuZB469xHMHxygxZD559CkRUAGR7ct4oeSlsAHQmKo= -git.openprivacy.ca/openprivacy/connectivity v1.2.2/go.mod h1:B7vzuVmChJtSKoh0ezph5vu6DQ0gIk0zHUNG6IgXCcA= -git.openprivacy.ca/openprivacy/connectivity v1.3.0 h1:e2EeV6CaMNwOb+PzAjF0hGCeOqAPagRaDL4en5ITf7U= -git.openprivacy.ca/openprivacy/connectivity v1.3.0/go.mod h1:s0/QhONuUqJQfYTAgUlu+ya7G3Ov6bKgpT5QkOhVxDI= -git.openprivacy.ca/openprivacy/libricochet-go v1.0.11 h1:C7QFFzG0p5XKu0zcOIdLGwEpA9uU0BceBM7CfVK5D40= -git.openprivacy.ca/openprivacy/libricochet-go v1.0.11/go.mod h1:yTMps/ZpYS+BNBBvANsNAft28FXrBvFHQauMYNWPrwE= -git.openprivacy.ca/openprivacy/libricochet-go v1.0.13 h1:Z86uL9K47onznY1wP1P/wWfWMbbyvk6xnCp94R180os= -git.openprivacy.ca/openprivacy/libricochet-go v1.0.13/go.mod h1:ZUuX1SOrgV4K18IEcp0hQJNPKszRr2oGb3UeK2iYe5U= -git.openprivacy.ca/openprivacy/log v1.0.0 h1:Rvqm1weUdR4AOnJ79b1upHCc9vC/QF1rhSD2Um7sr1Y= -git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= -git.openprivacy.ca/openprivacy/log v1.0.1 h1:NWV5oBTatvlSzUE6wtB+UQCulgyMOtm4BXGd34evMys= -git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= -github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI= -github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= -github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca h1:Q2r7AxHdJwWfLtBZwvW621M3sPqxPc6ITv2j1FGsYpw= -github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de h1:F7WD09S8QB4LrkEpka0dFPLSotH11HRpCsLIbIcJ7sU= -github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d h1:vr95xIx8Eg3vCzZPxY3rCwTfkjqNDt/FgVqTOk0WByk= -github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= -github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= -github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -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/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= -github.com/therecipe/qt v0.0.0-20191101232336-18864661ae4f h1:06ICDSmDOBUC9jwgv44ngvyHzwudJNLa5H+rbCyDFRY= -github.com/therecipe/qt v0.0.0-20191101232336-18864661ae4f/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us= -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/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-20191002095216-73192f6811d0/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4= -github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20191101232336-18864661ae4f h1:NLmalUtBOLr8mUB1/um4PO1KAx66AXlQF/lkrg5vTek= -github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20191101232336-18864661ae4f/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4= -github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41 h1:jTzKrQ6EIPvKw1B9/wwoKJLrXF+ManMsXoUzufxAdsg= -github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= -go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 h1:+ELyKg6m8UBf0nPFSqD0mi7zUfwPyXo23HNjMnXPz7w= -golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a h1:aczoJ0HPNE92XKa7DrIzkNN6esOKO2TBwiiYoKcINhA= -golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200210191831-6ca56c2f2e2b/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200210222208-86ce3cb69678 h1:wCWoJcFExDgyYx2m2hpHgwz8W3+FPdfldvIgzqDIhyg= -golang.org/x/crypto v0.0.0-20200210222208-86ce3cb69678/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200320181102-891825fb96df h1:lDWgvUvNnaTnNBc/dwOty86cFeKoKWbwy2wQj0gIxbU= -golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 h1:IhZPbxNd1UjBCaD5AfpSSbJTRlp+ZSuyuH5uoksNS04= -golang.org/x/crypto v0.0.0-20200420104511-884d27f42877/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI= -golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200320181208-1c781a10960a h1:KaxWXSFrOaE2ptiOotI+zFdzHxBsg9MW6XfCv497IRo= -golang.org/x/net v0.0.0-20200320181208-1c781a10960a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a h1:XCr/YX7O0uxRkLq2k1ApNQMims9eCioF9UpzIPBDmuo= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200320181252-af34d8274f85 h1:fD99hd4ciR6T3oPhr2EkmuKe9oHixHx9Hj/hND89j3g= -golang.org/x/sys v0.0.0-20200320181252-af34d8274f85/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789 h1:FF0rjo15h51+N6642mf5S3QuplmKo2aCrJUYkHTx85s= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200420001825-978e26b7c37c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go/handlers/peerHandler.go b/go/handlers/peerHandler.go index 0c48162e..4210616c 100644 --- a/go/handlers/peerHandler.go +++ b/go/handlers/peerHandler.go @@ -54,7 +54,12 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) { case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampReceived]) - uiManager.AddMessage(e.Data[event.RemotePeer], e.Data[event.RemotePeer], e.Data[event.Data], false, e.EventID, ts, true) + //uiManager.AddMessage(e.Data[event.RemotePeer], e.Data[event.RemotePeer], e.Data[event.Data], false, e.EventID, ts, true) + uiManager.AboutToAddMessage() + //time.Sleep(time.Millisecond) + peer.StoreMessage(e.Data[event.RemotePeer], e.Data[event.Data], ts) + uiManager.MessageJustAdded() + case event.PeerAcknowledgement: uiManager.Acknowledge(e.Data[event.EventID]) diff --git a/go/the/globals.go b/go/the/globals.go index 5ad7e9c2..99f211e5 100644 --- a/go/the/globals.go +++ b/go/the/globals.go @@ -8,7 +8,7 @@ import ( "git.openprivacy.ca/openprivacy/connectivity" ) -// Terrible, to be replaced when proper profile/password management comes in ~ 0.2 +// really awesome but nevertheless to be replaced when proper profile/password management comes in ~ 0.2 const AppPassword = "be gay do crime" var CwtchApp app.Application diff --git a/go/ui/gcd.go b/go/ui/gcd.go index 41f327b0..b317d85b 100644 --- a/go/ui/gcd.go +++ b/go/ui/gcd.go @@ -28,6 +28,7 @@ type GrandCentralDispatcher struct { Translator, OpaqueTranslator *core.QTranslator uIManagers map[string]Manager // profile-onion : Manager + TimelineInterface *MessageModel GlobalSettings *GlobalSettings @@ -39,7 +40,7 @@ type GrandCentralDispatcher struct { _ string `property:"os"` _ float32 `property:"themeScale,auto,changed"` - _ string `property:"theme,auto,changed` + _ string `property:"theme,auto,changed"` _ string `property:"locale,auto,changed"` _ string `property:"version"` _ string `property:"buildDate"` @@ -95,7 +96,7 @@ type GrandCentralDispatcher struct { _ func(password string) `signal:"unlockProfiles,auto"` _ func() `signal:"reloadProfileList,auto"` _ func(onion string) `signal:"deleteProfile,auto"` - _ func(onion, currentPassword, newPassword string, defaultPass bool) `signal:"changePassword,auto""` + _ func(onion, currentPassword, newPassword string, defaultPass bool) `signal:"changePassword,auto"` _ func(key, val string) `signal:"storeSetting,auto"` // operating a profile _ func(message string) `signal:"sendMessage,auto"` @@ -233,9 +234,12 @@ func (this *GrandCentralDispatcher) sendMessage(message string) { } } else { to := this.SelectedConversation() - mID := the.Peer.SendMessageToPeer(to, message) + prenum := this.TimelineInterface.num() + this.TimelineInterface.AddMessage(prenum) + /*mID := */the.Peer.SendMessageToPeer(to, message) + this.TimelineInterface.RequestEIR() - this.GetUiManager(this.selectedProfile()).AddMessage(to, "me", message, true, mID, time.Now(), false) + //this.GetUiManager(this.selectedProfile()).AddMessage(to, "me", message, true, mID, time.Now(), false) } } @@ -263,7 +267,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { this.requestGroupSettings(handle) tl := group.GetTimeline() - nick := getNick(handle) + nick := GetNick(handle) updateLastReadTime(group.GroupID) if nick == "" { this.SetToolbarTitle(handle) @@ -281,8 +285,8 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { handle = tl[i].PeerID } - name := getNick(tl[i].PeerID) - image := getProfilePic(tl[i].PeerID) + name := GetNick(tl[i].PeerID) + image := GetProfilePic(tl[i].PeerID) this.PrependMessage( handle, @@ -309,7 +313,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { var nick string if contact != nil { - nick = getNick(contact.Onion) + nick = GetNick(contact.Onion) } updateLastReadTime(contact.Onion) this.SetToolbarTitle(nick) @@ -323,8 +327,8 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { from = "me" } - displayname := getNick(messages[i].PeerID) - image := getProfilePic(messages[i].PeerID) + displayname := GetNick(messages[i].PeerID) + image := GetProfilePic(messages[i].PeerID) this.AppendMessage( from, @@ -357,7 +361,7 @@ func (this *GrandCentralDispatcher) requestPeerSettings(handle string) { return } - name := getNick(contact.Onion) + name := GetNick(contact.Onion) // Todo: Move to profile settings //blockunkownpeers, _ := the.Peer.GetAttribute(attr.GetPeerScope(constants.BlockUnknownPeersSetting)) @@ -417,13 +421,13 @@ func (this *GrandCentralDispatcher) requestGroupSettings(groupID string) { return } - nick := getNick(groupID) + nick := GetNick(groupID) invite, _ := the.Peer.ExportGroup(groupID) contactaddrs := the.Peer.GetContacts() contactnames := make([]string, len(contactaddrs)) for i, contact := range contactaddrs { - contactnames[i] = getNick(contact) + contactnames[i] = GetNick(contact) } this.SupplyGroupSettings(group.GroupID, nick, group.GroupServer, invite, group.Accepted, contactnames, contactaddrs) status := connections.ConnectionStateToType[group.State] diff --git a/go/ui/manager.go b/go/ui/manager.go index 6e991606..ff4db305 100644 --- a/go/ui/manager.go +++ b/go/ui/manager.go @@ -62,7 +62,7 @@ func getWithSetDefault(id string, key string, defaultVal string) string { return val } -func getNick(id string) string { +func GetNick(id string) string { if isGroup(id) { nick, exists := the.Peer.GetGroupAttribute(id, attr.GetLocalScope(constants.Name)) if !exists || nick == "" { @@ -100,8 +100,8 @@ func profilePicRelativize(filename string) string { return parts[len(parts)-1] } -// getProfilePic returns a string path to an image to display for hte given peer/group id -func getProfilePic(id string) string { +// GetProfilePic returns a string path to an image to display for hte given peer/group id +func GetProfilePic(id string) string { if isGroup(id) { if picVal, exists := the.Peer.GetGroupAttribute(id, attr.GetLocalScope(constants.Picture)); exists { pic, err := StringToImage(picVal) @@ -215,6 +215,9 @@ type Manager interface { UpdateContactAttribute(handle, key, value string) ChangePasswordResponse(error bool) + + AboutToAddMessage() + MessageJustAdded() } // NewManager returns a new Manager interface for a profile to the gcd @@ -246,9 +249,9 @@ func (this *manager) AddContact(handle string) { if group != nil { lastRead := initLastReadTime(group.GroupID) unread := countUnread(group.Timeline.GetMessages(), lastRead) - picture := getProfilePic(handle) + picture := GetProfilePic(handle) - this.gcd.AddContact(handle, getNick(handle), picture, unread, int(connections.ConnectionStateToType[group.State]), string(model.AuthApproved), false, getLastMessageTime(&group.Timeline)) + this.gcd.AddContact(handle, GetNick(handle), picture, unread, int(connections.ConnectionStateToType[group.State]), string(model.AuthApproved), false, getLastMessageTime(&group.Timeline)) } return } else if !isPeer(handle) { @@ -261,9 +264,9 @@ func (this *manager) AddContact(handle string) { if contact != nil { lastRead := initLastReadTime(contact.Onion) unread := countUnread(contact.Timeline.GetMessages(), lastRead) - picture := getProfilePic(handle) + picture := GetProfilePic(handle) - this.gcd.AddContact(handle, getNick(handle), picture, unread, int(connections.ConnectionStateToType[contact.State]), string(contact.Authorization), false, getLastMessageTime(&contact.Timeline)) + this.gcd.AddContact(handle, GetNick(handle), picture, unread, int(connections.ConnectionStateToType[contact.State]), string(contact.Authorization), false, getLastMessageTime(&contact.Timeline)) } }) } @@ -280,22 +283,33 @@ func (this *manager) AddSendMessageError(peer string, signature string, err stri }) } +func (this *manager) AboutToAddMessage() { + this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) +} + +func (this *manager) MessageJustAdded() { + this.gcd.TimelineInterface.RequestEIR() +} + // AddMessage adds a message to the message pane for the supplied conversation if it is active func (this *manager) AddMessage(handle string, from string, message string, fromMe bool, messageID string, timestamp time.Time, Acknowledged bool) { + log.Errorf("uiManager.AddMessage(...) uhhhh???? NO ZOOP ZEEP") this.gcd.DoIfProfile(this.profile, func() { - nick := getNick(handle) - image := getProfilePic(handle) + //nick := GetNick(handle) + //image := GetProfilePic(handle) // If we have this group loaded already this.gcd.DoIfConversation(handle, func() { 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.Unix(), false, false) + this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) + //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.Unix(), false, false) + this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) + //this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Unix(), false, false) } else { this.gcd.Acknowledged(messageID) } @@ -312,14 +326,14 @@ func (this *manager) ReloadProfiles() { // UpdateContactDisplayName updates a contact's display name in the contact list and conversations func (this *manager) UpdateContactDisplayName(handle string) { this.gcd.DoIfProfile(this.profile, func() { - this.gcd.UpdateContactDisplayName(handle, getNick(handle)) + this.gcd.UpdateContactDisplayName(handle, GetNick(handle)) }) } // UpdateContactPicture updates a contact's picture in the contact list and conversations func (this *manager) UpdateContactPicture(handle string) { this.gcd.DoIfProfile(this.profile, func() { - this.gcd.UpdateContactPicture(handle, getProfilePic(handle)) + this.gcd.UpdateContactPicture(handle, GetProfilePic(handle)) }) } diff --git a/main.go b/main.go index 52fab245..2fbea2c5 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,8 @@ package main import ( "crypto/rand" libapp "cwtch.im/cwtch/app" + "cwtch.im/cwtch/event" + "cwtch.im/cwtch/peer" "cwtch.im/cwtch/event/bridge" "cwtch.im/ui/go/handlers" os2 "cwtch.im/ui/go/os" @@ -40,6 +42,16 @@ func init() { } func main() { + peer.DefaultEventsToHandle = []event.Type{ + event.EncryptedGroupMessage, + //event.NewMessageFromPeer, + event.PeerAcknowledgement, + event.NewGroupInvite, + event.PeerError, + event.SendMessageToGroupError, + event.NewGetValMessageFromPeer, + } + if runtime.GOOS == "windows" { filelogger, err := log.NewFile(log.LevelInfo, "cwtch_log.txt") if err == nil { @@ -200,6 +212,9 @@ func mainUi(flagLocal bool, flagClientUI bool) { engine.SetNetworkAccessManagerFactory(factory) engine.RootContext().SetContextProperty("gcd", gcd) + gcd.TimelineInterface = ui.NewMessageModel(nil) + gcd.TimelineInterface.SetHandle("66b46c88c1475de1819af2a95d39548d") + engine.RootContext().SetContextProperty("mm", gcd.TimelineInterface) var androidCwtchActivity = android.NewCwtchActivity(nil) engine.RootContext().SetContextProperty("androidCwtchActivity", androidCwtchActivity) diff --git a/qml/overlays/ChatOverlay.qml b/qml/overlays/ChatOverlay.qml index cb1bce3c..1629f699 100644 --- a/qml/overlays/ChatOverlay.qml +++ b/qml/overlays/ChatOverlay.qml @@ -8,10 +8,10 @@ import "../opaque" as Opaque import "../opaque/controls" as Awesome import "../opaque/fonts/Twemoji.js" as T import "../utils.js" as Utils -import "../widgets" +import "../widgets" as W import "../opaque/theme" -Overlay { +W.Overlay { property bool loading //horizontalPadding: 15 * gcd.themeScale @@ -28,26 +28,26 @@ Overlay { Layout.fillWidth: true width: parent.width - model: messagesModel + model: mm//messagesModel// spacing: 6 clip: true ScrollBar.vertical: Opaque.ScrollBar {} maximumFlickVelocity: 1250 - delegate: Message { - handle: _handle - from: _from - displayName: _displayName - message: _message - rawMessage: _rawMessage - image: _image - messageID: _mid - fromMe: _fromMe - timestamp: _ts - ackd: _ackd - error: _error - calendarEvent: _handle == "calendar" + delegate: W.Message { + handle: PeerID + from: PeerID + displayName: mm.getNick(PeerID) + message: JSON.parse(RawMessage).d + rawMessage: RawMessage + image: mm.getImage(PeerID) + messageID: "-1"//_mid + fromMe: PeerID == gcd.SelectedProfile + timestamp: parseInt(Timestamp) + ackd: Acknowledged + error: Error + calendarEvent: PeerID == "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 @@ -58,9 +58,12 @@ Overlay { onClearMessages: function() { messagesModel.clear() + messagesListView.model = null + messagesListView.model = mm } onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ackd, error) { + return var msg try { msg = JSON.parse(message) @@ -116,6 +119,7 @@ Overlay { } onPrependMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ackd, error) { + return var msg try { msg = JSON.parse(message) @@ -171,8 +175,6 @@ Overlay { var msg = JSON.stringify({"o":1, "d":messageText.replace(/\[\:newline\:\]/g,"\n")}) gcd.sendMessage(msg) } - - } diff --git a/qml/widgets/ContactRow.qml b/qml/widgets/ContactRow.qml index 4eceb291..5f2dfaab 100644 --- a/qml/widgets/ContactRow.qml +++ b/qml/widgets/ContactRow.qml @@ -98,6 +98,7 @@ Opaque.PortraitRow { gcd.broadcast("ResetMessagePane") isActive = true theStack.pane = theStack.messagePane + mm.setHandle(handle) gcd.loadMessagesPane(handle) badge = 0 } From 7398bec25b673be54586405b985fdef605c3bc3a Mon Sep 17 00:00:00 2001 From: erinn Date: Fri, 9 Oct 2020 11:10:03 -0700 Subject: [PATCH 2/6] message model take one --- go/ui/messagemodel.go | 214 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 go/ui/messagemodel.go diff --git a/go/ui/messagemodel.go b/go/ui/messagemodel.go new file mode 100644 index 00000000..5d0735d1 --- /dev/null +++ b/go/ui/messagemodel.go @@ -0,0 +1,214 @@ +package ui + +import ( + "cwtch.im/cwtch/model" + "cwtch.im/ui/go/the" + "git.openprivacy.ca/openprivacy/log" + "github.com/therecipe/qt/core" + "reflect" + "strings" +) + +type MessageModel struct { + core.QAbstractTableModel + + handle string + //_ string `property:"handle,auto"` + _ func(string) `signal:"setHandle,auto"` + + _ map[int]*core.QByteArray `property:"roles"` + _ func() `constructor:"init"` + + _ func(int) `signal:"addMessage,auto"` + _ func(string) `signal:"createLocalFormEntry,auto"` + _ func() `signal:"requestEIR,auto"` // request this.EndInsertRecord() on gui thread + + _ func(string) string `slot:"getNick,auto"` + _ func(string) string `slot:"getImage,auto"` +} + +type MessageWrapper struct { + model.Message + core.QObject + + Timestamp int64 + PeerID string + Acknowledged bool + RawMessage string + Error string + _ bool `property:"ackd"` +} + +func (this *MessageModel) Handle() string{ + return this.handle +} + +func (this *MessageModel) setHandle(handle string) { + this.handle = handle +} + + +func (this *MessageModel) init() { + //mdt := reflect.TypeOf([]model.Message{}).Elem() + mdt := reflect.TypeOf([]MessageWrapper{}).Elem() + roles := make(map[int]*core.QByteArray) + for i := 0; i < mdt.NumField(); i++ { + roles[int(core.Qt__UserRole) + 1 + i] = core.NewQByteArray2(mdt.Field(i).Name, -1) + } + roles[int(core.Qt__DisplayRole)] = core.NewQByteArray2("display", -1) + this.SetRoles(roles) + + this.ConnectData(this.data) + this.ConnectRowCount(this.rowCount) + this.ConnectColumnCount(this.columnCount) + this.ConnectHeaderData(this.headerData) + this.ConnectRoleNames(this.roleNames) +} + +func (this *MessageModel) roleNames() map[int]*core.QByteArray { + return this.Roles() +} + +func (this *MessageModel) isGroup() bool { + return len(this.Handle()) == 32 +} + +func (this *MessageModel) getNick(handle string) string { + return GetNick(handle) +} + +func (this *MessageModel) getImage(handle string) string { + return GetProfilePic(handle) +} + +func (this *MessageModel) num() int { + if this.Handle() == "" || the.Peer == nil { + log.Debugf("num: early returning 0") + return 0 + } + + if this.isGroup() { + group := the.Peer.GetGroup(this.Handle()) + if group != nil { + return len(group.Timeline.Messages) + len(group.UnacknowledgedMessages) + } + } else { + contact := the.Peer.GetContact(this.Handle()) + if contact != nil { + log.Debugf("num: returning %v", len(contact.Timeline.Messages)) + return len(contact.Timeline.Messages) + } + } + + log.Warnf("group/contact was nil, returning 0") + return 0 +} + +func (this *MessageModel) getMessage(idx int) *MessageWrapper { + log.Infof("MessageModel.getMessage(%v)", idx) + + var modelmsg model.Message + + if this.isGroup() { + group := the.Peer.GetGroup(this.Handle()) + if idx >= len(group.Timeline.Messages) { + modelmsg = group.UnacknowledgedMessages[idx - len(group.Timeline.Messages)] + } else { + modelmsg = group.Timeline.Messages[idx] + } + } else { + contact := the.Peer.GetContact(this.Handle()) + if this.Handle() == "" || the.Peer == nil || contact == nil { + modelmsg = model.Message{Message:"oops test hi uhhhhh :/"} + } else if idx >= len(contact.Timeline.Messages) { + log.Errorf("this shouldnt happen") + //modelmsg = contact.UnacknowledgedMessages[idx-len(contact.Timeline.Messages)] + } else { + modelmsg = contact.Timeline.Messages[idx] + } + } + + return &MessageWrapper { + Message: modelmsg, + Timestamp: modelmsg.Timestamp.Unix(), + RawMessage: modelmsg.Message, + PeerID: modelmsg.PeerID, + Error: modelmsg.Error, + Acknowledged: modelmsg.Acknowledged, + } +} + +func (this *MessageModel) data(index *core.QModelIndex, role int) *core.QVariant { + log.Infof("MessageModel.data(%v, %v)", index.Row(), role) + + if !index.IsValid() { + return core.NewQVariant() + } + if index.Row() >= this.num() { + return core.NewQVariant() + } + + if role == int(core.Qt__DisplayRole) { + role = index.Column() + int(core.Qt__UserRole) + 1 + } + + // modelData-element [role]-field value (aka the data ~_~) + mderfv := reflect.ValueOf(*this.getMessage(index.Row())).Field(role - int(core.Qt__UserRole) - 1) + typeStr := reflect.TypeOf([]MessageWrapper{}).Elem().Field(role - int(core.Qt__UserRole) - 1).Type.String() + if typeStr == "string" { + return core.NewQVariant1(mderfv.String()) + } else if strings.HasPrefix(typeStr, "int") { + return core.NewQVariant1(mderfv.Int()) + } else if strings.HasPrefix(typeStr, "float") { + return core.NewQVariant1(mderfv.Float()) + } else if typeStr == "bool" { + return core.NewQVariant1(mderfv.Bool()) + } + + return core.NewQVariant1("unknown type " + typeStr) +} + +func (this *MessageModel) headerData(section int, orientation core.Qt__Orientation, role int) *core.QVariant { + if role != int(core.Qt__DisplayRole) || orientation == core.Qt__Vertical { + return this.HeaderDataDefault(section, orientation, role) + } + + mdt := reflect.TypeOf([]model.Message{}).Elem() + return core.NewQVariant12(mdt.Field(section).Name) +} + +func (this *MessageModel) rowCount(parent *core.QModelIndex) int { + return this.num() +} + +func (this *MessageModel) columnCount(parent *core.QModelIndex) int { + return reflect.TypeOf(MessageWrapper{}).NumField() +} + +func (this *MessageModel) addMessage(idx int) { + log.Debugf("MessageModel.addMessage() ZOOP ZOOP %v", this.handle) + this.BeginInsertRows(core.NewQModelIndex(), idx, idx)//this.num(), this.num()) + //this.modelData = append(this.modelData, *fe) + //this.RequestEIR() +} + +// perform this.EndInsertRows() on the gui thread +func (this *MessageModel) requestEIR() { + log.Debugf("MessageModel.requestEIR() ZEEP ZEEP %v", this.handle) + this.EndInsertRows() +} + + +func (this *MessageModel) createLocalFormEntry(name string) { + go this.createLocalFormEntry_thread(name) +} + +func (this *MessageModel) createLocalFormEntry_thread(name string) { + log.Debugf("nyi #9779729343959699492726648294050382") + /* + fe := &model.Message{ + Message: "hi!", + } + this.addMessage(fe) + */ +} \ No newline at end of file From 7bb21988790e86af5859aa67ca958f567cb2acdf Mon Sep 17 00:00:00 2001 From: erinn Date: Fri, 9 Oct 2020 11:27:06 -0700 Subject: [PATCH 3/6] update opaque --- qml/opaque | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qml/opaque b/qml/opaque index 5c33d6ed..12b7e514 160000 --- a/qml/opaque +++ b/qml/opaque @@ -1 +1 @@ -Subproject commit 5c33d6ed2c46f5fe039fc6fee3cb690cb562cb23 +Subproject commit 12b7e51497868515401edc68be5514c020472da9 From e09ad91ab5b8de0810828cd5ae9dbc5aeb413b1c Mon Sep 17 00:00:00 2001 From: erinn Date: Tue, 20 Oct 2020 15:57:34 -0700 Subject: [PATCH 4/6] finishing first attempt at message model pr. mainly group acks --- go/handlers/peerHandler.go | 13 +-- go/ui/gcd.go | 109 ++++++++------------- go/ui/manager.go | 46 +++++---- go/ui/messagemodel.go | 69 +++++++------- qml/overlays/ChatOverlay.qml | 180 +++++++++++++---------------------- 5 files changed, 174 insertions(+), 243 deletions(-) diff --git a/go/handlers/peerHandler.go b/go/handlers/peerHandler.go index 4210616c..84038e77 100644 --- a/go/handlers/peerHandler.go +++ b/go/handlers/peerHandler.go @@ -10,6 +10,7 @@ import ( "cwtch.im/ui/go/constants" "cwtch.im/ui/go/the" "cwtch.im/ui/go/ui" + "encoding/hex" "git.openprivacy.ca/openprivacy/log" "strconv" "time" @@ -54,19 +55,15 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) { case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampReceived]) - //uiManager.AddMessage(e.Data[event.RemotePeer], e.Data[event.RemotePeer], e.Data[event.Data], false, e.EventID, ts, true) - uiManager.AboutToAddMessage() - //time.Sleep(time.Millisecond) - peer.StoreMessage(e.Data[event.RemotePeer], e.Data[event.Data], ts) - uiManager.MessageJustAdded() - + uiManager.StoreAndNotify(peer, e.Data[event.RemotePeer], e.Data[event.Data], ts, onion) case event.PeerAcknowledgement: - uiManager.Acknowledge(e.Data[event.EventID]) + uiManager.Acknowledge(e.Data[event.RemotePeer], e.Data[event.EventID]) case event.NewMessageFromGroup: //event.TimestampReceived, event.TimestampSent, event.Data, event.GroupID, event.RemotePeer ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampSent]) - uiManager.AddMessage(e.Data[event.GroupID], e.Data[event.RemotePeer], e.Data[event.Data], e.Data[event.RemotePeer] == peer.GetOnion(), e.Data[event.Signature], ts, true) + uiManager.AddMessage(e.Data[event.GroupID], e.Data[event.RemotePeer], e.Data[event.Data], e.Data[event.RemotePeer] == peer.GetOnion(), hex.EncodeToString([]byte(e.Data[event.Signature])), ts, true) + case event.NewGroupInvite: gid, err := peer.ProcessInvite(e.Data[event.GroupInvite], e.Data[event.RemotePeer]) group := peer.GetGroup(gid) diff --git a/go/ui/gcd.go b/go/ui/gcd.go index b317d85b..a507abbd 100644 --- a/go/ui/gcd.go +++ b/go/ui/gcd.go @@ -2,6 +2,7 @@ package ui import ( "encoding/base64" + "strconv" "sync" "cwtch.im/cwtch/app" @@ -12,13 +13,11 @@ import ( "cwtch.im/ui/go/constants" "github.com/therecipe/qt/qml" - "encoding/base32" - "strings" - "time" - "cwtch.im/ui/go/the" + "encoding/base32" "git.openprivacy.ca/openprivacy/log" "github.com/therecipe/qt/core" + "strings" ) type GrandCentralDispatcher struct { @@ -66,8 +65,6 @@ 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 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"` @@ -120,6 +117,8 @@ type GrandCentralDispatcher struct { _ func() `signal:"blockUnknownPeers,auto"` _ func(onion string) `signal:"storeHistoryForPeer,auto"` _ func(onion string) `signal:"deleteHistoryForPeer,auto"` + // chat + _ func(mID string) `slot:"acktest,auto"` _ func(handle string) `signal:"requestServerSettings,auto"` @@ -175,6 +174,18 @@ func (this *GrandCentralDispatcher) DoIfProfile(profile string, fn func()) { } } +// Like DoIfProfile() but runs elseFn() if profile isn't the currently selected one in the UI +func (this *GrandCentralDispatcher) DoIfProfileElse(profile string, fn func(), elseFn func()) { + this.profileLock.Lock() + defer this.profileLock.Unlock() + + if this.m_selectedProfile == profile { + fn() + } else { + elseFn() + } +} + func (this *GrandCentralDispatcher) selectedConversation() string { this.conversationLock.Lock() defer this.conversationLock.Unlock() @@ -204,6 +215,18 @@ func (this *GrandCentralDispatcher) DoIfConversation(conversation string, fn fun } } +// like DoIfConversation() but +func (this *GrandCentralDispatcher) DoIfConversationElse(conversation string, fn func(), elseFn func()) { + this.conversationLock.Lock() + defer this.conversationLock.Unlock() + + if this.m_selectedConversation == conversation { + fn() + } else { + elseFn() + } +} + func (this *GrandCentralDispatcher) sendMessage(message string) { if len(message) > 65530 { this.InvokePopup("message is too long") @@ -224,22 +247,18 @@ func (this *GrandCentralDispatcher) sendMessage(message string) { } } - mID, err := the.Peer.SendMessageToGroupTracked(this.SelectedConversation(), message) - - this.GetUiManager(this.selectedProfile()).AddMessage(this.SelectedConversation(), "me", message, true, mID, time.Now(), false) + this.TimelineInterface.AddMessage(this.TimelineInterface.num()) + _, err := the.Peer.SendMessageToGroupTracked(this.SelectedConversation(), message) + this.TimelineInterface.RequestEIR() if err != nil { this.InvokePopup("failed to send message " + err.Error()) return } } else { - to := this.SelectedConversation() - prenum := this.TimelineInterface.num() - this.TimelineInterface.AddMessage(prenum) - /*mID := */the.Peer.SendMessageToPeer(to, message) + this.TimelineInterface.AddMessage(this.TimelineInterface.num()) + the.Peer.SendMessageToPeer(this.SelectedConversation(), message) this.TimelineInterface.RequestEIR() - - //this.GetUiManager(this.selectedProfile()).AddMessage(to, "me", message, true, mID, time.Now(), false) } } @@ -266,7 +285,6 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { this.UpdateContactStatus(group.GroupID, int(state), loading) this.requestGroupSettings(handle) - tl := group.GetTimeline() nick := GetNick(handle) updateLastReadTime(group.GroupID) if nick == "" { @@ -275,34 +293,6 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { this.SetToolbarTitle(nick) } - go func() { - // Janky hack to let the ui/qml respond to the status updates first before freezing under a deluge of new messages - time.Sleep(10 * time.Millisecond) - for i := len(tl) - 1; i >= 0; i-- { - if tl[i].PeerID == the.Peer.GetOnion() { - handle = "me" - } else { - handle = tl[i].PeerID - } - - name := GetNick(tl[i].PeerID) - image := GetProfilePic(tl[i].PeerID) - - this.PrependMessage( - handle, - tl[i].PeerID, - name, - tl[i].Message, - image, - string(tl[i].Signature), - tl[i].PeerID == the.Peer.GetOnion(), - 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, - ) - } - }() - return } // ELSE LOAD CONTACT @@ -317,32 +307,6 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { } updateLastReadTime(contact.Onion) this.SetToolbarTitle(nick) - - peer := the.Peer.GetContact(handle) - messages := peer.Timeline.GetMessages() - for i := range messages { - from := messages[i].PeerID - fromMe := messages[i].PeerID == the.Peer.GetOnion() - if fromMe { - from = "me" - } - - displayname := GetNick(messages[i].PeerID) - image := GetProfilePic(messages[i].PeerID) - - this.AppendMessage( - from, - messages[i].PeerID, - displayname, - messages[i].Message, - image, - string(messages[i].Signature), - fromMe, - messages[i].Timestamp.Unix(), - messages[i].Acknowledged, - messages[i].Error != "", - ) - } } func (this *GrandCentralDispatcher) requestSettings() { @@ -760,3 +724,8 @@ func (this *GrandCentralDispatcher) deleteProfile(onion string) { log.Infof("deleteProfile %v\n", onion) the.CwtchApp.DeletePeer(onion) } + +func (this *GrandCentralDispatcher) acktest(mID string) { + idx, _ := strconv.Atoi(mID) + this.TimelineInterface.EditMessage(idx) +} \ No newline at end of file diff --git a/go/ui/manager.go b/go/ui/manager.go index ff4db305..bf8f754a 100644 --- a/go/ui/manager.go +++ b/go/ui/manager.go @@ -4,6 +4,7 @@ import ( "cwtch.im/cwtch/app" "cwtch.im/cwtch/model" "cwtch.im/cwtch/model/attr" + "cwtch.im/cwtch/peer" "cwtch.im/cwtch/protocol/connections" "cwtch.im/ui/go/constants" "cwtch.im/ui/go/the" @@ -202,7 +203,7 @@ type manager struct { // manager also performs call filtering based on UI state: users of manager can safely always call it on events and not have to worry about weather the relevant ui is active // ie: you can always safely call AddMessage even if in the ui a different profile is selected. manager will check with gcd, and if the correct conditions are not met, it will not call on gcd to update the ui incorrectly type Manager interface { - Acknowledge(mID string) + Acknowledge(handle, mID string) AddContact(Handle string) AddSendMessageError(peer string, signature string, err string) AddMessage(handle string, from string, message string, fromMe bool, messageID string, timestamp time.Time, Acknowledged bool) @@ -218,6 +219,7 @@ type Manager interface { AboutToAddMessage() MessageJustAdded() + StoreAndNotify(peer.CwtchPeer, string, string, time.Time, string) } // NewManager returns a new Manager interface for a profile to the gcd @@ -226,9 +228,11 @@ func NewManager(profile string, gcd *GrandCentralDispatcher) Manager { } // Acknowledge acknowledges the given message id in the UI -func (this *manager) Acknowledge(mID string) { +func (this *manager) Acknowledge(handle, mID string) { this.gcd.DoIfProfile(this.profile, func() { - this.gcd.Acknowledged(mID) + this.gcd.DoIfConversation(handle, func(){ + this.gcd.Acktest(mID) + }) }) } @@ -291,28 +295,34 @@ func (this *manager) MessageJustAdded() { this.gcd.TimelineInterface.RequestEIR() } +func (this *manager) StoreAndNotify(pere peer.CwtchPeer, onion string, messageTxt string, sent time.Time, profileOnion string) { + this.gcd.DoIfProfileElse(this.profile, func() { + this.gcd.DoIfConversationElse(onion, func() { + updateLastReadTime(onion) + this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) + pere.StoreMessage(onion, messageTxt, sent) + this.gcd.TimelineInterface.RequestEIR() + }, func() { + updateLastReadTime(onion) + pere.StoreMessage(onion, messageTxt, sent) + }) + this.gcd.IncContactUnreadCount(onion) + }, func() { + the.CwtchApp.GetPeer(profileOnion).StoreMessage(onion, messageTxt, sent) + }) +} + // AddMessage adds a message to the message pane for the supplied conversation if it is active func (this *manager) AddMessage(handle string, from string, message string, fromMe bool, messageID string, timestamp time.Time, Acknowledged bool) { - log.Errorf("uiManager.AddMessage(...) uhhhh???? NO ZOOP ZEEP") this.gcd.DoIfProfile(this.profile, func() { - - //nick := GetNick(handle) - //image := GetProfilePic(handle) - - // If we have this group loaded already this.gcd.DoIfConversation(handle, func() { updateLastReadTime(handle) // If the message is not from the user then add it, otherwise, just acknowledge. - if !fromMe { - this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) - //this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Unix(), false, false) + if !fromMe || !Acknowledged { + this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()-1) + this.gcd.TimelineInterface.RequestEIR() } else { - if !Acknowledged { - this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) - //this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Unix(), false, false) - } else { - this.gcd.Acknowledged(messageID) - } + this.gcd.Acknowledged(messageID) } }) this.gcd.IncContactUnreadCount(handle) diff --git a/go/ui/messagemodel.go b/go/ui/messagemodel.go index 5d0735d1..33faab1a 100644 --- a/go/ui/messagemodel.go +++ b/go/ui/messagemodel.go @@ -3,6 +3,7 @@ package ui import ( "cwtch.im/cwtch/model" "cwtch.im/ui/go/the" + "encoding/hex" "git.openprivacy.ca/openprivacy/log" "github.com/therecipe/qt/core" "reflect" @@ -12,16 +13,16 @@ import ( type MessageModel struct { core.QAbstractTableModel + ackIdx int handle string - //_ string `property:"handle,auto"` _ func(string) `signal:"setHandle,auto"` _ map[int]*core.QByteArray `property:"roles"` _ func() `constructor:"init"` _ func(int) `signal:"addMessage,auto"` - _ func(string) `signal:"createLocalFormEntry,auto"` - _ func() `signal:"requestEIR,auto"` // request this.EndInsertRecord() on gui thread + _ func(int) `signal:"editMessage,auto"` + _ func() `signal:"requestEIR,auto"` _ func(string) string `slot:"getNick,auto"` _ func(string) string `slot:"getImage,auto"` @@ -36,6 +37,8 @@ type MessageWrapper struct { Acknowledged bool RawMessage string Error string + Day string + Signature string _ bool `property:"ackd"` } @@ -49,10 +52,12 @@ func (this *MessageModel) setHandle(handle string) { func (this *MessageModel) init() { - //mdt := reflect.TypeOf([]model.Message{}).Elem() mdt := reflect.TypeOf([]MessageWrapper{}).Elem() roles := make(map[int]*core.QByteArray) for i := 0; i < mdt.NumField(); i++ { + if mdt.Field(i).Name == "Acknowledged" { + this.ackIdx = int(core.Qt__UserRole) + 1 + i + } roles[int(core.Qt__UserRole) + 1 + i] = core.NewQByteArray2(mdt.Field(i).Name, -1) } roles[int(core.Qt__DisplayRole)] = core.NewQByteArray2("display", -1) @@ -83,7 +88,7 @@ func (this *MessageModel) getImage(handle string) string { func (this *MessageModel) num() int { if this.Handle() == "" || the.Peer == nil { - log.Debugf("num: early returning 0") + log.Debugf("MessageModel.num: early returning 0") return 0 } @@ -95,19 +100,17 @@ func (this *MessageModel) num() int { } else { contact := the.Peer.GetContact(this.Handle()) if contact != nil { - log.Debugf("num: returning %v", len(contact.Timeline.Messages)) return len(contact.Timeline.Messages) } } - log.Warnf("group/contact was nil, returning 0") + log.Warnf("MessageModel.num: group/contact was nil, returning 0") return 0 } func (this *MessageModel) getMessage(idx int) *MessageWrapper { - log.Infof("MessageModel.getMessage(%v)", idx) - var modelmsg model.Message + var ackd bool if this.isGroup() { group := the.Peer.GetGroup(this.Handle()) @@ -115,6 +118,7 @@ func (this *MessageModel) getMessage(idx int) *MessageWrapper { modelmsg = group.UnacknowledgedMessages[idx - len(group.Timeline.Messages)] } else { modelmsg = group.Timeline.Messages[idx] + ackd = true } } else { contact := the.Peer.GetContact(this.Handle()) @@ -122,9 +126,9 @@ func (this *MessageModel) getMessage(idx int) *MessageWrapper { modelmsg = model.Message{Message:"oops test hi uhhhhh :/"} } else if idx >= len(contact.Timeline.Messages) { log.Errorf("this shouldnt happen") - //modelmsg = contact.UnacknowledgedMessages[idx-len(contact.Timeline.Messages)] } else { modelmsg = contact.Timeline.Messages[idx] + ackd = modelmsg.Acknowledged } } @@ -134,13 +138,13 @@ func (this *MessageModel) getMessage(idx int) *MessageWrapper { RawMessage: modelmsg.Message, PeerID: modelmsg.PeerID, Error: modelmsg.Error, - Acknowledged: modelmsg.Acknowledged, + Acknowledged: ackd, + Day: modelmsg.Timestamp.Format("January 2, 2006"), + Signature: hex.EncodeToString(modelmsg.Signature), } } func (this *MessageModel) data(index *core.QModelIndex, role int) *core.QVariant { - log.Infof("MessageModel.data(%v, %v)", index.Row(), role) - if !index.IsValid() { return core.NewQVariant() } @@ -173,7 +177,7 @@ func (this *MessageModel) headerData(section int, orientation core.Qt__Orientati return this.HeaderDataDefault(section, orientation, role) } - mdt := reflect.TypeOf([]model.Message{}).Elem() + mdt := reflect.TypeOf([]MessageWrapper{}).Elem() return core.NewQVariant12(mdt.Field(section).Name) } @@ -185,30 +189,29 @@ func (this *MessageModel) columnCount(parent *core.QModelIndex) int { return reflect.TypeOf(MessageWrapper{}).NumField() } +// perform this.BeginInsertRows() on the gui thread +// important: +// 1. idx MUST be set to this.num()'s value *before* calling addMessage() +// 2. insert the message yourself +// 3. this.RequestEIR() *must* be called afterward func (this *MessageModel) addMessage(idx int) { - log.Debugf("MessageModel.addMessage() ZOOP ZOOP %v", this.handle) - this.BeginInsertRows(core.NewQModelIndex(), idx, idx)//this.num(), this.num()) - //this.modelData = append(this.modelData, *fe) - //this.RequestEIR() + this.BeginInsertRows(core.NewQModelIndex(), idx, idx) } -// perform this.EndInsertRows() on the gui thread +// perform this.EndInsertRows() on the gui thread after an AddMessage() func (this *MessageModel) requestEIR() { - log.Debugf("MessageModel.requestEIR() ZEEP ZEEP %v", this.handle) this.EndInsertRows() } - -func (this *MessageModel) createLocalFormEntry(name string) { - go this.createLocalFormEntry_thread(name) -} - -func (this *MessageModel) createLocalFormEntry_thread(name string) { - log.Debugf("nyi #9779729343959699492726648294050382") - /* - fe := &model.Message{ - Message: "hi!", +// notify the gui that the message acknowledgement at index idx has been modified +func (this *MessageModel) editMessage(idx int) { + if idx < 0 || idx >= this.num() { + log.Errorf("cant edit message %v. probably fine", idx) + return } - this.addMessage(fe) - */ -} \ No newline at end of file + + log.Debugf("editMessage(%v, %v)", idx, this.ackIdx) + indexObject := this.Index(idx, 0, core.NewQModelIndex()) + // replace third param with []int{} to update all attributes instead + this.DataChanged(indexObject, indexObject, []int{this.ackIdx}) +} diff --git a/qml/overlays/ChatOverlay.qml b/qml/overlays/ChatOverlay.qml index 1629f699..686b62c0 100644 --- a/qml/overlays/ChatOverlay.qml +++ b/qml/overlays/ChatOverlay.qml @@ -16,11 +16,30 @@ W.Overlay { //horizontalPadding: 15 * gcd.themeScale - ListModel { // MESSAGE OBJECTS ARE STORED HERE ... - id: messagesModel + Connections { + target: mm + onRowsInserted: { + if (messagesListView.atYEnd) thymer.running = true + + //todo: this won't fire for non-active convos + windowItem.alert(0) + if (gcd.os == "android" && windowItem.activeFocusItem == null) { + androidCwtchActivity.notification = "New Content" + } + } } - + // onRowsInserted is firing after the model is updated but before the delegate is inflated + // causing positionViewAtEnd() to scroll to "just above the last message" + // so we use this timer to delay scrolling by a few milliseconds + Timer { + id: thymer + interval: 30 + onTriggered: { + thymer.running = false + messagesListView.positionViewAtEnd() + } + } contentItem: ListView { id: messagesListView @@ -28,22 +47,26 @@ W.Overlay { Layout.fillWidth: true width: parent.width - model: mm//messagesModel// + model: mm spacing: 6 clip: true ScrollBar.vertical: Opaque.ScrollBar {} maximumFlickVelocity: 1250 + section.delegate: sectionHeading + section.property: "Day" + + delegate: W.Message { handle: PeerID from: PeerID displayName: mm.getNick(PeerID) - message: JSON.parse(RawMessage).d + message: JSON.parse(RawMessage).d+"//"+Signature rawMessage: RawMessage image: mm.getImage(PeerID) - messageID: "-1"//_mid - fromMe: PeerID == gcd.SelectedProfile + messageID: Signature + fromMe: PeerID == gcd.selectedProfile timestamp: parseInt(Timestamp) ackd: Acknowledged error: Error @@ -53,119 +76,48 @@ W.Overlay { width: messagesListView.width } + Component { + id: sectionHeading + Rectangle {// ⟵ outer rect because anchors._Margin isnt supported here + // with qt 5.15+ this↓ can be changed to... + // required property string section + property string txt: section + color: Theme.backgroundMainColor + width: childrenRect.width + height: childrenRect.height + 12 + anchors.horizontalCenter: parent.horizontalCenter + + Rectangle { + opacity: 1 + width: childrenRect.width + 66 + height: childrenRect.height + 6 + color: Theme.messageFromOtherBackgroundColor + radius: 15 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + + + Text { + // ... and this can be changed to + // text: parent.parent.section + text: parent.parent.txt + font.pixelSize: Theme.chatSize * gcd.themeScale + color: Theme.messageFromOtherTextColor + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + } + } + } + Connections { target: gcd onClearMessages: function() { - messagesModel.clear() messagesListView.model = null messagesListView.model = mm - } - - onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ackd, error) { - return - var msg - try { - msg = JSON.parse(message) - } catch (e) { - msg = {"o": 1, "d": "(legacy message type) " + message} - } - 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()) { - // new Day detected, Add Date message divider - 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, - "_from": from, - "_displayName": displayName, - "_message": msg.d, - "_rawMessage":msg.d, - "_image": image, - "_mid": mid, - "_fromMe": fromMe, - "_ts": ts, - "_ackd": ackd, - "_error": error == true ? "this message failed to send" : "", - }) - - messagesListView.positionViewAtEnd() - - // If the window is out of focus, alert the user (makes taskbar light up) - windowItem.alert(0) - if (gcd.os == "android" && windowItem.activeFocusItem == null) { - androidCwtchActivity.notification = "New Content" - } - } - - onPrependMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ackd, error) { - return - var msg - try { - msg = JSON.parse(message) - } catch (e) { - msg = {"o": 1, "d": "(legacy message type) " + message} - } - 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, - "_from": from, - "_displayName": displayName, - "_message": msg.d, - "_rawMessage":msg.d, - "_image": image, - "_mid": mid, - "_fromMe": fromMe, - "_ts": ts, - "_ackd": ackd, - "_error": error == true ? "this message failed to send" : "", - }) - - messagesListView.positionViewAtEnd() + messagesListView.positionViewAtEnd() + thymer.running = true } } } From cd241e45c41cc7f8374f1af99b22ca36f632d29a Mon Sep 17 00:00:00 2001 From: erinn Date: Thu, 22 Oct 2020 18:01:48 -0700 Subject: [PATCH 5/6] addressing review comments --- go.sum | 129 +++++++++++++++++++++++++++++++++++ go/the/globals.go | 2 +- go/ui/gcd.go | 4 +- go/ui/manager.go | 5 +- go/ui/messagemodel.go | 20 +++--- main.go | 3 +- qml/overlays/ChatOverlay.qml | 20 ++++-- 7 files changed, 160 insertions(+), 23 deletions(-) create mode 100644 go.sum diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..24d93a37 --- /dev/null +++ b/go.sum @@ -0,0 +1,129 @@ +cwtch.im/cwtch v0.4.2-0.20201008200820-a2c5a28e092d h1:CuqoPJdfmKqvGnZhQtrv/9YqTRei3t06AvCGrCmD3gU= +cwtch.im/cwtch v0.4.2-0.20201008200820-a2c5a28e092d/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI= +cwtch.im/cwtch v0.4.2-0.20201016053957-1933fb703fb0 h1:8d2hJyb6qupb9wS6px3734Hy1aHOrtwk4fpM1z/o3Tg= +cwtch.im/cwtch v0.4.2-0.20201016053957-1933fb703fb0/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI= +cwtch.im/cwtch v0.4.3 h1:xf/jMW4+UJckzbYm5g9rPJKTP7fr6O6JC5pH1xjTs/A= +cwtch.im/cwtch v0.4.3/go.mod h1:10gBkMSqAH95Pz4jTx5mpIHE+dkn+4kRC4BFTxWuQK8= +cwtch.im/tapir v0.2.0 h1:7MkoR5+uEuPW34/O0GZRidnIjq/01Cfm8nl5IRuqpGc= +cwtch.im/tapir v0.2.0/go.mod h1:xzzZ28adyUXNkYL1YodcHsAiTt3IJ8Loc29YVn9mIEQ= +git.openprivacy.ca/openprivacy/bine v0.0.3 h1:PSHUmNqaW7BZUX8n2eTDeNbjsuRe+t5Ae0Og+P+jDM0= +git.openprivacy.ca/openprivacy/bine v0.0.3/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLyqtXc46XBcnuXm/mU= +git.openprivacy.ca/openprivacy/connectivity v1.2.0/go.mod h1:B7vzuVmChJtSKoh0ezph5vu6DQ0gIk0zHUNG6IgXCcA= +git.openprivacy.ca/openprivacy/connectivity v1.2.1 h1:oRL56TR9ZQnKkGkTIQ9wYbJ2IkOOsi/zLYExYiAS+sE= +git.openprivacy.ca/openprivacy/connectivity v1.2.1/go.mod h1:B7vzuVmChJtSKoh0ezph5vu6DQ0gIk0zHUNG6IgXCcA= +git.openprivacy.ca/openprivacy/connectivity v1.3.0 h1:e2EeV6CaMNwOb+PzAjF0hGCeOqAPagRaDL4en5ITf7U= +git.openprivacy.ca/openprivacy/connectivity v1.3.0/go.mod h1:s0/QhONuUqJQfYTAgUlu+ya7G3Ov6bKgpT5QkOhVxDI= +git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= +git.openprivacy.ca/openprivacy/log v1.0.1 h1:NWV5oBTatvlSzUE6wtB+UQCulgyMOtm4BXGd34evMys= +git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= +github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca h1:Q2r7AxHdJwWfLtBZwvW621M3sPqxPc6ITv2j1FGsYpw= +github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d h1:vr95xIx8Eg3vCzZPxY3rCwTfkjqNDt/FgVqTOk0WByk= +github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +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/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= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= +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/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= +github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 h1:IhZPbxNd1UjBCaD5AfpSSbJTRlp+ZSuyuH5uoksNS04= +golang.org/x/crypto v0.0.0-20200420104511-884d27f42877/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d h1:V1BGE5ZHrUIYZYNEm0i7jrPwSo3ks0HSn1TrartSqME= +golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go/the/globals.go b/go/the/globals.go index 99f211e5..d9c51e12 100644 --- a/go/the/globals.go +++ b/go/the/globals.go @@ -8,7 +8,7 @@ import ( "git.openprivacy.ca/openprivacy/connectivity" ) -// really awesome but nevertheless to be replaced when proper profile/password management comes in ~ 0.2 +// foundation block of the entire app. critical. never change, only obey const AppPassword = "be gay do crime" var CwtchApp app.Application diff --git a/go/ui/gcd.go b/go/ui/gcd.go index a507abbd..4f4984c5 100644 --- a/go/ui/gcd.go +++ b/go/ui/gcd.go @@ -118,7 +118,7 @@ type GrandCentralDispatcher struct { _ func(onion string) `signal:"storeHistoryForPeer,auto"` _ func(onion string) `signal:"deleteHistoryForPeer,auto"` // chat - _ func(mID string) `slot:"acktest,auto"` + _ func(mID string) `slot:"peerAckAlert,auto"` _ func(handle string) `signal:"requestServerSettings,auto"` @@ -725,7 +725,7 @@ func (this *GrandCentralDispatcher) deleteProfile(onion string) { the.CwtchApp.DeletePeer(onion) } -func (this *GrandCentralDispatcher) acktest(mID string) { +func (this *GrandCentralDispatcher) peerAckAlert(mID string) { idx, _ := strconv.Atoi(mID) this.TimelineInterface.EditMessage(idx) } \ No newline at end of file diff --git a/go/ui/manager.go b/go/ui/manager.go index bf8f754a..54b0839d 100644 --- a/go/ui/manager.go +++ b/go/ui/manager.go @@ -231,7 +231,7 @@ func NewManager(profile string, gcd *GrandCentralDispatcher) Manager { func (this *manager) Acknowledge(handle, mID string) { this.gcd.DoIfProfile(this.profile, func() { this.gcd.DoIfConversation(handle, func(){ - this.gcd.Acktest(mID) + this.gcd.PeerAckAlert(mID) }) }) } @@ -298,12 +298,11 @@ func (this *manager) MessageJustAdded() { func (this *manager) StoreAndNotify(pere peer.CwtchPeer, onion string, messageTxt string, sent time.Time, profileOnion string) { this.gcd.DoIfProfileElse(this.profile, func() { this.gcd.DoIfConversationElse(onion, func() { - updateLastReadTime(onion) this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) pere.StoreMessage(onion, messageTxt, sent) this.gcd.TimelineInterface.RequestEIR() - }, func() { updateLastReadTime(onion) + }, func() { pere.StoreMessage(onion, messageTxt, sent) }) this.gcd.IncContactUnreadCount(onion) diff --git a/go/ui/messagemodel.go b/go/ui/messagemodel.go index 33faab1a..c33f12e1 100644 --- a/go/ui/messagemodel.go +++ b/go/ui/messagemodel.go @@ -109,7 +109,7 @@ func (this *MessageModel) num() int { } func (this *MessageModel) getMessage(idx int) *MessageWrapper { - var modelmsg model.Message + modelmsg := model.Message{Message:"[an unexpected cwtch error occurred]"} var ackd bool if this.isGroup() { @@ -121,14 +121,16 @@ func (this *MessageModel) getMessage(idx int) *MessageWrapper { ackd = true } } else { - contact := the.Peer.GetContact(this.Handle()) - if this.Handle() == "" || the.Peer == nil || contact == nil { - modelmsg = model.Message{Message:"oops test hi uhhhhh :/"} - } else if idx >= len(contact.Timeline.Messages) { - log.Errorf("this shouldnt happen") - } else { - modelmsg = contact.Timeline.Messages[idx] - ackd = modelmsg.Acknowledged + if this.Handle() != "" && the.Peer != nil { + contact := the.Peer.GetContact(this.Handle()) + if contact != nil { + if idx >= len(contact.Timeline.Messages) { + log.Errorf("requested message[%d] of only %d", idx, len(contact.Timeline.Messages)) + } else { + modelmsg = contact.Timeline.Messages[idx] + ackd = modelmsg.Acknowledged + } + } } } diff --git a/main.go b/main.go index 2fbea2c5..c78c6020 100644 --- a/main.go +++ b/main.go @@ -42,9 +42,9 @@ func init() { } func main() { + // suppress event.NewMessageFromPeer so we can handle it ourselves peer.DefaultEventsToHandle = []event.Type{ event.EncryptedGroupMessage, - //event.NewMessageFromPeer, event.PeerAcknowledgement, event.NewGroupInvite, event.PeerError, @@ -213,7 +213,6 @@ func mainUi(flagLocal bool, flagClientUI bool) { engine.RootContext().SetContextProperty("gcd", gcd) gcd.TimelineInterface = ui.NewMessageModel(nil) - gcd.TimelineInterface.SetHandle("66b46c88c1475de1819af2a95d39548d") engine.RootContext().SetContextProperty("mm", gcd.TimelineInterface) var androidCwtchActivity = android.NewCwtchActivity(nil) diff --git a/qml/overlays/ChatOverlay.qml b/qml/overlays/ChatOverlay.qml index 686b62c0..f31ccdcf 100644 --- a/qml/overlays/ChatOverlay.qml +++ b/qml/overlays/ChatOverlay.qml @@ -62,7 +62,7 @@ W.Overlay { handle: PeerID from: PeerID displayName: mm.getNick(PeerID) - message: JSON.parse(RawMessage).d+"//"+Signature + message: JSON.parse(RawMessage).d rawMessage: RawMessage image: mm.getImage(PeerID) messageID: Signature @@ -83,21 +83,23 @@ W.Overlay { // required property string section property string txt: section color: Theme.backgroundMainColor - width: childrenRect.width - height: childrenRect.height + 12 + width: parent.width + height: texmet.height + 6 + 12 * gcd.themeScale anchors.horizontalCenter: parent.horizontalCenter + Rectangle { opacity: 1 - width: childrenRect.width + 66 - height: childrenRect.height + 6 + width: texmet.width + radius * 4 + 6 + height: texmet.height + 6 color: Theme.messageFromOtherBackgroundColor - radius: 15 + radius: texmet.height / 2 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter Text { + id: txtDate // ... and this can be changed to // text: parent.parent.section text: parent.parent.txt @@ -106,6 +108,12 @@ W.Overlay { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } + + TextMetrics { + id: texmet + text: txtDate.text + font.pixelSize: Theme.chatSize * gcd.themeScale + } } } } From a52794d562e1a0782f5d16f70519c8729f9ccd9d Mon Sep 17 00:00:00 2001 From: erinn Date: Thu, 22 Oct 2020 18:14:04 -0700 Subject: [PATCH 6/6] addressing review comments --- Makefile | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 10ca2f16..6a66eee2 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ android: linux_build: date - qtdeploy -docker -qt_version "5.13.0" build linux 2>&1 | tee qtdeploy.log | pv + qtdeploy -qt_version "5.13.0" build linux 2>&1 | tee qtdeploy.log | pv date cp -R assets deploy/linux/ $(MAKE) linux_clean diff --git a/go.sum b/go.sum index 24d93a37..28d0bdd0 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ git.openprivacy.ca/openprivacy/connectivity v1.2.1 h1:oRL56TR9ZQnKkGkTIQ9wYbJ2Ik git.openprivacy.ca/openprivacy/connectivity v1.2.1/go.mod h1:B7vzuVmChJtSKoh0ezph5vu6DQ0gIk0zHUNG6IgXCcA= git.openprivacy.ca/openprivacy/connectivity v1.3.0 h1:e2EeV6CaMNwOb+PzAjF0hGCeOqAPagRaDL4en5ITf7U= git.openprivacy.ca/openprivacy/connectivity v1.3.0/go.mod h1:s0/QhONuUqJQfYTAgUlu+ya7G3Ov6bKgpT5QkOhVxDI= +git.openprivacy.ca/openprivacy/connectivity v1.3.1 h1:d1t7rtzn+Fc63Z2M4mAGmGYU8hSeoZqglvfVBYkg0Lw= +git.openprivacy.ca/openprivacy/connectivity v1.3.1/go.mod h1:s0/QhONuUqJQfYTAgUlu+ya7G3Ov6bKgpT5QkOhVxDI= git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= git.openprivacy.ca/openprivacy/log v1.0.1 h1:NWV5oBTatvlSzUE6wtB+UQCulgyMOtm4BXGd34evMys= git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=