-
Notifications
You must be signed in to change notification settings - Fork 389
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(example): r/mouss
#3472
Open
mous1985
wants to merge
28
commits into
gnolang:master
Choose a base branch
from
mous1985:home_page
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+430
−0
Open
feat(example): r/mouss
#3472
Changes from 11 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
b55e295
first commit
mous1985 4cc7820
fix: import
mous1985 51f75c6
simple home-page
mous1985 ac0c168
add follower
mous1985 2d47ee0
add recipe to my homepage
mous1985 05d0853
refactor v0 of home page
mous1985 918c773
refactor: replace bytes.Buffer with strings.builder
mous1985 844a61c
refactor: use p/moul/addrset
mous1985 b5e2868
ref: add p/moul/md
mous1985 f64569a
doc
mous1985 4959189
ref: func writeRecipe to method (r Recipe)Render
mous1985 91845a6
Merge remote-tracking branch 'upstream/master' into home_page
mous1985 cdbd8de
ref: replace strings.Builder by var out string
mous1985 48795c4
Update examples/gno.land/r/mouss/config/config.gno
mous1985 91baa9c
ref : SetBackup(newAddress std.Address)
mous1985 e7f2e73
test: add config_test.gno
mous1985 bb096ac
Update examples/gno.land/r/mouss/home/home.gno
mous1985 b62f386
Update examples/gno.land/r/mouss/home/home.gno
mous1985 933f759
Update examples/gno.land/r/mouss/home/home.gno
mous1985 27a0b5d
ref: add new line between func
mous1985 2caabf7
test: add home_test.gno
mous1985 68b6a02
ref: randomnew line in home.gno
mous1985 e584e45
ref: random new line in home_test.gno
mous1985 d9f02e1
feat: add unfollow function
mous1985 0586b1b
fix: ci
mous1985 aafaf5e
fix: ci
mous1985 7874d67
fix: ci
mous1985 7d1e347
fix: ci
mous1985 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"std" | ||
) | ||
|
||
var ( | ||
main std.Address // mouss's main address | ||
backup std.Address // backup address | ||
|
||
ErrorInvalidAddr = errors.New("config: invalid address") | ||
ErrorUnauthorized = errors.New("config: unauthorized") | ||
) | ||
|
||
func init() { | ||
main = "g1hrfvdh7jdvnlxpk2y20tp3scj9jqal3zzu7wjz" | ||
} | ||
func Address() std.Address { | ||
return main | ||
} | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
func Backup() std.Address { | ||
return backup | ||
} | ||
func SetBack(buAddress std.Address) error { | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if !buAddress.IsValid() { | ||
return ErrorInvalidAddr | ||
} | ||
|
||
if err := checkAuthorized(); err != nil { | ||
return err | ||
} | ||
|
||
backup = buAddress | ||
return nil | ||
} | ||
|
||
func checkAuthorized() error { | ||
caller := std.GetOrigCaller() | ||
if caller != main && caller != backup { | ||
return ErrorUnauthorized | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package config | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module gno.land/r/mouss/config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module gno.land/r/mouss/home |
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
package home | ||
|
||
import ( | ||
"std" | ||
"strconv" | ||
"strings" | ||
|
||
"gno.land/p/demo/mux" | ||
"gno.land/p/demo/ufmt" | ||
|
||
"gno.land/p/moul/addrset" | ||
"gno.land/p/moul/md" | ||
"gno.land/r/mouss/config" | ||
) | ||
|
||
// Profile represents my personal profile information. | ||
type Profile struct { | ||
AboutMe string | ||
Avatar string | ||
Email string | ||
Github string | ||
LinkedIn string | ||
Followers addrset.Set // Set of followers addresses. | ||
} | ||
|
||
// Recipe represents a cooking recipe with its details. | ||
type Recipe struct { | ||
Name string | ||
Origin string | ||
Author std.Address | ||
Ingredients string | ||
Instructions string | ||
Tips string | ||
} | ||
|
||
const ( | ||
RealmURL = "/r/mouss/home" | ||
Rec = RealmURL + ":recipe/" | ||
) | ||
|
||
var ( | ||
profile = Profile{ | ||
AboutMe: "👋 I'm Mustapha, a contributor to gno.land project from France. I'm passionate about coding, exploring new technologies, and contributing to open-source projects. Besides my tech journey, I'm also a pizzaiolo 🍕 who loves cooking and savoring good food.", | ||
Avatar: "https://github.com/mous1985/assets/blob/master/avatar.png?raw=true", | ||
Email: "[email protected]", | ||
Github: "https://github.com/mous1985", | ||
LinkedIn: "https://www.linkedin.com/in/mustapha-benazzouz-88646887/", | ||
Followers: addrset.Set{}, | ||
} | ||
router = mux.NewRouter() | ||
recipes []*Recipe | ||
margheritaPizza = &Recipe{ | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Name: "Authentic Margherita Pizza 🤌", | ||
Origin: "Naples, 🇮🇹", | ||
Author: config.Address(), | ||
Ingredients: " 1kg 00 flour\n 500ml water\n 3g fresh yeast\n 20g sea salt\n San Marzano tomatoes\n Fresh buffalo mozzarella\n Fresh basil\n Extra virgin olive oil", | ||
Instructions: " Mix flour and water until incorporated\n Add yeast and salt, knead for 20 minutes\n Let rise for 2 hours at room temperature\n Divide into 250g balls\n Cold ferment for 24-48 hours\n Shape by hand, being gentle with the dough\n Top with crushed tomatoes, torn mozzarella, and basil\n Cook at 450°C for 60-90 seconds", | ||
Tips: "Use a pizza steel or stone preheated for at least 1 hour. The dough should be soft and extensible. For best results, cook in a wood-fired oven.", | ||
} | ||
) | ||
|
||
// init initializes the router with the homepage and recipe routes. | ||
func init() { | ||
router.HandleFunc("", renderHomepage) | ||
router.HandleFunc("recipe/", renderRecipes) | ||
} | ||
|
||
// AddRecipe adds a new recipe in recipe page by users | ||
func AddRecipe(name, origin, ingredients, instructions, tips string) string { | ||
if err := validateRecipe(name, ingredients, instructions); err != nil { | ||
panic(err.Error()) | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
recipe := &Recipe{ | ||
Name: name, | ||
Origin: origin, | ||
Author: std.PrevRealm().Addr(), | ||
Ingredients: ingredients, | ||
Instructions: instructions, | ||
Tips: tips, | ||
} | ||
recipes = append(recipes, recipe) | ||
return "Recipe added successfully!" | ||
} | ||
|
||
// validateRecipe checks if the provided recipe details are valid. | ||
func validateRecipe(name, ingredients, instructions string) error { | ||
if name == "" { | ||
return ufmt.Errorf("recipe name cannot be empty") | ||
} | ||
if len(ingredients) == 0 { | ||
return ufmt.Errorf("ingredients cannot be empty") | ||
} | ||
if len(instructions) == 0 { | ||
return ufmt.Errorf("instructions cannot be empty") | ||
} | ||
return nil | ||
} | ||
|
||
// Follow allows a users to follow my home page. | ||
// It checks if the caller is a valid user and if the address is already being followed. | ||
// If the caller is not authorized, it returns an error. | ||
// If the address is already being followed, it returns an error. | ||
// Otherwise, it adds the address to the list of followers and returns nil. | ||
// TODO:any user can follow and to be followed by any other user | ||
// TODO: add a function to unfollow | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
func Follow(addr std.Address) error { | ||
caller := std.PrevRealm().Addr() | ||
if !isUser(caller) { | ||
return config.ErrorUnauthorized | ||
} | ||
if profile.Followers.Has(addr) { | ||
return ufmt.Errorf("address %s is already following", addr) | ||
} | ||
profile.Followers.Add(addr) //can't add the same address twice | ||
return nil | ||
} | ||
|
||
func isUser(addr std.Address) bool { | ||
return !isAuthorized(addr) | ||
} | ||
func isAuthorized(addr std.Address) bool { | ||
return addr == config.Address() || addr == config.Backup() | ||
} | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
func renderRecipes(res *mux.ResponseWriter, req *mux.Request) { | ||
var b strings.Builder | ||
b.WriteString("## World Kitchen\n\n------\n\n") | ||
|
||
b.WriteString(margheritaPizza.Render()) | ||
|
||
if len(recipes) == 0 { | ||
b.WriteString("No recipes yet. Be the first to add one!\n") | ||
res.Write(b.String()) | ||
return | ||
} | ||
|
||
for _, recipe := range recipes { | ||
b.WriteString(recipe.Render()) | ||
} | ||
|
||
res.Write(b.String()) | ||
} | ||
|
||
func (r Recipe) Render() string { | ||
var b strings.Builder | ||
b.WriteString(md.H2(r.Name)) | ||
b.WriteString(md.Bold("Author:") + "\n" + r.Author.String() + "\n\n") | ||
b.WriteString(md.Bold("Origin:") + "\n" + r.Origin + "\n\n") | ||
b.WriteString(md.Bold("Ingredients:") + "\n" + md.BulletList(strings.Split(r.Ingredients, "\n")) + "\n\n") | ||
b.WriteString(md.Bold("Instructions:") + "\n" + md.OrderedList(strings.Split(r.Instructions, "\n")) + "\n\n") | ||
|
||
if r.Tips != "" { | ||
b.WriteString(md.Italic("💡 Tips:"+"\n"+r.Tips) + "\n\n") | ||
} | ||
|
||
b.WriteString(md.HorizontalRule() + "\n") | ||
return b.String() | ||
} | ||
|
||
func renderHomepage(res *mux.ResponseWriter, req *mux.Request) { | ||
var b strings.Builder | ||
writeNavigation(&b) | ||
b.WriteString(profile.Render()) | ||
res.Write(b.String()) | ||
} | ||
|
||
func (p Profile) Render() string { | ||
var b strings.Builder | ||
|
||
b.WriteString(md.H1("Welcome to my Homepage") + "\n\n" + md.HorizontalRule() + "\n\n") | ||
writeGnoArt(&b) | ||
b.WriteString(md.HorizontalRule() + "\n\n" + md.H2("About Me") + "\n\n") | ||
b.WriteString(md.Image("avatar", p.Avatar) + "\n\n") | ||
b.WriteString(p.AboutMe + "\n\n" + md.HorizontalRule() + "\n\n") | ||
b.WriteString(md.H3("Contact") + "\n\n") | ||
b.WriteString(md.BulletList([]string{ | ||
"Email: " + p.Email, | ||
"GitHub: " + md.Link("@mous1985", p.Github), | ||
"LinkedIn: " + md.Link("Mustapha", p.LinkedIn), | ||
})) | ||
b.WriteString("\n\n" + md.Bold("👤 Followers: ") + strconv.Itoa(p.Followers.Size())) | ||
|
||
return b.String() | ||
} | ||
func writeNavigation(b *strings.Builder) { | ||
navItems := []string{ | ||
md.Link("Home", ""), | ||
md.Link("World Kitchen", Rec), | ||
md.Link("Hackerspace", "https://github.com/gnolang/hackerspace/issues/86#issuecomment-2535795751"), | ||
} | ||
b.WriteString(strings.Join(navItems, " | ") + "\n\n" + md.HorizontalRule() + "\n\n") | ||
} | ||
func Render(path string) string { | ||
return router.Render(path) | ||
} | ||
func writeGnoArt(b *strings.Builder) { | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
b.WriteString("```\n") | ||
for _, line := range []string{ | ||
" -==++. ", | ||
" *@@@@= @- -@", | ||
" #@@@@@: -==-.-- :-::===: .-++-. @- .===:.- .-.-==- .===:=@", | ||
" #@@@@@@@: -@@%**%@@ #@@#*#@@- *@@**@@* @- +%=::-*@ +@=-:-@* +%=::-*@", | ||
" +@%#**#%@@ %@+ :@@ *@+ #@=+@% %@+ @= :@: -@ +% +%.@: -@", | ||
" -: - *@%:..+@@ *@+ #@=-@@: :@@= @- .@= =@ +@ *%.@= =@", | ||
" --:==+=-:=. =%@%#*@@ *@+ #@+ =%@%%@%= #* %#=.:%*===*@ +% +% -%*===*@", | ||
" -++++=++++. =-:::*@# . . .::. .. :: .:: . . .:: .", | ||
" .-=+++=: .*###%#= ", | ||
" :: ", | ||
} { | ||
b.WriteString(line + "\n") | ||
} | ||
b.WriteString("```\n------") | ||
mous1985 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, sorry to go at this again; can you please check out the new code in
r/leon/config
, and use it that way? After this we can merge.