add account login screen, bump version number
This commit is contained in:
227
main.go
227
main.go
@@ -5,10 +5,12 @@ import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"io"
|
||||
_ "io/fs"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
@@ -17,7 +19,6 @@ import (
|
||||
"fyne.io/fyne/v2/storage"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
_ "fyne.io/x/fyne/theme"
|
||||
catppuccin "github.com/mbaklor/fyne-catppuccin"
|
||||
"mellium.im/xmpp/jid"
|
||||
"mellium.im/xmpp/muc"
|
||||
@@ -31,12 +32,12 @@ var version string = "3a"
|
||||
// license AGPL
|
||||
|
||||
type Message struct {
|
||||
Author string
|
||||
Content string
|
||||
ID string
|
||||
ReplyID string
|
||||
Author string
|
||||
Content string
|
||||
ID string
|
||||
ReplyID string
|
||||
ImageURL string
|
||||
Raw oasisSdk.XMPPChatMessage
|
||||
Raw oasisSdk.XMPPChatMessage
|
||||
}
|
||||
|
||||
type MucTab struct {
|
||||
@@ -47,11 +48,21 @@ type MucTab struct {
|
||||
isMuc bool
|
||||
}
|
||||
|
||||
type piConfig struct {
|
||||
Login oasisSdk.LoginInfo
|
||||
DMs []string
|
||||
Notifications bool
|
||||
}
|
||||
|
||||
var config piConfig
|
||||
var login oasisSdk.LoginInfo
|
||||
var DMs []string
|
||||
|
||||
var chatTabs = make(map[string]*MucTab)
|
||||
var tabs *container.AppTabs
|
||||
var selectedId widget.ListItemID
|
||||
var replying bool = false
|
||||
var notifications bool = true
|
||||
var notifications bool
|
||||
var connection bool = true
|
||||
|
||||
type myTheme struct{}
|
||||
@@ -117,13 +128,15 @@ func addChatTab(isMuc bool, chatJid jid.JID, nick string) {
|
||||
btn.Hidden = true // Hide by default
|
||||
msgContent := tabData.Messages[i].Content
|
||||
if tabData.Messages[i].ImageURL != "" {
|
||||
btn.Hidden = false
|
||||
btn.OnTapped = func(){fyne.Do(func() {
|
||||
u, _ := storage.ParseURI(tabData.Messages[i].ImageURL)
|
||||
image := canvas.NewImageFromURI(u)
|
||||
image.FillMode = canvas.ImageFillOriginal
|
||||
dialog.ShowCustom("Image", "Close", image, w)
|
||||
})}
|
||||
btn.Hidden = false
|
||||
btn.OnTapped = func() {
|
||||
fyne.Do(func() {
|
||||
u, _ := storage.ParseURI(tabData.Messages[i].ImageURL)
|
||||
image := canvas.NewImageFromURI(u)
|
||||
image.FillMode = canvas.ImageFillOriginal
|
||||
dialog.ShowCustom("Image", "Close", image, w)
|
||||
})
|
||||
}
|
||||
}
|
||||
// Check if the message is a quote
|
||||
lines := strings.Split(msgContent, "\n")
|
||||
@@ -155,31 +168,84 @@ func addChatTab(isMuc bool, chatJid jid.JID, nick string) {
|
||||
tabs.Append(tabItem)
|
||||
}
|
||||
|
||||
func main() {
|
||||
login := oasisSdk.LoginInfo{}
|
||||
func dropToSignInPage(reason string) {
|
||||
a = app.New()
|
||||
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))
|
||||
userEntry := widget.NewEntry()
|
||||
userEntry.SetPlaceHolder("Your JID")
|
||||
serverEntry := widget.NewEntry()
|
||||
serverEntry.SetPlaceHolder("Server and port")
|
||||
passwordEntry := widget.NewPasswordEntry()
|
||||
passwordEntry.SetPlaceHolder("Your Password")
|
||||
nicknameEntry := widget.NewEntry()
|
||||
nicknameEntry.SetPlaceHolder("Your Nickname")
|
||||
|
||||
DMs := []string{}
|
||||
userView := widget.NewFormItem("", userEntry)
|
||||
serverView := widget.NewFormItem("", serverEntry)
|
||||
passwordView := widget.NewFormItem("", passwordEntry)
|
||||
nicknameView := widget.NewFormItem("", nicknameEntry)
|
||||
items := []*widget.FormItem{
|
||||
serverView,
|
||||
userView,
|
||||
passwordView,
|
||||
nicknameView,
|
||||
}
|
||||
|
||||
btn := widget.NewButton("Create an account", func() {
|
||||
dialog.ShowForm("Create an account", "Create", "Dismiss", items, func(b bool) {
|
||||
if b {
|
||||
config := piConfig{}
|
||||
config.Login.Host = serverEntry.Text
|
||||
config.Login.User = userEntry.Text
|
||||
config.Login.Password = passwordEntry.Text
|
||||
config.Login.DisplayName = nicknameEntry.Text
|
||||
config.Notifications = true
|
||||
|
||||
bytes, err := json.MarshalIndent(config, "", " ")
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
os.Create("pi.json")
|
||||
os.WriteFile("pi.json", bytes, os.FileMode(os.O_RDWR)) // TODO: See if this works on non-unix like systems
|
||||
a.SendNotification(fyne.NewNotification("Done", "Relaunch the application"))
|
||||
w.Close()
|
||||
}
|
||||
}, w)
|
||||
})
|
||||
btn2 := widget.NewButton("Close pi", func() {
|
||||
w.Close()
|
||||
})
|
||||
w.SetContent(container.NewVBox(rt, btn, btn2,footer))
|
||||
w.ShowAndRun()
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
config = piConfig{}
|
||||
|
||||
bytes, err := os.ReadFile("./pi.json")
|
||||
if err != nil {
|
||||
a = app.New()
|
||||
w = a.NewWindow("Error")
|
||||
w.Resize(fyne.NewSize(500, 500))
|
||||
dialog.ShowInformation("Error", fmt.Sprintf("Please make sure there is a file named pi.json in the same directory you are running this executable...\n%s", err.Error()), w)
|
||||
w.ShowAndRun()
|
||||
dropToSignInPage(err.Error())
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(bytes, &login)
|
||||
if err != nil {
|
||||
fyne.Do(func() {
|
||||
a = app.New()
|
||||
w = a.NewWindow("Error")
|
||||
w.Resize(fyne.NewSize(500, 500))
|
||||
dialog.ShowError(err, w)
|
||||
w.ShowAndRun()
|
||||
})
|
||||
|
||||
|
||||
err = json.Unmarshal(bytes, &config)
|
||||
if err != nil {
|
||||
dropToSignInPage(fmt.Sprintf("Your pi.json file is invalid:\n%s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
login = config.Login
|
||||
DMs = config.DMs
|
||||
notifications = config.Notifications
|
||||
|
||||
client, err := oasisSdk.CreateClient(
|
||||
&login,
|
||||
func(client *oasisSdk.XmppClient, msg *oasisSdk.XMPPChatMessage) {
|
||||
@@ -194,7 +260,7 @@ func main() {
|
||||
}
|
||||
var img string = ""
|
||||
if strings.Contains(str, "https://") {
|
||||
lines := strings.Split(str, " ")
|
||||
lines := strings.Split(str, "\n")
|
||||
for i, line := range lines {
|
||||
s := strings.Split(line, " ")
|
||||
for j, v := range s {
|
||||
@@ -215,11 +281,11 @@ func main() {
|
||||
replyID = msg.Reply.ID
|
||||
}
|
||||
myMessage := Message{
|
||||
Author: msg.From.Resourcepart(),
|
||||
Content: str,
|
||||
ID: msg.ID,
|
||||
ReplyID: replyID,
|
||||
Raw: *msg,
|
||||
Author: msg.From.Resourcepart(),
|
||||
Content: str,
|
||||
ID: msg.ID,
|
||||
ReplyID: replyID,
|
||||
Raw: *msg,
|
||||
ImageURL: img,
|
||||
}
|
||||
|
||||
@@ -243,7 +309,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
if strings.Contains(str, "https://") {
|
||||
lines := strings.Split(str, " ")
|
||||
lines := strings.Split(str, "\n")
|
||||
for i, line := range lines {
|
||||
s := strings.Split(line, " ")
|
||||
for j, v := range s {
|
||||
@@ -396,7 +462,6 @@ func main() {
|
||||
entry.SetText("")
|
||||
})
|
||||
|
||||
|
||||
mit := fyne.NewMenuItem("about pi", func() {
|
||||
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)
|
||||
})
|
||||
@@ -427,6 +492,22 @@ func main() {
|
||||
}
|
||||
}, w)
|
||||
})
|
||||
|
||||
jtb := fyne.NewMenuItem("jump to bottom", func() {
|
||||
selectedScroller, ok := tabs.Selected().Content.(*widget.List)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
selectedScroller.ScrollToBottom()
|
||||
})
|
||||
|
||||
jtt := fyne.NewMenuItem("jump to top", func() {
|
||||
selectedScroller, ok := tabs.Selected().Content.(*widget.List)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
selectedScroller.ScrollToTop()
|
||||
})
|
||||
/*mib := fyne.NewMenuItem("Join a room", func() {
|
||||
nickEntry := widget.NewEntry()
|
||||
nickEntry.SetText(login.DisplayName)
|
||||
@@ -457,24 +538,56 @@ func main() {
|
||||
})*/
|
||||
|
||||
mic := fyne.NewMenuItem("upload a file", func() {
|
||||
var link string
|
||||
var bytes []byte
|
||||
var toperr error
|
||||
var topreader fyne.URIReadCloser
|
||||
dialog.ShowFileOpen(func(reader fyne.URIReadCloser, err error) {
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
}
|
||||
bytes, err := io.ReadAll(reader)
|
||||
link, err := client.UploadFileFromBytes(reader.URI().String(), bytes)
|
||||
if err != nil {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
if reader == nil {
|
||||
return
|
||||
}
|
||||
bytes, toperr = io.ReadAll(reader)
|
||||
topreader = reader
|
||||
|
||||
if toperr != nil {
|
||||
dialog.ShowError(toperr, w)
|
||||
return
|
||||
}
|
||||
|
||||
progress := make(chan oasisSdk.UploadProgress)
|
||||
myprogressbar := widget.NewProgressBar()
|
||||
dialog.ShowCustom("Uploading file", "Hide", myprogressbar, w)
|
||||
go func() {
|
||||
|
||||
client.UploadFileFromBytes(client.Ctx, topreader.URI().Name(), bytes, progress)
|
||||
}()
|
||||
for update := range progress {
|
||||
myprogressbar.Value = float64(update.Percentage)
|
||||
myprogressbar.Refresh()
|
||||
|
||||
if update.Error != nil {
|
||||
dialog.ShowError(update.Error, w)
|
||||
return
|
||||
}
|
||||
|
||||
if update.GetURL != "" {
|
||||
link = update.GetURL
|
||||
}
|
||||
}
|
||||
|
||||
a.Clipboard().SetContent(link)
|
||||
dialog.ShowInformation("file successfully uploaded\nURL copied to your clipboard", link, w)
|
||||
|
||||
}, w)
|
||||
})
|
||||
|
||||
menu_help := fyne.NewMenu("π", mit)
|
||||
menu_changeroom := fyne.NewMenu("β", mic)
|
||||
menu_configureview := fyne.NewMenu("γ", mia, mis)
|
||||
menu_configureview := fyne.NewMenu("γ", mia, mis, jtt, jtb)
|
||||
bit := fyne.NewMenuItem("mark selected message as read", func() {
|
||||
selectedScroller, ok := tabs.Selected().Content.(*widget.List)
|
||||
if !ok {
|
||||
@@ -495,7 +608,29 @@ func main() {
|
||||
bia := fyne.NewMenuItem("toggle replying to message", func() {
|
||||
replying = !replying
|
||||
})
|
||||
menu_messageoptions := fyne.NewMenu("Σ", bit, bia)
|
||||
|
||||
bic := fyne.NewMenuItem("open selected message in new window", func() {
|
||||
pre := widget.NewMultiLineEntry()
|
||||
|
||||
selectedScroller, ok := tabs.Selected().Content.(*widget.List)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var activeChatJid string
|
||||
for jid, tabData := range chatTabs {
|
||||
if tabData.Scroller == selectedScroller {
|
||||
activeChatJid = jid
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
m := chatTabs[activeChatJid].Messages[selectedId].Content
|
||||
pre.SetText(m)
|
||||
pre.Refresh()
|
||||
dialog.ShowCustom("Message", "Close", container.NewHBox(pre), w)
|
||||
})
|
||||
menu_messageoptions := fyne.NewMenu("Σ", bit, bia, bic)
|
||||
ma := fyne.NewMainMenu(menu_help, menu_changeroom, menu_configureview, menu_messageoptions)
|
||||
w.SetMainMenu(ma)
|
||||
|
||||
|
Reference in New Issue
Block a user