Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(examples): hall of fame #2842

Open
wants to merge 85 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
ac0d79e
feat: add p/avl/pager
moul Jul 14, 2024
a17edb2
chore: fixup
moul Jul 14, 2024
1a44f35
chore: fixup
moul Jul 14, 2024
291b92f
chore: fixup
moul Jul 14, 2024
6038562
chore: fixup
moul Jul 14, 2024
23db6aa
chore: fixup
moul Jul 14, 2024
fa7286b
chore: fixup
moul Jul 14, 2024
c0d435d
chore: fixup
moul Jul 14, 2024
1cff9f1
chore: fixup
moul Jul 14, 2024
04d62c7
Merge remote-tracking branch 'origin/master' into dev/moul/pagination
moul Jul 14, 2024
b2294ac
chore: fixup
moul Jul 14, 2024
2a1093e
chore: fixup
moul Jul 14, 2024
903fb48
Update pager_test.gno
moul Jul 14, 2024
f1adda0
chore: fixup
moul Jul 14, 2024
5d8a12b
add initial hof
leohhhn Sep 24, 2024
538f6f1
add
leohhhn Sep 24, 2024
7d44835
Merge branch 'master' into dev/moul/pagination
moul Sep 24, 2024
c8e4e1f
chore: fixup
moul Sep 24, 2024
a0be035
chore: fixup
moul Sep 24, 2024
5c3524d
chore: fixup
moul Sep 24, 2024
17b7ba6
add item & exh rendering
leohhhn Sep 25, 2024
29bb8dc
save
leohhhn Sep 25, 2024
5393e7b
update rendering, add upvote/downvote
leohhhn Sep 25, 2024
9a171ff
register temp
leohhhn Sep 26, 2024
97794d7
Merge remote-tracking branch 'origin/master' into dev/moul/pagination
moul Sep 26, 2024
1da8805
chore: new API
moul Sep 26, 2024
e2dcbca
Merge branch 'master' into hof
leohhhn Sep 30, 2024
ec2687b
add cmts
leohhhn Sep 30, 2024
3c21976
cmts
leohhhn Sep 30, 2024
fa11b61
start cs funcs
leohhhn Sep 30, 2024
48ebe1a
rm cmts
leohhhn Oct 1, 2024
5a5c1b5
add widget
leohhhn Oct 1, 2024
2cef5df
add temp exhib
leohhhn Oct 1, 2024
54e414b
rendering
leohhhn Oct 1, 2024
8f3d796
rendering
leohhhn Oct 1, 2024
4a6dad6
rm blog register
leohhhn Oct 1, 2024
5dc3d0f
save
leohhhn Oct 1, 2024
f0ce5de
save
leohhhn Oct 1, 2024
943df0c
Merge branch 'master' into dev/moul/pagination
moul Oct 3, 2024
296f7d8
rm errs
leohhhn Oct 4, 2024
1c10732
Update examples/gno.land/p/demo/avl/pager/pager.gno
moul Oct 5, 2024
79ffd7d
chore: fixup
moul Oct 5, 2024
adf95c0
Merge branch 'master' into dev/moul/pagination
moul Oct 5, 2024
3754a70
chore: fixup
moul Oct 5, 2024
19f7fa9
rm temp exhib
leohhhn Oct 7, 2024
a646518
add pausable
leohhhn Oct 7, 2024
94fc361
expose apis, add pausable
leohhhn Oct 7, 2024
cde9fe2
fix errors
leohhhn Oct 7, 2024
84ef0ea
update ownable/pausable, home, leon/home
leohhhn Oct 7, 2024
0c9b8a6
move
leohhhn Oct 7, 2024
d1d60ed
add shortlink
leohhhn Oct 7, 2024
f6d07a9
add shortpath, fix
leohhhn Oct 7, 2024
dd528a5
newline
leohhhn Oct 7, 2024
57fbda6
add tests
leohhhn Oct 7, 2024
e14f677
add sort avltree
leohhhn Oct 7, 2024
d3de1e1
add tests
leohhhn Oct 7, 2024
04061a8
add tests
leohhhn Oct 7, 2024
c3ea204
add godoc
leohhhn Oct 7, 2024
20b6d9a
Merge branch 'master' into hof
leohhhn Oct 8, 2024
f32070f
ownable
leohhhn Oct 8, 2024
1cecdd5
Merge remote-tracking branch 'moulfork/dev/moul/pagination' into hof
leohhhn Oct 8, 2024
822ae4b
register to hof, add pagination
leohhhn Oct 8, 2024
5b7afc8
renaming
leohhhn Oct 8, 2024
b40e128
add codeowner
leohhhn Oct 8, 2024
8a55c2a
add codeowner
leohhhn Oct 8, 2024
edc6915
rm hof
leohhhn Oct 8, 2024
f31c2e9
fix tests, fmt
leohhhn Oct 8, 2024
7602379
format import
leohhhn Oct 8, 2024
6e0f3c5
Merge branch 'master' into hof
leohhhn Oct 15, 2024
8bcf672
rm panics, just return
leohhhn Oct 15, 2024
3f35e68
fix tests
leohhhn Oct 15, 2024
2f88736
mod tidy
leohhhn Oct 15, 2024
0352dfc
Merge branch 'master' into hof
leohhhn Oct 16, 2024
1cc0a9e
update codeowners
leohhhn Oct 16, 2024
5f1d73a
Merge branch 'master' into hof
leohhhn Oct 22, 2024
cd2814e
using helplink
leohhhn Oct 22, 2024
40ba854
rm codeowners
leohhhn Oct 25, 2024
b2155e0
Merge branch 'master' into hof
leohhhn Oct 25, 2024
fe9092d
txlink
leohhhn Oct 25, 2024
72e5089
dashboard render
leohhhn Oct 25, 2024
3e5a640
tidy
leohhhn Oct 25, 2024
80b07e6
Merge branch 'master' into hof
leohhhn Nov 6, 2024
68c8ac6
Merge branch 'master' into hof
leohhhn Nov 7, 2024
882baf0
fix tests
leohhhn Nov 7, 2024
a43ccc1
update page size
leohhhn Nov 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/gno.land/p/demo/fqname/fqname.gno
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ func RenderLink(pkgPath, slug string) string {
if slug != "" {
return "[" + pkgPath + "](" + pkgLink + ")." + slug
}

return "[" + pkgPath + "](" + pkgLink + ")"
}

