From 93fb22f29b0d89a3a5c98f55a38972868019ceb7 Mon Sep 17 00:00:00 2001 From: Christian Ditaputratama Date: Thu, 31 Oct 2024 18:09:02 +0700 Subject: [PATCH] feat: Added clipboard functionality --- Makefile | 1 + bun.lockb | Bin 0 -> 46093 bytes internal/handler/views/home.templ | 19 +++++------ internal/handler/views/home_templ.go | 2 +- internal/handler/views/layout.templ | 1 + internal/handler/views/layout_templ.go | 41 ++++++++++++++++-------- internal/handler/views/src/css/main.css | 5 +++ internal/handler/views/src/js/main.js | 20 ++++++++++++ package.json | 1 + 9 files changed, 64 insertions(+), 26 deletions(-) create mode 100755 bun.lockb diff --git a/Makefile b/Makefile index 3ef5878..d448324 100644 --- a/Makefile +++ b/Makefile @@ -60,6 +60,7 @@ prepare: bun install --frozen-lockfile @mkdir -p ./internal/handler/views/assets/js cp ./node_modules/htmx.org/dist/htmx.min.js ./internal/handler/views/assets/js + cp ./node_modules/clipboard/dist/clipboard.min.js ./internal/handler/views/assets/js # Compile template .PHONY: templ diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..997b7580c52afa4252f18b0a77a594dd6b53e315 GIT binary patch literal 46093 zcmeHw2|QKZ*Z)LcjNYKcD~me%jBo+Gn4=zu&#~+H3E#&pyXJLzOhbc%d4e z>>v$RP`ILJSdb_PgTwU-@L_XU3?FW2Ad}As*A(qSqtPzsJbim$4!bqwQOV*PGmO0T zQmRi$-90*Fn5^FNPu%^=(OFOkLZl#~_53N06{e*lga>VrIUI@6XtBB?G@1;=J0KQ^ z*o((w@w{j>B}n&$bSjkV1#tv3kb__;I4=q5uEO%cTpk}Vw6v}?S|2!{17$=Z4q^sz z+1@nT2S_7tD2vDCgtKTG-DtESkRApxmXm=P^Zl4S?%W_6jon?qbB!*@4`%xix}Sh_ zKPdM`$X5n2>VI1pvv~|(4%d_B4<MgLJ7*r02 zvCa@nKpY_~@8!o0V0$w|eR!;JRuG>z6e`F155hlE5Qnmu-rnrcU}jJR_=A@pFU%{H z$z#!aKxJr$V0I{z4-E(ucKvHOkM`jEv4XJvo5J)1h_U@mP&x7vMgl$eOVelrAiV`* zC=%-fosD=mVLaE5?d1pM*gV!e7R0r19`(!)S;HON8vA*?? zkFk@S0KXez#C60|CNI$AXP#P667?;H7^;k&r9h)W(O7ecp~~2Sg9Yc+Aq`E9^=I?h zU>2G;CmbUhGt`%e{rG|N)VZO);~|B7rQqzSKaa&>dGTqqYmmnFdPCY5dT=O|!}`c^ zsHY_8UsZ_FK7$}eJoFt6Oc(o1Sp|=B$&f+b%Y(18y5;c4J5EbQ%#R;0+TU*x3M2}I`O1mXr5%%#* z?zom~EIaSThgr8q>Q6tl%Rf9UqSZ~o(m0{la;x&9ZCeWELIO{UnTlo84qU&uQpfsr z)A7Y>J<^t^4jpN;b3#;i_iaWi(}Grn`scV?RTd;KIb*)>tN5O|aXzorr-zLZ-Tv%h zT#pwz^7|J&&3uzhv$>e%SbWxVTXo>2Z7y%@t~t%A`SxiIvnjVaM2EDt8H$iH^n_M$fv@d)mF3+4X8md#EK(+jVrW!4ON2$aPlM3Eu0E zoPBupsc-HIcX?xt(K3d$NpaYJC`u?ZXdm0R=rrR+0b~Pa^LI= ztJ0e0c{_*~^s!%FoH^LVN;LA(5XtLaj0hj+RdsT%HWSl(7q@;hzppDREzNNpDsk_e zJv*;U>)kcBF`TnyN3srF4@~^HYkI?^eWRTpI!ITQnDl?TdHngF(V~^k3dX4`Ki%P- zZ@q7C*ehOg7KaljlJxdcbZ}D1^}D?8Yofh2kDoWB%X1IAy1HQ3^L5>lp46&3+ufVy z-f;C^k~w@ zl;E!%k;B2t77q__wT^M>ypn6YXF5GL%(bx5xVTfcFt49yh>DSkn1tSKm-M13?^9lN z#N%2p*1pQBrRHazVsZT->HgMJw)HsC8 z^zd2hjZ9VDKAV>(6+6>s^v*rM$U7@ztF?3QeB~0mO?JvVE_htqCoB1hU#pjO=8ERb zNUy4Gbi2*Lm#6k!s2=NL@8@w-!Ejo4&l?%0tYfol4u5z=^Q#qq98HeH)Z3?nZ;J;d zZpmZTuW?Q+2x`%9p5|{apCk2V?}^^#X?J#1X)C|bGAh2ARCg;pdHnm`~!50^SVpr0p>7Od#>^0dFY8Blb`6 z6F_Owe}IbCqcfF58M6LRz)ytwVL8z0y0HopUk-S*AL{}^yQv_F|9r^1y9}9TA{$Lty_ow=w20S_cVa0!H|7M~7;0FJZ{mtNJ4E-0T z5hDDl{;L6x?Z^86B#`#I3V3q-<2mwtM_gpNZg6u++P|~9BR7dR7UI$FDCBu8(_SFU zZ2>&?AJ&aN)L9)!{0+e4_(%IAmOKxK?FO=(7~FK?`jN!`ssFkIUPp+>d)GhJe+}Sq z{vdJWIBHjU$RzbI06cm9LJraoJBycrn{*RO`#Zvs`DFb*fS*Lc|LOQU0C==N$@i!F zR|8%T@K`T7hm$(C7nAjA!3_iAF-`h#dpI(W#Ipg9;~¬hI-i%I-Bz*|x3Zx2Jw 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%0Dt|{}0 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

