From ae5dbd3d18fa4c8795540e46fc48650b3ac6e05e Mon Sep 17 00:00:00 2001 From: Chris Howey Date: Sat, 20 Feb 2021 13:29:29 -0600 Subject: [PATCH] add settings tab --- Makefile | 4 +- about.go | 33 ++++++++ main.go | 223 +++------------------------------------------------- recv.go | 107 +++++++++++++++++++++++++ send.go | 111 ++++++++++++++++++++++++++ settings.go | 19 +++++ 6 files changed, 283 insertions(+), 214 deletions(-) create mode 100644 about.go create mode 100644 recv.go create mode 100644 send.go create mode 100644 settings.go diff --git a/Makefile b/Makefile index 08842ce..382c9ab 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,10 @@ all: crocgui.apk crocgui -crocgui.apk: main.go platforms_android.go AndroidManifest.xml +crocgui.apk: main.go send.go recv.go settings.go about.go platforms_android.go AndroidManifest.xml ANDROID_HOME=~/android fyne package -os android -appID com.github.howeyc.crocgui -icon metadata/en-US/images/icon.png -crocgui: main.go platforms-all.go +crocgui: main.go send.go recv.go settings.go about.go platforms-all.go go build clean: diff --git a/about.go b/about.go new file mode 100644 index 0000000..cfe089f --- /dev/null +++ b/about.go @@ -0,0 +1,33 @@ +package main + +import ( + _ "embed" + "net/url" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" +) + +func parseURL(s string) *url.URL { + link, _ := url.Parse(s) + return link +} + +//go:embed metadata/en-US/full_description.txt +var longdesc string + +func aboutTabItem() *container.TabItem { + aboutInfo := widget.NewLabel(longdesc) + aboutInfo.Wrapping = fyne.TextWrapWord + return container.NewTabItemWithIcon("About", theme.InfoIcon(), container.NewBorder(nil, + widget.NewForm( + widget.NewFormItem("croc GUI", widget.NewHyperlink("v1.0.0", parseURL("https://github.com/howeyc/crocgui"))), + widget.NewFormItem("croc", widget.NewHyperlink("v8.6.7", parseURL("https://github.com/schollz/croc"))), + ), + nil, + nil, + aboutInfo, + )) +} diff --git a/main.go b/main.go index c106a7b..ad11b4d 100644 --- a/main.go +++ b/main.go @@ -2,225 +2,14 @@ package main import ( _ "embed" - "net/url" - "sort" - "strings" - - "fmt" - "log" - "os" - "path/filepath" - "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/layout" - "fyne.io/fyne/v2/theme" - "fyne.io/fyne/v2/widget" - "github.com/schollz/croc/v8/src/croc" - "github.com/schollz/croc/v8/src/utils" ) -func parseURL(s string) *url.URL { - link, _ := url.Parse(s) - return link -} - -func aboutTabItem() *container.TabItem { - return container.NewTabItemWithIcon("About", theme.InfoIcon(), container.NewVBox( - widget.NewForm( - widget.NewFormItem("croc GUI", widget.NewHyperlink("v1.0.0", parseURL("https://github.com/howeyc/crocgui"))), - widget.NewFormItem("croc", widget.NewHyperlink("v8.6.7", parseURL("https://github.com/schollz/croc"))), - ), - )) -} - -func sendTabItem(w fyne.Window) *container.TabItem { - status := widget.NewLabel("") - defer func() { - if r := recover(); r != nil { - status.SetText(fmt.Sprint(r)) - } - }() - prog := widget.NewProgressBar() - prog.Hide() - topline := widget.NewLabel("Pick a file to send") - var currentCode string - copyCodeButton := widget.NewButtonWithIcon("", theme.ContentCopyIcon(), func() { - if currentCode != "" { - w.Clipboard().SetContent(currentCode) - } - }) - copyCodeButton.Hide() - return container.NewTabItemWithIcon("Send", theme.MailSendIcon(), - container.NewVBox( - topline, - widget.NewButtonWithIcon("File", theme.FileIcon(), func() { - dialog.ShowFileOpen(func(f fyne.URIReadCloser, e error) { - if e != nil { - return - } - randomName := utils.GetRandomName() - sender, err := croc.New(croc.Options{ - IsSender: true, - SharedSecret: randomName, - Debug: false, - RelayAddress: "croc.schollz.com:9009", - RelayPorts: []string{"9009", "9010", "9011", "9012", "9013"}, - RelayPassword: "pass123", - Stdout: false, - NoPrompt: true, - DisableLocal: true, - }) - var filename string - if err != nil { - log.Println(err) - } else if f != nil { - fpath := fixpath(f.URI().Path()) - - fi, sterr := os.Stat(fpath) - if sterr != nil { - status.SetText(fmt.Sprintf("Stat error: %s - %s", fpath, sterr.Error())) - return - } - status.SetText("Receive Code: " + randomName) - currentCode = randomName - copyCodeButton.Show() - filename = filepath.Base(fpath) - topline.SetText(fmt.Sprintf("Sending file: %s", filename)) - totalsize := fi.Size() - prog.Max = float64(totalsize) - prog.Show() - donechan := make(chan bool) - go func() { - ticker := time.NewTicker(time.Millisecond * 100) - for { - select { - case <-ticker.C: - prog.SetValue(float64(sender.TotalSent)) - case <-donechan: - ticker.Stop() - return - } - } - }() - go func() { - serr := sender.Send(croc.TransferOptions{ - PathToFiles: []string{fpath}, - }) - donechan <- true - prog.Hide() - prog.SetValue(0) - topline.SetText("Pick a file to send") - if serr != nil { - log.Println("Send failed:", serr) - } else { - status.SetText(fmt.Sprintf("Sent file %s", filename)) - } - currentCode = "" - copyCodeButton.Hide() - }() - } - }, w) - }), - prog, - container.NewHBox(status, copyCodeButton), - )) -} - -func recvTabItem() *container.TabItem { - status := widget.NewLabel("") - defer func() { - if r := recover(); r != nil { - status.SetText(fmt.Sprint(r)) - } - }() - - prog := widget.NewProgressBar() - prog.Hide() - recvEntry := widget.NewEntry() - topline := widget.NewLabel("Enter code to download") - return container.NewTabItemWithIcon("Receive", theme.DownloadIcon(), - container.NewVBox( - topline, - widget.NewForm(&widget.FormItem{Text: "Receive Code", Widget: recvEntry}), - widget.NewButtonWithIcon("Download", theme.DownloadIcon(), func() { - receiver, err := croc.New(croc.Options{ - IsSender: false, - SharedSecret: recvEntry.Text, - Debug: false, - RelayAddress: "croc.schollz.com:9009", - RelayPassword: "pass123", - Stdout: false, - NoPrompt: true, - DisableLocal: true, - }) - if err != nil { - log.Println("Receive setup error:", err) - } - prog.Show() - donechan := make(chan bool) - var filename string - receivednames := make(map[string]int) - go func() { - ticker := time.NewTicker(time.Millisecond * 100) - for { - select { - case <-ticker.C: - if receiver.Step2FileInfoTransfered { - cnum := receiver.FilesToTransferCurrentNum - fi := receiver.FilesToTransfer[cnum] - filename = filepath.Base(fi.Name) - receivednames[filename] = cnum - topline.SetText(fmt.Sprintf("Receiving file: %s (%d/%d)", filename, cnum+1, len(receiver.FilesToTransfer))) - prog.Max = float64(fi.Size) - prog.SetValue(float64(receiver.TotalSent)) - } - case <-donechan: - ticker.Stop() - return - } - } - }() - cderr := os.Chdir(DEFAULT_DOWNLOAD_DIR) - if cderr != nil { - log.Println("Unable to change to download dir") - } - status.SetText("") - rerr := receiver.Receive() - donechan <- true - prog.Hide() - prog.SetValue(0) - topline.SetText("Enter code to download") - if rerr != nil { - status.Text = "Receive failed: " + rerr.Error() - } else { - filesReceived := make([]string, len(receivednames)) - var i int - for f := range receivednames { - filesReceived[i] = f - i++ - } - sort.Slice(filesReceived, func(i, j int) bool { - return receivednames[filesReceived[i]] < receivednames[filesReceived[j]] - }) - - plural := "" - if len(filesReceived) > 1 { - plural = "s" - } - status.Text = fmt.Sprintf("Received file%s %s", plural, strings.Join(filesReceived, ",")) - } - }), - prog, - status, - )) - -} - //go:embed metadata/en-US/images/featureGraphic.png var textlogobytes []byte @@ -228,11 +17,21 @@ func main() { a := app.NewWithID("com.github.howeyc.crocgui") w := a.NewWindow("croc") + a.Preferences().StringWithFallback("relay-address", "croc.schollz.com:9009") + a.Preferences().StringWithFallback("relay-password", "pass123") + a.Preferences().StringWithFallback("relay-ports", "9009,9010,9011,9012,9013") + textlogores := fyne.NewStaticResource("text-logo", textlogobytes) textlogo := canvas.NewImageFromResource(textlogores) textlogo.SetMinSize(fyne.NewSize(205, 100)) top := container.NewHBox(layout.NewSpacer(), textlogo, layout.NewSpacer()) - w.SetContent(container.NewBorder(top, nil, nil, nil, container.NewAppTabs(sendTabItem(w), recvTabItem(), aboutTabItem()))) + w.SetContent(container.NewBorder(top, nil, nil, nil, + container.NewAppTabs( + sendTabItem(a, w), + recvTabItem(a), + settingsTabItem(a), + aboutTabItem(), + ))) w.Resize(fyne.NewSize(800, 600)) w.ShowAndRun() } diff --git a/recv.go b/recv.go new file mode 100644 index 0000000..3de63dc --- /dev/null +++ b/recv.go @@ -0,0 +1,107 @@ +package main + +import ( + "fmt" + "log" + "os" + "path/filepath" + "sort" + "strings" + "time" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" + "github.com/schollz/croc/v8/src/croc" +) + +func recvTabItem(a fyne.App) *container.TabItem { + status := widget.NewLabel("") + defer func() { + if r := recover(); r != nil { + status.SetText(fmt.Sprint(r)) + } + }() + + prog := widget.NewProgressBar() + prog.Hide() + recvEntry := widget.NewEntry() + topline := widget.NewLabel("Enter code to download") + return container.NewTabItemWithIcon("Receive", theme.DownloadIcon(), + container.NewVBox( + topline, + widget.NewForm(&widget.FormItem{Text: "Receive Code", Widget: recvEntry}), + widget.NewButtonWithIcon("Download", theme.DownloadIcon(), func() { + receiver, err := croc.New(croc.Options{ + IsSender: false, + SharedSecret: recvEntry.Text, + Debug: false, + RelayAddress: a.Preferences().String("relay-address"), + RelayPassword: a.Preferences().String("relay-password"), + Stdout: false, + NoPrompt: true, + DisableLocal: true, + }) + if err != nil { + log.Println("Receive setup error:", err) + } + prog.Show() + donechan := make(chan bool) + var filename string + receivednames := make(map[string]int) + go func() { + ticker := time.NewTicker(time.Millisecond * 100) + for { + select { + case <-ticker.C: + if receiver.Step2FileInfoTransfered { + cnum := receiver.FilesToTransferCurrentNum + fi := receiver.FilesToTransfer[cnum] + filename = filepath.Base(fi.Name) + receivednames[filename] = cnum + topline.SetText(fmt.Sprintf("Receiving file: %s (%d/%d)", filename, cnum+1, len(receiver.FilesToTransfer))) + prog.Max = float64(fi.Size) + prog.SetValue(float64(receiver.TotalSent)) + } + case <-donechan: + ticker.Stop() + return + } + } + }() + cderr := os.Chdir(DEFAULT_DOWNLOAD_DIR) + if cderr != nil { + log.Println("Unable to change to download dir") + } + status.SetText("") + rerr := receiver.Receive() + donechan <- true + prog.Hide() + prog.SetValue(0) + topline.SetText("Enter code to download") + if rerr != nil { + status.Text = "Receive failed: " + rerr.Error() + } else { + filesReceived := make([]string, len(receivednames)) + var i int + for f := range receivednames { + filesReceived[i] = f + i++ + } + sort.Slice(filesReceived, func(i, j int) bool { + return receivednames[filesReceived[i]] < receivednames[filesReceived[j]] + }) + + plural := "" + if len(filesReceived) > 1 { + plural = "s" + } + status.Text = fmt.Sprintf("Received file%s %s", plural, strings.Join(filesReceived, ",")) + } + }), + prog, + status, + )) + +} diff --git a/send.go b/send.go new file mode 100644 index 0000000..b8ec37d --- /dev/null +++ b/send.go @@ -0,0 +1,111 @@ +package main + +import ( + "fmt" + "log" + "os" + "path/filepath" + "strings" + "time" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/dialog" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" + "github.com/schollz/croc/v8/src/croc" + "github.com/schollz/croc/v8/src/utils" +) + +func sendTabItem(a fyne.App, w fyne.Window) *container.TabItem { + status := widget.NewLabel("") + defer func() { + if r := recover(); r != nil { + status.SetText(fmt.Sprint(r)) + } + }() + prog := widget.NewProgressBar() + prog.Hide() + topline := widget.NewLabel("Pick a file to send") + var currentCode string + copyCodeButton := widget.NewButtonWithIcon("", theme.ContentCopyIcon(), func() { + if currentCode != "" { + w.Clipboard().SetContent(currentCode) + } + }) + copyCodeButton.Hide() + return container.NewTabItemWithIcon("Send", theme.MailSendIcon(), + container.NewVBox( + topline, + widget.NewButtonWithIcon("File", theme.FileIcon(), func() { + dialog.ShowFileOpen(func(f fyne.URIReadCloser, e error) { + if e != nil { + return + } + randomName := utils.GetRandomName() + sender, err := croc.New(croc.Options{ + IsSender: true, + SharedSecret: randomName, + Debug: false, + RelayAddress: a.Preferences().String("relay-address"), + RelayPorts: strings.Split(a.Preferences().String("relay-ports"), ","), + RelayPassword: a.Preferences().String("relay-password"), + Stdout: false, + NoPrompt: true, + DisableLocal: true, + }) + var filename string + if err != nil { + log.Println(err) + } else if f != nil { + fpath := fixpath(f.URI().Path()) + + fi, sterr := os.Stat(fpath) + if sterr != nil { + status.SetText(fmt.Sprintf("Stat error: %s - %s", fpath, sterr.Error())) + return + } + status.SetText("Receive Code: " + randomName) + currentCode = randomName + copyCodeButton.Show() + filename = filepath.Base(fpath) + topline.SetText(fmt.Sprintf("Sending file: %s", filename)) + totalsize := fi.Size() + prog.Max = float64(totalsize) + prog.Show() + donechan := make(chan bool) + go func() { + ticker := time.NewTicker(time.Millisecond * 100) + for { + select { + case <-ticker.C: + prog.SetValue(float64(sender.TotalSent)) + case <-donechan: + ticker.Stop() + return + } + } + }() + go func() { + serr := sender.Send(croc.TransferOptions{ + PathToFiles: []string{fpath}, + }) + donechan <- true + prog.Hide() + prog.SetValue(0) + topline.SetText("Pick a file to send") + if serr != nil { + log.Println("Send failed:", serr) + } else { + status.SetText(fmt.Sprintf("Sent file %s", filename)) + } + currentCode = "" + copyCodeButton.Hide() + }() + } + }, w) + }), + prog, + container.NewHBox(status, copyCodeButton), + )) +} diff --git a/settings.go b/settings.go new file mode 100644 index 0000000..44c5901 --- /dev/null +++ b/settings.go @@ -0,0 +1,19 @@ +package main + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/data/binding" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" +) + +func settingsTabItem(a fyne.App) *container.TabItem { + return container.NewTabItemWithIcon("Settings", theme.SettingsIcon(), container.NewVBox( + widget.NewForm( + widget.NewFormItem("Relay Address", widget.NewEntryWithData(binding.BindPreferenceString("relay-address", a.Preferences()))), + widget.NewFormItem("Relay Password", widget.NewEntryWithData(binding.BindPreferenceString("relay-password", a.Preferences()))), + widget.NewFormItem("Relay Ports", widget.NewEntryWithData(binding.BindPreferenceString("relay-ports", a.Preferences()))), + ), + )) +}