if slug != "" {
return pkgPath + "." + slug
}

return pkgPath
}
1 change: 1 addition & 0 deletions examples/gno.land/r/gnoland/blog/gno.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ require (
gno.land/p/demo/blog v0.0.0-latest
gno.land/p/demo/context v0.0.0-latest
gno.land/p/gov/proposal v0.0.0-latest
gno.land/r/gnoland/hof v0.0.0-latest
)
17 changes: 17 additions & 0 deletions examples/gno.land/r/gnoland/hof/errors.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package hof

import (
"errors"
"strconv"
)

var (
ErrNoSuchItem = errors.New("hof: no such item exists")
ErrNoSuchExhibition = errors.New("hof: no such exhibition exists")
ErrInvalidTitle = errors.New("hof: invalid title")
ErrDoubleUpvote = errors.New("hof: cannot upvote twice")
ErrDoubleDownvote = errors.New("hof: cannot downvote twice")
ErrMinWidgetSize = errors.New("hof: widget size cannot be less than 1")
ErrMaxWidgetSize = errors.New("hof: widget size cannot be more than " + strconv.Itoa(MaxWidgetSize))
ErrNonCodeCall = errors.New("hof: non-code call")
)
8 changes: 8 additions & 0 deletions examples/gno.land/r/gnoland/hof/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module gno.land/r/gnoland/hof
leohhhn marked this conversation as resolved.
Show resolved Hide resolved

require (
gno.land/p/demo/avl v0.0.0-latest
gno.land/p/demo/fqname v0.0.0-latest
gno.land/p/demo/seqid v0.0.0-latest
gno.land/p/demo/ufmt v0.0.0-latest
)
174 changes: 174 additions & 0 deletions examples/gno.land/r/gnoland/hof/hof.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Package hof is the gno.land hall of fame realm.
// It contains a permanent exhibition of items in the hall of fame,
// a possibility to host temporary ones created by its admins.
package hof

import (
"std"
"strings"
"time"

"gno.land/p/demo/avl"
"gno.land/p/demo/seqid"
"gno.land/p/demo/ufmt"
)
leohhhn marked this conversation as resolved.
Show resolved Hide resolved

var (
exhibCounter seqid.ID
exhibitions *avl.Tree // id > *Exhibition
moul marked this conversation as resolved.
Show resolved Hide resolved
)

type (
Exhibition struct {
id seqid.ID // fixed per exhibition
itemCounter seqid.ID
title string
description string
startTime *time.Time // given in RFC3339
endTime *time.Time // end time of the event, given in RFC3339
items *avl.Tree // Item id > Item
}

Item struct {
id seqid.ID
exhibID seqid.ID
pkgpath string
deployer std.Address
blockNum int64
upvote *avl.Tree // std.Addr > struct{}{}
downvote *avl.Tree // std.Addr > struct{}{}
}
)

