|
|
@@ -1,7 +1,235 @@
|
|
|
package main
|
|
|
|
|
|
-import "fmt"
|
|
|
+import (
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ "github.com/diamondburned/arikawa/v2/api"
|
|
|
+ "github.com/diamondburned/arikawa/v2/discord"
|
|
|
+ "github.com/diamondburned/arikawa/v2/gateway"
|
|
|
+ "github.com/diamondburned/arikawa/v2/session"
|
|
|
+ "github.com/gdamore/tcell/v2"
|
|
|
+ "github.com/rigormorrtiss/discordo/ui"
|
|
|
+ "github.com/rigormorrtiss/discordo/util"
|
|
|
+ "github.com/rivo/tview"
|
|
|
+)
|
|
|
+
|
|
|
+var app *tview.Application
|
|
|
+var loginModal *tview.Modal
|
|
|
+var loginForm *tview.Form
|
|
|
+var guildsDropDown *tview.DropDown
|
|
|
+var channelsList *tview.List
|
|
|
+var messagesTextView *tview.TextView
|
|
|
+var messageInputField *tview.InputField
|
|
|
+var mainFlex *tview.Flex
|
|
|
+var loginVia string
|
|
|
+var discordSession *session.Session
|
|
|
+var guilds []gateway.GuildCreateEvent
|
|
|
+var currentGuild gateway.GuildCreateEvent
|
|
|
+var currentChannel discord.Channel
|
|
|
|
|
|
func main() {
|
|
|
- fmt.Println("Discordo")
|
|
|
+ loginModal = ui.NewLoginModal(onLoginModalDone)
|
|
|
+ guildsDropDown = ui.NewGuildsDropDown(onGuildsDropDownSelected)
|
|
|
+ channelsList = ui.NewChannelsList(onChannelsListSelected)
|
|
|
+ messagesTextView = ui.NewMessagesTextView(onMessagesTextViewChanged)
|
|
|
+ mainFlex = ui.NewMainFlex(guildsDropDown, channelsList, messagesTextView)
|
|
|
+ app = ui.NewApplication(onApplicationInputCapture)
|
|
|
+
|
|
|
+ email := util.GetPassword("email")
|
|
|
+ password := util.GetPassword("password")
|
|
|
+ token := util.GetPassword("token")
|
|
|
+ if email != "" && password != "" {
|
|
|
+ app.
|
|
|
+ SetRoot(mainFlex, true).
|
|
|
+ SetFocus(guildsDropDown)
|
|
|
+
|
|
|
+ discordSession = newSession(email, password, "")
|
|
|
+ } else if token != "" {
|
|
|
+ app.
|
|
|
+ SetRoot(mainFlex, true).
|
|
|
+ SetFocus(guildsDropDown)
|
|
|
+
|
|
|
+ discordSession = newSession("", "", token)
|
|
|
+ } else {
|
|
|
+ app.SetRoot(loginModal, true)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := app.Run(); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func onLoginFormQuitButtonSelected() {
|
|
|
+ app.Stop()
|
|
|
+}
|
|
|
+
|
|
|
+func onApplicationInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
|
|
+ if event.Key() == tcell.KeyCtrlR {
|
|
|
+ app.Sync()
|
|
|
+ }
|
|
|
+
|
|
|
+ return event
|
|
|
+}
|
|
|
+
|
|
|
+func onMessagesTextViewChanged() {
|
|
|
+ app.Draw()
|
|
|
+}
|
|
|
+
|
|
|
+func onLoginModalDone(buttonIndex int, buttonLabel string) {
|
|
|
+ if buttonLabel == ui.LoginViaEmailPasswordLoginModalButton {
|
|
|
+ loginVia = "emailpassword"
|
|
|
+ loginForm = ui.NewLoginForm(loginVia, onLoginFormLoginButtonSelected, onLoginFormQuitButtonSelected)
|
|
|
+ app.SetRoot(loginForm, true)
|
|
|
+ } else if buttonLabel == ui.LoginViaTokenLoginModalButton {
|
|
|
+ loginVia = "token"
|
|
|
+ loginForm = ui.NewLoginForm(loginVia, onLoginFormLoginButtonSelected, onLoginFormQuitButtonSelected)
|
|
|
+ app.SetRoot(loginForm, true)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func newSession(email string, password string, token string) *session.Session {
|
|
|
+ var sess *session.Session
|
|
|
+ var err error
|
|
|
+ if email != "" && password != "" {
|
|
|
+ api.UserAgent = `Mozilla/5.0 (X11; Linux x86_64; rv:90.0)` +
|
|
|
+ `Gecko/20100101 Firefox/90.0`
|
|
|
+ gateway.DefaultIdentity = gateway.IdentifyProperties{
|
|
|
+ OS: "Linux",
|
|
|
+ Browser: "Firefox",
|
|
|
+ Device: "",
|
|
|
+ }
|
|
|
+
|
|
|
+ sess, err = session.Login(email, password, "")
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ sess.AddHandler(onReady)
|
|
|
+ } else if token != "" {
|
|
|
+ sess, err = session.New(token)
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ sess.AddHandler(onGuildCreate)
|
|
|
+ sess.Gateway.AddIntents(gateway.IntentGuilds)
|
|
|
+ sess.Gateway.AddIntents(gateway.IntentGuildMessages)
|
|
|
+ }
|
|
|
+
|
|
|
+ sess.AddHandler(onMessageCreate)
|
|
|
+ if err = sess.Open(); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return sess
|
|
|
+}
|
|
|
+
|
|
|
+func onGuildCreate(guild *gateway.GuildCreateEvent) {
|
|
|
+ guildsDropDown.AddOption(guild.Name, nil)
|
|
|
+ guilds = append(guilds, *guild)
|
|
|
+}
|
|
|
+
|
|
|
+func onReady(ready *gateway.ReadyEvent) {
|
|
|
+ guilds = ready.Guilds
|
|
|
+ for i := 0; i < len(guilds); i++ {
|
|
|
+ guildsDropDown.AddOption(guilds[i].Name, nil)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func onMessageCreate(message *gateway.MessageCreateEvent) {
|
|
|
+ if currentChannel.ID == message.ChannelID {
|
|
|
+ util.WriteMessage(messagesTextView, message.Message)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func onGuildsDropDownSelected(text string, _ int) {
|
|
|
+ // Remove/clear all items from the channels List
|
|
|
+ channelsList.Clear()
|
|
|
+ // Remove/clear all text from the messages TextView buffer
|
|
|
+ messagesTextView.Clear()
|
|
|
+ // If the message InputField is not nil, remove the message InputField from the main Flex and set the message InputField to nil
|
|
|
+ if messageInputField != nil {
|
|
|
+ mainFlex.RemoveItem(messageInputField)
|
|
|
+ messageInputField = nil
|
|
|
+ }
|
|
|
+
|
|
|
+ for i := 0; i < len(guilds); i++ {
|
|
|
+ guild := guilds[i]
|
|
|
+ if guild.Name == text {
|
|
|
+ currentGuild = guild
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for i := 0; i < len(currentGuild.Channels); i++ {
|
|
|
+ channel := currentGuild.Channels[i]
|
|
|
+ channelsList.AddItem(channel.Name, "", 0, nil)
|
|
|
+ }
|
|
|
+
|
|
|
+ app.SetFocus(channelsList)
|
|
|
+}
|
|
|
+
|
|
|
+func onChannelsListSelected(i int, mainText string, secondaryText string, _ rune) {
|
|
|
+ // Remove/clear all text from the messages TextView buffer
|
|
|
+ messagesTextView.Clear()
|
|
|
+ // If the message InputField is nil, add a new message InputField to the main Flex and assign it to message InputField in instance
|
|
|
+ if messageInputField == nil {
|
|
|
+ messageInputField = ui.NewMessageInputField(onMessageInputFieldDone)
|
|
|
+ // Add the message InputField as a new item to the main Flex
|
|
|
+ mainFlex.AddItem(messageInputField, 3, 1, false)
|
|
|
+ }
|
|
|
+
|
|
|
+ app.SetFocus(messageInputField)
|
|
|
+
|
|
|
+ currentChannel = currentGuild.Channels[i]
|
|
|
+ // Set the title of the messages TextView Box to the name of the channel
|
|
|
+ messagesTextView.SetTitle(currentChannel.Name)
|
|
|
+
|
|
|
+ messages := util.GetMessages(discordSession, currentChannel.ID, 50)
|
|
|
+ for i := len(messages) - 1; i >= 0; i-- {
|
|
|
+ util.WriteMessage(messagesTextView, messages[i])
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func onMessageInputFieldDone(key tcell.Key) {
|
|
|
+ if key == tcell.KeyEnter {
|
|
|
+ currentText := messageInputField.GetText()
|
|
|
+ currentText = strings.TrimSpace(currentText)
|
|
|
+ // If the current text of the message InputField is an empty string and the enter key is pressed, do not proceed
|
|
|
+ if currentText == "" {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ util.SendMessage(discordSession, currentChannel.ID, currentText)
|
|
|
+ // Set the current text of the message InputField to an empty string after the message has been sent
|
|
|
+ messageInputField.SetText("")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func onLoginFormLoginButtonSelected() {
|
|
|
+ if loginVia == "emailpassword" {
|
|
|
+ email := loginForm.GetFormItemByLabel("Email").(*tview.InputField).GetText()
|
|
|
+ password := loginForm.GetFormItemByLabel("Password").(*tview.InputField).GetText()
|
|
|
+ if email == "" || password == "" {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ discordSession = newSession(email, password, "")
|
|
|
+
|
|
|
+ util.SetPassword("email", email)
|
|
|
+ util.SetPassword("password", password)
|
|
|
+ } else if loginVia == "token" {
|
|
|
+ token := loginForm.GetFormItemByLabel("Token").(*tview.InputField).GetText()
|
|
|
+ if token == "" {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ discordSession = newSession("", "", token)
|
|
|
+
|
|
|
+ util.SetPassword("token", token)
|
|
|
+ }
|
|
|
+
|
|
|
+ app.
|
|
|
+ SetRoot(mainFlex, true).
|
|
|
+ SetFocus(guildsDropDown)
|
|
|
}
|