Skip to content

Commit

Permalink
feat: add Matija's Homepage realm to examples (gnolang#2916)
Browse files Browse the repository at this point in the history
### Summary
This pull request adds a new realm example to the Gno `examples`
repository—Matija's Homepage. It showcases a personal homepage built on
the Gno chain where users can interact by voting with GNOT tokens to
change the page's color. The more tokens users send, the greater
influence they have on the color scheme, providing an interactive and
dynamic experience.

### Key Features
- **Profile Section**: Displays a personal profile with an image and
description.
- **Color Voting**: Users can vote for the page's color (red, green,
blue) by sending GNOT tokens. RGB values are adjusted based on the
amount sent.
- **Dynamic Updates**: The homepage dynamically updates the color based
on votes, showcasing real-time interaction on the Gno blockchain.
- **Links to GitHub and LinkedIn**: Includes buttons for GitHub and
LinkedIn, making it easy for users to connect.

### Tools & Technologies
- Utilizes Gno's native functions to handle voting and token transfers.
- Provides a simple, yet effective example of how personal realms can be
interactive and engaging on the Gno platform.

### Why this is valuable
This example highlights the possibilities of personal realms on Gno,
showing how users can create unique and interactive profiles. It’s a fun
and approachable entry point for anyone new to Gno development, while
also demonstrating the platform's flexibility and potential for creative
expression.

---------

Co-authored-by: Morgan <[email protected]>
Co-authored-by: Leon Hudak <[email protected]>
  • Loading branch information
3 people authored Dec 10, 2024
1 parent 8e7fb50 commit 4e7305b
Show file tree
Hide file tree
Showing 4 changed files with 437 additions and 0 deletions.
64 changes: 64 additions & 0 deletions examples/gno.land/r/matijamarjanovic/home/config.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package home

import (
"errors"
"std"
)

var (
mainAddr = std.Address("g1ej0qca5ptsw9kfr64ey8jvfy9eacga6mpj2z0y") // matija's main address
backupAddr std.Address // backup address

errorInvalidAddr = errors.New("config: invalid address")
errorUnauthorized = errors.New("config: unauthorized")
)

func Address() std.Address {
return mainAddr
}

func Backup() std.Address {
return backupAddr
}

func SetAddress(newAddress std.Address) error {
if !newAddress.IsValid() {
return errorInvalidAddr
}

if err := checkAuthorized(); err != nil {
return err
}

mainAddr = newAddress
return nil
}

func SetBackup(newAddress std.Address) error {
if !newAddress.IsValid() {
return errorInvalidAddr
}

if err := checkAuthorized(); err != nil {
return err
}

backupAddr = newAddress
return nil
}

func checkAuthorized() error {
caller := std.GetOrigCaller()
if caller != mainAddr && caller != backupAddr {
return errorUnauthorized
}

return nil
}

func AssertAuthorized() {
caller := std.GetOrigCaller()
if caller != mainAddr && caller != backupAddr {
panic(errorUnauthorized)
}
}
1 change: 1 addition & 0 deletions examples/gno.land/r/matijamarjanovic/home/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/r/matijamarjanovic/home
238 changes: 238 additions & 0 deletions examples/gno.land/r/matijamarjanovic/home/home.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
package home

import (
"std"
"strings"

"gno.land/p/demo/ufmt"
"gno.land/p/moul/md"
"gno.land/r/leon/hof"
)

var (
pfp string // link to profile picture
pfpCaption string // profile picture caption
abtMe string

modernVotes int64
classicVotes int64
minimalVotes int64
currentTheme string

modernLink string
classicLink string
minimalLink string
)

func init() {
pfp = "https://static.artzone.ai/media/38734/conversions/IPF9dR7ro7n05CmMLLrXIojycr1qdLFxgutaaanG-w768.webp"
pfpCaption = "My profile picture - Tarantula Nebula"
abtMe = `Motivated Computer Science student with strong
analytical and problem-solving skills. Proficient in
programming and version control, with a high level of
focus and attention to detail. Eager to apply academic
knowledge to real-world projects and contribute to
innovative technology solutions.
In addition to my academic pursuits,
I enjoy traveling and staying active through weightlifting.
I have a keen interest in electronic music and often explore various genres.
I believe in maintaining a balanced lifestyle that complements my professional development.`

modernVotes = 0
classicVotes = 0
minimalVotes = 0
currentTheme = "classic"
modernLink = "https://www.google.com"
classicLink = "https://www.google.com"
minimalLink = "https://www.google.com"
hof.Register()
}

func UpdatePFP(url, caption string) {
AssertAuthorized()
pfp = url
pfpCaption = caption
}

func UpdateAboutMe(col1 string) {
AssertAuthorized()
abtMe = col1
}

func maxOfThree(a, b, c int64) int64 {
max := a
if b > max {
max = b
}
if c > max {
max = c
}
return max
}

func VoteModern() {
ugnotAmount := std.GetOrigSend().AmountOf("ugnot")
votes := ugnotAmount
modernVotes += votes
updateCurrentTheme()
}

func VoteClassic() {
ugnotAmount := std.GetOrigSend().AmountOf("ugnot")
votes := ugnotAmount
classicVotes += votes
updateCurrentTheme()
}

func VoteMinimal() {
ugnotAmount := std.GetOrigSend().AmountOf("ugnot")
votes := ugnotAmount
minimalVotes += votes
updateCurrentTheme()
}

