~whereswaldon/arbor-dev

feat(Orchard): introduce Orchard store via toggle in settings v1 PROPOSED

: 1
 feat(Orchard): introduce Orchard store via toggle in settings

 3 files changed, 64 insertions(+), 21 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~whereswaldon/arbor-dev/patches/21786/mbox | git am -3
Learn more about email & git

[PATCH] feat(Orchard): introduce Orchard store via toggle in settings Export this patch

From: Jack Mordaunt <jackmordaunt@gmail.com>

- add a toggle to settings that enables Orchard
- default to Grove until we are satisfied to make Orchard default
- rename`SettingsService.GrovePath` => `SettingsService.DataPath` 
- refactor `newArborService` to initialize Orchard store based on the settings

---
 core/arbor-service.go    | 40 ++++++++++++++++++++++------------------
 core/settings-service.go | 20 +++++++++++++++++---
 settings-view.go         | 25 +++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 21 deletions(-)

diff --git a/core/arbor-service.go b/core/arbor-service.go
index 6481bf3..2e5bbbc 100644
--- a/core/arbor-service.go
+++ b/core/arbor-service.go
@@ -1,14 +1,17 @@
package core

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"time"

	status "git.sr.ht/~athorp96/forest-ex/active-status"
	"git.sr.ht/~athorp96/forest-ex/expiration"
	"git.sr.ht/~whereswaldon/forest-go"
	"git.sr.ht/~whereswaldon/forest-go/grove"
	"git.sr.ht/~whereswaldon/forest-go/orchard"
	"git.sr.ht/~whereswaldon/forest-go/store"
	"git.sr.ht/~whereswaldon/sprig/ds"
)
@@ -32,33 +35,34 @@ var _ ArborService = &arborService{}
// newArborService creates a new instance of the Arbor Service using
// the provided Settings within the app to acquire configuration.
func newArborService(settings SettingsService) (ArborService, error) {
	baseStore := func() (s forest.Store) {
		defer func() {
			if s == nil {
				log.Printf("falling back to in-memory storage")
				s = store.NewMemoryStore()
	s, err := func() (forest.Store, error) {
		path := settings.DataPath()
		if err := os.MkdirAll(path, 0770); err != nil {
			return nil, fmt.Errorf("preparing data directory for store: %v", err)
		}
		if settings.UseOrchardStore() {
			o, err := orchard.Open(filepath.Join(path, "orchard.db"))
			if err != nil {
				return nil, fmt.Errorf("opening Orchard store: %v", err)
			}
		}()
		var (
			err       error
			grovePath string = settings.GrovePath()
		)
		if err := os.MkdirAll(grovePath, 0770); err != nil {
			log.Printf("unable to create directory for grove: %v", err)
			return
			return o, nil
		}
		g, err := grove.New(grovePath)
		g, err := grove.New(path)
		if err != nil {
			log.Printf("Failed creating grove: %v", err)
			return nil, fmt.Errorf("opening Grove store: %v", err)
		}
		g.SetCorruptNodeHandler(func(id string) {
			log.Printf("Grove reported corrupt node %s", id)
			log.Printf("Grove: corrupt node %s", id)
		})
		return g
		return g, nil
	}()
	if err != nil {
		s = store.NewMemoryStore()
	}
	log.Printf("Store: %T\n", s)
	a := &arborService{
		SettingsService: settings,
		grove:           store.NewArchive(baseStore),
		grove:           store.NewArchive(s),
		done:            make(chan struct{}),
	}
	cl, err := ds.NewCommunityList(a.grove)
diff --git a/core/settings-service.go b/core/settings-service.go
index dcdc1bb..41f0daf 100644
--- a/core/settings-service.go
+++ b/core/settings-service.go
@@ -34,10 +34,12 @@ type SettingsService interface {
	SetDarkMode(bool)
	ActiveArborIdentityID() *fields.QualifiedHash
	Identity() (*forest.Identity, error)
	GrovePath() string
	DataPath() string
	Persist() error
	CreateIdentity(name string) error
	Builder() (*forest.Builder, error)
	UseOrchardStore() bool
	SetUseOrchardStore(bool)
}

type Settings struct {
@@ -65,6 +67,10 @@ type Settings struct {
	// the UI instead of appearing on top
	DockNavDrawer bool

	// whether the user wants to use the beta Orchard store for node storage.
	// Will become default in future release.
	OrchardStore bool

	Subscriptions []string
}

@@ -172,8 +178,8 @@ func (s *settingsService) SetAddress(addr string) {
	s.Settings.Address = addr
}

func (s *settingsService) GrovePath() string {
	return filepath.Join(s.dataDir, "grove")
func (s *settingsService) DataPath() string {
	return filepath.Join(s.dataDir, "data")
}

func (s *settingsService) BottomAppBar() bool {
@@ -192,6 +198,14 @@ func (s *settingsService) SetDarkMode(enabled bool) {
	s.Settings.DarkMode = enabled
}

func (s *settingsService) UseOrchardStore() bool {
	return s.Settings.OrchardStore
}

func (s *settingsService) SetUseOrchardStore(enabled bool) {
	s.Settings.OrchardStore = enabled
}

func (s *settingsService) SettingsFile() string {
	return filepath.Join(s.dataDir, "settings.json")
}
diff --git a/settings-view.go b/settings-view.go
index 0cc54f2..d294961 100644
--- a/settings-view.go
+++ b/settings-view.go
@@ -32,6 +32,7 @@ type SettingsView struct {
	BottomBarSwitch         widget.Bool
	DockNavSwitch           widget.Bool
	DarkModeSwitch          widget.Bool
	UseOrchardStoreSwitch   widget.Bool
}

type Section struct {
@@ -156,6 +157,10 @@ func (c *SettingsView) Update(gtx layout.Context) {
		c.Settings().SetDarkMode(c.DarkModeSwitch.Value)
		settingsChanged = true
	}
	if c.UseOrchardStoreSwitch.Changed() {
		c.Settings().SetUseOrchardStore(c.UseOrchardStoreSwitch.Value)
		settingsChanged = true
	}
	if settingsChanged {
		c.manager.ApplySettings(c.Settings())
		go c.Settings().Persist()
@@ -168,6 +173,7 @@ func (c *SettingsView) BecomeVisible() {
	c.BottomBarSwitch.Value = c.Settings().BottomAppBar()
	c.DockNavSwitch.Value = c.Settings().DockNavDrawer()
	c.DarkModeSwitch.Value = c.Settings().DarkMode()
	c.UseOrchardStoreSwitch.Value = c.Settings().UseOrchardStore()
}

func (c *SettingsView) Layout(gtx layout.Context) layout.Dimensions {
@@ -226,6 +232,25 @@ func (c *SettingsView) Layout(gtx layout.Context) layout.Dimensions {
				}.Layout,
			},
		},
		{
			Heading: "Store",
			Items: []layout.Widget{
				SimpleSectionItem{
					Theme: theme,
					Control: func(gtx C) D {
						return layout.Flex{Alignment: layout.Middle}.Layout(gtx,
							layout.Rigid(func(gtx C) D {
								return itemInset.Layout(gtx, material.Switch(theme, &c.UseOrchardStoreSwitch).Layout)
							}),
							layout.Rigid(func(gtx C) D {
								return itemInset.Layout(gtx, material.Body1(theme, "Use Orchard store").Layout)
							}),
						)
					},
					Context: "Orchard is a single-file read-oriented database for storing nodes.",
				}.Layout,
			},
		},
		{
			Heading: "User Interface",
			Items: []layout.Widget{
-- 
2.30.0.windows.1
This change looks good, though I'll wait to apply it until the orchard
work is itself merged.

Thanks for putting this together!
Chris