Compare commits
24
Commits
22fe1cac46
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23288e3dfa | ||
|
|
6d95c8419c | ||
|
|
a31d9e766d | ||
|
|
542ade77b2 | ||
|
|
183ec02918 | ||
|
|
881b72cb15 | ||
|
|
4d0e29550c | ||
|
|
b926173f43 | ||
|
|
2667b0ccfd | ||
|
|
3aa8054dc0 | ||
|
|
ad9a0ea9a8 | ||
|
|
de40a5dec8 | ||
|
|
78c7f0175d | ||
|
|
7bab52f033 | ||
|
|
652fd3ea19 | ||
|
|
536ce4cae6 | ||
|
|
202e3ba6b1 | ||
|
|
7f01f38436 | ||
|
|
4afe2de35d | ||
|
|
04083a5ec4 | ||
|
|
02dcd4b453 | ||
|
|
85b82b2d3b | ||
|
|
a847ba5cdd | ||
|
|
d5ec58be68 |
No files matched your search
@@ -1,3 +1,11 @@
|
|||||||
|
# Notice
|
||||||
|
|
||||||
|
Pi is on hiatus for the time being. The reason why being that the libraries that Pi uses, being the Oasis SDK and the Mellium libraries, have multiple fundamental issues and bugs that are unlikely to be fixed. In addition, I began writing this project with a much less consolidated knowledge of Go and programming in general, meaning there are core architectural issues with this project. Regardless, you are still free to use Pi, and I may even rewrite the project to add some new features. Who knows.
|
||||||
|
|
||||||
|
I mostly work on [Lambda](https://forge.sunglocto.net/sunglocto/lambda) these days, which has already surpassed Pi in terms of features and usability.
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<img width="100" height="100" src="https://forge.sunglocto.net/sunglocto/pi-im/raw/branch/master/pi.png">
|
<img width="100" height="100" src="https://forge.sunglocto.net/sunglocto/pi-im/raw/branch/master/pi.png">
|
||||||
</center>
|
</center>
|
||||||
@@ -112,7 +120,7 @@ go build -tags wayland .
|
|||||||
## εγκατάσταση
|
## εγκατάσταση
|
||||||
(installation)
|
(installation)
|
||||||
|
|
||||||
pi currently has no consolidated way of installing it. There is an [Arch User Repository package available](https://aur.archlinux.org/pi-im), which is maintained by [snit](https://isekai.rocks/~snit).
|
pi currently has no consolidated way of installing it. There is an [Arch User Repository package available](https://aur.archlinux.org/packages/pi-im), which is maintained by [snit](https://isekai.rocks/~snit).
|
||||||
|
|
||||||
## υποστήριξη
|
## υποστήριξη
|
||||||
(support)
|
(support)
|
||||||
|
|||||||
@@ -3,41 +3,49 @@ module pi-im
|
|||||||
go 1.25.1
|
go 1.25.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
fyne.io/fyne/v2 v2.6.3
|
fyne.io/fyne/v2 v2.7.1
|
||||||
fyne.io/x/fyne v0.0.0-20250910205345-ecc79984d005
|
fyne.io/x/fyne v0.0.0-20251214153509-fa68a7d234d5
|
||||||
|
github.com/gen2brain/beeep v0.11.2
|
||||||
github.com/makeworld-the-better-one/go-isemoji v1.3.0
|
github.com/makeworld-the-better-one/go-isemoji v1.3.0
|
||||||
github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d
|
github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d
|
||||||
github.com/shreve/musicwand v0.0.1
|
github.com/shreve/musicwand v0.0.1
|
||||||
github.com/sunglocto/oasis-sdk v0.0.0-20251128101950-083ea4658d9c
|
github.com/sunglocto/oasis-sdk v0.0.0-20260103142308-7f1848e2aac0
|
||||||
mellium.im/xmpp v0.22.0
|
mellium.im/xmpp v0.22.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
fyne.io/systray v1.11.0 // indirect
|
fyne.io/systray v1.11.1-0.20250603113521-ca66a66d8b58 // indirect
|
||||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
git.sr.ht/~jackmordaunt/go-toast v1.1.2 // indirect
|
||||||
|
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fredbi/uri v1.1.0 // indirect
|
github.com/esiqveland/notify v0.13.3 // indirect
|
||||||
|
github.com/fredbi/uri v1.1.1 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||||
github.com/fyne-io/gl-js v0.2.0 // indirect
|
github.com/fyne-io/gl-js v0.2.0 // indirect
|
||||||
github.com/fyne-io/glfw-js v0.3.0 // indirect
|
github.com/fyne-io/glfw-js v0.3.0 // indirect
|
||||||
github.com/fyne-io/image v0.1.1 // indirect
|
github.com/fyne-io/image v0.1.1 // indirect
|
||||||
github.com/fyne-io/oksvg v0.1.0 // indirect
|
github.com/fyne-io/oksvg v0.2.0 // indirect
|
||||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
|
||||||
|
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||||
github.com/go-text/render v0.2.0 // indirect
|
github.com/go-text/render v0.2.0 // indirect
|
||||||
github.com/go-text/typesetting v0.2.1 // indirect
|
github.com/go-text/typesetting v0.2.1 // indirect
|
||||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||||
github.com/hack-pad/go-indexeddb v0.3.2 // indirect
|
github.com/hack-pad/go-indexeddb v0.3.2 // indirect
|
||||||
github.com/hack-pad/safejs v0.1.0 // indirect
|
github.com/hack-pad/safejs v0.1.0 // indirect
|
||||||
|
github.com/jackmordaunt/icns/v3 v3.0.1 // indirect
|
||||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect
|
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect
|
||||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
|
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.5.1 // indirect
|
github.com/nicksnyder/go-i18n/v2 v2.5.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/rymdport/portal v0.4.1 // indirect
|
github.com/rymdport/portal v0.4.2 // indirect
|
||||||
|
github.com/sergeymakinen/go-bmp v1.0.0 // indirect
|
||||||
|
github.com/sergeymakinen/go-ico v1.0.0-beta.0 // indirect
|
||||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
|
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
|
||||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
||||||
github.com/stretchr/testify v1.10.0 // indirect
|
github.com/stretchr/testify v1.11.1 // indirect
|
||||||
|
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
|
||||||
github.com/yuin/goldmark v1.7.8 // indirect
|
github.com/yuin/goldmark v1.7.8 // indirect
|
||||||
golang.org/x/crypto v0.36.0 // indirect
|
golang.org/x/crypto v0.36.0 // indirect
|
||||||
golang.org/x/image v0.24.0 // indirect
|
golang.org/x/image v0.24.0 // indirect
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
fyne.io/fyne/v2 v2.6.3 h1:cvtM2KHeRuH+WhtHiA63z5wJVBkQ9+Ay0UMl9PxFHyA=
|
fyne.io/fyne/v2 v2.7.1 h1:ja7rNHWWEooha4XBIZNnPP8tVFwmTfwMJdpZmLxm2Zc=
|
||||||
fyne.io/fyne/v2 v2.6.3/go.mod h1:NGSurpRElVoI1G3h+ab2df3O5KLGh1CGbsMMcX0bPIs=
|
fyne.io/fyne/v2 v2.7.1/go.mod h1:xClVlrhxl7D+LT+BWYmcrW4Nf+dJTvkhnPgji7spAwE=
|
||||||
fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
|
fyne.io/systray v1.11.1-0.20250603113521-ca66a66d8b58 h1:eA5/u2XRd8OUkoMqEv3IBlFYSruNlXD8bRHDiqm0VNI=
|
||||||
fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
|
fyne.io/systray v1.11.1-0.20250603113521-ca66a66d8b58/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
|
||||||
fyne.io/x/fyne v0.0.0-20250910205345-ecc79984d005 h1:CmdApAnt07juL0dhcFReFGpADUdRjjm0eDVJDS01uKE=
|
fyne.io/x/fyne v0.0.0-20251214153509-fa68a7d234d5 h1:kDuBckHtdKTNV+jq0AornXroGSd/GMq06dBNXOWfmyY=
|
||||||
fyne.io/x/fyne v0.0.0-20250910205345-ecc79984d005/go.mod h1:kQFmF5meMIXnyCioLoCrXol5opruSS/PHYGKMBIE3SU=
|
fyne.io/x/fyne v0.0.0-20251214153509-fa68a7d234d5/go.mod h1:kQFmF5meMIXnyCioLoCrXol5opruSS/PHYGKMBIE3SU=
|
||||||
|
git.sr.ht/~jackmordaunt/go-toast v1.1.2 h1:/yrfI55LRt1M7H1vkaw+NaH1+L1CDxrqDltwm5euVuE=
|
||||||
|
git.sr.ht/~jackmordaunt/go-toast v1.1.2/go.mod h1:jA4OqHKTQ4AFBdwrSnwnskUIIS3HYzlJSgdzCKqfavo=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/esiqveland/notify v0.13.3 h1:QCMw6o1n+6rl+oLUfg8P1IIDSFsDEb2WlXvVvIJbI/o=
|
||||||
|
github.com/esiqveland/notify v0.13.3/go.mod h1:hesw/IRYTO0x99u1JPweAl4+5mwXJibQVUcP0Iu5ORE=
|
||||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||||
github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8=
|
github.com/fredbi/uri v1.1.1 h1:xZHJC08GZNIUhbP5ImTHnt5Ya0T8FI2VAwI/37kh2Ko=
|
||||||
github.com/fredbi/uri v1.1.0/go.mod h1:aYTUoAXBOq7BLfVJ8GnKmfcuURosB1xyHDIfWeC/iW4=
|
github.com/fredbi/uri v1.1.1/go.mod h1:4+DZQ5zBjEwQCDmXW5JdIjz0PUA+yJbvtBv+u+adr5o=
|
||||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
github.com/fyne-io/gl-js v0.2.0 h1:+EXMLVEa18EfkXBVKhifYB6OGs3HwKO3lUElA0LlAjs=
|
github.com/fyne-io/gl-js v0.2.0 h1:+EXMLVEa18EfkXBVKhifYB6OGs3HwKO3lUElA0LlAjs=
|
||||||
@@ -23,12 +27,16 @@ github.com/fyne-io/glfw-js v0.3.0 h1:d8k2+Y7l+zy2pc7wlGRyPfTgZoqDf3AI4G+2zOWhWUk
|
|||||||
github.com/fyne-io/glfw-js v0.3.0/go.mod h1:Ri6te7rdZtBgBpxLW19uBpp3Dl6K9K/bRaYdJ22G8Jk=
|
github.com/fyne-io/glfw-js v0.3.0/go.mod h1:Ri6te7rdZtBgBpxLW19uBpp3Dl6K9K/bRaYdJ22G8Jk=
|
||||||
github.com/fyne-io/image v0.1.1 h1:WH0z4H7qfvNUw5l4p3bC1q70sa5+YWVt6HCj7y4VNyA=
|
github.com/fyne-io/image v0.1.1 h1:WH0z4H7qfvNUw5l4p3bC1q70sa5+YWVt6HCj7y4VNyA=
|
||||||
github.com/fyne-io/image v0.1.1/go.mod h1:xrfYBh6yspc+KjkgdZU/ifUC9sPA5Iv7WYUBzQKK7JM=
|
github.com/fyne-io/image v0.1.1/go.mod h1:xrfYBh6yspc+KjkgdZU/ifUC9sPA5Iv7WYUBzQKK7JM=
|
||||||
github.com/fyne-io/oksvg v0.1.0 h1:7EUKk3HV3Y2E+qypp3nWqMXD7mum0hCw2KEGhI1fnBw=
|
github.com/fyne-io/oksvg v0.2.0 h1:mxcGU2dx6nwjJsSA9PCYZDuoAcsZ/OuJlvg/Q9Njfo8=
|
||||||
github.com/fyne-io/oksvg v0.1.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI=
|
github.com/fyne-io/oksvg v0.2.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI=
|
||||||
|
github.com/gen2brain/beeep v0.11.2 h1:+KfiKQBbQCuhfJFPANZuJ+oxsSKAYNe88hIpJuyKWDA=
|
||||||
|
github.com/gen2brain/beeep v0.11.2/go.mod h1:jQVvuwnLuwOcdctHn/uyh8horSBNJ8uGb9Cn2W4tvoc=
|
||||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
|
||||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||||
|
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||||
github.com/go-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc=
|
github.com/go-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc=
|
||||||
github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU=
|
github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU=
|
||||||
github.com/go-text/typesetting v0.2.1 h1:x0jMOGyO3d1qFAPI0j4GSsh7M0Q3Ypjzr4+CEVg82V8=
|
github.com/go-text/typesetting v0.2.1 h1:x0jMOGyO3d1qFAPI0j4GSsh7M0Q3Ypjzr4+CEVg82V8=
|
||||||
@@ -44,6 +52,8 @@ github.com/hack-pad/go-indexeddb v0.3.2 h1:DTqeJJYc1usa45Q5r52t01KhvlSN02+Oq+tQb
|
|||||||
github.com/hack-pad/go-indexeddb v0.3.2/go.mod h1:QvfTevpDVlkfomY498LhstjwbPW6QC4VC/lxYb0Kom0=
|
github.com/hack-pad/go-indexeddb v0.3.2/go.mod h1:QvfTevpDVlkfomY498LhstjwbPW6QC4VC/lxYb0Kom0=
|
||||||
github.com/hack-pad/safejs v0.1.0 h1:qPS6vjreAqh2amUqj4WNG1zIw7qlRQJ9K10eDKMCnE8=
|
github.com/hack-pad/safejs v0.1.0 h1:qPS6vjreAqh2amUqj4WNG1zIw7qlRQJ9K10eDKMCnE8=
|
||||||
github.com/hack-pad/safejs v0.1.0/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio=
|
github.com/hack-pad/safejs v0.1.0/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio=
|
||||||
|
github.com/jackmordaunt/icns/v3 v3.0.1 h1:xxot6aNuGrU+lNgxz5I5H0qSeCjNKp8uTXB1j8D4S3o=
|
||||||
|
github.com/jackmordaunt/icns/v3 v3.0.1/go.mod h1:5sHL59nqTd2ynTnowxB/MDQFhKNqkK8X687uKNygaSQ=
|
||||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade h1:FmusiCI1wHw+XQbvL9M+1r/C3SPqKrmBaIOYwVfQoDE=
|
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade h1:FmusiCI1wHw+XQbvL9M+1r/C3SPqKrmBaIOYwVfQoDE=
|
||||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o=
|
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o=
|
||||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
||||||
@@ -65,8 +75,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||||||
github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d h1:l3+2LWCbVxn5itfvXAfH9n4YL9jh8l1g5zcncbIc1cs=
|
github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d h1:l3+2LWCbVxn5itfvXAfH9n4YL9jh8l1g5zcncbIc1cs=
|
||||||
github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d/go.mod h1:TbpErkob6SY7cyozRVSGoB3OlO2qOAgVN8O3KAJ4fMI=
|
github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d/go.mod h1:TbpErkob6SY7cyozRVSGoB3OlO2qOAgVN8O3KAJ4fMI=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/rymdport/portal v0.4.1 h1:2dnZhjf5uEaeDjeF/yBIeeRo6pNI2QAKm7kq1w/kbnA=
|
github.com/rymdport/portal v0.4.2 h1:7jKRSemwlTyVHHrTGgQg7gmNPJs88xkbKcIL3NlcmSU=
|
||||||
github.com/rymdport/portal v0.4.1/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
|
github.com/rymdport/portal v0.4.2/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
|
||||||
|
github.com/sergeymakinen/go-bmp v1.0.0 h1:SdGTzp9WvCV0A1V0mBeaS7kQAwNLdVJbmHlqNWq0R+M=
|
||||||
|
github.com/sergeymakinen/go-bmp v1.0.0/go.mod h1:/mxlAQZRLxSvJFNIEGGLBE/m40f3ZnUifpgVDlcUIEY=
|
||||||
|
github.com/sergeymakinen/go-ico v1.0.0-beta.0 h1:m5qKH7uPKLdrygMWxbamVn+tl2HfiA3K6MFJw4GfZvQ=
|
||||||
|
github.com/sergeymakinen/go-ico v1.0.0-beta.0/go.mod h1:wQ47mTczswBO5F0NoDt7O0IXgnV4Xy3ojrroMQzyhUk=
|
||||||
github.com/shreve/musicwand v0.0.1 h1:uF1GDmk6b9xZPAGJU3iWBSqKruyVeyVs/cqM6YzaJ3k=
|
github.com/shreve/musicwand v0.0.1 h1:uF1GDmk6b9xZPAGJU3iWBSqKruyVeyVs/cqM6YzaJ3k=
|
||||||
github.com/shreve/musicwand v0.0.1/go.mod h1:y7oBkMLTfGmpIxoKQFwXlzWLtffcQIpX/1no+iNPxwQ=
|
github.com/shreve/musicwand v0.0.1/go.mod h1:y7oBkMLTfGmpIxoKQFwXlzWLtffcQIpX/1no+iNPxwQ=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
@@ -75,15 +89,18 @@ github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS
|
|||||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
|
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
|
||||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
|
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/sunglocto/oasis-sdk v0.0.0-20251128095406-3c003b830815 h1:HsI7kxYauygjRK15Iwf3FlZnU8XJwRPSmbtoNfeyBYk=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/sunglocto/oasis-sdk v0.0.0-20251128095406-3c003b830815/go.mod h1:Y5iPruMLvqNwGVqB+n/+wylQjCTPKQx37I/PyLWhuzk=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/sunglocto/oasis-sdk v0.0.0-20251128100941-f53b1dabbcac h1:pVarwnSbjNSDpeQer/SERztTEpkl6Cnb5xuyxXmb50k=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/sunglocto/oasis-sdk v0.0.0-20251128100941-f53b1dabbcac/go.mod h1:Y5iPruMLvqNwGVqB+n/+wylQjCTPKQx37I/PyLWhuzk=
|
github.com/sunglocto/oasis-sdk v0.0.0-20260103142308-7f1848e2aac0 h1:7zNLaQVg8jYYrNZ6KqBv23k/RYu58p3wL9YS72B+eNM=
|
||||||
github.com/sunglocto/oasis-sdk v0.0.0-20251128101950-083ea4658d9c h1:peWSGIl0xBvx3sJR3+kHV1xOe1X8dbQ9xtvEXyXogCo=
|
github.com/sunglocto/oasis-sdk v0.0.0-20260103142308-7f1848e2aac0/go.mod h1:Y5iPruMLvqNwGVqB+n/+wylQjCTPKQx37I/PyLWhuzk=
|
||||||
github.com/sunglocto/oasis-sdk v0.0.0-20251128101950-083ea4658d9c/go.mod h1:Y5iPruMLvqNwGVqB+n/+wylQjCTPKQx37I/PyLWhuzk=
|
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk=
|
||||||
|
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
|
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
|
||||||
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||||
@@ -97,6 +114,7 @@ golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
|||||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||||
|
|||||||
@@ -3,9 +3,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
//core - required
|
//core - required
|
||||||
"context"
|
"context"
|
||||||
|
_ "embed"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
_ "image/jpeg"
|
||||||
|
_ "image/png"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
@@ -24,20 +28,27 @@ import (
|
|||||||
"fyne.io/fyne/v2/storage"
|
"fyne.io/fyne/v2/storage"
|
||||||
"fyne.io/fyne/v2/theme"
|
"fyne.io/fyne/v2/theme"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
extraWidgets "fyne.io/x/fyne/widget"
|
"fyne.io/fyne/v2/layout"
|
||||||
|
"github.com/gen2brain/beeep"
|
||||||
"github.com/makeworld-the-better-one/go-isemoji"
|
"github.com/makeworld-the-better-one/go-isemoji"
|
||||||
"github.com/rrivera/identicon"
|
"github.com/rrivera/identicon"
|
||||||
"github.com/shreve/musicwand/pkg/mpris"
|
"github.com/shreve/musicwand/pkg/mpris"
|
||||||
|
|
||||||
// xmpp - required
|
// xmpp - required
|
||||||
|
oasisSdk "github.com/sunglocto/oasis-sdk"
|
||||||
"mellium.im/xmpp/bookmarks"
|
"mellium.im/xmpp/bookmarks"
|
||||||
|
xmppColor "mellium.im/xmpp/color"
|
||||||
"mellium.im/xmpp/jid"
|
"mellium.im/xmpp/jid"
|
||||||
"mellium.im/xmpp/muc"
|
"mellium.im/xmpp/muc"
|
||||||
oasisSdk "github.com/sunglocto/oasis-sdk"
|
"mellium.im/xmpp/pubsub"
|
||||||
|
"mellium.im/xmpp/stanza"
|
||||||
// TODO: integrated theme switcher
|
// TODO: integrated theme switcher
|
||||||
)
|
)
|
||||||
|
|
||||||
var version string = "3.1i"
|
//go:embed pi.png
|
||||||
|
var iconBytes []byte
|
||||||
|
|
||||||
|
var version string = "3.14i"
|
||||||
var statBar widget.Label
|
var statBar widget.Label
|
||||||
var chatInfo fyne.Container
|
var chatInfo fyne.Container
|
||||||
var chatSidebar fyne.Container
|
var chatSidebar fyne.Container
|
||||||
@@ -45,6 +56,8 @@ var replyNameIcon string = ">"
|
|||||||
var replyBodyIcon string = ">"
|
var replyBodyIcon string = ">"
|
||||||
var newlineIcon string = " |-> "
|
var newlineIcon string = " |-> "
|
||||||
var agreesToSendingHotFuckIntoChannel bool = false
|
var agreesToSendingHotFuckIntoChannel bool = false
|
||||||
|
var sendEmpty bool = false
|
||||||
|
var OccupantIdsToBlock = make(map[string]string)
|
||||||
|
|
||||||
// by sunglocto
|
// by sunglocto
|
||||||
// license AGPL
|
// license AGPL
|
||||||
@@ -55,6 +68,7 @@ type Message struct {
|
|||||||
ID string
|
ID string
|
||||||
ReplyID string
|
ReplyID string
|
||||||
ImageURL string
|
ImageURL string
|
||||||
|
Corrected bool
|
||||||
Raw oasisSdk.XMPPChatMessage
|
Raw oasisSdk.XMPPChatMessage
|
||||||
Important bool
|
Important bool
|
||||||
Readers []jid.JID
|
Readers []jid.JID
|
||||||
@@ -158,14 +172,14 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
|||||||
im := ii.Image(25)
|
im := ii.Image(25)
|
||||||
ico := canvas.NewImageFromImage(im)
|
ico := canvas.NewImageFromImage(im)
|
||||||
ico.FillMode = canvas.ImageFillOriginal
|
ico.FillMode = canvas.ImageFillOriginal
|
||||||
author := widget.NewLabel("author")
|
author := canvas.NewText("author", color.RGBA{255, 255, 255, 255})
|
||||||
author.TextStyle.Bold = true
|
author.TextStyle.Bold = true
|
||||||
author.Selectable = true
|
// author.Selectable = true
|
||||||
content := widget.NewLabel("content")
|
content := widget.NewLabel("content")
|
||||||
content.Wrapping = fyne.TextWrapWord
|
content.Wrapping = fyne.TextWrapWord
|
||||||
content.Selectable = true
|
content.Selectable = true
|
||||||
content.Importance = widget.MediumImportance
|
content.Importance = widget.MediumImportance
|
||||||
//content.SizeName = fyne.ThemeSizeName(theme.SizeNameText)
|
content.SizeName = fyne.ThemeSizeName(theme.SizeNameText)
|
||||||
icon := theme.FileVideoIcon()
|
icon := theme.FileVideoIcon()
|
||||||
replytext := widget.NewLabel(">fallback reply text")
|
replytext := widget.NewLabel(">fallback reply text")
|
||||||
replytext.Hide()
|
replytext.Hide()
|
||||||
@@ -176,12 +190,17 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
|||||||
btn := widget.NewButtonWithIcon("View media", icon, func() {
|
btn := widget.NewButtonWithIcon("View media", icon, func() {
|
||||||
|
|
||||||
})
|
})
|
||||||
|
btn.Hide()
|
||||||
|
|
||||||
reactions := container.NewHBox()
|
reactions := container.NewHBox()
|
||||||
|
|
||||||
return container.NewVBox(replytext, container.NewHBox(ico, author), content, btn, reactions)
|
pencil := widget.NewButtonWithIcon("", theme.DocumentCreateIcon(), func(){})
|
||||||
|
pencil.Hidden = true
|
||||||
|
|
||||||
|
return container.NewVBox(replytext, container.NewHBox(ico, author, layout.NewSpacer(), pencil), content, btn, reactions)
|
||||||
},
|
},
|
||||||
func(i widget.ListItemID, co fyne.CanvasObject) {
|
func(i widget.ListItemID, co fyne.CanvasObject) {
|
||||||
|
|
||||||
vbox := co.(*fyne.Container)
|
vbox := co.(*fyne.Container)
|
||||||
authorBox := vbox.Objects[1].(*fyne.Container)
|
authorBox := vbox.Objects[1].(*fyne.Container)
|
||||||
replytext := vbox.Objects[0].(*widget.Label)
|
replytext := vbox.Objects[0].(*widget.Label)
|
||||||
@@ -194,10 +213,31 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
|||||||
authorBox.Objects[0].(*canvas.Image).FillMode = canvas.ImageFillOriginal
|
authorBox.Objects[0].(*canvas.Image).FillMode = canvas.ImageFillOriginal
|
||||||
authorBox.Objects[0].Refresh()
|
authorBox.Objects[0].Refresh()
|
||||||
|
|
||||||
|
pencil := authorBox.Objects[3].(*widget.Button)
|
||||||
|
|
||||||
// Icon generate end
|
// Icon generate end
|
||||||
|
|
||||||
author := authorBox.Objects[1].(*widget.Label)
|
author := authorBox.Objects[1].(*canvas.Text)
|
||||||
|
col := xmppColor.String(chatTabs[chatJidStr].Messages[i].Author, 0, xmppColor.None)
|
||||||
|
author.Color = col
|
||||||
|
|
||||||
content := vbox.Objects[2].(*widget.Label)
|
content := vbox.Objects[2].(*widget.Label)
|
||||||
|
unknown_tags := chatTabs[chatJidStr].Messages[i].Raw.Unknown
|
||||||
|
for _, v := range unknown_tags {
|
||||||
|
if v.XMLName.Local == "occupant-id" {
|
||||||
|
for _, attr := range v.Attrs {
|
||||||
|
if attr.Name.Local == "id" {
|
||||||
|
reason, ok := OccupantIdsToBlock[attr.Value]
|
||||||
|
if ok {
|
||||||
|
author.Text = ("Ignored user")
|
||||||
|
content.SetText("This user is ignored due to: " + reason)
|
||||||
|
content.Importance = widget.LowImportance
|
||||||
|
return // message is from blocked user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
btn := vbox.Objects[3].(*widget.Button)
|
btn := vbox.Objects[3].(*widget.Button)
|
||||||
reactions := vbox.Objects[4].(*fyne.Container)
|
reactions := vbox.Objects[4].(*fyne.Container)
|
||||||
reactions = container.NewVBox()
|
reactions = container.NewVBox()
|
||||||
@@ -210,7 +250,20 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
|||||||
|
|
||||||
if chatTabs[chatJidStr].Messages[i].Important {
|
if chatTabs[chatJidStr].Messages[i].Important {
|
||||||
content.Importance = widget.DangerImportance
|
content.Importance = widget.DangerImportance
|
||||||
|
} else {
|
||||||
|
content.Importance = widget.MediumImportance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if chatTabs[chatJidStr].Messages[i].Corrected {
|
||||||
|
pencil.Hidden = false
|
||||||
|
pencil.OnTapped = func() {
|
||||||
|
dialog.ShowInformation("Original", *chatTabs[chatJidStr].Messages[i].Raw.CleanedBody, w)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pencil.Hidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
btn.Hidden = true // Hide by default
|
btn.Hidden = true // Hide by default
|
||||||
msgContent := chatTabs[chatJidStr].Messages[i].Content
|
msgContent := chatTabs[chatJidStr].Messages[i].Content
|
||||||
if chatTabs[chatJidStr].Messages[i].Raw.OutOfBandMedia != nil {
|
if chatTabs[chatJidStr].Messages[i].Raw.OutOfBandMedia != nil {
|
||||||
@@ -270,27 +323,31 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
|||||||
for i := len(chatTabs[chatJidStr].Messages) - 1; i >= 0; i-- {
|
for i := len(chatTabs[chatJidStr].Messages) - 1; i >= 0; i-- {
|
||||||
if reply.ID == chatTabs[chatJidStr].Messages[i].Raw.StanzaID.ID {
|
if reply.ID == chatTabs[chatJidStr].Messages[i].Raw.StanzaID.ID {
|
||||||
replytext.Show()
|
replytext.Show()
|
||||||
replytext.SetText(fmt.Sprintf("%s %s", replyBodyIcon, strings.ReplaceAll(chatTabs[chatJidStr].Messages[i].Content, "\n", newlineIcon)))
|
replytext.Text = fmt.Sprintf("%s %s", replyBodyIcon, strings.ReplaceAll(chatTabs[chatJidStr].Messages[i].Content, "\n", newlineIcon))
|
||||||
guy = chatTabs[chatJidStr].Messages[i].Author
|
guy = chatTabs[chatJidStr].Messages[i].Author
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
author.SetText(fmt.Sprintf("%s %s %s", chatTabs[chatJidStr].Messages[i].Author, replyNameIcon, guy))
|
author.Text = (fmt.Sprintf("%s %s %s", chatTabs[chatJidStr].Messages[i].Author, replyNameIcon, guy))
|
||||||
} else {
|
} else {
|
||||||
author.SetText(chatTabs[chatJidStr].Messages[i].Author)
|
author.Text = (chatTabs[chatJidStr].Messages[i].Author)
|
||||||
replytext.Hide()
|
replytext.Hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
sl := strings.Split(msgContent, " ")
|
sl := strings.Split(msgContent, " ")
|
||||||
|
|
||||||
|
content.SizeName = fyne.ThemeSizeName(theme.SizeNameText)
|
||||||
if len(sl) == 1 && isemoji.IsEmoji(sl[0]) {
|
if len(sl) == 1 && isemoji.IsEmoji(sl[0]) {
|
||||||
content.SizeName = fyne.ThemeSizeName(theme.SizeNameHeadingText)
|
content.SizeName = fyne.ThemeSizeName(theme.SizeNameHeadingText)
|
||||||
content.Refresh()
|
content.Refresh()
|
||||||
|
} else {
|
||||||
|
content.SizeName = fyne.ThemeSizeName(theme.SizeNameText)
|
||||||
|
content.Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
if sl[0] == "/me" {
|
if sl[0] == "/me" {
|
||||||
author.SetText(author.Text + " " + strings.Join(sl[1:], " "))
|
author.Text = (author.Text + " " + strings.Join(sl[1:], " "))
|
||||||
content.SetText(" ")
|
content.SetText(" ")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +465,9 @@ func dropToSignInPage(reason string) {
|
|||||||
dialog.ShowError(err, w)
|
dialog.ShowError(err, w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
a.SendNotification(fyne.NewNotification("Done", "Relaunch the application"))
|
// a.SendNotification(fyne.NewNotification("Done", "Relaunch the application"))
|
||||||
|
beeep.Notify("Done", "Relaunch the application", iconBytes)
|
||||||
|
|
||||||
a.Quit()
|
a.Quit()
|
||||||
//w.Close()
|
//w.Close()
|
||||||
}
|
}
|
||||||
@@ -423,9 +482,12 @@ func dropToSignInPage(reason string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
beeep.AppName = "pi"
|
||||||
muc.Since(time.Now())
|
muc.Since(time.Now())
|
||||||
config = piConfig{}
|
config = piConfig{}
|
||||||
|
res := fyne.NewStaticResource("image", iconBytes)
|
||||||
a = app.NewWithID("pi-im")
|
a = app.NewWithID("pi-im")
|
||||||
|
a.SetIcon(res)
|
||||||
reader, err := a.Storage().Open("pi.xml")
|
reader, err := a.Storage().Open("pi.xml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dropToSignInPage(err.Error())
|
dropToSignInPage(err.Error())
|
||||||
@@ -465,7 +527,8 @@ func main() {
|
|||||||
if ok {
|
if ok {
|
||||||
str := *msg.CleanedBody
|
str := *msg.CleanedBody
|
||||||
if notifications {
|
if notifications {
|
||||||
a.SendNotification(fyne.NewNotification(fmt.Sprintf("%s says", userJidStr), str))
|
// a.SendNotification(fyne.NewNotification(fmt.Sprintf("%s says", userJidStr), str))
|
||||||
|
beeep.Notify("Direct message", fmt.Sprintf("%s says:\n%s", userJidStr, str), iconBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range msg.Unknown {
|
for _, v := range msg.Unknown {
|
||||||
@@ -503,7 +566,9 @@ func main() {
|
|||||||
if correction {
|
if correction {
|
||||||
for i := len(tab.Messages) - 1; i > 0; i-- {
|
for i := len(tab.Messages) - 1; i > 0; i-- {
|
||||||
if tab.Messages[i].Raw.From.String() == msg.From.String() {
|
if tab.Messages[i].Raw.From.String() == msg.From.String() {
|
||||||
tab.Messages[i].Content = *msg.CleanedBody + " (corrected)"
|
// tab.Messages[i].Content = *msg.CleanedBody + " (corrected)"
|
||||||
|
tab.Messages[i].Content = *msg.CleanedBody
|
||||||
|
tab.Messages[i].Corrected = true
|
||||||
fyne.Do(func() {
|
fyne.Do(func() {
|
||||||
UITabs[userJidStr].Scroller.Refresh()
|
UITabs[userJidStr].Scroller.Refresh()
|
||||||
})
|
})
|
||||||
@@ -571,7 +636,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
if !donotnotify && !ignore && notifications {
|
if !donotnotify && !ignore && notifications {
|
||||||
if !correction && msg.From.String() != client.JID.String() && strings.Contains(str, login.DisplayName) || (msg.Reply != nil && strings.Contains(msg.Reply.To, login.DisplayName)) {
|
if !correction && msg.From.String() != client.JID.String() && strings.Contains(str, login.DisplayName) || (msg.Reply != nil && strings.Contains(msg.Reply.To, login.DisplayName)) {
|
||||||
a.SendNotification(fyne.NewNotification(fmt.Sprintf("Mentioned in %s", mucJidStr), str))
|
// a.SendNotification(fyne.NewNotification(fmt.Sprintf("Mentioned in %s", mucJidStr), str))
|
||||||
|
beeep.Notify(fmt.Sprintf("Mentioned in %s by %s", jid.MustParse(mucJidStr).Localpart(), msg.From.Resourcepart()), str, iconBytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.Contains(str, "https://") {
|
if strings.Contains(str, "https://") {
|
||||||
@@ -612,7 +678,9 @@ func main() {
|
|||||||
if correction {
|
if correction {
|
||||||
for i := len(tab.Messages) - 1; i > 0; i-- {
|
for i := len(tab.Messages) - 1; i > 0; i-- {
|
||||||
if tab.Messages[i].Raw.From.String() == msg.From.String() {
|
if tab.Messages[i].Raw.From.String() == msg.From.String() {
|
||||||
tab.Messages[i].Content = *msg.CleanedBody + " (corrected)"
|
// tab.Messages[i].Content = *msg.CleanedBody + " (corrected)"
|
||||||
|
tab.Messages[i].Content = *msg.CleanedBody
|
||||||
|
tab.Messages[i].Corrected = true
|
||||||
fyne.Do(func() {
|
fyne.Do(func() {
|
||||||
UITabs[mucJidStr].Scroller.Refresh()
|
UITabs[mucJidStr].Scroller.Refresh()
|
||||||
})
|
})
|
||||||
@@ -636,6 +704,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
important = false
|
important = false
|
||||||
fyne.Do(func() {
|
fyne.Do(func() {
|
||||||
|
_, ok := UITabs[mucJidStr]
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
UITabs[mucJidStr].Scroller.Refresh()
|
UITabs[mucJidStr].Scroller.Refresh()
|
||||||
if scrollDownOnNewMessage {
|
if scrollDownOnNewMessage {
|
||||||
tab, ok := UITabs[mucJidStr]
|
tab, ok := UITabs[mucJidStr]
|
||||||
@@ -674,7 +746,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
client.SetPresenceHandler(func(client *oasisSdk.XmppClient, from jid.JID, p oasisSdk.UserPresence) {
|
client.SetPresenceHandler(func(client *oasisSdk.XmppClient, from jid.JID, p oasisSdk.UserPresence) {
|
||||||
log.Println(p.Type)
|
fmt.Println(p.Header.Type == stanza.UnavailablePresence)
|
||||||
bareAcc := from.Bare()
|
bareAcc := from.Bare()
|
||||||
tab, ok := chatTabs[bareAcc.String()]
|
tab, ok := chatTabs[bareAcc.String()]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -684,6 +756,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tab.isMuc {
|
if tab.isMuc {
|
||||||
|
fmt.Println(p.Type)
|
||||||
tab.Members[from.String()] = p
|
tab.Members[from.String()] = p
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -757,7 +830,7 @@ func main() {
|
|||||||
w = a.NewWindow("pi")
|
w = a.NewWindow("pi")
|
||||||
w.SetCloseIntercept(func() {
|
w.SetCloseIntercept(func() {
|
||||||
w.RequestFocus()
|
w.RequestFocus()
|
||||||
dialog.ShowConfirm("Close pi", "You hit the close button. Do you want Pi to close completely (confirm) or minimize to the tray? (cancel)", func(b bool) {
|
dialog.ShowConfirm("Close pi", "You hit the close button. Do you want Pi to close completely?", func(b bool) {
|
||||||
if b {
|
if b {
|
||||||
w.Close()
|
w.Close()
|
||||||
a.Quit()
|
a.Quit()
|
||||||
@@ -768,6 +841,7 @@ func main() {
|
|||||||
}, w)
|
}, w)
|
||||||
})
|
})
|
||||||
w.Resize(fyne.NewSize(500, 500))
|
w.Resize(fyne.NewSize(500, 500))
|
||||||
|
w.SetIcon(res)
|
||||||
|
|
||||||
entry := NewCustomMultiLineEntry()
|
entry := NewCustomMultiLineEntry()
|
||||||
entry.SetPlaceHolder("Say something, you know you want to.\nCtrl+Enter for newline")
|
entry.SetPlaceHolder("Say something, you know you want to.\nCtrl+Enter for newline")
|
||||||
@@ -776,7 +850,13 @@ func main() {
|
|||||||
|
|
||||||
SendCallback := func() {
|
SendCallback := func() {
|
||||||
text := entry.Text
|
text := entry.Text
|
||||||
if AppTabs.Selected() == nil || AppTabs.Selected().Content == nil || text == "" {
|
if text == "" {
|
||||||
|
dialog.ShowConfirm("Empty message", "Send an empty message?", func(b bool) {
|
||||||
|
sendEmpty = b
|
||||||
|
}, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
if AppTabs.Selected() == nil || AppTabs.Selected().Content == nil || (text == "" && !sendEmpty) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,6 +918,9 @@ func main() {
|
|||||||
text = fmt.Sprintf("%s %s", text, jid.MustParse(name).Resourcepart())
|
text = fmt.Sprintf("%s %s", text, jid.MustParse(name).Resourcepart())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a := pubsub.Fetch(context.TODO(), client.Session, pubsub.Query{})
|
||||||
|
log.Println(a.Item())
|
||||||
|
|
||||||
err = client.SendText(jid.MustParse(activeMucJid).Bare(), text)
|
err = client.SendText(jid.MustParse(activeMucJid).Bare(), text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dialog.ShowError(err, w)
|
dialog.ShowError(err, w)
|
||||||
@@ -1026,6 +1109,34 @@ func main() {
|
|||||||
}, w)
|
}, w)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
getMAM := fyne.NewMenuItem("send stanza", func() {
|
||||||
|
sendiq := false
|
||||||
|
b := container.NewVBox()
|
||||||
|
note := widget.NewRichTextFromMarkdown(fmt.Sprintf("# How to send a stanza\nThe stanza must be formed properly or the client will disconnect! Some actions such as joining rooms should be done via the client.\n Here is an example of a typical stanza:\n\n```\n<message from=’abc@example.com’ to=’xyz@example.com’ type=’chat’>\n\t<body>We have had a most delightful evening, a most excellent ball.</body>\n</message>\n```\n\nThe `from` attribute should be your JID `(%s)` and the `to` attribute should be the intended recipient. The `type` attribute can be `chat`, `groupchat`, `headline` and more.\n\nFor more information, read [RFC 6120](https://www.rfc-editor.org/rfc/rfc6120.html).", client.JID.String()))
|
||||||
|
note.Hidden = true
|
||||||
|
// note.Wrapping = fyne.TextWrapWord
|
||||||
|
b.Add(note)
|
||||||
|
isiq := widget.NewCheck("IQ stanza (get a reponse back)", func(b bool) {sendiq=b})
|
||||||
|
b.Add(isiq)
|
||||||
|
hlpbtn := widget.NewButton("Help!", func() {note.Hidden = !note.Hidden})
|
||||||
|
b.Add(hlpbtn)
|
||||||
|
entry := widget.NewMultiLineEntry()
|
||||||
|
entry.SetPlaceHolder(fmt.Sprintf("<message type='chat' from='%s' id='ilovepi' to='friend@home.org'><body>Hello from Pi!</body></message>", client.JID.String()))
|
||||||
|
b.Add(entry)
|
||||||
|
btn := widget.NewButton("Send", func() {
|
||||||
|
fmt.Println(sendiq)
|
||||||
|
msg := entry.Text
|
||||||
|
err := client.Session.Send(context.TODO(), xml.NewDecoder(strings.NewReader(msg)))
|
||||||
|
if err != nil {
|
||||||
|
dialog.ShowError(err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
b.Add(btn)
|
||||||
|
dialog.ShowCustom("Send a custom XML stanza", "Close", b, w)
|
||||||
|
})
|
||||||
|
|
||||||
leaveRoom := fyne.NewMenuItem("disconnect from current room", func() {
|
leaveRoom := fyne.NewMenuItem("disconnect from current room", func() {
|
||||||
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -1061,7 +1172,13 @@ func main() {
|
|||||||
for address, bookmark := range bookmarks {
|
for address, bookmark := range bookmarks {
|
||||||
bookmarkWidget := container.NewGridWithColumns(7)
|
bookmarkWidget := container.NewGridWithColumns(7)
|
||||||
|
|
||||||
nameLabel := widget.NewLabel(bookmark.Name)
|
var nameLabel *widget.RichText
|
||||||
|
|
||||||
|
if bookmark.Name != "" {
|
||||||
|
nameLabel = widget.NewRichTextFromMarkdown(bookmark.Name)
|
||||||
|
} else {
|
||||||
|
nameLabel = widget.NewRichTextFromMarkdown("_no name_")
|
||||||
|
}
|
||||||
nameLabel.Wrapping = fyne.TextWrapBreak
|
nameLabel.Wrapping = fyne.TextWrapBreak
|
||||||
|
|
||||||
bookmarkWidget.Add(nameLabel)
|
bookmarkWidget.Add(nameLabel)
|
||||||
@@ -1081,9 +1198,8 @@ func main() {
|
|||||||
if bookmark.Nick == "" {
|
if bookmark.Nick == "" {
|
||||||
bookmark.Nick = client.Login.DisplayName
|
bookmark.Nick = client.Login.DisplayName
|
||||||
}
|
}
|
||||||
var zero uint64 = uint64(0)
|
|
||||||
addChatTab(true, bookmark.JID, bookmark.Nick)
|
addChatTab(true, bookmark.JID, bookmark.Nick)
|
||||||
_, err := client.ConnectMuc(bookmark, oasisSdk.MucLegacyHistoryConfig{MaxCount: &zero}, context.TODO())
|
_, err := client.ConnectMuc(bookmark, oasisSdk.MucLegacyHistoryConfig{}, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fyne.Do(func() {
|
fyne.Do(func() {
|
||||||
joinRoomButton.Enable()
|
joinRoomButton.Enable()
|
||||||
@@ -1169,14 +1285,7 @@ func main() {
|
|||||||
|
|
||||||
joinARoom := fyne.NewMenuItem("connect to a room", func() {
|
joinARoom := fyne.NewMenuItem("connect to a room", func() {
|
||||||
dialog.ShowEntryDialog("connect to a room", "JID:", func(s string) {
|
dialog.ShowEntryDialog("connect to a room", "JID:", func(s string) {
|
||||||
i := resourcePiloadingGif
|
d := dialog.NewCustom("Please wait", "Close", widget.NewProgressBarInfinite(), w)
|
||||||
gif, err := extraWidgets.NewAnimatedGifFromResource(i)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
gif.Start()
|
|
||||||
gif.Show()
|
|
||||||
d := dialog.NewCustom("Please wait", "Close", gif, w)
|
|
||||||
d.Show()
|
d.Show()
|
||||||
go func() {
|
go func() {
|
||||||
myjid, err := jid.Parse(s)
|
myjid, err := jid.Parse(s)
|
||||||
@@ -1191,8 +1300,7 @@ func main() {
|
|||||||
mychannel.Nick = login.DisplayName
|
mychannel.Nick = login.DisplayName
|
||||||
//ch, err := client.MucClient.Join(client.Ctx, joinjid, client.Session)
|
//ch, err := client.MucClient.Join(client.Ctx, joinjid, client.Session)
|
||||||
addChatTab(true, myjid, login.DisplayName)
|
addChatTab(true, myjid, login.DisplayName)
|
||||||
num := uint64(0)
|
_, err = client.ConnectMuc(*mychannel, oasisSdk.MucLegacyHistoryConfig{}, context.TODO())
|
||||||
_, err = client.ConnectMuc(*mychannel, oasisSdk.MucLegacyHistoryConfig{MaxCount: &num}, context.TODO())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.Hide()
|
d.Hide()
|
||||||
dialog.ShowError(err, w)
|
dialog.ShowError(err, w)
|
||||||
@@ -1204,16 +1312,9 @@ func main() {
|
|||||||
}, w)
|
}, w)
|
||||||
})
|
})
|
||||||
|
|
||||||
beginADM := fyne.NewMenuItem("Start a DM", func() {
|
beginADM := fyne.NewMenuItem("start a DM", func() {
|
||||||
dialog.ShowEntryDialog("Start a DM", "JID:", func(s string) {
|
dialog.ShowEntryDialog("Start a DM", "JID:", func(s string) {
|
||||||
i := resourcePiloadingGif
|
d := dialog.NewCustom("Please wait", "Close", widget.NewLabel("Opening a DM with "+s), w)
|
||||||
gif, err := extraWidgets.NewAnimatedGifFromResource(i)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
gif.Start()
|
|
||||||
gif.Show()
|
|
||||||
d := dialog.NewCustom("Please wait", "Close", gif, w)
|
|
||||||
d.Show()
|
d.Show()
|
||||||
go func() {
|
go func() {
|
||||||
myjid, err := jid.Parse(s)
|
myjid, err := jid.Parse(s)
|
||||||
@@ -1231,7 +1332,7 @@ func main() {
|
|||||||
|
|
||||||
menu_help := fyne.NewMenu("π", mit, reconnect, licensesbtn)
|
menu_help := fyne.NewMenu("π", mit, reconnect, licensesbtn)
|
||||||
|
|
||||||
menu_changeroom := fyne.NewMenu("Α", mic, beginADM, joinARoom, leaveRoom, manageBookmarks)
|
menu_changeroom := fyne.NewMenu("Α", mic, beginADM, joinARoom, leaveRoom, manageBookmarks, getMAM)
|
||||||
menu_configureview := fyne.NewMenu("Β", mia, jtt, jtb)
|
menu_configureview := fyne.NewMenu("Β", mia, jtt, jtb)
|
||||||
hafjag := fyne.NewMenuItem("Hafjag", func() {
|
hafjag := fyne.NewMenuItem("Hafjag", func() {
|
||||||
entry.Text = "Hafjag"
|
entry.Text = "Hafjag"
|
||||||
@@ -1278,6 +1379,13 @@ func main() {
|
|||||||
entry.Text = old
|
entry.Text = old
|
||||||
})
|
})
|
||||||
|
|
||||||
|
wspeed := fyne.NewMenuItem("W Speed ❤️🩹❤️🩹", func() {
|
||||||
|
old := entry.Text
|
||||||
|
entry.Text = "W Speed ❤️🩹❤️🩹"
|
||||||
|
SendCallback()
|
||||||
|
entry.Text = old
|
||||||
|
})
|
||||||
|
|
||||||
exposed_suffix := fyne.NewMenuItem(".exposed", func() {
|
exposed_suffix := fyne.NewMenuItem(".exposed", func() {
|
||||||
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -1354,7 +1462,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
menu_jokes := fyne.NewMenu("Δ", mycurrenttime, mycurrentplayingsong, hafjag, hotfuck, agree, kai, mipipiemi, exposed_suffix)
|
menu_jokes := fyne.NewMenu("Δ", mycurrenttime, mycurrentplayingsong, hafjag, hotfuck, agree, kai, mipipiemi, exposed_suffix, wspeed)
|
||||||
bit := fyne.NewMenuItem("mark selected message as read", func() {
|
bit := fyne.NewMenuItem("mark selected message as read", func() {
|
||||||
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -1372,6 +1480,36 @@ func main() {
|
|||||||
client.MarkAsRead(&m)
|
client.MarkAsRead(&m)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
rec := fyne.NewMenuItem("retract selected message", func() {
|
||||||
|
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var activeMucJid string
|
||||||
|
for jid, tabData := range UITabs {
|
||||||
|
if tabData.Scroller == selectedScroller {
|
||||||
|
activeMucJid = jid
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !chatTabs[activeMucJid].isMuc {
|
||||||
|
return // TODO: For 1:1 DMs we use OccupantID for the ID and send message type 'chat'
|
||||||
|
}
|
||||||
|
|
||||||
|
id := chatTabs[activeMucJid].Messages[selectedId].Raw.StanzaID
|
||||||
|
if id == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := fmt.Sprintf("<message type='groupchat' to='%s' id='retract-message-1'><retract id='%s' xmlns='urn:xmpp:message-retract:1'/><fallback xmlns='urn:xmpp:fallback:0' for='urn:xmpp:message-retract:1' /><body>This user retracted a previous message, but it's unsupported by your client.</body><store xmlns='urn:xmpp:hints'/></message>", activeMucJid, id.ID)
|
||||||
|
fmt.Println(msg)
|
||||||
|
err := client.Session.Send(context.TODO(), xml.NewDecoder(strings.NewReader(msg)))
|
||||||
|
if err != nil {
|
||||||
|
dialog.ShowError(err, w)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
bia := fyne.NewMenuItem("toggle replying to message", func() {
|
bia := fyne.NewMenuItem("toggle replying to message", func() {
|
||||||
replying = !replying
|
replying = !replying
|
||||||
})
|
})
|
||||||
@@ -1403,6 +1541,48 @@ func main() {
|
|||||||
dialog.ShowCustom("Message", "Close", pre, w)
|
dialog.ShowCustom("Message", "Close", pre, w)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
blck := fyne.NewMenuItem("ignore messages from this user", func() {
|
||||||
|
|
||||||
|
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeChatJid string
|
||||||
|
for jid, tabData := range UITabs {
|
||||||
|
if tabData.Scroller == selectedScroller {
|
||||||
|
activeChatJid = jid
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m := chatTabs[activeChatJid].Messages[selectedId]
|
||||||
|
unknown_tags := m.Raw.Unknown
|
||||||
|
for _, v := range unknown_tags {
|
||||||
|
if v.XMLName.Local == "occupant-id" {
|
||||||
|
for _, attr := range v.Attrs {
|
||||||
|
if attr.Name.Local == "id" {
|
||||||
|
occupant_id := attr.Value
|
||||||
|
reason, ok := OccupantIdsToBlock[occupant_id]
|
||||||
|
if !ok {
|
||||||
|
dialog.ShowConfirm("ignore user", "All messages sent by users with an occupant ID of\n"+occupant_id+"\nwill be ignored. Continue?", func(b bool) {
|
||||||
|
if b {
|
||||||
|
OccupantIdsToBlock[occupant_id] = "User requested"
|
||||||
|
}
|
||||||
|
}, w)
|
||||||
|
} else {
|
||||||
|
dialog.ShowConfirm("unignore user", "This user is currently ignored due to:\n"+reason+"\nWould you like to unignore them?", func(b bool) {
|
||||||
|
if b {
|
||||||
|
delete(OccupantIdsToBlock, occupant_id)
|
||||||
|
}
|
||||||
|
}, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
red := fyne.NewMenuItem("show read receipts on message", func() {
|
red := fyne.NewMenuItem("show read receipts on message", func() {
|
||||||
pre := container.NewVBox()
|
pre := container.NewVBox()
|
||||||
|
|
||||||
@@ -1439,13 +1619,13 @@ func main() {
|
|||||||
dialog.ShowCustom("Message", "Close", pre, w)
|
dialog.ShowCustom("Message", "Close", pre, w)
|
||||||
})
|
})
|
||||||
|
|
||||||
menu_messageoptions := fyne.NewMenu("Γ", bit, bia, bic, red)
|
menu_messageoptions := fyne.NewMenu("Γ", bit, bia, bic, rec, red, blck)
|
||||||
ma := fyne.NewMainMenu(menu_help, menu_changeroom, menu_configureview, menu_messageoptions, menu_jokes)
|
ma := fyne.NewMainMenu(menu_help, menu_changeroom, menu_configureview, menu_messageoptions, menu_jokes)
|
||||||
w.SetMainMenu(ma)
|
w.SetMainMenu(ma)
|
||||||
|
|
||||||
desk, ok := a.(desktop.App)
|
desk, ok := a.(desktop.App)
|
||||||
if ok {
|
if ok {
|
||||||
desk.SetSystemTrayMenu(fyne.NewMenu("", fyne.NewMenuItem("show", w.Show)))
|
desk.SetSystemTrayMenu(fyne.NewMenu("", fyne.NewMenuItem("Show window", w.Show)))
|
||||||
}
|
}
|
||||||
|
|
||||||
AppTabs = container.NewDocTabs(
|
AppTabs = container.NewDocTabs(
|
||||||
@@ -1479,10 +1659,11 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
dialog.ShowError(err, w)
|
dialog.ShowError(err, w)
|
||||||
}
|
}
|
||||||
|
fyne.Do(func() {
|
||||||
AppTabs.Selected().Text = fmt.Sprintf("%s (disconnected)", AppTabs.Selected().Text)
|
AppTabs.Selected().Text = fmt.Sprintf("%s (disconnected)", AppTabs.Selected().Text)
|
||||||
AppTabs.Remove(ti)
|
AppTabs.Remove(ti)
|
||||||
delete(UITabs, activeChatJid)
|
delete(UITabs, activeChatJid)
|
||||||
|
})
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1494,7 +1675,18 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppTabs.OnUnselected = func(ti *container.TabItem) {
|
||||||
|
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectedScroller.Hidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var MainSplit *container.Split
|
||||||
|
|
||||||
AppTabs.OnSelected = func(ti *container.TabItem) {
|
AppTabs.OnSelected = func(ti *container.TabItem) {
|
||||||
|
chatSidebar.Resize(chatSidebar.Size())
|
||||||
if AppTabs.Selected() == AppTabs.Items[0] {
|
if AppTabs.Selected() == AppTabs.Items[0] {
|
||||||
chatSidebar.Hidden = true
|
chatSidebar.Hidden = true
|
||||||
return
|
return
|
||||||
@@ -1504,6 +1696,8 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectedScroller.Hidden = false
|
||||||
|
|
||||||
var activeChatJid string
|
var activeChatJid string
|
||||||
for jid, tabData := range UITabs {
|
for jid, tabData := range UITabs {
|
||||||
if tabData.Scroller == selectedScroller {
|
if tabData.Scroller == selectedScroller {
|
||||||
@@ -1521,8 +1715,8 @@ func main() {
|
|||||||
nameLabel.Truncation = fyne.TextTruncateEllipsis
|
nameLabel.Truncation = fyne.TextTruncateEllipsis
|
||||||
memberLabel := widget.NewLabel(fmt.Sprintf("%d members ", len(tab.Members)))
|
memberLabel := widget.NewLabel(fmt.Sprintf("%d members ", len(tab.Members)))
|
||||||
memberLabel.Truncation = fyne.TextTruncateEllipsis
|
memberLabel.Truncation = fyne.TextTruncateEllipsis
|
||||||
box := container.NewVBox(nameLabel, )
|
box := container.NewVBox(nameLabel)
|
||||||
chatSidebar.Objects = []fyne.CanvasObject{}
|
// chatSidebar.Objects = []fyne.CanvasObject{}
|
||||||
|
|
||||||
for name, p := range tab.Members {
|
for name, p := range tab.Members {
|
||||||
log.Println(string(p.Type))
|
log.Println(string(p.Type))
|
||||||
@@ -1564,23 +1758,28 @@ func main() {
|
|||||||
}
|
}
|
||||||
s.Truncation = fyne.TextTruncateEllipsis
|
s.Truncation = fyne.TextTruncateEllipsis
|
||||||
box.Add(s)
|
box.Add(s)
|
||||||
|
box.Refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
chatSidebar = *container.NewGridWithColumns(1, container.NewVScroll(box))
|
chatSidebar = *container.NewGridWithColumns(1, container.NewVScroll(box))
|
||||||
|
} else {
|
||||||
|
if activeChatJid == config.Login.User {
|
||||||
|
chatSidebar = *container.NewVBox(widget.NewRichTextFromMarkdown("# "+activeChatJid), widget.NewLabel("Hey, that's you!"))
|
||||||
} else {
|
} else {
|
||||||
chatSidebar = *container.NewVBox(widget.NewRichTextFromMarkdown("# " + activeChatJid))
|
chatSidebar = *container.NewVBox(widget.NewRichTextFromMarkdown("# " + activeChatJid))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
chatSidebar.Hidden = false
|
chatSidebar.Hidden = false
|
||||||
chatSidebar.Refresh()
|
chatSidebar.Show()
|
||||||
|
MainSplit.Resize(MainSplit.Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
chatSidebar.Hidden = false
|
chatSidebar.Hidden = false
|
||||||
statBar.SetText("")
|
statBar.SetText("")
|
||||||
chatInfo = *container.NewHBox(widget.NewLabel(""))
|
chatInfo = *container.NewHBox(widget.NewLabel(""))
|
||||||
MainSplit := container.NewHSplit(AppTabs, &chatSidebar)
|
MainSplit = container.NewHSplit(AppTabs, &chatSidebar)
|
||||||
DownSplit := container.NewHSplit(entry, container.NewGridWithRows(1, sendbtn, replybtn))
|
DownSplit := container.NewHSplit(entry, container.NewGridWithRows(1, sendbtn, replybtn))
|
||||||
|
|
||||||
BigSplit := container.NewVSplit(MainSplit, DownSplit)
|
BigSplit := container.NewVSplit(MainSplit, DownSplit)
|
||||||
@@ -1592,5 +1791,15 @@ func main() {
|
|||||||
|
|
||||||
MasterSplit.SetOffset(1)
|
MasterSplit.SetOffset(1)
|
||||||
w.SetContent(MasterSplit)
|
w.SetContent(MasterSplit)
|
||||||
|
if time.Now().Month() == time.April && time.Now().Day() == 1 {
|
||||||
|
dialog.ShowConfirm("We care about your privacy", "We and our 5832 partner(s) would like to use your data for the following purposes:\n- Selling your organs\n- Stealing your identity\n- Putting you in jail\nYou're in control of your in data.\nDo you want us to do this? We'll do it anyway if you say no.", func(b bool) {
|
||||||
|
if b {
|
||||||
|
u, err := url.Parse("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
||||||
|
if err == nil {
|
||||||
|
a.OpenURL(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, w)
|
||||||
|
}
|
||||||
w.ShowAndRun()
|
w.ShowAndRun()
|
||||||
}
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// auto-generated
|
|
||||||
// Code generated by '$ fyne bundle'. DO NOT EDIT.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "fyne.io/fyne/v2"
|
|
||||||
|
|
||||||
var resourcePiloadingGif = &fyne.StaticResource{
|
|
||||||
StaticName: "piloading.gif",
|
|
||||||
StaticContent: []byte(
|
|
||||||
"GIF87a@\x01@\x01w\x00\x00!\xff\vNETSCAPE2.0\x03\x01\x00\x00\x00!\xf9\x04\t2\x00\x00\x00,\x00\x00\x00\x00@\x01@\x01\x80\x00\x00\x00\" 4\x02\xff\x84\x8f\xa9\xcb\xed\x0f\xa3\x9c\xb4ڋ\xb3\u07bc\xfb\x0f\x86\xe2H\x96扦\xeaʶ\xee\v\xc7\xf2L\xd7\xf6\x8d\xe7\xfa\xce\xf7\xfe\x0f\f\n\x87Ģ\xf1\x88L*\x97̦\xf3\t\x8dJ\xa7Ԫ\xf5\x8a\xcdj\xb7ܮ\xf7\v\x0e\x8b\xc7\xe4\xb2\xf9\x8cN\xab\xd7\xec\xb6\xfb\r\x8f\xcb\xe7\xf4\xba\xfd\x8e\xcf\xeb\xf7\xfc\xbe\xff\x0f\x18(8HXhx\x88\x98\xa8\xb8\xc8\xd8\xe8\xf8\b\x19)9IYiy\x89\x99\xa9\xb9\xc9\xd9\xe9\xf9\t\x1a*:JZjz\x8a\x9a\xaa\xba\xca\xda\xea\xfa\n\x1b+;K[k{\x8b\x9b\xab\xbb\xcb\xdb\xeb\xfb\v\x1c,<L\\l|\x8c\x9c\xac\xbc\xcc\xdc\xec\xfc\f\x1d-=M]m}\x8d\x9d\xad\xbd\xcd\xdd\xed\xfd\r\x1e.>N^n~\x8e\x9e\xae\xbe\xce\xde\xee\xfe\x0e\x1f/?\xcf\x1c`\x7f\x8f\x9f\xaf\xbf\xcf\xdf\xef\xff\x0f\xd0\x1e\xbd\x80\x04\v\x1a<\x98o \u0085\f\x1b\x06P\xe80\xa2\xc4~\x10'Z\xb4X\xf1\xa2Ɔ\xff\x197z4\xd8\xf1\xa3\xc8\x7f!G\x9a\xd4W\xf2\xa4ʇ\xf3\xfc\x01qْ\xe2\x0f\x98\xf2h\xf6\xb0\t\x0f\xe7\x0e\x9d\xeex\xe6\xf0\xc9\x0e\xe8\r\xa1\xea\x88\xd60\x8a\x0e\xe9\f\xa5\xe6\x98\xc6pJ\x0e\xea\v\xa9⨶\xb0\xea\x00\xeb-\xad*\xb8.\xf0J\v\xec\t\xb1\b\xc8\xc62K\x02-\x00\xb5\xae؆P\xeb\x96U\xdc\x0fpe*\x9b\xeb\xa1.\xbfzvo\xf6\xcd\xfb\xf7\x18\xde\x0ez\xf7\xf1\xdd;30\x87\xc1\xa8\x18op\xec\fr\x06ɇ\r'F\\S\xf1O\xcdA9\x0f\xf5\\\x14\xf4Q\xd1II/5\xdd\x14\xf5S\xd5QYOu]\x15\xf6U\xd9\xe0(_\xb0}\x97\xf6\n\xdc\xc9xS\xf0-XwW\xe1݀K0^\f9\x04\xe5Øg%\xce\xcdy\x03\xe9\xc0\xa8\x7f\x85\xbeͺ\x02\xed\xbd\xb8\x97\xc5\xfe\x1dso\xf0%\n\xa3\\\xe6\xfd\x80\xf9\x84\xe8ɧu\xbf\x16~[\xf9o᧗t?\xbex\xc0\xfb\x83\xf7\xffױ\x1e>\x95\x9d\xe7C\x80\xf7\f\xc8^\x81\xf6\xd1'\x17\x83t-\xf8_r+M(`}\x11\x12Ca\x86,\x81\x90\x1f$\x1aR(B\x87\x8f|8a\x88\x0e\xaaB\xe2J&^\xd8\\\x8a'\xadhYn.\x8e\x04#\x81\xe3\xcd(R\x8d\tވ\xa3G:V(c\x8f\x1b\xfdx`{,z!\xa2#I\xa6\xb0$#M\x8eub*O\x9a0e\"U\xbewd0W\x8e\xb0\xa5!]Z\x18#\x8f6\x92\xf1%!e>\x98euQ\x12q\xa6 m\x12\xb6\xe6)o.\x16\xa7)s>Vg)wj\xb0g\x1f}b\xf0\xe7\x1e\x81Z0h\x1e\x85\xfe\x96')\x87N\xb0\xa8\x1d\x8dF\xf0(\x1d\x91>0\xa9\x1c\x95N\x97\xe8(\x972\xb0\xe9\x1b\x9dn\x97\xa9(\x9f&0*\x1b\xa5\xaa\x17j(\xa7\x1a\xb0j\x1a\xad\xb6\x8aƫ\xa9\x82\"k\x9a\xbf\xd4\x1a&2\xb8\x8e\xe9_\xaec\xc0zƮ;\xea:\xebN\xc5z\",\x90b\xff\x0e\xfb뱝$[d\x90\xbc\x8a\x01\xac\x19\xd0\nd\xa4\xaf\xd4:\xcbɵ\x1b.\xab,\x99\xdcn\xe2-\x82\xe16k\xab/\xe5f;m\x18Ֆ\xb1\xae\xb4\xccn\x9bnw\xe3\xda\xf0\xae\xb8\xf5b\x91/\xbaں{o&\xf1\x82\x1b-\xbc\x01c20\xb1\xfb^\xd1/\xbd\xff\x82\xd10\xc0\v[\x111\xc4\a\x9f6q.\t\xf7ڮ\xc5\x19㲱1!K\xf8\xf1\x14\x15\x7f12\x86\x17\xcbp2\x92+\xafV\xb2-)\xb7\x18s\x14-w1\xb309k\xf92\f7s\xb1\xb3\x9a5C\xf1\xf3\x16A\xdf\xda\xf3kC\xcfr\xb4\xbaI\xbbP\xb4\x16Mۻ\xb4\x13Qg15/Yﲵ.]k\xfc\xf4lU\x9f\x156\vW\xf3[\xf6ni+\xb96\x93m;\xf96\x94c\xc3\xf25\xc8qSy\xf7\x1f>✷\x1f{\x03ݷ\x9fC\xf2=\xb7\x9e\x83\x03^\xb8\xa2\x87\x1b\x1d8\x1f\x7f3\x9e\xb8\xa6\x8bKݸ\xa0\x93gc]\xb9\x1e\x8fS\x1e\xb9\xa8\x97\xa3\xdd9=\xa2\x8fNz馟\x8ezꪯ\xcez뮿\x0e{\xec\xb2\xcfN{\xed\xb6ߎ{\xee\xba\xef\xce{\xef\xbe\xff\x0e|\xf0\xc2\x0fO|\xf1\xc6\x1f\x8f|\xf2\xca/\xcf|\xf3\xce?\x0f}\xf4\xd2OO}\xf5\xd6_\x8f}\xf6\xdao\xcf}\xf7\xde\x7f\x0f~\xf8\xe2\x8fO~\xf9\xe63Q\x00\x00!\xf9\x04\t\n\x00\x00\x00,2\x00P\x00\xb4\x00\xb4\x00\x80\x00\x00\x00\" 4\x02\xff\x84\x8f\xa9\xcb\xed\x19\xa2\x9c\xb4\xda;\x9f\u07bc\xfb\x0f\x86\x10F\x96\x98\x88\xa6\xeaʎ\xe6\xfb\xb6\xf2L\xd7\xf0]\xd6\xfa\xces\xf8o\xe9\t\x87B\xa0QBL*[\xc7\xe3\xf2\t\xfd4\x8dѪ\x951\x05^\xb7\xdb\xec\x8f\v摖\xdeJ8<V\x96)gp:\xb9δ\xbb'u<2\xa7_\xc8\xf7@\xfe\xfaF\xd4\xe7\xf7W\x1584XhX\aק\x18uX\xe4\xf8\xf8\x14ٓHɷGi\x99)ƨ\xd8\xe9\xa9#zV::s\xea\x06\x8a\xfa\xb9\xf9\xa8ں\x12\xab\x17${\xc9\xfaG{+\xb2k\xe5\xcb+\x95\x9b\a\x1c\xdcQ\f\x85l\xac\xa1\xaci\xbb\x9c:<\xd7\f\x8d%\xddF]\xad\x90-x\xad\r\u008d\xe8\xfd\xed\x11.\xf9J\x9eb\x8e\x8b\x9e\xde;\xbe\xda\xee\x0e\x0eϵ\xae}\xbf\x93\x0f\xbd\xff.?[/T@q\xffT\xf4\xb3S0\xd9\xc0c\v\x895t\xf5L\xc6\xc1F\t+=dv\xd1TF\x1b\xff\x1b\x1bL\xecVљ\x19\x1a\x1f\tF\x04\xd4\xd1ZHN)%\xb6\xdc\xf6\xf2WL\x80+\xe9լ\x85\x03\xcdL|T❜'L\x8bϑ@C8\x19ʦ\xa8ў\xf6vV;\xda\xf4\xa6R\x17_\x90ʙZ\x8e)ΤX\x19\n\x8d\xfa\xb3\xab\x03\xa8[\xaf\x8a\xc58(mճhպ5\xc1v\xc3۹9\xe2>\xa0\x8b7\xac]\x04y\xfb\"\xd9\xeb\xd1o_\xc0\x81\x05\xe3%\xac\xd2\xf0\\\xc4\v\x14\x1ffLձZȑ\xb9\x96\xfdKQ/6\xa7(JV6[ȳ\x0f\xcecI\x934mS3)\xd4.\xa5\x9eS\xcd\xd1\xf5\"\xd9\x10\x89\x82\x84m\x15\xf3e<\bq\x83\xb5\x8d\x92\xb6:\xd6L\x88{\xf5\xdd\x1ayp寁7\xb7\xbc\xdc9c\xd1\x06\x8d\xb7\xa2>\\\xb8R읭\xa3\xe2\xee\x8fyW\xf0K\xb5\x17%\x9fZ:b\xf4A\xc5ce\x9f\xd5<P\xf8\xc7\xd5\x13\xa6?Z\xfe<\xfcr\xbd\x8f\xff\xe2ߖ}\x80\x01x\x97\x7f\x9e\x10X\x9a~\xee X\x98{S1\x98\x98\x80{Aؘ\x81\x99P\b\x93\x82\xe9`\xf8\x99n\x94qȗ\x85,i\xf8\x1ch\x90\x81x\x00\x8a\n\x91Ȏ\x83ۉ\x98\x1et'\xc2؞\x84v\xa9\b\x00\x8e\"\xc9\xe8\x10\x8b<\xf9\xa8\x0f\x8d\xa1\tY\x1f\x8f\xeb\x11\x99\x9f\x8b\xe7!\xd9\x1f\x90\xfc0\x19\xa0\x91\xf7AY\xa0\x93\xcb\xe0\xa8co6\xfe&\xe5\x80T&\xa8\xe4|_6\xb8%[X\x8eɥ\x89=\x86\xb9\x1f\x95YfVft]N\x88f\x85V\x1as\xe6\x9d\xc1\xe4\xc9\xe6\x82uf\xd8\xe7\x86\x7fv\xc8\x1be\x06\xf0\x19\xa7X\x88\xcey\xe3\xa0!\xea\xc9ˢjLine truncated
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user