Skip to content

Commit 2fed38d

Browse files
authored
feat(gnoweb): improve help page (#3362)
Adds JavaScript features listed #3355 regarding Help section in gnoweb. - Adds localStorage feature for address - Fixes txlink - Minor UI styles
1 parent 7f106b9 commit 2fed38d

File tree

7 files changed

+68
-11
lines changed

7 files changed

+68
-11
lines changed

gno.land/pkg/gnoweb/components/help.gohtml

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
{{ range .Params }}
7070
<div class="flex flex-col gap-3 items-stretch text-gray-400 mb-2">
7171
<div class="group relative overflow-hidden flex w-full border rounded-sm has-[:focus]:border-gray-300 hover:border-gray-300">
72-
<label for="func-{{ $funcName }}-param-{{ .Name }}" class="flex gap-3 items-center bg-gray-50 px-4 font-semibold text-gray-600">{{ .Name }}</label>
72+
<label for="func-{{ $funcName }}-param-{{ .Name }}" class="flex gap-3 items-center bg-gray-50 px-4 font-semibold text-gray-600 text-100">{{ .Name }}</label>
7373
<input type="text"
7474
{{- if eq $data.SelectedFunc $funcName }}
7575
value="{{ getSelectedArgValue $data . }}"

gno.land/pkg/gnoweb/components/index.gohtml

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
{{ end }}
6565

6666
{{ define "header" }}
67-
<header class="main-header sticky top-0 bg-light border-b border-gray-400 text-100 z-max">
67+
<header class="main-header sticky top-0 bg-light border-b text-100 z-max">
6868
<nav aria-label="Realm navigation" class="max-w-screen-max mx-auto px-4 md:px-10 grid grid-cols-10 grid-flow-dense gap-4 md:gap-x-8 lg:gap-x-20 xxl:gap-x-32 items-center">
6969
<div class="main-navigation flex items-center gap-1 col-span-7 max-w-screen-max h-full py-2">
7070
<a href="/" class="rounded border border-gray-100 cursor-pointer h-10 w-10 shrink-0">
@@ -118,7 +118,7 @@
118118
{{ end }}
119119

120120
{{ define "footer" }}
121-
<footer class="w-full text-100 py-1.5 border-t border-gray-300">
121+
<footer class="w-full text-100 py-1.5 border-t">
122122
<nav class="max-w-screen-max mx-auto px-4 md:px-10 mb-8 md:mb-0 grid grid-cols-1 md:grid-cols-4 justify-between items-start xl:items-center gap-2 xl:gap-20 pt-2 xl:pt-0">
123123
<!-- Footer Navigation -->
124124
<div class="col-span-1 pb-8 md:pb-0">

gno.land/pkg/gnoweb/frontend/js/realmhelp.ts

+50-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { debounce } from "./utils";
2+
13
class Help {
24
private DOM: {
35
el: HTMLElement | null;
@@ -40,18 +42,33 @@ class Help {
4042
this.DOM.addressInput = el.querySelector<HTMLInputElement>(Help.SELECTORS.addressInput);
4143
this.DOM.cmdModeSelect = el.querySelector<HTMLSelectElement>(Help.SELECTORS.cmdModeSelect);
4244

43-
console.log(this.DOM);
4445
this.funcList = this.DOM.funcs.map((funcEl) => new HelpFunc(funcEl));
4546

47+
this.restoreAddress();
4648
this.bindEvents();
4749
}
4850

51+
private restoreAddress(): void {
52+
const { addressInput } = this.DOM;
53+
if (addressInput) {
54+
const storedAddress = localStorage.getItem("helpAddressInput");
55+
if (storedAddress) {
56+
addressInput.value = storedAddress;
57+
this.funcList.forEach((func) => func.updateAddr(storedAddress));
58+
}
59+
}
60+
}
61+
4962
private bindEvents(): void {
5063
const { addressInput, cmdModeSelect } = this.DOM;
5164

52-
addressInput?.addEventListener("input", () => {
53-
this.funcList.forEach((func) => func.updateAddr(addressInput.value));
65+
const debouncedUpdate = debounce((addressInput: HTMLInputElement) => {
66+
const address = addressInput.value;
67+
68+
localStorage.setItem("helpAddressInput", address);
69+
this.funcList.forEach((func) => func.updateAddr(address));
5470
});
71+
addressInput?.addEventListener("input", () => debouncedUpdate(addressInput));
5572

5673
cmdModeSelect?.addEventListener("change", (e) => {
5774
const target = e.target as HTMLSelectElement;
@@ -66,6 +83,7 @@ class HelpFunc {
6683
addrs: HTMLElement[];
6784
args: HTMLElement[];
6885
modes: HTMLElement[];
86+
paramInputs: HTMLInputElement[];
6987
};
7088

7189
private funcName: string | null;
@@ -83,27 +101,52 @@ class HelpFunc {
83101
addrs: Array.from(el.querySelectorAll<HTMLElement>(HelpFunc.SELECTORS.address)),
84102
args: Array.from(el.querySelectorAll<HTMLElement>(HelpFunc.SELECTORS.args)),
85103
modes: Array.from(el.querySelectorAll<HTMLElement>(HelpFunc.SELECTORS.mode)),
104+
paramInputs: Array.from(el.querySelectorAll<HTMLInputElement>(HelpFunc.SELECTORS.paramInput)),
86105
};
87106

88107
this.funcName = el.dataset.func || null;
89108

109+
this.initializeArgs();
90110
this.bindEvents();
91111
}
92112

113+
private static sanitizeArgsInput(input: HTMLInputElement) {
114+
const paramName = input.dataset.param || "";
115+
const paramValue = input.value.trim();
116+
117+
if (!paramName) {
118+
console.warn("sanitizeArgsInput: param is missing in arg input dataset.");
119+
}
120+
121+
return { paramName, paramValue };
122+
}
123+
93124
private bindEvents(): void {
125+
const debouncedUpdate = debounce((paramName: string, paramValue: string) => {
126+
if (paramName) this.updateArg(paramName, paramValue);
127+
});
128+
94129
this.DOM.el.addEventListener("input", (e) => {
95130
const target = e.target as HTMLInputElement;
96131
if (target.dataset.role === "help-param-input") {
97-
this.updateArg(target.dataset.param || "", target.value);
132+
const { paramName, paramValue } = HelpFunc.sanitizeArgsInput(target);
133+
debouncedUpdate(paramName, paramValue);
98134
}
99135
});
100136
}
101137

138+
private initializeArgs(): void {
139+
this.DOM.paramInputs.forEach((input) => {
140+
const { paramName, paramValue } = HelpFunc.sanitizeArgsInput(input);
141+
if (paramName) this.updateArg(paramName, paramValue);
142+
});
143+
}
144+
102145
public updateArg(paramName: string, paramValue: string): void {
103146
this.DOM.args
104147
.filter((arg) => arg.dataset.arg === paramName)
105148
.forEach((arg) => {
106-
arg.textContent = paramValue.trim() || "";
149+
arg.textContent = paramValue || "";
107150
});
108151
}
109152

@@ -116,7 +159,8 @@ class HelpFunc {
116159
public updateMode(mode: string): void {
117160
this.DOM.modes.forEach((cmd) => {
118161
const isVisible = cmd.dataset.codeMode === mode;
119-
cmd.className = isVisible ? "inline" : "hidden";
162+
cmd.classList.toggle("inline", isVisible);
163+
cmd.classList.toggle("hidden", !isVisible);
120164
cmd.dataset.copyContent = isVisible ? `help-cmd-${this.funcName}` : "";
121165
});
122166
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export function debounce<T extends (...args: any[]) => void>(func: T, delay: number = 250): (...args: Parameters<T>) => void {
2+
let timeoutId: ReturnType<typeof setTimeout> | undefined;
3+
4+
return function (this: any, ...args: Parameters<T>) {
5+
if (timeoutId !== undefined) {
6+
clearTimeout(timeoutId);
7+
}
8+
timeoutId = setTimeout(() => {
9+
func.apply(this, args);
10+
}, delay);
11+
};
12+
}

gno.land/pkg/gnoweb/public/js/realmhelp.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
function r(t,n=250){let e;return function(...i){e!==void 0&&clearTimeout(e),e=setTimeout(()=>{t.apply(this,i)},n)}}export{r as debounce};

gno.land/pkg/gnoweb/public/styles.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)