Skip to content

Commit 51f200c

Browse files
Working on snippet store
1 parent 079e572 commit 51f200c

10 files changed

Lines changed: 26019 additions & 17998 deletions

File tree

playground/internal/common/snippetStore.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@ package common
66
// This interfaces allows the network access to be replaced
77
// with a mock implementation for testing.
88
type SnippetStore interface {
9-
10-
// TODO(grantnelson-wf): Update to work better with predefined snippets.
11-
//
129
// Read fetches the code snippet with the given hash (including the `#/`)
1310
// from the snippet store.
1411
// If the has is `#` without the `/`, the remainder is checked to see
1512
// if it matches any pre-defined snippets, i.e. `#Hello`.
1613
// If the hash is empty or invalid, it returns the default code.
17-
// This will block while waiting for the network request to complete.
18-
Read(hash string) (string, error)
14+
//
15+
// This will not block but the then method will be called after
16+
// the network request has completed.
17+
Read(hash string, then func(string, error))
1918

2019
// Write sends the given code snippet to the snippet store and returns
2120
// the snippet hash (including the `#/`) on success.
22-
// This will block while waiting for the network request to complete.
23-
Write(code string) (string, error)
21+
//
22+
// This will not block but the then method will be called after
23+
// the network request has completed.
24+
Write(code string, then func(string, error))
2425
}

playground/internal/react/codeBox.go

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,42 +29,39 @@ func codeBoxComponent(props Props) *Element {
2929
lineNumsRef = UseRef()
3030
)
3131

32-
newCBA := func() *codeBoxAssistant {
33-
return &codeBoxAssistant{
34-
curCode: curCode,
35-
setCode: setCode,
36-
onSave: onSave,
37-
onEscape: onEscape,
38-
textAreaRef: textAreaRef,
39-
}
40-
}
41-
4232
onInput := UseCallback(func(e *js.Object) {
43-
code := e.Get(`target`).Get(`value`).String()
33+
newCode := e.Get(`target`).Get(`value`).String()
4434
sel := getSelection(textAreaRef)
45-
globals.UndoRedo().RecordCodeChange(sel, curCode, code)
46-
setCode(code)
47-
}, []any{curCode})
35+
globals.UndoRedo().RecordCodeChange(sel, curCode, newCode)
36+
setCode(newCode)
37+
}, []any{curCode, setCode, textAreaRef})
4838

4939
onKeyDown := UseCallback(func(e *js.Object) {
5040
key := e.Get(`key`).String()
5141
shift := e.Get(`shiftKey`).Bool()
5242
ctrl := e.Get(`metaKey`).Bool() || e.Get(`ctrlKey`).Bool()
53-
if editor.ProcessKeyDown(newCBA(), key, shift, ctrl) {
43+
cba := &codeBoxAssistant{
44+
curCode: curCode,
45+
setCode: setCode,
46+
onSave: onSave,
47+
onEscape: onEscape,
48+
textAreaRef: textAreaRef,
49+
}
50+
if editor.ProcessKeyDown(cba, key, shift, ctrl) {
5451
e.Call(`preventDefault`)
5552
e.Call(`stopPropagation`)
5653
}
57-
}, []any{curCode})
54+
}, []any{curCode, setCode, onSave, onEscape, textAreaRef})
5855

5956
onScroll := UseCallback(func(e *js.Object) {
6057
scrollTop := e.Get(`target`).Get(`scrollTop`).Int()
6158
lineNumsRef.Set(`scrollTop`, scrollTop)
62-
}, []any{})
59+
}, []any{lineNumsRef})
6360

6461
onSelect := UseCallback(func(e *js.Object) {
6562
// Don't normalize the selection so that the direction is preserved.
6663
globals.UndoRedo().RecordSelectionChange(getSelection(textAreaRef))
67-
}, []any{})
64+
}, []any{textAreaRef})
6865

6966
// TODO(grantnelson-wf): If it is possible to detect a paste event,
7067
// then maybe we could indent the pasted code automatically to match

playground/internal/react/globals.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ var globals = struct {
2424
Runner func() common.Runner
2525
}{
2626
UndoRedo: OnceValue(undoRedo.NewStack),
27-
SnippetsStore: OnceValue(snippets.NewStore),
27+
SnippetsStore: OnceValue(snippets.NewLocalStore), // TODO(grantnelson-wf): Switch to snippets.NewStore before deploying
2828
Runner: OnceValue(func() common.Runner { return runner.New(runner.NewFetcher()) }),
2929
}
3030

playground/internal/react/playground.go

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package react
22

