Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
3f6b87623d | |||
d3bffcef81 | |||
53367e5982 | |||
b765e8f11c | |||
969199b0d7 | |||
5b0072a488 | |||
636df591b8 | |||
d4433a20ed | |||
80489d1877 | |||
713bde2d23 | |||
ffd6023ae2 | |||
003a156c50 | |||
402383f516 | |||
c0d19e4335 | |||
853bed70e7 | |||
21564cc70e | |||
f9ac50392e | |||
fa11b3ee87 | |||
7eabb0c30e | |||
1da705a1b0 | |||
5988eead04 | |||
2fd5f48334 | |||
d2b9f9843f | |||
65e4e3380c | |||
8e58139fcb | |||
![]() |
50caef2f39 | ||
4b64de882d | |||
dfaf56a330 | |||
02f6adad02 | |||
![]() |
a6285b0d8a | ||
6267a4a072 | |||
ac5d0aa2bf | |||
c20f77ce0f | |||
59ef99f200 | |||
56797b92eb | |||
e391ea9ad6 | |||
a02a043808 | |||
bd34df424b | |||
efa801b393 | |||
f65cf4a17d | |||
7e8ceb2b2a | |||
6ab9dd8ff8 | |||
![]() |
91881439a4 | ||
![]() |
2972c86641 | ||
e5f391edfd |
34
.github/workflows/go.yml
vendored
34
.github/workflows/go.yml
vendored
@@ -1,34 +0,0 @@
|
||||
# This workflow will build a golang project
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
|
||||
|
||||
name: build this now
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.24'
|
||||
- name: Install X11 dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libgl1-mesa-dev libglu1-mesa-dev libxxf86vm-dev
|
||||
|
||||
- name: Build
|
||||
run: go build .
|
||||
|
||||
- name: Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pi-binary
|
||||
path: pi-im
|
||||
|
123
README.md
123
README.md
@@ -1,9 +1,7 @@
|
||||
<center>
|
||||
<img width="100" height="100" src="https://github.com/sunglocto/pi/blob/255bc3749c089e3945871ddf19dd17d14a83f9ff/pi.png">
|
||||
<img width="100" height="100" src="https://forge.sunglocto.net/sunglocto/pi-im/raw/branch/master/pi.png">
|
||||
</center>
|
||||
|
||||
[](https://github.com/sunglocto/pi/actions/workflows/go.yml)
|
||||
<img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/9e2d9209-6ad5-4f22-94d0-4cc18c835372" />
|
||||
<img alt="Pi screenshot" src="https://github.com/user-attachments/assets/9e2d9209-6ad5-4f22-94d0-4cc18c835372" />
|
||||
|
||||
|
||||
## the XMPP client from hell
|
||||
@@ -58,27 +56,65 @@ As of writing, pi supports basic message sending and receiving, replies, file up
|
||||
|
||||
To build pi, you will need the latest version of Go, at least 1.21. You can grab it [here](https://go.dev).
|
||||
|
||||
You must have a C compiler on your system also present. This will be the case for virtually all PC operating systems except Windows.
|
||||
|
||||
The build instructions are very simple. Simply clone the repo, fetch the repositories and build the program.
|
||||
|
||||
Here is a summary of the commands you would need to use:
|
||||
```bash
|
||||
git clone https://github.com/sunglocto/pi-im
|
||||
git clone https://forge.sunglocto.net/sunglocto/pi-im
|
||||
cd pi-im
|
||||
go mod tidy
|
||||
go build .
|
||||
./pi-im
|
||||
|
||||
```
|
||||
> Uh, Windows???
|
||||
|
||||
Eventually. Don't count on it.
|
||||
Fyne has first-class support for Windows and all of my dependencies are platform imdependent. I've built this app for Android before. If you compile it, it will most likely work with no issues.
|
||||
Windows requires more steps to setup, specifically you need an MSYS2 environment. As per [the Fyne documentation](https://docs.fyne.io/started/)
|
||||
|
||||
Static executable snapshots are also provided for GNU/Linux systems on every new version, and CI runs on every commit, producing a binary on every successful build. You're welcome.
|
||||
|
||||
The MSYS2 platform is the recommended approach for working on Windows. Proceed as follows:
|
||||
|
||||
Install MSYS2 from msys2.org
|
||||
Once installed do not use the MSYS terminal that opens
|
||||
Open “MSYS2 MinGW 64-bit” from the start menu
|
||||
|
||||
Execute the following commands (if asked for install options be sure to choose “all”):
|
||||
|
||||
$ pacman -Syu
|
||||
$ pacman -S git mingw-w64-x86_64-toolchain mingw-w64-x86_64-go
|
||||
|
||||
You will need to add ~/Go/bin to your $PATH, for MSYS2 you can paste the following command into your terminal:
|
||||
|
||||
$ echo "export PATH=\$PATH:~/Go/bin" >> ~/.bashrc
|
||||
|
||||
For the compiler to work on other terminals you will need to set up the windows %PATH% variable to find these tools. Go to the “Edit the system environment variables” control panel, tap “Advanced” and add “C:\msys64\mingw64\bin” to the Path list.
|
||||
|
||||
|
||||
<img alt="image" src="https://github.com/user-attachments/assets/5a6c188f-e890-4398-856c-e88f5804e9d2" />
|
||||
|
||||
pi has been tested on FreeBSD and NetBSD with no issues. Please read their respective Wiki entries.
|
||||
|
||||
Static executable snapshots are also provided for GNU/Linux systems on every new version.
|
||||
|
||||
## Wayland
|
||||
On BSD and Linux systems, you may want to build an executable for Wayland only, meaning it will not run through XWayland. This will increase performance and also allow drag-on-drop functionality. Most Wayland setups can run X11 apps, but no X11 setup can run Wayland apps. Because of this, all executables are shipped for use with X11. This may change in the future, but if you want to build for Wayland, it's as simple as the commands above, but just adding a `wayland` tag to the build command.
|
||||
|
||||
A Wayland-only executable will also substantially decrease the level of screen tearing and lag.
|
||||
|
||||
```bash
|
||||
git clone https://forge.sunglocto.net/sunglocto/pi-im
|
||||
cd pi-im
|
||||
go mod tidy
|
||||
go build -tags wayland .
|
||||
./pi-im
|
||||
```
|
||||
|
||||
## εγκατάσταση
|
||||
(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/pi-im), which is maintained by [snit](https://isekai.rocks/~snit).
|
||||
|
||||
## υποστήριξη
|
||||
(support)
|
||||
@@ -87,6 +123,71 @@ You can file an issue and explain the problem you are having.
|
||||
|
||||
If you would like a more instant method of communication, join the [pi XMPP room.](xmpp:pi@room.sunglocto.net?join)
|
||||
|
||||
|
||||
## εξαρτήσεις
|
||||
(dependencies)
|
||||
|
||||
### Running
|
||||
Pi will require no additional dependencies to run on MacOS and Windows systems.
|
||||
|
||||
On other *NIX systems, `dbus` is needed for notification support, but is not required.
|
||||
If your system has an X11 or Wayland setup, Pi will most likely work without issues.
|
||||
|
||||
Pi does not require GTK, Qt or any other graphical layout.
|
||||
|
||||
### Compiling
|
||||
In general, you need Go, a C compiler and graphical libraries.
|
||||
|
||||
*This information is from the [the Fyne documentation.](https://docs.fyne.io/started) Windows and MacOS users are heavily reccomended to simply use pre-compiled binaries, due a more complex set of dependencies.*
|
||||
|
||||
Linux systems:
|
||||
|
||||
Debian, Ubuntu and Raspberry Pi OS: `sudo apt-get install golang gcc libgl1-mesa-dev xorg-dev libxkbcommon-dev`
|
||||
|
||||
Fedora: `sudo dnf install golang golang-misc gcc libXcursor-devel libXrandr-devel mesa-libGL-devel libXi-devel libXinerama-devel libXxf86vm-devel libxkbcommon-devel wayland-devel`
|
||||
|
||||
Arch Linux: `sudo pacman -S go xorg-server-devel libxcursor libxrandr libxinerama libxi libxkbcommon`
|
||||
|
||||
Solus: `sudo eopkg it -c system.devel golang mesalib-devel libxrandr-devel libxcursor-devel libxi-devel libxinerama-devel libxkbcommon-devel`
|
||||
|
||||
openSUSE: `sudo zypper install go gcc libXcursor-devel libXrandr-devel Mesa-libGL-devel libXi-devel libXinerama-devel libXxf86vm-devel libxkbcommon-devel`
|
||||
|
||||
Void Linux: `sudo xbps-install -S go base-devel xorg-server-devel libXrandr-devel libXcursor-devel libXinerama-devel libXxf86vm-devel libxkbcommon-devel wayland-devel`
|
||||
|
||||
Alpine Linux: `sudo apk add go gcc libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev linux-headers mesa-dev libxkbcommon-dev wayland-dev``
|
||||
|
||||
NixOS: `nix-shell -p libGL pkg-config xorg.libX11.dev xorg.libXcursor xorg.libXi xorg.libXinerama xorg.libXrandr xorg.libXxf86vm libxkbcommon wayland`
|
||||
|
||||
BSD systems:
|
||||
|
||||
FreeBSD: `sudo pkg install go gcc xorg pkgconf`
|
||||
|
||||
OpenBSD: `sudo pkg_add go`
|
||||
|
||||
NetBSD: `sudo pkgin install go pkgconf`
|
||||
|
||||
## αρμονία
|
||||
(compatibility)
|
||||
|
||||
pi will run on the following operating systems:
|
||||
- Windows 10 and up
|
||||
- Most modern GNU/Linux installations
|
||||
- FreeBSD
|
||||
- NetBSD
|
||||
- OpenBSD
|
||||
- MacOS
|
||||
|
||||
pi has experimental support for the following operating system:
|
||||
- Android [1]
|
||||
|
||||
pi most likely will **not** run on the following operating systems:
|
||||
- 32-bit systems
|
||||
- iOS
|
||||
- ARM systems
|
||||
|
||||
|
||||
If you use pi on a specific operating system and it does not work, file an issue and describe the problem you have having.
|
||||
|
||||
## μαρτυρίες
|
||||
(testimonials)
|
||||
From fellow insane and schizophrenic XMPP users:
|
||||
@@ -108,7 +209,7 @@ From fellow insane and schizophrenic XMPP users:
|
||||
## επιπλέον
|
||||
(extra)
|
||||
|
||||
Pi version numbers are the digits of Pi followed by a letter indicating the phase of development the program is in.
|
||||
pi version numbers are the digits of Pi followed by a letter indicating the phase of development the program is in.
|
||||
|
||||
For example, the version string:
|
||||
|
||||
@@ -121,3 +222,5 @@ The digits of Pi will reset back to `3` when moving to a new phase.
|
||||
If the number gets too long, it will reset to one digit of 2π. Once that gets too long, it will be digits of 3π and etc.
|
||||
|
||||
Named after [Psi](https://github.com/psi-im/psi).
|
||||
|
||||
[1] Android is not a supported platform, however it's possible to compile and run pi for it. If you want to become suicidal, you can go for it, but pi is a primarily PC-oriented client. There are multiple mobile clients that already exist which will give you a substantially better experience.
|
||||
|
4016
credits.go
Normal file
4016
credits.go
Normal file
File diff suppressed because it is too large
Load Diff
42
go.mod
42
go.mod
@@ -1,50 +1,52 @@
|
||||
module pi-im
|
||||
|
||||
go 1.24.5
|
||||
go 1.24.6
|
||||
|
||||
require (
|
||||
fyne.io/fyne/v2 v2.6.2
|
||||
fyne.io/x/fyne v0.0.0-20250418202416-58a230ad1acb
|
||||
fyne.io/fyne/v2 v2.6.3
|
||||
fyne.io/x/fyne v0.0.0-20250827163406-39fd826f385e
|
||||
github.com/makeworld-the-better-one/go-isemoji v1.3.0
|
||||
github.com/rrivera/identicon v0.0.0-20240116195454-d5ba35832c0d
|
||||
github.com/shreve/musicwand v0.0.1
|
||||
mellium.im/xmpp v0.22.0
|
||||
pain.agency/oasis-sdk v0.0.0-20250809192709-a3e5dff1aa61
|
||||
pain.agency/oasis-sdk v0.0.0-20250831105702-85385dca3a95
|
||||
)
|
||||
|
||||
require (
|
||||
fyne.io/systray v1.11.0 // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fredbi/uri v1.1.1 // indirect
|
||||
github.com/fredbi/uri v1.1.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.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/image v0.1.1 // indirect
|
||||
github.com/fyne-io/oksvg v0.1.0 // indirect
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728 // indirect
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
|
||||
github.com/go-text/render v0.2.0 // indirect
|
||||
github.com/go-text/typesetting v0.3.0 // indirect
|
||||
github.com/go-text/typesetting v0.2.1 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/hack-pad/go-indexeddb v0.3.2 // indirect
|
||||
github.com/hack-pad/safejs v0.1.1 // indirect
|
||||
github.com/hack-pad/safejs v0.1.0 // indirect
|
||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rymdport/portal v0.4.2 // indirect
|
||||
github.com/rymdport/portal v0.4.1 // indirect
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/yuin/goldmark v1.7.13 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/image v0.30.0 // indirect
|
||||
golang.org/x/mod v0.27.0 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
github.com/yuin/goldmark v1.7.8 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/image v0.24.0 // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/net v0.37.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/tools v0.25.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
mellium.im/reader v0.1.0 // indirect
|
||||
mellium.im/sasl v0.3.2 // indirect
|
||||
|
94
go.sum
94
go.sum
@@ -1,17 +1,20 @@
|
||||
fyne.io/fyne/v2 v2.6.2 h1:RPgwmXWn+EuP/TKwO7w5p73ILVC26qHD9j3CZUZNwgM=
|
||||
fyne.io/fyne/v2 v2.6.2/go.mod h1:9IJ8uWgzfcMossFoUkLiOrUIEtaDvF4nML114WiCtXU=
|
||||
fyne.io/fyne/v2 v2.6.3 h1:cvtM2KHeRuH+WhtHiA63z5wJVBkQ9+Ay0UMl9PxFHyA=
|
||||
fyne.io/fyne/v2 v2.6.3/go.mod h1:NGSurpRElVoI1G3h+ab2df3O5KLGh1CGbsMMcX0bPIs=
|
||||
fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
|
||||
fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
|
||||
fyne.io/x/fyne v0.0.0-20250418202416-58a230ad1acb h1:2BazNmb/kwgqRdvE9L+NgW8sfoWGn3iy1Ox8R4+CSmc=
|
||||
fyne.io/x/fyne v0.0.0-20250418202416-58a230ad1acb/go.mod h1:u3LF1EkElytjOT8OHxft16trctGndF9qpsoH6YIDOUU=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
fyne.io/x/fyne v0.0.0-20250827163406-39fd826f385e h1:oJM+HGkpSuq1J+JqUq/jo7KPrKj2K2/VIZlyus04w3Y=
|
||||
fyne.io/x/fyne v0.0.0-20250827163406-39fd826f385e/go.mod h1:u3LF1EkElytjOT8OHxft16trctGndF9qpsoH6YIDOUU=
|
||||
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.4.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/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/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/fredbi/uri v1.1.1 h1:xZHJC08GZNIUhbP5ImTHnt5Ya0T8FI2VAwI/37kh2Ko=
|
||||
github.com/fredbi/uri v1.1.1/go.mod h1:4+DZQ5zBjEwQCDmXW5JdIjz0PUA+yJbvtBv+u+adr5o=
|
||||
github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8=
|
||||
github.com/fredbi/uri v1.1.0/go.mod h1:aYTUoAXBOq7BLfVJ8GnKmfcuURosB1xyHDIfWeC/iW4=
|
||||
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/fyne-io/gl-js v0.2.0 h1:+EXMLVEa18EfkXBVKhifYB6OGs3HwKO3lUElA0LlAjs=
|
||||
@@ -24,34 +27,35 @@ github.com/fyne-io/oksvg v0.1.0 h1:7EUKk3HV3Y2E+qypp3nWqMXD7mum0hCw2KEGhI1fnBw=
|
||||
github.com/fyne-io/oksvg v0.1.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI=
|
||||
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/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728 h1:RkGhqHxEVAvPM0/R+8g7XRwQnHatO0KAuVcwHo8q9W8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728/go.mod h1:SyRD8YfuKk+ZXlDqYiqe1qMSqjNgtHzBTG810KUagMc=
|
||||
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-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc=
|
||||
github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU=
|
||||
github.com/go-text/typesetting v0.3.0 h1:OWCgYpp8njoxSRpwrdd1bQOxdjOXDj9Rqart9ML4iF4=
|
||||
github.com/go-text/typesetting v0.3.0/go.mod h1:qjZLkhRgOEYMhU9eHBr3AR4sfnGJvOXNLt8yRAySFuY=
|
||||
github.com/go-text/typesetting v0.2.1 h1:x0jMOGyO3d1qFAPI0j4GSsh7M0Q3Ypjzr4+CEVg82V8=
|
||||
github.com/go-text/typesetting v0.2.1/go.mod h1:mTOxEwasOFpAMBjEQDhdWRckoLLeI/+qrQeBCTGEt6M=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066 h1:qCuYC+94v2xrb1PoS4NIDe7DGYtLnU2wWiQe9a1B1c0=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/hack-pad/go-indexeddb v0.3.2 h1:DTqeJJYc1usa45Q5r52t01KhvlSN02+Oq+tQbSBI91A=
|
||||
github.com/hack-pad/go-indexeddb v0.3.2/go.mod h1:QvfTevpDVlkfomY498LhstjwbPW6QC4VC/lxYb0Kom0=
|
||||
github.com/hack-pad/safejs v0.1.1 h1:d5qPO0iQ7h2oVtpzGnLExE+Wn9AtytxIfltcS2b9KD8=
|
||||
github.com/hack-pad/safejs v0.1.1/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio=
|
||||
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/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/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/makeworld-the-better-one/go-isemoji v1.3.0 h1:vrxfd0W0Xs8t7BnIYXkvSK7m+GDk/0x1ClXPbWjQ5A0=
|
||||
github.com/makeworld-the-better-one/go-isemoji v1.3.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1 h1:IxtPxYsR9Gp60cGXjfuR/llTqV8aYMsC472zD0D1vHk=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||
@@ -60,35 +64,45 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
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/rymdport/portal v0.4.2 h1:7jKRSemwlTyVHHrTGgQg7gmNPJs88xkbKcIL3NlcmSU=
|
||||
github.com/rymdport/portal v0.4.2/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
|
||||
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.1/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
|
||||
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/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE=
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA=
|
||||
github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/image v0.30.0 h1:jD5RhkmVAnjqaCUXfbGBrn3lpxbknfN9w2UhHHU+5B4=
|
||||
golang.org/x/image v0.30.0/go.mod h1:SAEUTxCCMWSrJcCy/4HwavEsfZZJlYxeHLc6tTiAe/c=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
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/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
||||
golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
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/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
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/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
|
||||
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
mellium.im/reader v0.1.0 h1:UUEMev16gdvaxxZC7fC08j7IzuDKh310nB6BlwnxTww=
|
||||
@@ -99,5 +113,5 @@ mellium.im/xmlstream v0.15.4 h1:gLKxcWl4rLMUpKgtzrTBvr4OexPeO/edYus+uK3F6ZI=
|
||||
mellium.im/xmlstream v0.15.4/go.mod h1:yXaCW2++fmVO4L9piKVkyLDqnCmictVYF7FDQW8prb4=
|
||||
mellium.im/xmpp v0.22.0 h1:UthQVSwEAr7SNrmyc90c2ykGpVHxjn/3yw8Ey4+Im8s=
|
||||
mellium.im/xmpp v0.22.0/go.mod h1:WSjq12nhREFD88Vy/0WD6Q8inE8t6a8w7QjzwivWitw=
|
||||
pain.agency/oasis-sdk v0.0.0-20250809192709-a3e5dff1aa61 h1:7zb69SAfLAJhXoqXZaS0pq/p1Y9W19Pm4FjcwWjTVoE=
|
||||
pain.agency/oasis-sdk v0.0.0-20250809192709-a3e5dff1aa61/go.mod h1:eyvDgfpHo+9bdB/AkMEMZ3ETeoSONTULVx9X4w9kGAU=
|
||||
pain.agency/oasis-sdk v0.0.0-20250831105702-85385dca3a95 h1:BcB7/hnMnQIU+pERvQRGFMt9i0/o8XCnHbK1kYG3/K4=
|
||||
pain.agency/oasis-sdk v0.0.0-20250831105702-85385dca3a95/go.mod h1:eyvDgfpHo+9bdB/AkMEMZ3ETeoSONTULVx9X4w9kGAU=
|
||||
|
554
main.go
554
main.go
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
//core - required
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
_ "image/color"
|
||||
"io"
|
||||
@@ -22,20 +23,23 @@ import (
|
||||
"fyne.io/fyne/v2/storage"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"github.com/rrivera/identicon"
|
||||
extraWidgets "fyne.io/x/fyne/widget"
|
||||
"github.com/makeworld-the-better-one/go-isemoji"
|
||||
"github.com/rrivera/identicon"
|
||||
"github.com/shreve/musicwand/pkg/mpris"
|
||||
|
||||
// xmpp - required
|
||||
"mellium.im/xmpp/disco"
|
||||
_ "mellium.im/xmpp/disco"
|
||||
"mellium.im/xmpp/jid"
|
||||
"mellium.im/xmpp/muc"
|
||||
_ "mellium.im/xmpp/stanza"
|
||||
oasisSdk "pain.agency/oasis-sdk"
|
||||
// gui - optional
|
||||
// catppuccin "github.com/mbaklor/fyne-catppuccin"
|
||||
// TODO: integrated theme switcher
|
||||
)
|
||||
|
||||
var version string = "3.142a"
|
||||
var version string = "3i"
|
||||
var statBar widget.Label
|
||||
var chatInfo fyne.Container
|
||||
var chatSidebar fyne.Container
|
||||
@@ -105,6 +109,7 @@ type piConfig struct {
|
||||
Login oasisSdk.LoginInfo
|
||||
DMs []string
|
||||
Notifications bool
|
||||
JoinBookmarks bool
|
||||
}
|
||||
|
||||
var config piConfig
|
||||
@@ -161,14 +166,18 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
||||
content.Wrapping = fyne.TextWrapWord
|
||||
content.Selectable = true
|
||||
icon := theme.FileVideoIcon()
|
||||
replytext := widget.NewLabel("> fallback reply text")
|
||||
replytext.Hide()
|
||||
replytext.Importance = widget.SuccessImportance
|
||||
btn := widget.NewButtonWithIcon("View media", icon, func() {
|
||||
|
||||
})
|
||||
return container.NewVBox(container.NewHBox(ico, author), content, btn)
|
||||
return container.NewVBox(replytext, container.NewHBox(ico, author), content, btn)
|
||||
},
|
||||
func(i widget.ListItemID, co fyne.CanvasObject) {
|
||||
vbox := co.(*fyne.Container)
|
||||
authorBox := vbox.Objects[0].(*fyne.Container)
|
||||
authorBox := vbox.Objects[1].(*fyne.Container)
|
||||
replytext := vbox.Objects[0].(*widget.Label)
|
||||
// generate a Icon
|
||||
|
||||
gen, _ := identicon.New("github", 5, 3)
|
||||
@@ -181,8 +190,8 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
||||
// Icon generate end
|
||||
|
||||
author := authorBox.Objects[1].(*widget.Label)
|
||||
content := vbox.Objects[1].(*widget.Label)
|
||||
btn := vbox.Objects[2].(*widget.Button)
|
||||
content := vbox.Objects[2].(*widget.Label)
|
||||
btn := vbox.Objects[3].(*widget.Button)
|
||||
if chatTabs[chatJidStr].Messages[i].Important {
|
||||
//content.Importance = widget.DangerImportance TODO: Fix highlighting messages with mentions, it's currently broken
|
||||
}
|
||||
@@ -199,7 +208,8 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
||||
})
|
||||
return
|
||||
}
|
||||
if strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp4") || strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp3") {
|
||||
|
||||
if strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp4") || strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "mp3") || strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "gif") || strings.HasSuffix(chatTabs[chatJidStr].Messages[i].ImageURL, "webp") { // FIXME: This code is fucking terrible // TODO: Could check mime?
|
||||
url, err := url.Parse(chatTabs[chatJidStr].Messages[i].ImageURL)
|
||||
if err != nil {
|
||||
fyne.Do(func() {
|
||||
@@ -232,18 +242,39 @@ func CreateUITab(chatJidStr string) ChatTabUI {
|
||||
//content.ParseMarkdown(msgContent)
|
||||
content.SetText(msgContent)
|
||||
if chatTabs[chatJidStr].Messages[i].ReplyID != "PICLIENT:UNAVAILABLE" {
|
||||
author.SetText(fmt.Sprintf("%s > %s", chatTabs[chatJidStr].Messages[i].Author, jid.MustParse(chatTabs[chatJidStr].Messages[i].Raw.Reply.To).Resourcepart()))
|
||||
reply := chatTabs[chatJidStr].Messages[i].Raw.Reply
|
||||
guy := jid.MustParse(reply.To).Resourcepart()
|
||||
// TODO: EXPERIMENTALLY GET REPLIED TO TEXT
|
||||
|
||||
for i := len(chatTabs[chatJidStr].Messages) - 1; i >= 0; i-- {
|
||||
if reply.ID == chatTabs[chatJidStr].Messages[i].Raw.StanzaID.ID {
|
||||
replytext.Show()
|
||||
replytext.SetText(fmt.Sprintf("> %s", chatTabs[chatJidStr].Messages[i].Content))
|
||||
guy = chatTabs[chatJidStr].Messages[i].Author
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
author.SetText(fmt.Sprintf("%s > %s", chatTabs[chatJidStr].Messages[i].Author, guy))
|
||||
} else {
|
||||
author.SetText(chatTabs[chatJidStr].Messages[i].Author)
|
||||
replytext.Hide()
|
||||
}
|
||||
|
||||
sl := strings.Split(msgContent, " ")
|
||||
|
||||
if len(sl) == 1 && isemoji.IsEmoji(sl[0]) {
|
||||
content.SizeName = fyne.ThemeSizeName(theme.SizeNameHeadingText)
|
||||
content.Refresh()
|
||||
}
|
||||
|
||||
if sl[0] == "/me" {
|
||||
author.SetText(author.Text + " " + strings.Join(sl[1:], " "))
|
||||
content.SetText(" ")
|
||||
}
|
||||
|
||||
scroller.SetItemHeight(i, vbox.MinSize().Height)
|
||||
vbox.Refresh()
|
||||
},
|
||||
)
|
||||
|
||||
@@ -287,7 +318,7 @@ func addChatTab(isMuc bool, chatJid jid.JID, nick string) {
|
||||
var icon fyne.Resource
|
||||
if isMuc {
|
||||
icon = theme.HomeIcon()
|
||||
} else{
|
||||
} else {
|
||||
icon = theme.AccountIcon()
|
||||
}
|
||||
|
||||
@@ -297,7 +328,7 @@ func addChatTab(isMuc bool, chatJid jid.JID, nick string) {
|
||||
}
|
||||
|
||||
func dropToSignInPage(reason string) {
|
||||
w = a.NewWindow("Welcome to Pi")
|
||||
w = a.NewWindow("Welcome to pi")
|
||||
w.Resize(fyne.NewSize(500, 500))
|
||||
rt := widget.NewRichTextFromMarkdown("# Welcome to pi\nIt appears you do not have a valid account configured. Let's create one!")
|
||||
footer := widget.NewRichTextFromMarkdown(fmt.Sprintf("Reason for being dropped to the sign-in page:\n\n```%s```", reason))
|
||||
@@ -367,6 +398,7 @@ func main() {
|
||||
|
||||
config = piConfig{}
|
||||
a = app.NewWithID("pi-im")
|
||||
//a.Settings().SetTheme(&myTheme{})
|
||||
reader, err := a.Storage().Open("pi.xml")
|
||||
if err != nil {
|
||||
dropToSignInPage(err.Error())
|
||||
@@ -391,69 +423,16 @@ func main() {
|
||||
notifications = config.Notifications
|
||||
|
||||
client, err := oasisSdk.CreateClient(
|
||||
&login,
|
||||
func(client *oasisSdk.XmppClient, msg *oasisSdk.XMPPChatMessage) {
|
||||
fmt.Println(msg)
|
||||
userJidStr := msg.From.Bare().String()
|
||||
tab, ok := chatTabs[userJidStr]
|
||||
fmt.Println(msg.From.String())
|
||||
if ok {
|
||||
str := *msg.CleanedBody
|
||||
if notifications {
|
||||
a.SendNotification(fyne.NewNotification(fmt.Sprintf("%s says", userJidStr), str))
|
||||
}
|
||||
var img string = ""
|
||||
if strings.Contains(str, "https://") {
|
||||
lines := strings.Split(str, "\n")
|
||||
for i, line := range lines {
|
||||
s := strings.Split(line, " ")
|
||||
for _, v := range s {
|
||||
_, err := url.Parse(v)
|
||||
if err == nil && strings.HasPrefix(v, "https://") {
|
||||
if strings.HasSuffix(v, ".png") || strings.HasSuffix(v, ".jpg") || strings.HasSuffix(v, ".jpeg") || strings.HasSuffix(v, ".webp") || strings.HasSuffix(v, ".mp4") {
|
||||
img = v
|
||||
}
|
||||
}
|
||||
}
|
||||
lines[i] = strings.Join(s, " ")
|
||||
}
|
||||
str = strings.Join(lines, " ")
|
||||
}
|
||||
var replyID string
|
||||
if msg.Reply == nil {
|
||||
replyID = "PICLIENT:UNAVAILABLE"
|
||||
} else {
|
||||
replyID = msg.Reply.ID
|
||||
}
|
||||
myMessage := Message{
|
||||
Author: msg.From.Resourcepart(),
|
||||
Content: str,
|
||||
ID: msg.ID,
|
||||
ReplyID: replyID,
|
||||
Raw: *msg,
|
||||
ImageURL: img,
|
||||
}
|
||||
&login)
|
||||
|
||||
tab.Messages = append(tab.Messages, myMessage)
|
||||
fyne.Do(func() {
|
||||
UITabs[userJidStr].Scroller.Refresh()
|
||||
if scrollDownOnNewMessage {
|
||||
UITabs[userJidStr].Scroller.ScrollToBottom()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
func(client *oasisSdk.XmppClient, muc *muc.Channel, msg *oasisSdk.XMPPChatMessage) {
|
||||
// HACK: IGNORING ALL MESSAGES FROM CLASSIC MUC HISTORY IN PREPARATION OF MAM SUPPORT
|
||||
ignore := false
|
||||
correction := false
|
||||
important := false
|
||||
for _, v := range msg.Unknown {
|
||||
if v.XMLName.Local == "delay" { // Classic history message
|
||||
//ignore = true
|
||||
//fmt.Println("ignoring!")
|
||||
//return //what is blud doing
|
||||
}
|
||||
client.SetDmHandler(func(client *oasisSdk.XmppClient, msg *oasisSdk.XMPPChatMessage) {
|
||||
correction := false
|
||||
userJidStr := msg.From.Bare().String()
|
||||
tab, ok := chatTabs[userJidStr]
|
||||
if ok {
|
||||
str := *msg.CleanedBody
|
||||
if notifications {
|
||||
a.SendNotification(fyne.NewNotification(fmt.Sprintf("%s says", userJidStr), str))
|
||||
}
|
||||
|
||||
for _, v := range msg.Unknown {
|
||||
@@ -463,105 +442,186 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
var ImageID string = ""
|
||||
mucJidStr := msg.From.Bare().String()
|
||||
if tab, ok := chatTabs[mucJidStr]; ok {
|
||||
chatTabs[mucJidStr].Muc = muc
|
||||
str := *msg.CleanedBody
|
||||
if strings.Contains(str, login.DisplayName) {
|
||||
fmt.Println(str)
|
||||
important = true
|
||||
}
|
||||
if !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)) {
|
||||
a.SendNotification(fyne.NewNotification(fmt.Sprintf("Mentioned in %s", mucJidStr), str))
|
||||
}
|
||||
}
|
||||
if strings.Contains(str, "https://") {
|
||||
lines := strings.Split(str, "\n")
|
||||
for i, line := range lines {
|
||||
s := strings.Split(line, " ")
|
||||
for _, v := range s {
|
||||
_, err := url.Parse(v)
|
||||
if err == nil && strings.HasPrefix(v, "https://") {
|
||||
if strings.HasSuffix(v, ".png") || strings.HasSuffix(v, ".jpg") || strings.HasSuffix(v, ".jpeg") || strings.HasSuffix(v, ".webp") || strings.HasSuffix(v, ".mp4") || strings.HasSuffix(v, ".mp3") {
|
||||
ImageID = v
|
||||
}
|
||||
var img string = ""
|
||||
if strings.Contains(str, "https://") {
|
||||
lines := strings.Split(str, "\n")
|
||||
for i, line := range lines {
|
||||
s := strings.Split(line, " ")
|
||||
for _, v := range s {
|
||||
_, err := url.Parse(v)
|
||||
if err == nil && strings.HasPrefix(v, "https://") {
|
||||
if strings.HasSuffix(v, ".png") || strings.HasSuffix(v, ".jpg") || strings.HasSuffix(v, ".jpeg") || strings.HasSuffix(v, ".webp") || strings.HasSuffix(v, ".mp4") || strings.HasSuffix(v, ".gif") {
|
||||
img = v
|
||||
}
|
||||
}
|
||||
lines[i] = strings.Join(s, " ")
|
||||
}
|
||||
str = strings.Join(lines, " ")
|
||||
fmt.Println(str)
|
||||
}
|
||||
fmt.Println(msg.ID)
|
||||
var replyID string
|
||||
if msg.Reply == nil {
|
||||
replyID = "PICLIENT:UNAVAILABLE"
|
||||
} else {
|
||||
replyID = msg.Reply.To
|
||||
lines[i] = strings.Join(s, " ")
|
||||
}
|
||||
str = strings.Join(lines, " ")
|
||||
}
|
||||
var replyID string
|
||||
if msg.Reply == nil {
|
||||
replyID = "PICLIENT:UNAVAILABLE"
|
||||
} else {
|
||||
replyID = msg.Reply.ID
|
||||
}
|
||||
|
||||
if correction {
|
||||
for i := len(tab.Messages) - 1; i > 0; i-- {
|
||||
if tab.Messages[i].Raw.From.String() == msg.From.String() {
|
||||
tab.Messages[i].Content = *msg.CleanedBody + " (edited)"
|
||||
fyne.Do(func() {
|
||||
UITabs[mucJidStr].Scroller.Refresh()
|
||||
})
|
||||
return
|
||||
if correction {
|
||||
for i := len(tab.Messages) - 1; i > 0; i-- {
|
||||
if tab.Messages[i].Raw.From.String() == msg.From.String() {
|
||||
tab.Messages[i].Content = *msg.CleanedBody + " (edited)"
|
||||
fyne.Do(func() {
|
||||
UITabs[userJidStr].Scroller.Refresh()
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myMessage := Message{
|
||||
Author: msg.From.Resourcepart(),
|
||||
Content: str,
|
||||
ID: msg.ID,
|
||||
ReplyID: replyID,
|
||||
Raw: *msg,
|
||||
ImageURL: img,
|
||||
}
|
||||
|
||||
tab.Messages = append(tab.Messages, myMessage)
|
||||
fyne.Do(func() {
|
||||
UITabs[userJidStr].Scroller.Refresh()
|
||||
if scrollDownOnNewMessage {
|
||||
UITabs[userJidStr].Scroller.ScrollToBottom()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
client.SetGroupChatHandler(func(client *oasisSdk.XmppClient, muc *muc.Channel, msg *oasisSdk.XMPPChatMessage) {
|
||||
// HACK: IGNORING ALL MESSAGES FROM CLASSIC MUC HISTORY IN PREPARATION OF MAM SUPPORT
|
||||
ignore := false
|
||||
correction := false
|
||||
important := false
|
||||
donotnotify := false
|
||||
for _, v := range msg.Unknown {
|
||||
if v.XMLName.Local == "delay" { // Classic history message
|
||||
donotnotify = true
|
||||
//ignore = true
|
||||
//fmt.Println("ignoring!")
|
||||
//return //what is blud doing
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range msg.Unknown {
|
||||
if v.XMLName.Local == "replace" {
|
||||
correction = true
|
||||
break // dont need to look at more fields
|
||||
}
|
||||
}
|
||||
|
||||
var ImageID string = ""
|
||||
mucJidStr := msg.From.Bare().String()
|
||||
if tab, ok := chatTabs[mucJidStr]; ok {
|
||||
chatTabs[mucJidStr].Muc = muc
|
||||
str := *msg.CleanedBody
|
||||
if strings.Contains(str, login.DisplayName) {
|
||||
fmt.Println(str)
|
||||
important = true
|
||||
}
|
||||
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)) {
|
||||
a.SendNotification(fyne.NewNotification(fmt.Sprintf("Mentioned in %s", mucJidStr), str))
|
||||
}
|
||||
}
|
||||
if strings.Contains(str, "https://") {
|
||||
lines := strings.Split(str, "\n")
|
||||
for i, line := range lines {
|
||||
s := strings.Split(line, " ")
|
||||
for _, v := range s {
|
||||
_, err := url.Parse(v)
|
||||
if err == nil && strings.HasPrefix(v, "https://") {
|
||||
if strings.HasSuffix(v, ".png") || strings.HasSuffix(v, ".jpg") || strings.HasSuffix(v, ".jpeg") || strings.HasSuffix(v, ".webp") || strings.HasSuffix(v, ".mp4") || strings.HasSuffix(v, ".mp3") || strings.HasSuffix(v, ".gif") {
|
||||
ImageID = v
|
||||
}
|
||||
}
|
||||
}
|
||||
lines[i] = strings.Join(s, " ")
|
||||
}
|
||||
str = strings.Join(lines, " ")
|
||||
fmt.Println(str)
|
||||
}
|
||||
fmt.Println(msg.ID)
|
||||
var replyID string
|
||||
if msg.Reply == nil {
|
||||
replyID = "PICLIENT:UNAVAILABLE"
|
||||
} else {
|
||||
replyID = msg.Reply.To
|
||||
}
|
||||
|
||||
myMessage := Message{
|
||||
Author: msg.From.Resourcepart(),
|
||||
Content: str,
|
||||
ID: msg.ID,
|
||||
ReplyID: replyID,
|
||||
Raw: *msg,
|
||||
ImageURL: ImageID,
|
||||
Important: important,
|
||||
}
|
||||
if !ignore {
|
||||
tab.Messages = append(tab.Messages, myMessage)
|
||||
}
|
||||
fyne.Do(func() {
|
||||
UITabs[mucJidStr].Scroller.Refresh()
|
||||
if scrollDownOnNewMessage {
|
||||
UITabs[mucJidStr].Scroller.ScrollToBottom()
|
||||
if correction {
|
||||
for i := len(tab.Messages) - 1; i > 0; i-- {
|
||||
if tab.Messages[i].Raw.From.String() == msg.From.String() {
|
||||
tab.Messages[i].Content = *msg.CleanedBody + " (edited)"
|
||||
fyne.Do(func() {
|
||||
UITabs[mucJidStr].Scroller.Refresh()
|
||||
})
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
func(_ *oasisSdk.XmppClient, from jid.JID, state oasisSdk.ChatState) {
|
||||
switch state {
|
||||
case oasisSdk.ChatStateComposing:
|
||||
fyne.Do(func() {
|
||||
statBar.SetText(fmt.Sprintf("%s is typing...", from.Resourcepart()))
|
||||
})
|
||||
case oasisSdk.ChatStatePaused:
|
||||
|
||||
fyne.Do(func() {
|
||||
statBar.SetText(fmt.Sprintf("%s has stopped typing.", from.Resourcepart()))
|
||||
})
|
||||
case oasisSdk.ChatStateInactive:
|
||||
fyne.Do(func() {
|
||||
statBar.SetText(fmt.Sprintf("%s is idle", from.Resourcepart()))
|
||||
})
|
||||
case oasisSdk.ChatStateGone:
|
||||
fyne.Do(func() {
|
||||
statBar.SetText(fmt.Sprintf("%s is gone", from.Resourcepart()))
|
||||
})
|
||||
default:
|
||||
fyne.Do(func() {
|
||||
statBar.SetText("")
|
||||
})
|
||||
myMessage := Message{
|
||||
Author: msg.From.Resourcepart(),
|
||||
Content: str,
|
||||
ID: msg.ID,
|
||||
ReplyID: replyID,
|
||||
Raw: *msg,
|
||||
ImageURL: ImageID,
|
||||
Important: important,
|
||||
}
|
||||
},
|
||||
if !ignore {
|
||||
tab.Messages = append(tab.Messages, myMessage)
|
||||
}
|
||||
fyne.Do(func() {
|
||||
UITabs[mucJidStr].Scroller.Refresh()
|
||||
if scrollDownOnNewMessage {
|
||||
UITabs[mucJidStr].Scroller.ScrollToBottom()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
client.SetChatstateHandler(func(_ *oasisSdk.XmppClient, from jid.JID, state oasisSdk.ChatState) {
|
||||
switch state {
|
||||
case oasisSdk.ChatStateComposing:
|
||||
fyne.Do(func() {
|
||||
statBar.SetText(fmt.Sprintf("%s is typing...", from.Resourcepart()))
|
||||
})
|
||||
case oasisSdk.ChatStatePaused:
|
||||
|
||||
fyne.Do(func() {
|
||||
statBar.SetText(fmt.Sprintf("%s has stopped typing.", from.Resourcepart()))
|
||||
})
|
||||
case oasisSdk.ChatStateInactive:
|
||||
fyne.Do(func() {
|
||||
statBar.SetText(fmt.Sprintf("%s is idle", from.Resourcepart()))
|
||||
})
|
||||
case oasisSdk.ChatStateGone:
|
||||
fyne.Do(func() {
|
||||
statBar.SetText(fmt.Sprintf("%s is gone", from.Resourcepart()))
|
||||
})
|
||||
default:
|
||||
fyne.Do(func() {
|
||||
statBar.SetText("")
|
||||
})
|
||||
}
|
||||
})
|
||||
client.SetDeliveryReceiptHandler(
|
||||
func(_ *oasisSdk.XmppClient, from jid.JID, id string) {
|
||||
fmt.Printf("Delivered %s to %s", id, from.String())
|
||||
},
|
||||
})
|
||||
|
||||
client.SetReadReceiptHandler(
|
||||
func(_ *oasisSdk.XmppClient, from jid.JID, id string) {
|
||||
for _, tab := range chatTabs {
|
||||
for i := len(tab.Messages) - 1; i >= 0; i-- {
|
||||
@@ -576,8 +636,8 @@ func main() {
|
||||
}
|
||||
}
|
||||
fmt.Printf("%s has seen %s\n", from.String(), id)
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln("Could not create client - " + err.Error())
|
||||
}
|
||||
@@ -600,7 +660,7 @@ func main() {
|
||||
}()
|
||||
|
||||
a = app.New()
|
||||
//a.Settings().SetTheme(myTheme{})
|
||||
//a.Settings().SetTheme(&myTheme{})
|
||||
w = a.NewWindow("pi")
|
||||
w.Resize(fyne.NewSize(500, 500))
|
||||
|
||||
@@ -647,12 +707,15 @@ func main() {
|
||||
|
||||
url, uerr := url.Parse(strings.Split(text, " ")[0])
|
||||
if uerr == nil && strings.HasPrefix(strings.Split(text, " ")[0], "https://") {
|
||||
//err = client.SendImage(jid.MustParse(activeMucJid).Bare(), text, url.String(), &text)
|
||||
err = client.SendSingleFileMessage(jid.MustParse(activeMucJid).Bare(), url.String(), nil)
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
}
|
||||
return
|
||||
dialog.ShowConfirm("Confirm", "Do you want to embed this link into your message?", func(b bool) {
|
||||
if b {
|
||||
err = client.SendSingleFileMessage(jid.MustParse(activeMucJid).Bare(), url.String(), nil)
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
}
|
||||
return
|
||||
}
|
||||
}, w)
|
||||
}
|
||||
err = client.SendText(jid.MustParse(activeMucJid).Bare(), text)
|
||||
|
||||
@@ -691,6 +754,10 @@ func main() {
|
||||
dialog.ShowInformation("about pi", fmt.Sprintf("the XMPP client from hell\n\npi is an experimental XMPP client\nwritten by Sunglocto in Go.\n\nVersion %s", version), w)
|
||||
})
|
||||
|
||||
licensesbtn := fyne.NewMenuItem("license", func() {
|
||||
CreditsWindow(fyne.CurrentApp(), fyne.NewSize(800, 400)).Show()
|
||||
})
|
||||
|
||||
reconnect := fyne.NewMenuItem("reconnect", func() {
|
||||
go func() {
|
||||
err := client.Connect()
|
||||
@@ -735,6 +802,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
selectedScroller.ScrollToBottom()
|
||||
selectedScroller.Refresh()
|
||||
})
|
||||
|
||||
jtt := fyne.NewMenuItem("jump to top", func() {
|
||||
@@ -743,6 +811,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
selectedScroller.ScrollToTop()
|
||||
selectedScroller.Refresh()
|
||||
})
|
||||
|
||||
w.SetOnDropped(func(p fyne.Position, u []fyne.URI) {
|
||||
@@ -916,31 +985,66 @@ func main() {
|
||||
|
||||
})
|
||||
|
||||
servDisc := fyne.NewMenuItem("Disco features", func() {
|
||||
var search jid.JID
|
||||
dialog.ShowEntryDialog("Disco features", "JID: ", func(s string) { // TODO: replace with undeprecated widget
|
||||
search, err = jid.Parse(s)
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
/*
|
||||
servDisc := fyne.NewMenuItem("Disco features", func() {
|
||||
//var search jid.JID
|
||||
dialog.ShowEntryDialog("Disco features", "JID: ", func(s string) { // TODO: replace with undeprecated widgetd
|
||||
d := dialog.NewCustom("Please wait", "Close", widget.NewLabel("..."), w)
|
||||
d.Show()
|
||||
go func() {
|
||||
//search, err = jid.Parse(s)
|
||||
//if err != nil {
|
||||
// d.Hide()
|
||||
// dialog.ShowError(err, w)
|
||||
// return
|
||||
//}
|
||||
txt := `<iq from='ringen@muc.isekai.rocks/sunglocto'
|
||||
to='ringen@muc.iskai.rocks/snit'
|
||||
type='get'
|
||||
id='vc2'>
|
||||
<vCard xmlns='vcard-temp'/>
|
||||
</iq>`
|
||||
var stan stanza.IQ
|
||||
xml.Unmarshal([]byte(txt), &stan)
|
||||
if err != nil {
|
||||
d.Hide()
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
r, err := client.Session.EncodeIQ(client.Ctx, stan)
|
||||
if err != nil {
|
||||
d.Hide()
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
ra, _ := r.Token()
|
||||
t, _ := xml.MarshalIndent(ra, "", "\t")
|
||||
fmt.Println(string(t))
|
||||
d.Hide()
|
||||
/*
|
||||
|
||||
myBox := container.NewGridWithColumns(1, widget.NewLabel("Items"))
|
||||
info, err := disco.GetInfo(client.Ctx, "", search, client.Session)
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
m := info.Features
|
||||
for _, v := range m {
|
||||
myBox.Add(widget.NewLabel(v.Var))
|
||||
myBox.Refresh()
|
||||
}
|
||||
myBox := container.NewGridWithColumns(1, widget.NewLabel("Items"))
|
||||
info, err := disco.GetInfo(client.Ctx, "", search, client.Session)
|
||||
if err != nil {
|
||||
d.Hide()
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
m := info.Identity
|
||||
bytes, err := xml.MarshalIndent(m, "", "\t")
|
||||
if err != nil {
|
||||
d.Hide()
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
fyne.Do(func() {d.Hide()})
|
||||
myBox.Objects = append(myBox.Objects, widget.NewLabel(string(bytes)))
|
||||
dialog.ShowCustom("Service discovery", "cancel", myBox, w)
|
||||
}()
|
||||
|
||||
dialog.ShowCustom("Features", "cancel", myBox, w)
|
||||
|
||||
}, w)
|
||||
})
|
||||
}, w)
|
||||
})
|
||||
*/
|
||||
|
||||
savedata := fyne.NewMenuItem("DEBUG: Save tab data to disk", func() {
|
||||
d := []ChatTab{}
|
||||
@@ -955,9 +1059,34 @@ func main() {
|
||||
os.Create("test.xml")
|
||||
os.WriteFile("text.xml", b, os.ModeAppend)
|
||||
})
|
||||
menu_help := fyne.NewMenu("π", mit, reconnect, savedata)
|
||||
|
||||
menu_changeroom := fyne.NewMenu("Α", mic, servDisc, beginADM, joinARoom, leaveRoom)
|
||||
jbookmarks := fyne.NewMenuItem("Join rooms in bookmarks", func() {
|
||||
// FIXME: Race condition
|
||||
client.FetchBookmarks()
|
||||
rooms := client.BookmarkCache()
|
||||
for _, v := range rooms {
|
||||
go func() {
|
||||
if v.Autojoin == true {
|
||||
joinjid, err := v.JID.WithResource(login.DisplayName)
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
room, err := client.MucClient.Join(client.Ctx, joinjid, client.Session)
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
client.MucChannels[v.JID.String()] = room
|
||||
addChatTab(true, v.JID, login.DisplayName)
|
||||
}
|
||||
}()
|
||||
}
|
||||
})
|
||||
|
||||
menu_help := fyne.NewMenu("π", mit, reconnect, licensesbtn, savedata)
|
||||
|
||||
menu_changeroom := fyne.NewMenu("Α", mic, beginADM, joinARoom, leaveRoom, jbookmarks)
|
||||
menu_configureview := fyne.NewMenu("Β", mia, mis, jtt, jtb)
|
||||
hafjag := fyne.NewMenuItem("Hafjag", func() {
|
||||
entry.Text = "Hafjag"
|
||||
@@ -994,7 +1123,42 @@ func main() {
|
||||
entry.Text = fmt.Sprintf("It is currently %s", time.Now().Format(time.RFC850))
|
||||
SendCallback()
|
||||
})
|
||||
menu_jokes := fyne.NewMenu("Δ", mycurrenttime, hafjag, hotfuck, agree)
|
||||
|
||||
mycurrentplayingsong := fyne.NewMenuItem("Get currently playing song", func() {
|
||||
client, err := mpris.NewClient()
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
present := false
|
||||
for _, player := range client.Players() {
|
||||
fmt.Println(player.RawMetadata())
|
||||
old := entry.Text
|
||||
newtext := ""
|
||||
title, t_ok := player.RawMetadata()["xesam:title"]
|
||||
artist, a_ok := player.RawMetadata()["xesam:artist"]
|
||||
if t_ok && a_ok {
|
||||
newtext = fmt.Sprintf("I'm currently listening to %s by %s", title.String(), artist.String())
|
||||
} else if t_ok {
|
||||
newtext = fmt.Sprintf("I'm currently listening to %s", title.String())
|
||||
} else if a_ok {
|
||||
newtext = fmt.Sprintf("I'm currently listening to a song by %s", artist.String())
|
||||
} else {
|
||||
dialog.ShowError(errors.New("error: There's a playing song, but we could not get the artist or title information."), w)
|
||||
return
|
||||
}
|
||||
entry.SetText(newtext)
|
||||
SendCallback()
|
||||
entry.SetText(old)
|
||||
present = true
|
||||
}
|
||||
|
||||
if !present {
|
||||
dialog.ShowInformation("Failed", "Could not find any open players. You might need an MPRIS plugin for players such as mpv.\nSee the MPRIS ArchWiki article for more information:\nhttps://wiki.archlinux.org/title/MPRIS", w)
|
||||
}
|
||||
})
|
||||
|
||||
menu_jokes := fyne.NewMenu("Δ", mycurrenttime, hafjag, hotfuck, agree, mycurrentplayingsong)
|
||||
bit := fyne.NewMenuItem("mark selected message as read", func() {
|
||||
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||
if !ok {
|
||||
@@ -1017,8 +1181,7 @@ func main() {
|
||||
})
|
||||
|
||||
bic := fyne.NewMenuItem("show message XML", func() {
|
||||
pre := widget.NewMultiLineEntry()
|
||||
|
||||
pre := widget.NewLabel("")
|
||||
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||
if !ok {
|
||||
return
|
||||
@@ -1039,11 +1202,12 @@ func main() {
|
||||
return
|
||||
}
|
||||
pre.SetText(string(bytes))
|
||||
pre.Selectable = true
|
||||
pre.Refresh()
|
||||
dialog.ShowCustom("Message", "Close", pre, w)
|
||||
})
|
||||
|
||||
red := fyne.NewMenuItem("show people who have read this message", func() {
|
||||
red := fyne.NewMenuItem("show read receipts on message", func() {
|
||||
pre := container.NewVBox()
|
||||
|
||||
selectedScroller, ok := AppTabs.Selected().Content.(*widget.List)
|
||||
|
Reference in New Issue
Block a user