Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

render.gno

2.35 Kb · 120 lines
  1package craft
  2
  3import (
  4	"net/url"
  5	"strconv"
  6	"strings"
  7)
  8
  9func Render(iURL string) string {
 10	u, err := url.Parse(iURL)
 11	if err != nil {
 12		return renderRecipeError("Invalid URL")
 13	}
 14
 15	switch u.Path {
 16	case "":
 17		return renderRecipeHome()
 18	case "recipe":
 19		return renderRecipeResult(u.Query().Get("recipe"))
 20	case "recipes":
 21		return renderRecipeList(u.Query().Get("page"))
 22	default:
 23		return renderRecipeError("Not found")
 24	}
 25}
 26
 27func renderRecipeHome() string {
 28	return `# AKKADIA Recipe
 29
 30Ingredients are bound to occupied occupancy bits from slot 0 upward.
 31
 32Current craft fee is ` + strconv.FormatInt(GetCraftFee(), 10) + `ugnot.
 33
 34Enter a recipe to find its item ID.
 35
 36<gno-form path="recipe">
 37  <gno-input name="recipe" placeholder="0013|iron:1|iron:2|stick:3" />
 38</gno-form>
 39
 40* [Browse Recipes](./craft:recipes)
 41`
 42}
 43
 44func renderRecipeList(rawPage string) string {
 45	page := 1
 46	if rawPage != "" {
 47		parsed, err := strconv.Atoi(rawPage)
 48		if err != nil || parsed < 1 {
 49			return renderRecipeError("Invalid page")
 50		}
 51		page = parsed
 52	}
 53
 54	count := 20
 55	if count > listLimit {
 56		count = listLimit
 57	}
 58
 59	output := `# Recipes
 60
 61[← Back](./craft:)
 62
 63`
 64	total := GetRecipeCount()
 65	if total == 0 {
 66		return output + `*No recipes stored yet.*
 67`
 68	}
 69
 70	rows := ListRecipes(page, count)
 71	if len(rows) == 0 {
 72		return renderRecipeError("Invalid page")
 73	}
 74	for _, row := range rows {
 75		output += "* " + formatRecipeCode(row["recipe"]) + " → " + row["itemId"] + "\n"
 76	}
 77	return output
 78}
 79
 80func renderRecipeResult(recipe string) string {
 81	if recipe == "" {
 82		return renderRecipeError("Recipe is required")
 83	}
 84
 85	canonical, _, errMsg := parseRecipe(recipe)
 86	if errMsg != "" {
 87		return renderRecipeError("Invalid recipe")
 88	}
 89	if !recipes.Has(canonical) {
 90		return renderRecipeError("Recipe not found")
 91	}
 92
 93	return `# Recipe Result
 94
 95* **Recipe**: ` + formatRecipeCode(canonical) + `
 96* **Item ID**: ` + strconv.FormatUint(uint64(mustGetRecipeItemID(canonical)), 10) + `
 97
 98[← Back](./craft:)
 99`
100}
101
102func renderRecipeError(message string) string {
103	return `# Error
104
105> ` + message + `
106
107[← Back](./craft:)
108`
109}
110
111// Recipes use | and - as syntax. A code span keeps those characters
112// literal so gnoweb does not show backslash escapes.
113func formatRecipeCode(recipe string) string {
114	recipe = strings.ReplaceAll(recipe, "\n", " ")
115	fence := "`"
116	for strings.Contains(recipe, fence) {
117		fence += "`"
118	}
119	return fence + recipe + fence
120}