func updateCurrentTheme() {
maxVotes := maxOfThree(modernVotes, classicVotes, minimalVotes)

if maxVotes == modernVotes {
currentTheme = "modern"
} else if maxVotes == classicVotes {
currentTheme = "classic"
} else {
currentTheme = "minimal"
}
}

func CollectBalance() {
AssertAuthorized()

banker := std.GetBanker(std.BankerTypeRealmSend)
ownerAddr := Address()

banker.SendCoins(std.CurrentRealm().Addr(), ownerAddr, banker.GetCoins(std.CurrentRealm().Addr()))
}

func Render(path string) string {
var sb strings.Builder

// Theme-specific header styling
switch currentTheme {
case "modern":
// Modern theme - Clean and minimalist with emojis
sb.WriteString(md.H1("🚀 Matija's Space"))
sb.WriteString(md.Image(pfpCaption, pfp))
sb.WriteString("\n")
sb.WriteString(md.Italic(pfpCaption))
sb.WriteString("\n")
sb.WriteString(md.HorizontalRule())
sb.WriteString(abtMe)
sb.WriteString("\n")

case "minimal":
// Minimal theme - No emojis, minimal formatting
sb.WriteString(md.H1("Matija Marjanovic"))
sb.WriteString("\n")
sb.WriteString(abtMe)
sb.WriteString("\n")
sb.WriteString(md.Image(pfpCaption, pfp))
sb.WriteString("\n")
sb.WriteString(pfpCaption)
sb.WriteString("\n")

default: // classic
// Classic theme - Traditional blog style with decorative elements
sb.WriteString(md.H1("✨ Welcome to Matija's Homepage ✨"))
sb.WriteString("\n")
sb.WriteString(md.Image(pfpCaption, pfp))
sb.WriteString("\n")
sb.WriteString(pfpCaption)
sb.WriteString("\n")
sb.WriteString(md.HorizontalRule())
sb.WriteString(md.H2("About me"))
sb.WriteString("\n")
sb.WriteString(abtMe)
sb.WriteString("\n")
}

// Theme-specific voting section
switch currentTheme {
case "modern":
sb.WriteString(md.HorizontalRule())
sb.WriteString(md.H2("🎨 Theme Selector"))
sb.WriteString("Choose your preferred viewing experience:\n")
items := []string{
md.Link(ufmt.Sprintf("Modern Design (%d votes)", modernVotes), modernLink),
md.Link(ufmt.Sprintf("Classic Style (%d votes)", classicVotes), classicLink),
md.Link(ufmt.Sprintf("Minimal Look (%d votes)", minimalVotes), minimalLink),
}
sb.WriteString(md.BulletList(items))

case "minimal":
sb.WriteString("\n")
sb.WriteString(md.H3("Theme Selection"))
sb.WriteString(ufmt.Sprintf("Current theme: %s\n", currentTheme))
sb.WriteString(ufmt.Sprintf("Votes - Modern: %d | Classic: %d | Minimal: %d\n",
modernVotes, classicVotes, minimalVotes))
sb.WriteString(md.Link("Modern", modernLink))
sb.WriteString(" | ")
sb.WriteString(md.Link("Classic", classicLink))
sb.WriteString(" | ")
sb.WriteString(md.Link("Minimal", minimalLink))
sb.WriteString("\n")

default: // classic
sb.WriteString(md.HorizontalRule())
sb.WriteString(md.H2("✨ Theme Customization ✨"))
sb.WriteString(md.Bold("Choose Your Preferred Theme:"))
sb.WriteString("\n\n")
items := []string{
ufmt.Sprintf("Modern 🚀 (%d votes) - %s", modernVotes, md.Link("Vote", modernLink)),
ufmt.Sprintf("Classic ✨ (%d votes) - %s", classicVotes, md.Link("Vote", classicLink)),
ufmt.Sprintf("Minimal ⚡ (%d votes) - %s", minimalVotes, md.Link("Vote", minimalLink)),
}
sb.WriteString(md.BulletList(items))
}

// Theme-specific footer/links section
switch currentTheme {
case "modern":
sb.WriteString(md.HorizontalRule())
sb.WriteString(md.Link("GitHub", "https://github.com/matijamarjanovic"))
sb.WriteString(" | ")
sb.WriteString(md.Link("LinkedIn", "https://www.linkedin.com/in/matijamarjanovic"))
sb.WriteString("\n")

case "minimal":
sb.WriteString("\n")
sb.WriteString(md.Link("GitHub", "https://github.com/matijamarjanovic"))
sb.WriteString(" | ")
sb.WriteString(md.Link("LinkedIn", "https://www.linkedin.com/in/matijamarjanovic"))
sb.WriteString("\n")

default: // classic
sb.WriteString(md.HorizontalRule())
sb.WriteString(md.H3("✨ Connect With Me"))
items := []string{
md.Link("🌟 GitHub", "https://github.com/matijamarjanovic"),
md.Link("💼 LinkedIn", "https://www.linkedin.com/in/matijamarjanovic"),
}
sb.WriteString(md.BulletList(items))
}

return sb.String()
}

func UpdateModernLink(link string) {
AssertAuthorized()
modernLink = link
}

func UpdateClassicLink(link string) {
AssertAuthorized()
classicLink = link
}

func UpdateMinimalLink(link string) {
AssertAuthorized()
minimalLink = link
}
Loading

0 comments on commit 4e7305b

Please sign in to comment.