diff --git a/examples/gno.land/p/demo/boardsv2/draf2/boards.gno b/examples/gno.land/p/demo/boardsv2/draf2/boards.gno new file mode 100644 index 00000000000..ad8f0937ed6 --- /dev/null +++ b/examples/gno.land/p/demo/boardsv2/draf2/boards.gno @@ -0,0 +1,135 @@ +package boards + +const ( + LevelBoard = iota + LevelThread + LevelComment +) + +type App struct { + c Context +} + + +func New(st post.Storage) App { + a := App{ + st: st, + plugs: make(map[post.PluginName]plugin.Plugin), + } + + a.plugs[pluginbody.Name] = pluginbody.New(st) // load global state from st + + return a +} + +type Board struct { + post.Post + c Context +} + +func (b Board) Content() BoardContent { + return b.c.Plugin(pluginbasiccontent.Name).Content(b.Post) +} + +func (b Board) Render() string { + +} + +type Thread struct { + post.Post + c Context +} + +func (t Thread) TextContent() ThreadTextContent { + +} + +func (t Thread) PollContent() ThreadPollContent {} +func (t Thread) Type() ContentType {} + +// Comments returns a list of comments sent to the thread. +// The comment slice will be non-nil only when Thread is initiated +// through ThreadWithComments. +func (t Thread) Comments() []Comment {} + +type Comment struct { + post.Post + c Context +} + +func (c Comment) Content() CommentContent {} + +func (a App) Board(path string) ([]Board, error) { + a.c.Get(level, path func(){}) +} +func (a App) LockBoard(path string) (error) {} +func (a App) ForkBoard(path string) (error) {} + +func (a App) Boards(c post.Cursor) ([]Board, error) {} +func (a App) CreateBoard(c BoardContent) (Board, error) {} + +func (b App) Thread(path string) (Thread, error) { + return ThreadWithComments(path, nil) +} +func (a App) LockThread(path string) (error) {} +func (a App) ForkThread(path string) {} + +// ThreadWithComments returns a thread with its comments with the comment depth +// configured with commentDepth for direct and child comments. +// For ex. +// To get a thread with only 10 direct (parent level) comments use: +// - []int{10} +// To get a thread with 10 direct comments and 3 of their child comments use: +// - []int{10, 3} +// You can define configure this for more levels until you reach to value defined +// by MaxCommentDepth. +// By default the configuration is as follows: +// - []int{20, 3} +func (b App) ThreadWithComments(path string, commentDepth []int) (Thread, error) {} +func (b App) Threads(c post.Cursor) ([]Thread, error) {} +func (b App) CreateTextThread(c ThreadTextContent) (Thread, error) {} +func (b App) CreatePollThread(c ThreadPollContent) (Thread, error) {} + +// parentPath could be a path to thread (root), or path to any of the +// nested comments. +func (b App) Comments(parentPath string, c Cursor) ([]Comment, error) {} +func (b App) CreateComment(path string, c plugincomment.Content) (Comment, error) { + post, err := a.c.Plugin(plugincomment.Name).NewPost(c, LevelComment) + if err != nil { + return Comment{}, err + } + return Comment{Post: post, c: a.c} +} + +func (a App) Render(path string) string {} + +type Context struct { + opts []Option + st post.Storage + plugs map[post.PluginName]plugin.Plugin +} + +func (c Context) Plugin(n post.PluginName) post.Plugin { + +} + +func (c Context) Set(p *Post) (updated bool) { + key := newKey(p.Level, p.Slug()) + return b.posts.Set(key, p) +} + +func (c Context) Remove(level int, path string) (_ *Post, removed bool) { + key := newKey(level, path) + if v, removed := b.posts.Remove(key); removed { + return v.(*Post), true + } + return nil, false +} + +func (c Context) Get(level int, path string, iterator func()) (_ *Post, found bool) { + key := newKey(level, path) + if v, found := b.posts.Get(key); found { + return v.(*Post), true + } + return "", false +} diff --git a/examples/gno.land/p/demo/boardsv2/draf2/body_board.gno b/examples/gno.land/p/demo/boardsv2/draf2/body_board.gno new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/gno.land/p/demo/boardsv2/draf2/body_comment.gno b/examples/gno.land/p/demo/boardsv2/draf2/body_comment.gno new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/gno.land/p/demo/boardsv2/draf2/body_thread.gno b/examples/gno.land/p/demo/boardsv2/draf2/body_thread.gno new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/gno.land/p/demo/boardsv2/draf2/comments.gno b/examples/gno.land/p/demo/boardsv2/draf2/comments.gno new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/gno.land/p/demo/boardsv2/draf2/option.gno b/examples/gno.land/p/demo/boardsv2/draf2/option.gno new file mode 100644 index 00000000000..48ab0cc1bff --- /dev/null +++ b/examples/gno.land/p/demo/boardsv2/draf2/option.gno @@ -0,0 +1,19 @@ +package boards + +type Option struct{} + +// LinearReputationPolicy allows upvoting or downvoting a post by one +// for each account. +func LinearReputationPolicy() Option {} + +// TokenBasedReputationPolicy allows upvoting or downvoting a post propotional +// to the specified tokens that an account holds. +func TokenBasedReputationPolicy() Option {} + +// MaxPostDepth configures the max depth for nested comments. +// 0 -> boards +// 1 -> threads +// 2 -> comments-1 (direct comments to the threads) +// The above are already reserved. +// Setting it to zero will disable comments. +func MaxCommentDepth(d int) Option {} diff --git a/examples/gno.land/p/demo/boardsv2/draf2/post/cursor.gno b/examples/gno.land/p/demo/boardsv2/draf2/post/cursor.gno new file mode 100644 index 00000000000..44f8ebe85f6 --- /dev/null +++ b/examples/gno.land/p/demo/boardsv2/draf2/post/cursor.gno @@ -0,0 +1,8 @@ +package post + +type Cursor struct { + FromID string + Count int +} + +func NewCursor(fromID string, count int) Cursor {} diff --git a/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/comment/comment.gno b/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/comment/comment.gno new file mode 100644 index 00000000000..f657df880bc --- /dev/null +++ b/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/comment/comment.gno @@ -0,0 +1,33 @@ +package plugincomment + +const Name = "post-comment" + +func New(st Storage) Plugin { +} + +type Plugin struct { + st Storage +} + +type Content struct { + Title string + Description string + Tags []string +} + +func NewPost(id string, c Content, level int) (*Post, error) { + post := &Post{ + ID: id, + Level: level, + } + return post, p.SetContent(post, c) +} + +func (p Plugin) Content(post *Post) Content { + return post.Body[Name].(Content) +} + +func (p Plugin) SetContent(post *Post, c Content) error { + post.Body[Name] = c + return p.st.Set(post.ID, post) +} diff --git a/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/plugin.gno b/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/plugin.gno new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/text/text.gno b/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/text/text.gno new file mode 100644 index 00000000000..f0e98e95ced --- /dev/null +++ b/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/text/text.gno @@ -0,0 +1,3 @@ +package contenttext + +const Name = "post-text" diff --git a/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/title/title.gno b/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/title/title.gno new file mode 100644 index 00000000000..5a052076993 --- /dev/null +++ b/examples/gno.land/p/demo/boardsv2/draf2/post/plugin/title/title.gno @@ -0,0 +1,24 @@ +package contenttitle + +const Name = "post-title-only" + +func New(st Storage) Plugin { +} + +type Plugin struct { + st Storage +} + +type Content struct { + Title string + Description string + Tags []string +} + +func (p Plugin) Content(post *Post) Content { + return post.Body[Name].(Content) +} + +func (p Plugin) SetContent(post *Post, c Content) { + post.Body[Name] = c +} diff --git a/examples/gno.land/p/demo/boardsv2/draf2/post/post.gno b/examples/gno.land/p/demo/boardsv2/draf2/post/post.gno new file mode 100644 index 00000000000..a697c15ed27 --- /dev/null +++ b/examples/gno.land/p/demo/boardsv2/draf2/post/post.gno @@ -0,0 +1,31 @@ +package boardsv2 + +import ( + "strconv" + "time" +) + +type ( + Body interface { + Type() string // NOTE: The idea is to avoid casting + } + + // TODO: ID is the full path to the post + + Post struct { + ID string // NOTE: It would be nice to use a type alias for the ID field type + Body Body // NOTE: Maybe should be called Type (board as content is odd) + Parent *Post // NOTE: If all is a post we need to have a parent + 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)) +} diff --git a/examples/gno.land/p/demo/boardsv2/draf2/post/store/store.gno b/examples/gno.land/p/demo/boardsv2/draf2/post/store/store.gno new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/gno.land/p/demo/boardsv2/draf2/threads.gno b/examples/gno.land/p/demo/boardsv2/draf2/threads.gno new file mode 100644 index 00000000000..e69de29bb2d