Skip to content

Commit

Permalink
wip: improvements
Browse files Browse the repository at this point in the history
These changes were done before the change of direction for the boards
implementation. Commiting them to avoid loosing the ideas and
improvements present here.
  • Loading branch information
jeronimoalbi committed Oct 29, 2024
1 parent cecf7a8 commit 0f48ffb
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 52 deletions.
20 changes: 15 additions & 5 deletions examples/gno.land/p/demo/boardsv2/draft3/app.gno
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package boards
import (
"gno.land/p/demo/boards/post"
"gno.land/p/demo/boards/post/plugin"
pluginfork "gno.land/p/demo/boards/post/plugin/fork"
pluginpoll "gno.land/p/demo/boards/post/plugin/poll"
pluginreputation "gno.land/p/demo/boards/post/plugin/reputation"
plugintitle "gno.land/p/demo/boards/post/plugin/title"
)
Expand Down Expand Up @@ -38,14 +40,13 @@ func New(st post.Store, options ...Option) App {
pluginreputation.UsePolicy(app.reputationPolicy),
pluginreputation.AllowedPostLevels(post.LevelPost, post.LevelComment),
),
pluginfork.New(
pluginfork.AllowedPostLevels(post.LevelPost),
),
)
return app
}

func (a App) GetPost(path string) (_ *post.Post, found bool) {
return a.post.Get(path) // NOTE: Allowing this enables us to have generic functions like Lock
}