33
import (
4+
"fmt"
5+
46
"github.com/gopherjs/gopherjs/compiler"
57
"github.com/gopherjs/gopherjs/js"
68
)
@@ -31,14 +33,15 @@ func playgroundComponent(props Props) *Element {
3133

3234
UseEffect(func() {
3335
hash := getLocation().Get(`hash`).String()
34-
code, err := globals.SnippetsStore().Read(hash)
35-
if err != nil {
36-
o := Output(setOutput)
37-
o.Clear()
38-
o.AddError(err)
39-
}
40-
// even on error, set the code so the default code is shown.
41-
setCode.Invoke(code)
36+
globals.SnippetsStore().Read(hash, func(snippet string, err error) {
37+
if err != nil {
38+
o := Output(setOutput)
39+
o.Clear()
40+
o.AddError(err)
41+
}
42+
// even on error, set the code so the default code is shown.
43+
setCode.Invoke(snippet)
44+
})
4245
}, []any{})
4346

4447
/* TODO(grantnelson-wf): Implement hashchange loading
@@ -55,11 +58,11 @@ func playgroundComponent(props Props) *Element {
5558
// like they would be able to with tab stops but our editor is consuming
5659
// tab key presses so tab stops won't work when in the text area.
5760
runButtonRef.Call(`focus`)
58-
}, []any{})
61+
}, []any{runButtonRef})
5962

6063
onSaveKeyPress := UseCallback(func() {
61-
println("Save key pressed") // TODO(grantnelson-wf): Implement by running format (and maybe sharing)
62-
}, []any{})
64+
println("Save key pressed (fmtImports:", fmtImports, ")") // TODO(grantnelson-wf): Implement by running format
65+
}, []any{fmtImports})
6366

6467
onRunClick := UseCallback(func() {
6568
println("Run clicked") // TODO(grantnelson-wf): Implement
@@ -70,8 +73,18 @@ func playgroundComponent(props Props) *Element {
7073
}, []any{fmtImports})
7174

7275
onShareClick := UseCallback(func() {
73-
println("Share URL Clicked") // TODO(grantnelson-wf): Implement
74-
}, []any{})
76+
fmt.Printf(">> Code to share: %q\n", code) // TODO(grantnelson-wf): REMOVE
77+
globals.SnippetsStore().Write(code, func(url string, err error) {
78+
if err != nil {
79+
setShareUrl.Invoke(``)
80+
output := Output(setOutput)
81+
output.Clear()
82+
output.AddError(err)
83+
return
84+
}
85+
setShareUrl.Invoke(url)
86+
})
87+
}, []any{code, setOutput, setShareUrl})
7588

7689
return Fragment(
7790
Div(Props{

playground/internal/react/shareUrlControl.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ func shareUrlComponent(props Props) *Element {
2222
}
2323
}, []any{shareUrl})
2424

25+
onShareClick := UseCallback(func(e *js.Object) {
26+
onShare() // call without the dom target
27+
}, []any{onShare})
28+
2529
onShareUrlFocus := UseCallback(func(e *js.Object) {
2630
e.Get(`target`).Call(`select`)
2731
}, []any{})
@@ -32,7 +36,7 @@ func shareUrlComponent(props Props) *Element {
3236
}
3337

3438
return Fragment(
35-
Button(`share-button`, `Share`, nil, onShare),
39+
Button(`share-button`, `Share`, nil, onShareClick),
3640
CreateElement(`input`, Props{
3741
`id`: `share-url`,
3842
`type`: `text`,

playground/internal/react/toggleBox.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func toggleBoxComponent(props Props) *Element {
2323

2424
onChange := UseCallback(func(e *js.Object) {
2525
setChecked(e.Get(`target`).Get(`checked`).Bool())
26-
}, []any{})
26+
}, []any{setChecked})
2727

2828
return Div(Props{
2929
`id`: id,

playground/internal/snippets/snippets.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,37 @@ import _ "embed"
88
//go:embed default.go.txt
99
var DefaultCode string
1010

11+
//go:embed workGroup.go.txt
12+
var workGroupCode string
13+
1114
// predefined contains the pre-defined code snippets that are available
1215
// in the playground, keyed by the display name.
1316
//
1417
// TODO(grantnelson-wf): Add more pre-defined snippets.
1518
var predefined = map[string]string{
16-
`Hello`: DefaultCode,
19+
`Hello`: DefaultCode,
20+
`Work Group`: workGroupCode,
21+
}
22+
23+
// SnippetNames returns the names of all predefined snippets.
24+
// The names do not include the leading '#' character.
25+
func SnippetNames() []string {
26+
names := make([]string, 0, len(predefined))
27+
for name := range predefined {
28+
names = append(names, name)
29+
}
30+
return names
31+
}
32+
33+
// getSnippetName returns the name of the predefined snippet that
34+
// matches the given code.
35+
// The returned name does not include the leading '#' character.
36+
// If no predefined snippet matches the given code, false is returned.
37+
func getSnippetName(code string) (string, bool) {
38+
for name, snippet := range predefined {
39+
if code == snippet {
40+
return name, true
41+
}
42+
}
43+
return ``, false
1744
}

0 commit comments

Comments
 (0)