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}