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