From 2208b9f14832ac1107aaa5e43c1e594f1eea97c7 Mon Sep 17 00:00:00 2001 From: Dominik Hebeler <dominik@suma-ev.de> Date: Tue, 6 Dec 2022 13:49:46 +0100 Subject: [PATCH] mobile optimization for key page --- pass/public/images/download.svg | 126 +++++++++++++++++++++++++++++ pass/public/images/metager_key.png | Bin 0 -> 2399 bytes pass/public/styles/base.less | 47 +++++------ pass/public/styles/key.less | 92 +++++++++++++++++---- pass/resources/js/base.js | 20 ++--- pass/routes/key.js | 5 +- pass/views/key.ejs | 32 +++++--- 7 files changed, 257 insertions(+), 65 deletions(-) create mode 100644 pass/public/images/download.svg create mode 100644 pass/public/images/metager_key.png diff --git a/pass/public/images/download.svg b/pass/public/images/download.svg new file mode 100644 index 0000000..8028584 --- /dev/null +++ b/pass/public/images/download.svg @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="37mm" + height="26mm" + viewBox="0 0 131.10236 92.125983" + id="svg6085" + version="1.1" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)" + sodipodi:docname="download.svg"> + <defs + id="defs6087" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-178.97587" + inkscape:cy="-102.28552" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1920" + inkscape:window-height="996" + inkscape:window-x="0" + inkscape:window-y="840" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" + inkscape:document-rotation="0" /> + <metadata + id="metadata6090"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Laag 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-960.23623)"> + <path + style="opacity:1;fill:#6c5353;fill-opacity:0.94509804;fill-rule:nonzero;stroke:none;stroke-width:1.58158517;stroke-miterlimit:4;stroke-dasharray:1.58158517, 3.16317034;stroke-dashoffset:0;stroke-opacity:1" + d="" + id="path6839" + inkscape:connector-curvature="0" + transform="translate(0,960.23623)" /> + <g + transform="matrix(3.5157803,0,0,2.9717293,12.854909,961.75597)" + id="g3" + style="fill:#6c5353;fill-opacity:0.945098" + inkscape:transform-center-x="-552.71044" + inkscape:transform-center-y="87.848018"> + <path + inkscape:connector-curvature="0" + d="m 25.462,19.105 v 6.848 H 4.515 V 19.105 H 0.489 v 8.861 c 0,1.111 0.9,2.012 2.016,2.012 h 24.967 c 1.115,0 2.016,-0.9 2.016,-2.012 v -8.861 z" + id="path5" + style="fill:#6c5353;fill-opacity:0.945098" /> + <path + inkscape:connector-curvature="0" + d="M 14.62,18.426 8.856,11.461 c 0,0 -0.877,-0.828 0.074,-0.828 0.951,0 3.248,0 3.248,0 0,0 0,-0.557 0,-1.416 0,-2.449 0,-6.906 0,-8.723 0,0 -0.129,-0.494 0.615,-0.494 0.75,0 4.035,0 4.572,0 0.536,0 0.524,0.416 0.524,0.416 0,1.762 0,6.373 0,8.742 0,0.768 0,1.266 0,1.266 0,0 1.842,0 2.998,0 1.154,0 0.285,0.867 0.285,0.867 0,0 -4.904,6.51 -5.588,7.193 -0.492,0.495 -0.964,-0.058 -0.964,-0.058 z" + id="path7" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g9" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g11" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g13" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g15" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g17" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g19" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g21" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g23" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g25" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g27" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g29" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g31" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g33" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g35" + style="fill:#6c5353;fill-opacity:0.945098" /> + <g + id="g37" + style="fill:#6c5353;fill-opacity:0.945098" /> + </g> + </g> +</svg> diff --git a/pass/public/images/metager_key.png b/pass/public/images/metager_key.png new file mode 100644 index 0000000000000000000000000000000000000000..951f48fe8cb15f8001e3ff303fbb6f31a8a60496 GIT binary patch literal 2399 zcmZ`*Ur1Y598UMJu4OI{F576fWelcpUy8m2#-_De*Fe%3a~)e>x;pYCBup6S2nlpW zF+(3FQiB`fl#pw6jDesd=!y-p__i_eA(%BI58Etj!e}GQ;=b>k8*?(*!}TV)_nhDF z_x(Fg^j&+W>HLNB7K^3Hb+xA-_xrq_c^ZGePfQKr_LQrqOCLFNcp>tm#d7W?etUSY zEB3|@pIf?qe(ld_;LE`mrdD6R_2k>{q94Bg`0UW?@sn@%-h6fM`p)+CKStggdc``l z`s>ZrkKbBZn;Ku+EB^08N5@jhIgm|;{pqFl0k>w}wv2o;K2K(HdT~P8z<T4|qDKqq zZf(9VuC>fKam~e?dQeZq>@!$o%Po~WN^wUdp0V3P$*i7Dx@}xIo$;WQ5&mkhKaN$# zVE=|O(p{L0<^HO7S$@!&$j{-i*j(#aD4oOZTZhU>+tDvFdYfq3j*hY{!6F=C*k5dX z_u}0$cVmll8k^<52g!9~R`2i?LnXEHu3mN7rZakR4Eq~y@zH}_(f06S`#|_|A*b|l zGy1609ax?<cMtWCF6MhNjUBig2UH|F1i(4ba|mFdM4OQXBL1{lrxj=#`2^O_X_224 zCdaJ<Dc?sZE<sE!kSfW*T+Ah_y9!*^G9zd>RhQMc0hbagRwWMuSsep4*B;9U&bRBb zIkawG4J@zwHjMIZGFO_2d9gk$_AB*5B4V3xW4lI8PfqOYN!v}<QNARhw3DWGgY(QQ zdfj(au7J#nqAcy8Z^KykQEfRfLO5Sn0nk4K5eD^5Bi}3ABoi(m!QUV;0cjI?SKRUV ztV76`DiEsRi&dBCNx+j$rhIMCC^s$NZ)C!)Ic-jHVT95c=O6Y<q1Zvn(QPRkCwVO@ zUU=^BPj8&O=}EV;&%p9XH?Kk>-vq(n`?_y*vDS98N@L`Gxdb#jr7COUgf(cQSv`oM zrGicmOVM*!ZxT}x5BhtlB;6qD#<k7g>c|$iFZwso3*Q|i|AGM&!cUWIv@9yIaQXC* z@D5pLg3w1E-YGxf&XN~)32GfmDwQ8}gZ9({frPk#dm+Jm2!cMq!gLVkt0d}SH2%-M z7ft_Q_co(44XGUUq&r<)%TQ_LZoB%+XYf2rx6F8j11R2BB!G!z!_AWpeNqq7eMk5b zeRhz<++0jy+o1!$U<IbDQvi^a+>Mk2BLCzP^qKM%dj&SNJOG>Ahj6LRi<Ix&Evp)7 zwy`L1tckAJ`1-DX098vp3xtD=INxY@p&8)T0=F?{cLf?SPl5S}3^COx%*1>a(g3P5 z`xNUHx9^BJa%%G;N4c6B_KKwEK$9jwn6oh+qO;&jBpAfQ5)c(NF9RB-!4XPFr|V?z zShqyV2GOsSGFdbrMK8}4k!Ugyw-gbZ;VjdGIub$G;G6hKzWi5@Q8SkrRG5?jjJ%U) zjfhblOe)f!a%`^P%wl&$B7}j+2NfqTAxPDkot1Wk7h{U<HL(_nb@B@dnT4sPUR6a_ z9yu0q&h;|JA&6QI^H?P^yalzY;+GxkaT|~#TD;KwSSHlJ0cXR~jY<mGwnS4hj7ZKX z%tR@fXN|mx<5Y>&&Tu@FBim@=h&eA3ULO4rF6yyMb%=e(%33w2<f{@u^)p#HAQWR& btvi<vQ@=la_IdorWN}@&*7Nn{4{rSnBbukE literal 0 HcmV?d00001 diff --git a/pass/public/styles/base.less b/pass/public/styles/base.less index 86340f6..eadfe96 100644 --- a/pass/public/styles/base.less +++ b/pass/public/styles/base.less @@ -53,37 +53,30 @@ button { cursor: pointer; } -.copy { +.button.copy, +.button.share, +.button.download { display: none; - &.active { - display: block; - } - &::after { - content: ""; - background-image: url("/images/copy.svg"); - width: 1rem; - height: 1rem; - display: block; - background-size: 0.7rem; - background-repeat: no-repeat; - background-position: center; + &.download { + display: flex; + img { + height: 2em; + } } -} - -.share { - display: none; + align-items: center; + gap: 0.5rem; + padding: 0.5rem; + font-size: 0.8rem; &.active { - display: block; + display: flex; + } + &.success img { + filter: brightness(0) invert(74%) sepia(42%) saturate(2242%) + hue-rotate(65deg) brightness(102%) contrast(104%); } - &::after { - content: ""; - background-image: url("/images/share.svg"); - width: 1rem; - height: 1rem; - display: block; - background-size: 0.7rem; - background-repeat: no-repeat; - background-position: center; + img { + filter: brightness(0) invert(); + height: 1.5rem; } } diff --git a/pass/public/styles/key.less b/pass/public/styles/key.less index 3f94219..37e6976 100644 --- a/pass/public/styles/key.less +++ b/pass/public/styles/key.less @@ -1,29 +1,36 @@ -#key-info { - display: grid; - grid-template-columns: auto auto; - grid-template-rows: auto auto auto auto auto; - max-width: 1200px; - margin: 0 auto; - align-items: center; +@max-width: 980px; +@key-breakpoint-1: 675px; - > h1 { - grid-column: span 2; - justify-self: center; - } +main { + max-width: @max-width; + margin: 0 auto; + display: grid; + row-gap: 1rem; + padding-right: 1rem; + grid-template-columns: auto 1fr; + grid-template-rows: auto 1fr auto auto; + grid-template-areas: "qr key " "qr setting-url" "qr buttons" "amount charge"; - #qr { - grid-row: span 3; + > #qr { + grid-area: qr; justify-self: center; } #key { - font-size: 1.5rem; + grid-area: key; + font-size: clamp(0.9rem, 4.8vw, 1.5rem); font-weight: bold; width: max-content; + margin-top: 11px; + margin-right: 1rem; } #setting-url { + grid-area: setting-url; + align-self: start; display: flex; + padding: 0.5rem 1rem; + border-radius: 5px; > input { line-height: 1.5; padding: 0.1rem 0.5rem; @@ -32,10 +39,63 @@ } } + > #buttons { + grid-area: buttons; + display: flex; + gap: 1rem; + margin-bottom: 17px; + justify-content: flex-end; + @media (max-width: 435px) { + display: grid; + grid-template-columns: 1fr; + .button { + width: auto; + } + > * { + display: grid; + justify-items: center; + text-align: center; + } + } + } + > #amount { - grid-column: span 2; + grid-area: amount; + max-width: 200px; justify-self: center; - font-size: 3rem; padding: 2rem; + display: grid; + > h3 { + font-size: 1.5rem; + margin: 0; + } + > div.amount { + font-size: 3rem; + justify-self: center; + } + } + + > #charge { + grid-area: charge; + } + + @media (max-width: @key-breakpoint-1) { + padding: 0 1rem; + grid-template-rows: auto auto auto auto auto; + grid-template-areas: "qr qr " "key key" "setting-url setting-url" "buttons buttons " "amount charge "; + + > #key { + margin: 0; + justify-self: center; + } + + > #setting-url { + text-align: center; + } + + > #buttons { + justify-content: center; + margin-bottom: 0; + } } } diff --git a/pass/resources/js/base.js b/pass/resources/js/base.js index a9aca10..c3e34e2 100644 --- a/pass/resources/js/base.js +++ b/pass/resources/js/base.js @@ -4,10 +4,9 @@ document.querySelectorAll(".share").forEach((element) => { } element.addEventListener("pointerdown", (e) => { let share_data = { - url: element.parentElement.querySelector("input[type=text]").value, + url: document.getElementById(element.dataset.share_url_target).value, title: element.dataset.share_title, }; - console.log(share_data); navigator.share(share_data).catch((reason) => { console.error(reason); }); @@ -16,14 +15,15 @@ document.querySelectorAll(".share").forEach((element) => { document.querySelectorAll(".copy").forEach((element) => { element.classList.add("active"); - let input_field = element.parentElement.querySelector("input[type=text]"); element.addEventListener("click", () => { - input_field.focus(); - input_field.setSelectionRange(0, input_field.value.length); - navigator.clipboard.writeText(input_field.value); - }); - input_field.addEventListener("click", () => { - input_field.setSelectionRange(0, input_field.value.length); - navigator.clipboard.writeText(input_field.value); + let target = document.getElementById(element.dataset.target); + target.focus(); + target.setSelectionRange(0, target.value.length); + navigator.clipboard.writeText(target.value).then(() => { + element.classList.add("success"); + setTimeout(() => { + element.classList.remove("success"); + }, 1000); + }); }); }); diff --git a/pass/routes/key.js b/pass/routes/key.js index 174109e..c8ca4ee 100644 --- a/pass/routes/key.js +++ b/pass/routes/key.js @@ -5,7 +5,7 @@ var Key = require("../app/Key"); router.get("/create", function (req, res, next) { Key.GET_NEW_KEY().then((key) => { - res.redirect("/key/" + key); + res.redirect("/key/" + key + "?new=true"); }); }); @@ -18,8 +18,9 @@ router.get("/:key", async (req, res) => { let QRCode = require("qrcode"); let qr_data_uri = await QRCode.toDataURL(metager_url); - + console.log(req.query.new === "true"); res.render("key", { + created_new: req.query.new === "true" ? true : false, key: { key: key, settings_url: metager_url, diff --git a/pass/views/key.ejs b/pass/views/key.ejs index cecab38..fe25176 100644 --- a/pass/views/key.ejs +++ b/pass/views/key.ejs @@ -1,16 +1,28 @@ <%- include('templates/page_header', {css: ["/styles/key.css"], js: []}); %> -<div id="key-info"> - <h1>MetaGer Schlüssel</h1> - <img id="qr" src="<%= key.qr %> "></img> - <div id="key"><%= key.key %> </div> - <div id="setting-url"> - <input type="text" readonly value="<%= key.settings_url %>" /> - <button class="copy"></button> - <button class="share" data-share_title="MetaGer Schlüssel"></button> +<img id="qr" src="<%= key.qr %> "></img> +<div id="key"><%= key.key %> </div> +<input id="setting-url" type="text" readonly value="<%= key.settings_url %>" /> +<div id="buttons"> + <button class="copy button" data-target="setting-url"><img src="/images/copy.svg" /><div>URL kopieren</div></button> + <button class="share button" data-share_title="MetaGer Schlüssel" data-share_url_target="setting-url"><img src="/images/share.svg" /><div>Teilen</div></button> + <a class="download button" href="<%= key.qr %>" target="_blank" download="metager_key.png"><img src="/images/download.svg" /><div>In Datei sichern</div></a> +</div> + +<div id="amount"> + <h3>Gültig für</h3> + <div class="amount">0</div> + <div>Suchanfragen</div> +</div> + +<div id="charge"> + <% if (created_new) { %> + <div id="store"> + <p>Ihr MetaGer Schlüssel wurde erstellt. Bevor Sie </p> </div> - <div id="hint">Benutzen Sie diese URL oder diesen QR Code um Ihren MetaGer Schlüssel auf beliebig vielen Endgeräten einzurichten.</div> - <div id="amount">0 Suchanfragen</div> + <% } %> </div> + + <%- include('templates/page_footer'); -%> \ No newline at end of file -- GitLab