func (a App) GetBoard(path string) (_ Board, found bool) {
p, found := a.posts.Get(path)
if !found || p.Level != LevelBoard {
Expand Down Expand Up @@ -73,7 +74,16 @@ func (a App) GetComment(path string) (_ Comment, found bool) {
func (a App) CreateBoard(slug, title, description string, tags []string) (Board, error) {}

// Fork forks either a board or a thread by their path.
func (a App) Fork(path, newPath string) error {}
func (a App) ForkBoard(b Board, newPath string) error {
// NOTE: Instead of `app.ForkBoard()` we could use `b.Fork(newPath)` instead but that requires Board to have plugin access
// NOTE: This case gets the plugin from the plugin list to fork
p, _ := a.plugins.Get(pluginfork.Name)
return p.Fork(b.Post, newPath)
}

func (a App) ForkThread(t Thread, newPath string) error {
// TODO: Implement thread fork app support
}

// Lock locks either a board or a thread by their path.
// Once a board is locked new threads to the board and comments to the existing
Expand Down
25 changes: 16 additions & 9 deletions examples/gno.land/p/demo/boardsv2/draft3/board.gno
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
package boards

import (
"gno.land/p/demo/boards/post"
pluginfork "gno.land/p/demo/boards/post/plugin/fork"
pluginreputation "gno.land/p/demo/boards/post/plugin/reputation"
plugintitle "gno.land/p/demo/boards/post/plugin/title"
)

type Board struct {
*post.Post
}
type (
BoardContent plugintitle.Content

Board struct {
*post.Post
}
)

func (b Board) Title() string {
return b.getContent().Title
func NewBoard(pst *post.Post) Board {
// TODO: Local plugins must be initialized here (same for other plugins)
return Board{pst}
}

func (b Board) Description() string {
return b.getContent().Description
func (b Board) Info() BoardContent {
return BoardContent(b.getContent())
}

func (b Board) Tags() string {
return b.getContent().Tags
func (b Board) Update(c BoardContent) {
b.PluginStore[plugintitle.Name] = plugintitle.Content(c)
}

func (b Board) Upvote() error {
Expand Down
47 changes: 47 additions & 0 deletions examples/gno.land/p/demo/boardsv2/draft3/post/plugin/fork/fork.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package pluginfork

import (
"gno.land/p/demo/boards/post"
)

const Name = "fork"

// TODO: Implement fork plugin to support thread forking
type Plugin struct {
AllowedPostLevels []int
}

func New(o ...Option) Plugin {
var p Plugin
for _, apply := range o {
apply(&p)
}
return p
}

func (p Plugin) Name() string {
return Name
}

func (p Plugin) Render() string {
// TODO: Implement render support for text
return ""
}

func (p Plugin) HasForkSupport(pst *post.Post) bool {
if len(p.AllowedPostLevels) == 0 {
return true
}

for _, lvl := range p.AllowedPostLevels {
if pst.Level == lvl {
return true
}
}
return false
}

func (p Plugin) Fork(pst *post.Post, newPath string) error {
// TODO: Implement fork support
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package pluginfork

type Option func(*Plugin)

func AllowedPostLevels(levels []int) Option {
return func(p *Plugin) {
p.AllowedPostLevels = levels
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package pluginreputation

import "errors"
import (
"errors"
"std"
)

// NOTE: Think about implementing a reputation based policy
const (
PolicyLinear Policy = iota
PolicyTokenBased
Expand All @@ -14,15 +18,15 @@ var ErrNotSupported = errors.New("reputation not supported")
type (
Policy int

// TODO: Implement reputation plugin
Plugin struct {
Store Store
Policy Policy
AllowedPostLevels []int
}

Reputation struct {
Upvotes uint
Downbotes uint
Downvotes uint
}
)

Expand Down Expand Up @@ -55,28 +59,41 @@ func (p Plugin) HasReputationSupport(pst *post.Post) bool {
return false
}

func (p *Plugin) Votes(pst *post.Post) uint32 {
func (p Plugin) Votes(pst *post.Post) (upvotes uint64, downvotes uint64) {
if !p.HasReputationSupport(pst) {
return ErrNotSupported
}

// TODO: Implement
r := pst.PluginStore[Name].(*Reputation)
return r.Upvotes, r.Downvotes
}

func (p Plugin) Voters(pst *post.Post) []std.Address {
if !p.HasReputationSupport(pst) {
return ErrNotSupported
}

// TODO: Implement support for tracking voters
}

func (p *Plugin) Upvote(pst *post.Post) error {
if !p.HasReputationSupport(pst) {
return ErrNotSupported
}

// TODO: Modify global state
// TODO: Modify local state
// TODO: Handle accounts and change downvotes for existing accounts that downvoted
r := pst.PluginStore[Name].(*Reputation)
r.Upvotes++
p.store.inc(pst.ID)
}

func (p *Plugin) Downvote(pst *post.Post) error {
if !p.HasReputationSupport(pst) {
return ErrNotSupported
}

// TODO: Implement
// TODO: Handle accounts and change upvotes for existing accounts that upvoted
r := pst.PluginStore[Name].(*Reputation)
r.Downvotes++
p.store.dec(pst.ID)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package pluginreputation

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

type (
VotesIterFn = func(votes uint64, path string) bool

Store struct {
votes avl.Tree // string(count) -> string(path)
}
)

func (s Store) Iterate(fn VotesIterFn) bool {
// TODO: Support pagination of votes?
return s.votes.Iterate("", "", func(key string, v interface{}) bool {
count, _ := seqid.FromBinary(key)
return fn(uint64(count), v.(string))
})
}

func (s *Store) inc(path string) uint64 {
var (
current seqid.ID
v, found = s.votes.Get(path)
)
if found {
current = v.(seqid.ID)
// TODO: Implement the right solution because this is not right, just showcase
s.votes.Remove(current.Binary())
}

current.Next()
s.votes.Set(current.Binary(), path)
return uint64(current)
}

func (s *Store) dec(path string) uint64 {
var (
current seqid.ID
v, found = s.votes.Get(path)
)
if found {
current = v.(seqid.ID)
}

if current == 0 {
return current
}

s.votes.Remove(current.Binary())
current--
if current != 0 {
s.votes.Set(current.Binary(), current)
}
return uint64(current)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// plugintext is a content type for representing a tweet, blog post or a thread like Reddit.
package plugintext

import (
"gno.land/p/demo/boards/post" // NOTE: Plugins should be at the same level of post package
)

const Name = "post-text"

type (
Plugin struct{}
Text struct {
Plugin struct{}
Content struct {
Title string
Body string
Tags []string
Expand All @@ -26,9 +30,9 @@ func (p Plugin) Render() string {
}

func (p Plugin) Content(pst *post.Post) Content {
return pst.Body[Name].(*Text)
return pst.Body[Name].(*Content)
}

func (p Plugin) SetContent(pst *post.Post, t Text) {
func (p Plugin) SetContent(pst *post.Post, c Content) {
pst.Body[Name] = c
}
26 changes: 12 additions & 14 deletions examples/gno.land/p/demo/boardsv2/draft3/post/post.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@ import (
"gno.land/p/demo/boards/post/plugin"
)

type (
Post struct {
ID string
PluginStore plugin.Plugin
Parent *Post
Level int
Base *Post
Children []*Post
Forks []*Post
UpdatedAt time.Time
CreatedAt time.Time
Creator std.Address
}
)
type Post struct {
ID string
PluginStore plugin.Plugin
Parent *Post
Level int
Base *Post
Children []*Post
Forks []*Post
UpdatedAt time.Time
CreatedAt time.Time
Creator std.Address
}

func (p Post) NextIncrementalKey(baseKey string) string {
return baseKey + "/" + strconv.Itoa(len(p.Children))
Expand Down
Loading

0 comments on commit 0f48ffb

Please sign in to comment.