func init() {
exhibitions = avl.NewTree()

exhibitions.Set(seqid.ID(0).String(),
&Exhibition{ // permanent exhibition, ID=0
id: seqid.ID(0),
items: avl.NewTree(),
title: "Permanent Exhibition",
})
}

// CreateTemporaryExhibition creates a temporary exhibition to be displayed while it's active
func CreateTemporaryExhibition(title, description string, start, end *time.Time) error {
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
// todo add admin checks

if strings.TrimSpace(title) == "" {
return ErrInvalidTitle
}

id := exhibCounter.Next()
e := &Exhibition{
id: id,
title: title,
description: description,
items: avl.NewTree(),
startTime: start,
endTime: end,
}

exhibitions.Set(id.String(), e)

return nil
}

// Register registers to the permanent exhibition
func Register() (string, error) {
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
return RegisterFor(seqid.ID(0))
}

// RegisterFor registers your realm for a specific exhibition
func RegisterFor(exhibID seqid.ID) (string, error) {
submission := std.PrevRealm()
pkgpath := submission.PkgPath()

raw, ok := exhibitions.Get(exhibID.String())
if !ok {
return "", ErrNoSuchExhibition
}

e := raw.(*Exhibition)

// Must not already exist and must be called from code
if e.items.Has(pkgpath) || submission.IsUser() {
return "", ErrNonCodeCall
}

id := e.itemCounter.Next()
e.items.Set(
id.String(),
&Item{
id: id,
exhibID: e.id,
pkgpath: pkgpath,
deployer: std.GetOrigCaller(),
blockNum: std.GetHeight(),
upvote: avl.NewTree(),
downvote: avl.NewTree(),
})

return ufmt.Sprintf("Registered %s at ID %s for exhibition %s", pkgpath, id.String(), e.title), nil
}

func Upvote(exhibID, itemID seqid.ID) error {
raw, ok := exhibitions.Get(exhibID.String())
if !ok {
return ErrNoSuchExhibition
}

e := raw.(*Exhibition)

rawItem, ok := e.items.Get(itemID.String())
if !ok {
return ErrNoSuchItem
}

item := rawItem.(*Item)
caller := std.PrevRealm().Addr().String()

if item.upvote.Has(caller) {
return ErrDoubleUpvote
}

item.upvote.Set(caller, struct{}{})
return nil
}

func Downvote(exhibID, itemID seqid.ID) error {
raw, ok := exhibitions.Get(exhibID.String())
if !ok {
return ErrNoSuchExhibition
}

e := raw.(*Exhibition)

rawItem, ok := e.items.Get(itemID.String())
if !ok {
return ErrNoSuchItem
}

item := rawItem.(*Item)
caller := std.PrevRealm().Addr().String()

if item.downvote.Has(caller) {
return ErrDoubleDownvote
}

item.downvote.Set(caller, struct{}{})
return nil
}

func Delete(exhibID, itemID seqid.ID) error {
raw, ok := exhibitions.Get(exhibID.String())
if !ok {
return ErrNoSuchExhibition
}

if _, removed := raw.(*Exhibition).items.Remove(itemID.String()); !removed {
return ErrNoSuchItem
}

return nil
}
121 changes: 121 additions & 0 deletions examples/gno.land/r/gnoland/hof/rendering.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package hof

import (
"gno.land/p/demo/fqname"
"gno.land/p/demo/seqid"
"gno.land/p/demo/ufmt"
)

const (
MaxWidgetSize = 5
likesBar = "#### [%d 👍](/r/gnoland/hof?help&__func=Upvote&exhibID=%s&itemID=%s) - [%d 👎](/r/gnoland/hof?help&__func=Downvote&exhibID=%s&itemID=%s)\n\n"
delBar = "[Delete](/r/gnoland/hof?help&__func=Delete&exhibID=%s&itemID=%s)\n\n"
)

func Render(path string) string {
out := "# Hall of Fame\n\n"

// Render permanent exhib
permanent, _ := exhibitions.Get(seqid.ID(0).String())
out += permanent.(*Exhibition).Render(path == "dashboard")

if exhibitions.Size() > 1 {
out += "---\n\n"
}

exhibitions.Iterate(seqid.ID(1).String(), "", func(key string, value interface{}) bool {
e := value.(*Exhibition)
out += e.Render(path == "dashboard")

out += "---\n\n"
return false
})

return out
}

