mirror of
https://github.com/fiatjaf/nak.git
synced 2025-12-08 16:48:51 +00:00
view: basic req functionality.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"strings"
|
||||
@@ -63,7 +62,7 @@ func updateEvent() {
|
||||
if currentKeyer != nil {
|
||||
signAndFinalize := func() {
|
||||
if currentKeyer != nil {
|
||||
if err := currentKeyer.SignEvent(context.Background(), &result); err == nil {
|
||||
if err := currentKeyer.SignEvent(ctx, &result); err == nil {
|
||||
finalize()
|
||||
} else {
|
||||
statusLabel.SetText("failed to sign: " + err.Error())
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"fiatjaf.com/nostr"
|
||||
"fiatjaf.com/nostr/nip19"
|
||||
"fiatjaf.com/nostr/nip49"
|
||||
"fiatjaf.com/nostr/sdk"
|
||||
"github.com/therecipe/qt/widgets"
|
||||
)
|
||||
|
||||
@@ -18,6 +20,8 @@ var (
|
||||
currentKeyer nostr.Keyer
|
||||
statusLabel *widgets.QLabel
|
||||
debounced = debouncer.New(800 * time.Millisecond)
|
||||
sys = sdk.NewSystem()
|
||||
ctx = context.Background()
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
352
view/req.go
352
view/req.go
@@ -1 +1,353 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/therecipe/qt/core"
|
||||
"github.com/therecipe/qt/widgets"
|
||||
)
|
||||
|
||||
type reqVars struct {
|
||||
authorsEdits []*widgets.QLineEdit
|
||||
idsEdits []*widgets.QLineEdit
|
||||
kindsEdits []*widgets.QLineEdit
|
||||
kindsLabels []*widgets.QLabel
|
||||
relaysEdits []*widgets.QLineEdit
|
||||
sinceEdit *widgets.QDateTimeEdit
|
||||
untilEdit *widgets.QDateTimeEdit
|
||||
limitSpin *widgets.QSpinBox
|
||||
|
||||
filter nostr.Filter
|
||||
|
||||
outputEdit *widgets.QTextEdit
|
||||
resultsEdit *widgets.QTextEdit
|
||||
}
|
||||
|
||||
var req = reqVars{}
|
||||
|
||||
func setupReqTab() *widgets.QWidget {
|
||||
tab := widgets.NewQWidget(nil, 0)
|
||||
layout := widgets.NewQVBoxLayout()
|
||||
tab.SetLayout(layout)
|
||||
|
||||
// authors
|
||||
authorsLabel := widgets.NewQLabel2("authors:", nil, 0)
|
||||
layout.AddWidget(authorsLabel, 0, 0)
|
||||
authorsVBox := widgets.NewQVBoxLayout()
|
||||
layout.AddLayout(authorsVBox, 0)
|
||||
req.authorsEdits = []*widgets.QLineEdit{}
|
||||
var addAuthorEdit func()
|
||||
addAuthorEdit = func() {
|
||||
edit := widgets.NewQLineEdit(nil)
|
||||
req.authorsEdits = append(req.authorsEdits, edit)
|
||||
authorsVBox.AddWidget(edit, 0, 0)
|
||||
edit.ConnectTextChanged(func(text string) {
|
||||
if strings.TrimSpace(text) != "" {
|
||||
if edit == req.authorsEdits[len(req.authorsEdits)-1] {
|
||||
addAuthorEdit()
|
||||
}
|
||||
} else {
|
||||
n := len(req.authorsEdits)
|
||||
if n >= 2 && strings.TrimSpace(req.authorsEdits[n-1].Text()) == "" && strings.TrimSpace(req.authorsEdits[n-2].Text()) == "" {
|
||||
authorsVBox.Layout().RemoveWidget(req.authorsEdits[n-1])
|
||||
req.authorsEdits[n-1].DeleteLater()
|
||||
req.authorsEdits = req.authorsEdits[0 : n-1]
|
||||
}
|
||||
}
|
||||
updateReq()
|
||||
})
|
||||
}
|
||||
addAuthorEdit()
|
||||
|
||||
// ids
|
||||
idsLabel := widgets.NewQLabel2("ids:", nil, 0)
|
||||
layout.AddWidget(idsLabel, 0, 0)
|
||||
idsVBox := widgets.NewQVBoxLayout()
|
||||
layout.AddLayout(idsVBox, 0)
|
||||
req.idsEdits = []*widgets.QLineEdit{}
|
||||
var addIdEdit func()
|
||||
addIdEdit = func() {
|
||||
edit := widgets.NewQLineEdit(nil)
|
||||
req.idsEdits = append(req.idsEdits, edit)
|
||||
idsVBox.AddWidget(edit, 0, 0)
|
||||
edit.ConnectTextChanged(func(text string) {
|
||||
if strings.TrimSpace(text) != "" {
|
||||
if edit == req.idsEdits[len(req.idsEdits)-1] {
|
||||
addIdEdit()
|
||||
}
|
||||
} else {
|
||||
n := len(req.idsEdits)
|
||||
if n >= 2 && strings.TrimSpace(req.idsEdits[n-1].Text()) == "" && strings.TrimSpace(req.idsEdits[n-2].Text()) == "" {
|
||||
idsVBox.Layout().RemoveWidget(req.idsEdits[n-1])
|
||||
req.idsEdits[n-1].DeleteLater()
|
||||
req.idsEdits = req.idsEdits[0 : n-1]
|
||||
}
|
||||
}
|
||||
updateReq()
|
||||
})
|
||||
}
|
||||
addIdEdit()
|
||||
|
||||
// kinds
|
||||
kindsLabel := widgets.NewQLabel2("kinds:", nil, 0)
|
||||
layout.AddWidget(kindsLabel, 0, 0)
|
||||
kindsVBox := widgets.NewQVBoxLayout()
|
||||
layout.AddLayout(kindsVBox, 0)
|
||||
req.kindsEdits = []*widgets.QLineEdit{}
|
||||
req.kindsLabels = []*widgets.QLabel{}
|
||||
var addKindEdit func()
|
||||
addKindEdit = func() {
|
||||
hbox := widgets.NewQHBoxLayout()
|
||||
kindsVBox.AddLayout(hbox, 0)
|
||||
edit := widgets.NewQLineEdit(nil)
|
||||
req.kindsEdits = append(req.kindsEdits, edit)
|
||||
hbox.AddWidget(edit, 0, 0)
|
||||
label := widgets.NewQLabel2("", nil, 0)
|
||||
req.kindsLabels = append(req.kindsLabels, label)
|
||||
hbox.AddWidget(label, 0, 0)
|
||||
edit.ConnectTextChanged(func(text string) {
|
||||
if strings.TrimSpace(text) != "" {
|
||||
if edit == req.kindsEdits[len(req.kindsEdits)-1] {
|
||||
addKindEdit()
|
||||
}
|
||||
} else {
|
||||
n := len(req.kindsEdits)
|
||||
if n >= 2 && strings.TrimSpace(req.kindsEdits[n-1].Text()) == "" && strings.TrimSpace(req.kindsEdits[n-2].Text()) == "" {
|
||||
lastItem := kindsVBox.ItemAt(kindsVBox.Count() - 1)
|
||||
kindsVBox.RemoveItem(lastItem)
|
||||
lastHBox := lastItem.Layout()
|
||||
lastHBox.RemoveWidget(req.kindsEdits[n-1])
|
||||
lastHBox.RemoveWidget(req.kindsLabels[n-1])
|
||||
req.kindsEdits[n-1].DeleteLater()
|
||||
req.kindsLabels[n-1].DeleteLater()
|
||||
lastHBox.DeleteLater()
|
||||
req.kindsEdits = req.kindsEdits[0 : n-1]
|
||||
req.kindsLabels = req.kindsLabels[0 : n-1]
|
||||
}
|
||||
}
|
||||
updateReq()
|
||||
})
|
||||
}
|
||||
addKindEdit()
|
||||
|
||||
// since
|
||||
sinceHBox := widgets.NewQHBoxLayout()
|
||||
layout.AddLayout(sinceHBox, 0)
|
||||
sinceLabel := widgets.NewQLabel2("since:", nil, 0)
|
||||
sinceHBox.AddWidget(sinceLabel, 0, 0)
|
||||
req.sinceEdit = widgets.NewQDateTimeEdit(nil)
|
||||
{
|
||||
time := core.NewQDateTime3(core.NewQDate3(0, 0, 0), core.NewQTime3(0, 0, 0, 0), 0)
|
||||
time.SetMSecsSinceEpoch(0)
|
||||
req.sinceEdit.SetDateTime(time)
|
||||
}
|
||||
sinceHBox.AddWidget(req.sinceEdit, 0, 0)
|
||||
req.sinceEdit.ConnectDateTimeChanged(func(*core.QDateTime) {
|
||||
updateReq()
|
||||
})
|
||||
|
||||
// until
|
||||
untilHBox := widgets.NewQHBoxLayout()
|
||||
layout.AddLayout(untilHBox, 0)
|
||||
untilLabel := widgets.NewQLabel2("until:", nil, 0)
|
||||
untilHBox.AddWidget(untilLabel, 0, 0)
|
||||
req.untilEdit = widgets.NewQDateTimeEdit(nil)
|
||||
{
|
||||
time := core.NewQDateTime3(core.NewQDate3(0, 0, 0), core.NewQTime3(0, 0, 0, 0), 0)
|
||||
time.SetMSecsSinceEpoch(0)
|
||||
req.untilEdit.SetDateTime(time)
|
||||
}
|
||||
untilHBox.AddWidget(req.untilEdit, 0, 0)
|
||||
req.untilEdit.ConnectDateTimeChanged(func(*core.QDateTime) {
|
||||
updateReq()
|
||||
})
|
||||
|
||||
// limit
|
||||
limitHBox := widgets.NewQHBoxLayout()
|
||||
layout.AddLayout(limitHBox, 0)
|
||||
limitLabel := widgets.NewQLabel2("limit:", nil, 0)
|
||||
limitHBox.AddWidget(limitLabel, 0, 0)
|
||||
req.limitSpin = widgets.NewQSpinBox(nil)
|
||||
req.limitSpin.SetMinimum(0)
|
||||
req.limitSpin.SetMaximum(1000)
|
||||
limitHBox.AddWidget(req.limitSpin, 0, 0)
|
||||
req.limitSpin.ConnectValueChanged(func(int) {
|
||||
updateReq()
|
||||
})
|
||||
|
||||
// output
|
||||
outputLabel := widgets.NewQLabel2("filter:", nil, 0)
|
||||
layout.AddWidget(outputLabel, 0, 0)
|
||||
req.outputEdit = widgets.NewQTextEdit(nil)
|
||||
req.outputEdit.SetReadOnly(true)
|
||||
layout.AddWidget(req.outputEdit, 0, 0)
|
||||
|
||||
// relays
|
||||
relaysLabel := widgets.NewQLabel2("relays:", nil, 0)
|
||||
layout.AddWidget(relaysLabel, 0, 0)
|
||||
relaysVBox := widgets.NewQVBoxLayout()
|
||||
layout.AddLayout(relaysVBox, 0)
|
||||
req.relaysEdits = []*widgets.QLineEdit{}
|
||||
var addRelayEdit func()
|
||||
addRelayEdit = func() {
|
||||
edit := widgets.NewQLineEdit(nil)
|
||||
req.relaysEdits = append(req.relaysEdits, edit)
|
||||
relaysVBox.AddWidget(edit, 0, 0)
|
||||
edit.ConnectTextChanged(func(text string) {
|
||||
if strings.TrimSpace(text) != "" {
|
||||
if edit == req.relaysEdits[len(req.relaysEdits)-1] {
|
||||
addRelayEdit()
|
||||
}
|
||||
} else {
|
||||
n := len(req.relaysEdits)
|
||||
if n >= 2 && strings.TrimSpace(req.relaysEdits[n-1].Text()) == "" && strings.TrimSpace(req.relaysEdits[n-2].Text()) == "" {
|
||||
relaysVBox.Layout().RemoveWidget(req.relaysEdits[n-1])
|
||||
req.relaysEdits[n-1].DeleteLater()
|
||||
req.relaysEdits = req.relaysEdits[0 : n-1]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
addRelayEdit()
|
||||
|
||||
// send button
|
||||
buttonHBox := widgets.NewQHBoxLayout()
|
||||
layout.AddLayout(buttonHBox, 0)
|
||||
sendButton := widgets.NewQPushButton2("send request", nil)
|
||||
buttonHBox.AddWidget(sendButton, 0, 0)
|
||||
buttonHBox.AddStretch(1)
|
||||
|
||||
// results
|
||||
resultsLabel := widgets.NewQLabel2("results:", nil, 0)
|
||||
layout.AddWidget(resultsLabel, 0, 0)
|
||||
req.resultsEdit = widgets.NewQTextEdit(nil)
|
||||
req.resultsEdit.SetReadOnly(true)
|
||||
layout.AddWidget(req.resultsEdit, 0, 0)
|
||||
|
||||
sendButton.ConnectClicked(func(checked bool) {
|
||||
req.subscribe()
|
||||
})
|
||||
|
||||
return tab
|
||||
}
|
||||
|
||||
func updateReq() {
|
||||
req.filter = nostr.Filter{}
|
||||
|
||||
// collect authors
|
||||
authors := []nostr.PubKey{}
|
||||
for _, edit := range req.authorsEdits {
|
||||
if pk, err := nostr.PubKeyFromHex(strings.TrimSpace(edit.Text())); err == nil {
|
||||
authors = append(authors, pk)
|
||||
}
|
||||
}
|
||||
if len(authors) > 0 {
|
||||
req.filter.Authors = authors
|
||||
}
|
||||
|
||||
// collect ids
|
||||
ids := []nostr.ID{}
|
||||
for _, edit := range req.idsEdits {
|
||||
if id, err := nostr.IDFromHex(strings.TrimSpace(edit.Text())); err == nil {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
if len(ids) > 0 {
|
||||
req.filter.IDs = ids
|
||||
}
|
||||
|
||||
// collect kinds
|
||||
kinds := []nostr.Kind{}
|
||||
for _, edit := range req.kindsEdits {
|
||||
text := strings.TrimSpace(edit.Text())
|
||||
if k, err := strconv.Atoi(text); err == nil {
|
||||
kinds = append(kinds, nostr.Kind(k))
|
||||
}
|
||||
}
|
||||
if len(kinds) > 0 {
|
||||
req.filter.Kinds = kinds
|
||||
}
|
||||
|
||||
// update kind labels
|
||||
for i, kind := range kinds {
|
||||
if i < len(req.kindsLabels) {
|
||||
name := kind.Name()
|
||||
if name != "unknown" {
|
||||
req.kindsLabels[i].SetText(name)
|
||||
} else {
|
||||
req.kindsLabels[i].SetText("")
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := len(kinds); i < len(req.kindsLabels); i++ {
|
||||
req.kindsLabels[i].SetText("")
|
||||
}
|
||||
|
||||
// since
|
||||
if req.sinceEdit.DateTime().IsValid() {
|
||||
ts := nostr.Timestamp(req.sinceEdit.DateTime().ToMSecsSinceEpoch() / 1000)
|
||||
req.filter.Since = ts
|
||||
}
|
||||
|
||||
// until
|
||||
if req.untilEdit.DateTime().IsValid() {
|
||||
ts := nostr.Timestamp(req.untilEdit.DateTime().ToMSecsSinceEpoch() / 1000)
|
||||
req.filter.Until = ts
|
||||
}
|
||||
|
||||
// limit
|
||||
if req.limitSpin.Value() > 0 {
|
||||
req.filter.Limit = req.limitSpin.Value()
|
||||
}
|
||||
|
||||
jsonBytes, _ := json.Marshal(req.filter)
|
||||
req.outputEdit.SetPlainText(string(jsonBytes))
|
||||
}
|
||||
|
||||
func (req reqVars) subscribe() {
|
||||
// collect relays
|
||||
relays := []string{}
|
||||
for _, edit := range req.relaysEdits {
|
||||
url := strings.TrimSpace(edit.Text())
|
||||
if url != "" {
|
||||
relays = append(relays, url)
|
||||
}
|
||||
}
|
||||
if len(relays) == 0 {
|
||||
statusLabel.SetText("no relays specified")
|
||||
return
|
||||
}
|
||||
|
||||
// subscribe
|
||||
statusLabel.SetText("subscribed to " + strings.Join(relays, " "))
|
||||
eoseChan := make(chan struct{})
|
||||
eventsChan := sys.Pool.SubscribeManyNotifyEOSE(ctx, relays, req.filter, eoseChan, nostr.SubscriptionOptions{
|
||||
Label: "nakv-req",
|
||||
})
|
||||
|
||||
// collect events
|
||||
go func() {
|
||||
eosed := false
|
||||
for {
|
||||
select {
|
||||
case ie, ok := <-eventsChan:
|
||||
if !ok {
|
||||
statusLabel.SetText("subscription ended")
|
||||
return
|
||||
}
|
||||
|
||||
jsonBytes, _ := json.Marshal(ie.Event)
|
||||
if eosed {
|
||||
req.resultsEdit.SetPlainText(string(jsonBytes) + "\n" + req.resultsEdit.ToPlainText())
|
||||
} else {
|
||||
req.resultsEdit.InsertPlainText("\n" + string(jsonBytes))
|
||||
}
|
||||
case <-eoseChan:
|
||||
eosed = true
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user