mirror of https://github.com/Bios-Marcel/cordless
191 lines
7.1 KiB
Go
191 lines
7.1 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/Bios-Marcel/cordless/tview"
|
|
"github.com/Bios-Marcel/discordgo"
|
|
|
|
"github.com/Bios-Marcel/cordless/commands/commandimpls"
|
|
"github.com/Bios-Marcel/cordless/config"
|
|
"github.com/Bios-Marcel/cordless/readstate"
|
|
"github.com/Bios-Marcel/cordless/shortcuts"
|
|
"github.com/Bios-Marcel/cordless/ui"
|
|
"github.com/Bios-Marcel/cordless/version"
|
|
)
|
|
|
|
// SetupApplicationWithAccount launches the whole application and might
|
|
// abort in case it encounters an error. The login will attempt
|
|
// using the account specified, unless the argument is empty.
|
|
// If the account can't be found, the login page will be shown.
|
|
func SetupApplicationWithAccount(app *tview.Application, account string) {
|
|
configuration := config.Current
|
|
|
|
//We do this right after loading the configuration, as this might take
|
|
//longer than all following calls.
|
|
updateAvailableChannel := version.CheckForUpdate(configuration.DontShowUpdateNotificationFor)
|
|
|
|
configDir, configErr := config.GetConfigDirectory()
|
|
if configErr != nil {
|
|
log.Fatalf("Unable to determine configuration directory (%s)\n", configErr.Error())
|
|
}
|
|
|
|
loginScreen := ui.NewLogin(app, configDir)
|
|
app.SetRoot(loginScreen, true)
|
|
app.MouseEnabled = configuration.MouseEnabled
|
|
|
|
go func() {
|
|
if strings.TrimSpace(account) != "" {
|
|
configuration.Token = configuration.GetAccountToken(account)
|
|
}
|
|
|
|
shortcutsLoadError := shortcuts.Load()
|
|
if shortcutsLoadError != nil {
|
|
panic(shortcutsLoadError)
|
|
}
|
|
|
|
discord, readyEvent := attemptLogin(loginScreen, "", configuration)
|
|
|
|
config.Current.Token = discord.Token
|
|
|
|
persistError := config.PersistConfig()
|
|
if persistError != nil {
|
|
app.Stop()
|
|
log.Fatalf("Error persisting configuration (%s).\n", persistError.Error())
|
|
}
|
|
|
|
discord.State.MaxMessageCount = 100
|
|
|
|
readstate.Load(discord.State)
|
|
|
|
if isUpdateAvailable := <-updateAvailableChannel; isUpdateAvailable {
|
|
waitForUpdateDialogChannel := make(chan bool, 1)
|
|
|
|
dialog := tview.NewModal()
|
|
dialog.SetText(fmt.Sprintf("Version %s of cordless is available!\nYou are currently running version %s.\n\nUpdates have to be installed manually or via your package manager.\n\nThe snap package manager isn't supported by cordless anymore!", version.GetLatestRemoteVersion(), version.Version))
|
|
buttonOk := "Thanks for the info"
|
|
buttonDontRemindAgainForThisVersion := fmt.Sprintf("Skip reminders for %s", version.GetLatestRemoteVersion())
|
|
buttonNeverRemindMeAgain := "Never remind me again"
|
|
dialog.AddButtons([]string{buttonOk, buttonDontRemindAgainForThisVersion, buttonNeverRemindMeAgain})
|
|
dialog.SetDoneFunc(func(index int, label string) {
|
|
if label == buttonDontRemindAgainForThisVersion {
|
|
configuration.DontShowUpdateNotificationFor = version.GetLatestRemoteVersion()
|
|
config.PersistConfig()
|
|
} else if label == buttonNeverRemindMeAgain {
|
|
configuration.ShowUpdateNotifications = false
|
|
config.PersistConfig()
|
|
}
|
|
|
|
waitForUpdateDialogChannel <- true
|
|
})
|
|
|
|
app.QueueUpdateDraw(func() {
|
|
app.SetRoot(dialog, true)
|
|
})
|
|
|
|
<-waitForUpdateDialogChannel
|
|
close(waitForUpdateDialogChannel)
|
|
}
|
|
|
|
app.QueueUpdateDraw(func() {
|
|
window, createError := ui.NewWindow(app, discord, readyEvent)
|
|
|
|
if createError != nil {
|
|
app.Stop()
|
|
//Otherwise the logger output can't be seen, since we are stopping the TUI either way.
|
|
log.SetOutput(os.Stdout)
|
|
log.Fatalf("Error constructing window (%s).\n", createError.Error())
|
|
}
|
|
|
|
window.RegisterCommand(commandimpls.NewVersionCommand())
|
|
statusGetCmd := commandimpls.NewStatusGetCommand(discord)
|
|
statusSetCmd := commandimpls.NewStatusSetCommand(discord)
|
|
statusSetCustomCmd := commandimpls.NewStatusSetCustomCommand(discord)
|
|
window.RegisterCommand(statusSetCmd)
|
|
window.RegisterCommand(statusGetCmd)
|
|
window.RegisterCommand(statusSetCustomCmd)
|
|
window.RegisterCommand(commandimpls.NewStatusCommand(statusGetCmd, statusSetCmd, statusSetCustomCmd))
|
|
window.RegisterCommand(commandimpls.NewFileSendCommand(discord, window))
|
|
accountLogout := commandimpls.NewAccountLogout(func() { SetupApplication(app) }, window)
|
|
window.RegisterCommand(accountLogout)
|
|
window.RegisterCommand(commandimpls.NewAccount(accountLogout, window))
|
|
window.RegisterCommand(commandimpls.NewManualCommand(window))
|
|
window.RegisterCommand(commandimpls.NewFixLayoutCommand(window))
|
|
window.RegisterCommand(commandimpls.NewFriendsCommand(discord))
|
|
userSetCmd := commandimpls.NewUserSetCommand(window, discord)
|
|
userGetCmd := commandimpls.NewUserGetCommand(window, discord)
|
|
window.RegisterCommand(userSetCmd)
|
|
window.RegisterCommand(userGetCmd)
|
|
window.RegisterCommand(commandimpls.NewUserCommand(userSetCmd, userGetCmd))
|
|
serverJoinCmd := commandimpls.NewServerJoinCommand(window, discord)
|
|
serverLeaveCmd := commandimpls.NewServerLeaveCommand(window, discord)
|
|
serverCreateCmd := commandimpls.NewServerCreateCommand(discord)
|
|
window.RegisterCommand(serverJoinCmd)
|
|
window.RegisterCommand(serverLeaveCmd)
|
|
window.RegisterCommand(serverCreateCmd)
|
|
window.RegisterCommand(commandimpls.NewServerCommand(serverJoinCmd, serverLeaveCmd, serverCreateCmd))
|
|
window.RegisterCommand(commandimpls.NewNickSetCmd(discord, window))
|
|
tfaEnableCmd := commandimpls.NewTFAEnableCommand(window, discord)
|
|
tfaDisableCmd := commandimpls.NewTFADisableCommand(discord)
|
|
tfaBackupGetCmd := commandimpls.NewTFABackupGetCmd(discord, window)
|
|
tfaBackupResetCmd := commandimpls.NewTFABackupResetCmd(discord, window)
|
|
window.RegisterCommand(commandimpls.NewTFACommand(tfaEnableCmd, tfaDisableCmd, tfaBackupGetCmd, tfaBackupResetCmd))
|
|
window.RegisterCommand(tfaEnableCmd)
|
|
window.RegisterCommand(tfaDisableCmd)
|
|
window.RegisterCommand(tfaBackupGetCmd)
|
|
window.RegisterCommand(tfaBackupResetCmd)
|
|
window.RegisterCommand(commandimpls.NewDMOpenCmd(discord, window))
|
|
})
|
|
}()
|
|
}
|
|
|
|
// SetupApplication launches the whole application and might abort in case
|
|
// it encounters an error.
|
|
func SetupApplication(app *tview.Application) {
|
|
SetupApplicationWithAccount(app, "")
|
|
}
|
|
|
|
func attemptLogin(loginScreen *ui.Login, loginMessage string, configuration *config.Config) (*discordgo.Session, *discordgo.Ready) {
|
|
var (
|
|
session *discordgo.Session
|
|
readyEvent *discordgo.Ready
|
|
discordError error
|
|
)
|
|
|
|
if configuration.Token == "" {
|
|
session, discordError = loginScreen.RequestLogin(loginMessage)
|
|
} else {
|
|
session, discordError = discordgo.NewWithToken(configuration.Token)
|
|
}
|
|
|
|
if discordError != nil {
|
|
configuration.Token = ""
|
|
return attemptLogin(loginScreen, fmt.Sprintf("Error during last login attempt:\n\n[red]%s", discordError), configuration)
|
|
}
|
|
|
|
if session == nil {
|
|
configuration.Token = ""
|
|
return attemptLogin(loginScreen, "Error during last login attempt:\n\n[red]Received session is nil", configuration)
|
|
}
|
|
|
|
readyChan := make(chan *discordgo.Ready, 1)
|
|
session.AddHandlerOnce(func(s *discordgo.Session, event *discordgo.Ready) {
|
|
readyChan <- event
|
|
})
|
|
|
|
discordError = session.Open()
|
|
|
|
if discordError != nil {
|
|
configuration.Token = ""
|
|
return attemptLogin(loginScreen, fmt.Sprintf("Error during last login attempt:\n\n[red]%s", discordError), configuration)
|
|
}
|
|
|
|
readyEvent = <-readyChan
|
|
close(readyChan)
|
|
|
|
return session, readyEvent
|
|
}
|