My Stagenet Public Node

Stagenet is what you need to learn Monero safely. Stagenet is technically equivalent to mainnet, both in terms of features and consensus rules.

-
@@ -97,7 +96,7 @@ templ Home() { P2P -
@@ -109,7 +108,7 @@ templ Home() { RPC -
@@ -121,7 +120,7 @@ templ Home() { RPC SSL - @@ -131,7 +130,6 @@ templ Home() {

My Testnet Public Node

Testnet is the "experimental" network and blockchain where things get released long before mainnet. As a normal user, use mainnet instead.

-
@@ -139,7 +137,7 @@ templ Home() { P2P -
@@ -151,7 +149,7 @@ templ Home() { RPC -
@@ -163,7 +161,7 @@ templ Home() { RPC SSL -
@@ -199,9 +197,8 @@ templ Home() {

If you find this project useful, please consider making a donation to help cover the ongoing expenses. Your contribution will go towards ensuring the continued availability of this website, my stagenet and testnet public nodes.

- - -
diff --git a/internal/handler/views/home_templ.go b/internal/handler/views/home_templ.go index d8856aa..f3c5a64 100644 --- a/internal/handler/views/home_templ.go +++ b/internal/handler/views/home_templ.go @@ -74,7 +74,7 @@ func Home() templ.Component { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("etc; can be an other good reference for you.

You can find few resources I provide related to Monero below:

My Stagenet Public Node

Stagenet is what you need to learn Monero safely. Stagenet is technically equivalent to mainnet, both in terms of features and consensus rules.

P2P
RPC
RPC SSL

My Testnet Public Node

Testnet is the \"experimental\" network and blockchain where things get released long before mainnet. As a normal user, use mainnet instead.

P2P
RPC
RPC SSL

Since we desire privacy, we must ensure that each party to a transaction have knowledge only of that which is directly necessary for that transaction.

Eric Hughes in A Cypherpunk's Manifesto.


If you find this project useful, please consider making a donation to help cover the ongoing expenses. Your contribution will go towards ensuring the continued availability of this website, my stagenet and testnet public nodes.

\"ditatompel's

Thank you so much! It means a lot to me. 🥰

") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("etc; can be an other good reference for you.

You can find few resources I provide related to Monero below:

My Stagenet Public Node

Stagenet is what you need to learn Monero safely. Stagenet is technically equivalent to mainnet, both in terms of features and consensus rules.

P2P
RPC
RPC SSL

My Testnet Public Node

Testnet is the \"experimental\" network and blockchain where things get released long before mainnet. As a normal user, use mainnet instead.

P2P
RPC
RPC SSL

Since we desire privacy, we must ensure that each party to a transaction have knowledge only of that which is directly necessary for that transaction.

Eric Hughes in A Cypherpunk's Manifesto.


If you find this project useful, please consider making a donation to help cover the ongoing expenses. Your contribution will go towards ensuring the continued availability of this website, my stagenet and testnet public nodes.

\"ditatompel's

Thank you so much! It means a lot to me. 🥰

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/handler/views/layout.templ b/internal/handler/views/layout.templ index 07ec568..a4f8f39 100644 --- a/internal/handler/views/layout.templ +++ b/internal/handler/views/layout.templ @@ -39,6 +39,7 @@ templ base(m Meta) { + diff --git a/internal/handler/views/layout_templ.go b/internal/handler/views/layout_templ.go index 4b55c46..7269842 100644 --- a/internal/handler/views/layout_templ.go +++ b/internal/handler/views/layout_templ.go @@ -181,14 +181,27 @@ func base(m Meta) templ.Component { return templ_7745c5c3_Err } var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/assets/js/main.min.js?t=%d", buildTime)) + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/assets/js/clipboard.min.js?t=%d", buildTime)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/layout.templ`, Line: 42, Col: 70} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/layout.templ`, Line: 42, Col: 75} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -209,12 +222,12 @@ func base(m Meta) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(config.Version) + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(config.Version) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/layout.templ`, Line: 51, Col: 50} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/layout.templ`, Line: 52, Col: 50} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -242,12 +255,12 @@ func BaseLayout(m Meta, cmp templ.Component) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var14 := templ.GetChildren(ctx) - if templ_7745c5c3_Var14 == nil { - templ_7745c5c3_Var14 = templ.NopComponent + templ_7745c5c3_Var15 := templ.GetChildren(ctx) + if templ_7745c5c3_Var15 == nil { + templ_7745c5c3_Var15 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Var15 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_Var16 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { @@ -265,7 +278,7 @@ func BaseLayout(m Meta, cmp templ.Component) templ.Component { } return templ_7745c5c3_Err }) - templ_7745c5c3_Err = base(m).Render(templ.WithChildren(ctx, templ_7745c5c3_Var15), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = base(m).Render(templ.WithChildren(ctx, templ_7745c5c3_Var16), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -289,9 +302,9 @@ func BlankLayout(cmp templ.Component) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var16 := templ.GetChildren(ctx) - if templ_7745c5c3_Var16 == nil { - templ_7745c5c3_Var16 = templ.NopComponent + templ_7745c5c3_Var17 := templ.GetChildren(ctx) + if templ_7745c5c3_Var17 == nil { + templ_7745c5c3_Var17 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = cmp.Render(ctx, templ_7745c5c3_Buffer) diff --git a/internal/handler/views/src/css/main.css b/internal/handler/views/src/css/main.css index 594c11b..6aed813 100644 --- a/internal/handler/views/src/css/main.css +++ b/internal/handler/views/src/css/main.css @@ -17,6 +17,11 @@ a.external { @apply py-0.5 md:py-3 px-4 md:px-1 border-s-2 md:border-s-0 md:border-b-2 border-orange-400 font-medium text-neutral-200 focus:outline-none; } +/** home page **/ a.btn-link { @apply py-1 px-3 mt-2 inline-flex items-center gap-x-1 text-sm font-medium rounded-lg border border-neutral-700 bg-neutral-800 text-white shadow-sm hover:bg-neutral-700; } +/* my nodes copy input button */ +button.copy-input { + @apply px-2 shrink-0 inline-flex justify-center items-center gap-x-2 text-sm font-semibold rounded-e-md border border-transparent bg-orange-600 text-white hover:brightness-125 focus:outline-none focus:bg-orange-700 disabled:opacity-50 disabled:pointer-events-none; +} diff --git a/internal/handler/views/src/js/main.js b/internal/handler/views/src/js/main.js index ae822d6..f3cb4c1 100644 --- a/internal/handler/views/src/js/main.js +++ b/internal/handler/views/src/js/main.js @@ -1,5 +1,25 @@ import "@preline/collapse"; +window.addEventListener("load", () => { + var clipboard = new ClipboardJS(".clipboard"); + clipboard.on("success", function (e) { + let btnText = e.trigger.textContent; + let successText = e.trigger.getAttribute("data-success-text"); + if (successText === null) { + successText = "Copied 👍"; + } + e.trigger.textContent = successText; + e.trigger.disabled = true; + setTimeout(function () { + e.trigger.textContent = btnText; + e.trigger.disabled = false; + }, 1000); + }); + clipboard.on("error", function (e) { + console.error("Clipboard error", e.trigger); + }); +}); + htmx.onLoad(function () { // Auto init preline JS, see https://preline.co/docs/preline-javascript.html // This need to be inside `htmx.onLoad` to be work together with hx-boost. diff --git a/package.json b/package.json index 50ebe4a..a2398e5 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "@preline/collapse": "^2.5.0", "@tailwindcss/forms": "^0.5.9", "@tailwindcss/typography": "^0.5.15", + "clipboard": "^2.0.11", "htmx.org": "^1.9.12", "tailwindcss": "^3.4.14" }