summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android_shared_android.go16
-rw-r--r--android_shared_stub.go2
-rw-r--r--main.go72
-rw-r--r--main_test.go116
4 files changed, 182 insertions, 24 deletions
diff --git a/android_shared_android.go b/android_shared_android.go
index e46fab2..b29f830 100644
--- a/android_shared_android.go
+++ b/android_shared_android.go
@@ -7,20 +7,20 @@ import (
"path/filepath"
)
-// readSharedFromCache tries to read the shared text written by the Android activity.
-// The activity writes into getCacheDir()/quicklogger-shared.txt; on Go, os.TempDir()
-// maps to the same location in Android (app cache directory).
-func readSharedFromCache() (string, error) {
+// sharedTextCachePath returns the cache file used for Android share intents.
+func sharedTextCachePath() string {
dir, derr := os.UserCacheDir()
if derr != nil || dir == "" {
dir = os.TempDir()
}
- path := filepath.Join(dir, "quicklogger-shared.txt")
- b, err := os.ReadFile(path)
+ return filepath.Join(dir, "quicklogger-shared.txt")
+}
+
+// readSharedFromCache tries to read the shared text written by the Android activity.
+func readSharedFromCache() (string, error) {
+ b, err := os.ReadFile(sharedTextCachePath())
if err != nil {
return "", err
}
- // best-effort cleanup; ignore errors
- _ = os.Remove(path)
return string(b), nil
}
diff --git a/android_shared_stub.go b/android_shared_stub.go
index 9ebe1a3..82429f7 100644
--- a/android_shared_stub.go
+++ b/android_shared_stub.go
@@ -3,3 +3,5 @@
package main
func readSharedFromCache() (string, error) { return "", nil }
+
+func sharedTextCachePath() string { return "" }
diff --git a/main.go b/main.go
index d913835..dd7fc9c 100644
--- a/main.go
+++ b/main.go
@@ -52,6 +52,44 @@ func prepareSharedTextLoad(text string, autoLog bool) (sharedTextLoadMode, strin
return sharedTextLoadPrefill, text, true
}
+func clearSharedTextCache() {
+ if path := sharedTextCachePath(); path != "" {
+ _ = os.Remove(path)
+ }
+}
+
+func handleSharedTextLoad(
+ text string,
+ autoLog bool,
+ dir string,
+ prefill func(string),
+ focus func(),
+ resetInput func(),
+ clearCache func(),
+ logFn func(string, string) error,
+ showInfo func(string, string),
+ showError func(error),
+) {
+ mode, sharedText, ok := prepareSharedTextLoad(text, autoLog)
+ if !ok {
+ clearCache()
+ return
+ }
+ if mode == sharedTextLoadAutoLog {
+ if err := logFn(dir, sharedText); err != nil {
+ showError(err)
+ return
+ }
+ showInfo("Logged", "Shared text has been logged.")
+ resetInput()
+ clearCache()
+ return
+ }
+ prefill(sharedText)
+ focus()
+ clearCache()
+}
+
// newInputWidget creates the multi-line text entry with platform-appropriate
// wrapping and row count settings.
func newInputWidget() *widget.Entry {
@@ -152,27 +190,29 @@ func createMainWindow(a fyne.App) fyne.Window {
}
return
}
- mode, sharedText, ok := prepareSharedTextLoad(txt, a.Preferences().BoolWithFallback("AutoLogSharedText", false))
- if !ok {
- return
- }
loadingSharedText = true
defer func() {
loadingSharedText = false
}()
- if mode == sharedTextLoadAutoLog {
- dir := a.Preferences().StringWithFallback("Directory", defaultDirectory)
- if err := logEntry(dir, sharedText); err != nil {
+ handleSharedTextLoad(
+ txt,
+ a.Preferences().BoolWithFallback("AutoLogSharedText", false),
+ a.Preferences().StringWithFallback("Directory", defaultDirectory),
+ input.SetText,
+ func() {
+ window.Canvas().Focus(input)
+ },
+ resetInput,
+ clearSharedTextCache,
+ logEntry,
+ func(title, message string) {
+ dialog.ShowInformation(title, message, window)
+ },
+ func(err error) {
dialog.ShowError(err, window)
- return
- }
- dialog.ShowInformation("Logged", "Shared text has been logged.", window)
- resetInput()
- return
- }
- input.SetText(sharedText)
- charCount.SetText(fmt.Sprintf("%d chars", len(sharedText)))
- window.Canvas().Focus(input)
+ },
+ )
+ charCount.SetText(fmt.Sprintf("%d chars", len(input.Text)))
}
if fyne.CurrentDevice().IsMobile() {
diff --git a/main_test.go b/main_test.go
index 8d6fac8..399158a 100644
--- a/main_test.go
+++ b/main_test.go
@@ -1,6 +1,8 @@
package main
import (
+ "errors"
+ "fmt"
"os"
"path/filepath"
"strings"
@@ -113,3 +115,117 @@ func TestPrepareSharedTextLoadAllowsLongText(t *testing.T) {
t.Fatalf("expected original text to be preserved, got %d bytes", len(gotText))
}
}
+
+func TestHandleSharedTextLoadAutoLogSuccessRemovesCache(t *testing.T) {
+ cacheDir := t.TempDir()
+ cachePath := filepath.Join(cacheDir, "quicklogger-shared.txt")
+ if err := os.WriteFile(cachePath, []byte("hello"), 0o644); err != nil {
+ t.Fatalf("writing cache file: %v", err)
+ }
+
+ var infoTitle, infoMessage string
+ var resetCalls, clearCalls int
+ handleSharedTextLoad(
+ "hello",
+ true,
+ cacheDir,
+ func(string) {
+ t.Fatal("prefill should not be called in auto-log mode")
+ },
+ func() {
+ t.Fatal("focus should not be called in auto-log mode")
+ },
+ func() {
+ resetCalls++
+ },
+ func() {
+ clearCalls++
+ if err := os.Remove(cachePath); err != nil && !errors.Is(err, os.ErrNotExist) {
+ t.Fatalf("removing cache file: %v", err)
+ }
+ },
+ func(dir, text string) error {
+ if dir != cacheDir {
+ t.Fatalf("expected dir %q, got %q", cacheDir, dir)
+ }
+ if text != "hello" {
+ t.Fatalf("expected text %q, got %q", "hello", text)
+ }
+ return nil
+ },
+ func(title, message string) {
+ infoTitle = title
+ infoMessage = message
+ },
+ func(err error) {
+ t.Fatalf("unexpected auto-log error: %v", err)
+ },
+ )
+
+ if resetCalls != 1 {
+ t.Fatalf("expected resetInput to be called once, got %d", resetCalls)
+ }
+ if clearCalls != 1 {
+ t.Fatalf("expected cache cleanup once, got %d", clearCalls)
+ }
+ if infoTitle != "Logged" || infoMessage != "Shared text has been logged." {
+ t.Fatalf("unexpected info dialog: %q / %q", infoTitle, infoMessage)
+ }
+ if _, err := os.Stat(cachePath); !errors.Is(err, os.ErrNotExist) {
+ t.Fatalf("expected cache file to be removed, stat err=%v", err)
+ }
+}
+
+func TestHandleSharedTextLoadAutoLogFailureKeepsCache(t *testing.T) {
+ cacheDir := t.TempDir()
+ cachePath := filepath.Join(cacheDir, "quicklogger-shared.txt")
+ if err := os.WriteFile(cachePath, []byte("hello"), 0o644); err != nil {
+ t.Fatalf("writing cache file: %v", err)
+ }
+
+ logErr := fmt.Errorf("boom")
+ var errorCalled bool
+ var clearCalls int
+ handleSharedTextLoad(
+ "hello",
+ true,
+ cacheDir,
+ func(string) {
+ t.Fatal("prefill should not be called in auto-log mode")
+ },
+ func() {
+ t.Fatal("focus should not be called in auto-log mode")
+ },
+ func() {
+ t.Fatal("resetInput should not be called on auto-log failure")
+ },
+ func() {
+ clearCalls++
+ if err := os.Remove(cachePath); err != nil {
+ t.Fatalf("unexpected cleanup on failure: %v", err)
+ }
+ },
+ func(string, string) error {
+ return logErr
+ },
+ func(string, string) {
+ t.Fatal("info dialog should not be shown on failure")
+ },
+ func(err error) {
+ if !errors.Is(err, logErr) {
+ t.Fatalf("expected log error %v, got %v", logErr, err)
+ }
+ errorCalled = true
+ },
+ )
+
+ if !errorCalled {
+ t.Fatal("expected error dialog callback")
+ }
+ if clearCalls != 0 {
+ t.Fatalf("expected cache to remain on failure, cleanup calls=%d", clearCalls)
+ }
+ if _, err := os.Stat(cachePath); err != nil {
+ t.Fatalf("expected cache file to remain, stat err=%v", err)
+ }
+}