func (e Exhibition) Render(dashboard bool) string {
out := ufmt.Sprintf("## %s\n\n", e.title)
out += ufmt.Sprintf("%s\n\n", e.description)
out += ufmt.Sprintf("Exhibition ID: %s\n\n", e.id.String())

if e.items.Size() == 0 {
out += "No items in this exhibition currently.\n\n"
return out
}

out += "<div class='columns-2'>\n\n"

e.items.ReverseIterate("", "", func(key string, value interface{}) bool {
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
out += "<div>\n\n"
id, _ := seqid.FromString(key)
out += ufmt.Sprintf("### Submission #%d\n\n", int(id))
out += value.(*Item).Render(dashboard)
out += "</div>"

return false
})

out += "</div><!-- /columns-2 -->\n\n"

return out
}

func (i Item) Render(dashboard bool) string {
out := ufmt.Sprintf("\n```\n%s\n```\n\n", i.pkgpath)
out += ufmt.Sprintf("by %s\n\n", i.deployer.String())
out += ufmt.Sprintf("Published at Block #%d\n\n", i.blockNum)
out += ufmt.Sprintf(
likesBar,
i.upvote.Size(),
i.exhibID.String(),
i.id.String(),
i.downvote.Size(),
i.exhibID.String(),
i.id.String(),
)

if dashboard {
out += ufmt.Sprintf(
delBar,
i.exhibID.String(),
i.id.String(),
)
}

return out
}

func RenderExhibWidget(exhibID seqid.ID, itemsToRender int) (string, error) {
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
if itemsToRender > MaxWidgetSize {
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
return "", ErrMaxWidgetSize
}

if itemsToRender < 1 {
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
return "", ErrMinWidgetSize
}

e, ok := exhibitions.Get(exhibID.String())
if !ok {
return "", ErrNoSuchExhibition
}

exhib := e.(*Exhibition)
if exhib.items.Size() == 0 {
return "No items in this exhibition.", nil
}

out := ""
i := 0

exhib.items.Iterate("", "", func(key string, value interface{}) bool {
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
item := value.(*Item)

out += ufmt.Sprintf("- %s\n", fqname.RenderLink(item.pkgpath, ""))

i++
return i >= itemsToRender
})

return out, nil
}
2 changes: 2 additions & 0 deletions examples/gno.land/r/gnoland/home/gno.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ module gno.land/r/gnoland/home

require (
gno.land/p/demo/ownable v0.0.0-latest
gno.land/p/demo/seqid v0.0.0-latest
gno.land/p/demo/ufmt v0.0.0-latest
gno.land/p/demo/ui v0.0.0-latest
gno.land/r/gnoland/blog v0.0.0-latest
gno.land/r/gnoland/events v0.0.0-latest
gno.land/r/gnoland/hof v0.0.0-latest
)
13 changes: 12 additions & 1 deletion examples/gno.land/r/gnoland/home/home.gno
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"std"

"gno.land/p/demo/ownable"
"gno.land/p/demo/seqid"
"gno.land/p/demo/ufmt"
"gno.land/p/demo/ui"
blog "gno.land/r/gnoland/blog"
events "gno.land/r/gnoland/events"
"gno.land/r/gnoland/hof"
)

// XXX: p/demo/ui API is crappy, we need to make it more idiomatic
Expand Down Expand Up @@ -37,7 +39,7 @@ func Render(_ string) string {
ui.Columns{3, []ui.Element{
lastBlogposts(4),
upcomingEvents(),
lastContributions(4),
latestHOFItems(5),
}},
)

Expand Down Expand Up @@ -90,6 +92,15 @@ func upcomingEvents() ui.Element {
}
}

func latestHOFItems(num int) ui.Element {
submissions, _ := hof.RenderExhibWidget(seqid.ID(0), num)

return ui.Element{
ui.H3("[Hall of Fame](/r/gnoland/hof)"),
ui.Text(submissions),
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
}
}

func introSection() ui.Element {
return ui.Element{
ui.H3("We’re building gno.land, set to become the leading open-source smart contract platform, using Gno, an interpreted and fully deterministic variation of the Go programming language for succinct and composable smart contracts."),
Expand Down
1 change: 1 addition & 0 deletions examples/gno.land/r/leon/home/gno.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ require (
gno.land/p/demo/ufmt v0.0.0-latest
gno.land/r/demo/art/gnoface v0.0.0-latest
gno.land/r/demo/art/millipede v0.0.0-latest
gno.land/r/gnoland/hof v0.0.0-latest
gno.land/r/leon/config v0.0.0-latest
)
Loading
Loading