mevebu 1.7.2 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,7 @@ import {
7
7
  $, $$, el, icon, getFavorites, isFavorite, toggleFavorite, setTheme,
8
8
  modal, modalHead, button, copyButton, openPalette, shuffle, toolcard, blank,
9
9
  VERSION, PACKAGE_NAME, checkForUpdate, updateCommand, compareVersions, releaseUrl,
10
+ textInput, textArea, panel,
10
11
  } from "../libs/js/core.js";
11
12
 
12
13
  const DONATE_URL = "https://buymeacoffee.com/fastro";
@@ -754,28 +755,115 @@ function moreFromMev(tool) {
754
755
  );
755
756
  }
756
757
 
757
- function reportLink(tool) {
758
- const title = `Bug in ${tool.name}`;
759
- const body = [
760
- "### What I was doing",
761
- "<!-- one line is enough -->",
762
- "",
763
- "### What happened",
764
- "",
765
- "### What I expected",
766
- "",
767
- `### Tool`,
768
- `mevebu ${VERSION}`,
769
- `Page: #/${tool.category}/${tool.id}`,
770
- "",
771
- "### Browser",
772
- ].join("\n");
773
- return el("a", {
774
- class: "mt-3 flex items-center gap-1.5 self-start text-2xs font-semibold text-ink-3 no-underline hover:text-ink-2",
775
- href: `https://github.com/mevebu/mevebu/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`,
776
- target: "_blank",
777
- rel: "noopener",
778
- }, icon("bug"), el("span", {}, "Report a problem"));
758
+ // What the browser tells us about itself, without asking the user to retype it.
759
+ // Every field can come back empty (a hardened browser, a private mode), so the
760
+ // form still works when it does.
761
+ function browserFacts() {
762
+ const ua = navigator.userAgent;
763
+ const browser = /Edg\//.test(ua) ? "Edge"
764
+ : /OPR\//.test(ua) ? "Opera"
765
+ : /Firefox\//.test(ua) ? "Firefox"
766
+ : /Chrome\//.test(ua) ? "Chrome"
767
+ : /Safari\//.test(ua) ? "Safari"
768
+ : "Unknown";
769
+ const version = (ua.match(new RegExp(browser + "\\/([\\d.]+)")) ?? [])[1] ?? "";
770
+ const platform = navigator.userAgentData?.platform
771
+ ?? (/Windows/.test(ua) ? "Windows" : /Mac OS X/.test(ua) ? "macOS"
772
+ : /Android/.test(ua) ? "Android" : /iPhone|iPad/.test(ua) ? "iOS"
773
+ : /Linux/.test(ua) ? "Linux" : "");
774
+ const screen = `${window.screen.width}x${window.screen.height} @${window.devicePixelRatio}x`;
775
+ return { browser: `${browser} ${version}`.trim(), platform, screen };
776
+ }
777
+
778
+ function openReport(tool) {
779
+ const facts = browserFacts();
780
+ const doing = textArea({ rows: 3, placeholder: "I was building a daily expression for a backup job." });
781
+ const happened = textArea({ rows: 3, placeholder: "The preview stayed empty when I typed 0 3." });
782
+ const expected = textArea({ rows: 3, placeholder: "I expected it to read \"03:00 every day\"." });
783
+ const browserField = textInput({ value: facts.browser });
784
+ const platformField = textInput({ value: [facts.platform, facts.screen].filter(Boolean).join(" · ") });
785
+ let opened = false;
786
+
787
+ const submit = button("Open GitHub issue", { icon: "external-link", kind: "fill" });
788
+ // The actions row renders outside the form, so the button names it explicitly.
789
+ submit.type = "submit";
790
+ submit.setAttribute("form", "report-form");
791
+ submit.disabled = true;
792
+ submit.setAttribute("aria-disabled", "true");
793
+ const validate = () => {
794
+ const ready = happened.value.trim().length > 0 && doing.value.trim().length > 0;
795
+ submit.disabled = !ready;
796
+ if (ready) submit.removeAttribute("aria-disabled");
797
+ else submit.setAttribute("aria-disabled", "true");
798
+ };
799
+ for (const area of [doing, happened]) area.addEventListener("input", validate);
800
+
801
+ const form = el(
802
+ "form",
803
+ {
804
+ id: "report-form",
805
+ class: "grid gap-3.5",
806
+ onsubmit: (event) => {
807
+ event.preventDefault();
808
+ if (opened || submit.disabled) return;
809
+ opened = true;
810
+ const body = [
811
+ "### What I was doing",
812
+ doing.value.trim() || "_not given_",
813
+ "",
814
+ "### What happened",
815
+ happened.value.trim() || "_not given_",
816
+ "",
817
+ "### What I expected",
818
+ expected.value.trim() || "_not given_",
819
+ "",
820
+ "### Where",
821
+ `- Tool: ${tool.name} (\`${tool.id}\`)`,
822
+ `- Page: #/${tool.category}/${tool.id}`,
823
+ `- mevebu: ${VERSION}`,
824
+ "",
825
+ "### Browser",
826
+ `- ${browserField.value || "unknown"}`,
827
+ `- ${platformField.value || "unknown"}`,
828
+ ].join("\n");
829
+ const title = `Bug in ${tool.name}`;
830
+ const href = `https://github.com/mevebu/mevebu/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`;
831
+ window.open(href, "_blank", "noopener");
832
+ },
833
+ },
834
+ panel("What were you doing?", doing),
835
+ panel("What happened?", happened),
836
+ panel("What did you expect?", expected, "Optional"),
837
+ el(
838
+ "div",
839
+ { class: "grid gap-3 rounded-r2 border border-orbit bg-deck-2 p-3.5" },
840
+ el("p", { class: "m-0 text-2xs text-ink-3" },
841
+ "Already filled in from this tab. Edit it if something is off."),
842
+ panel("Browser", browserField),
843
+ panel("Screen", platformField),
844
+ ),
845
+ submit
846
+ );
847
+
848
+ modal({
849
+ label: `Report a problem with ${tool.name}`,
850
+ panelClass: "m-auto w-[min(560px,100%)] p-[clamp(22px,3vw,28px)] max-h-[calc(100dvh-40px)] overflow-y-auto",
851
+ body: [
852
+ modalHead("flag", `Report a problem with ${tool.name}`),
853
+ el("p", { class: "m-0 text-sm text-ink-2" },
854
+ "Tell us what went wrong and the issue opens on GitHub with this page and browser already filled in."),
855
+ form,
856
+ ],
857
+ actions: [submit],
858
+ });
859
+ }
860
+
861
+ function reportButton(tool) {
862
+ return button("Report a problem", {
863
+ icon: "flag",
864
+ class: "mt-4",
865
+ onclick: () => openReport(tool),
866
+ });
779
867
  }
780
868
 
781
869
  async function toolPage(tool, category) {
@@ -788,7 +876,7 @@ async function toolPage(tool, category) {
788
876
  { class: PAGE_NARROW },
789
877
  benchHead(tool, category),
790
878
  slot,
791
- el("div", { class: "flex flex-col items-stretch" }, reportLink(tool)),
879
+ el("div", { class: "flex flex-col items-start" }, reportButton(tool)),
792
880
  more
793
881
  );
794
882
 
@@ -301,6 +301,9 @@
301
301
  .mt-3\.5 {
302
302
  margin-top: calc(var(--spacing) * 3.5);
303
303
  }
304
+ .mt-4 {
305
+ margin-top: calc(var(--spacing) * 4);
306
+ }
304
307
  .mt-5 {
305
308
  margin-top: calc(var(--spacing) * 5);
306
309
  }
@@ -466,6 +469,9 @@
466
469
  .max-h-\[380px\] {
467
470
  max-height: 380px;
468
471
  }
472
+ .max-h-\[calc\(100dvh-40px\)\] {
473
+ max-height: calc(100dvh - 40px);
474
+ }
469
475
  .max-h-\[min\(60vh\,360px\)\] {
470
476
  max-height: min(60vh, 360px);
471
477
  }
@@ -520,6 +526,9 @@
520
526
  .w-\[min\(480px\,100\%\)\] {
521
527
  width: min(480px, 100%);
522
528
  }
529
+ .w-\[min\(560px\,100\%\)\] {
530
+ width: min(560px, 100%);
531
+ }
523
532
  .w-\[min\(640px\,100\%\)\] {
524
533
  width: min(640px, 100%);
525
534
  }
@@ -658,9 +667,6 @@
658
667
  .items-start {
659
668
  align-items: flex-start;
660
669
  }
661
- .items-stretch {
662
- align-items: stretch;
663
- }
664
670
  .justify-between {
665
671
  justify-content: space-between;
666
672
  }
@@ -736,9 +742,6 @@
736
742
  .gap-y-3 {
737
743
  row-gap: calc(var(--spacing) * 3);
738
744
  }
739
- .self-start {
740
- align-self: flex-start;
741
- }
742
745
  .truncate {
743
746
  overflow: hidden;
744
747
  text-overflow: ellipsis;
@@ -926,6 +929,9 @@
926
929
  .p-2 {
927
930
  padding: calc(var(--spacing) * 2);
928
931
  }
932
+ .p-3\.5 {
933
+ padding: calc(var(--spacing) * 3.5);
934
+ }
929
935
  .p-5 {
930
936
  padding: calc(var(--spacing) * 5);
931
937
  }
@@ -750,7 +750,7 @@ export function blank(iconName, text) {
750
750
  // ---------- version ----------
751
751
 
752
752
  // Kept in one place. The CLI reads the same value from package.json.
753
- export const VERSION = "1.7.2";
753
+ export const VERSION = "1.7.3";
754
754
  export const PACKAGE_NAME = "mevebu";
755
755
  export const REPO_SLUG = "mevebu/mevebu";
756
756
 
@@ -1,5 +1,5 @@
1
1
  // GENERATED FILE, DO NOT EDIT.
2
- // Source: lucide v1.59.0 (ISC), icons/169 names from scripts/vendor-icons.mjs
2
+ // Source: lucide v1.59.0 (ISC), icons/173 names from scripts/vendor-icons.mjs
3
3
  // Regenerate with: npm run icons
4
4
 
5
5
  const D = {
@@ -13,6 +13,7 @@ const D = {
13
13
  "coffee": [ ["path", { d: "M10 2v2" }], ["path", { d: "M14 2v2" }], [ "path", { d: "M16 8a1 1 0 0 1 1 1v8a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1h14a4 4 0 1 1 0 8h-1" } ], ["path", { d: "M6 2v2" }] ],
14
14
  "external-link": [ ["path", { d: "M15 3h6v6" }], ["path", { d: "M10 14 21 3" }], ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }] ],
15
15
  "corner-down-left": [ ["path", { d: "M20 4v7a4 4 0 0 1-4 4H4" }], ["path", { d: "m9 10-5 5 5 5" }] ],
16
+ "flag": [ [ "path", { d: "M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528" } ] ],
16
17
  "info": [ ["circle", { cx: "12", cy: "12", r: "10" }], ["path", { d: "M12 16v-4" }], ["path", { d: "M12 8h.01" }] ],
17
18
  "circle-question-mark": [ ["circle", { cx: "12", cy: "12", r: "10" }], ["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }], ["path", { d: "M12 17h.01" }] ],
18
19
  "circle-arrow-up": [ ["circle", { cx: "12", cy: "12", r: "10" }], ["path", { d: "m16 12-4-4-4 4" }], ["path", { d: "M12 16V8" }] ],
@@ -58,6 +59,9 @@ const D = {
58
59
  "loader": [ ["path", { d: "M12 2v4" }], ["path", { d: "m16.2 7.8 2.9-2.9" }], ["path", { d: "M18 12h4" }], ["path", { d: "m16.2 16.2 2.9 2.9" }], ["path", { d: "M12 18v4" }], ["path", { d: "m4.9 19.1 2.9-2.9" }], ["path", { d: "M2 12h4" }], ["path", { d: "m4.9 4.9 2.9 2.9" }] ],
59
60
  "play": [ [ "path", { d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z" } ] ],
60
61
  "lock": [ ["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2" }], ["path", { d: "M7 11V7a5 5 0 0 1 10 0v4" }] ],
62
+ "wrench": [ [ "path", { d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z" } ] ],
63
+ "gauge": [ ["path", { d: "m12 14 4-4" }], ["path", { d: "M3.34 19a10 10 0 1 1 17.32 0" }] ],
64
+ "monitor": [ ["rect", { width: "20", height: "14", x: "2", y: "3", rx: "2" }], ["line", { x1: "8", x2: "16", y1: "21", y2: "21" }], ["line", { x1: "12", x2: "12", y1: "17", y2: "21" }] ],
61
65
  "calendar-days": [ ["path", { d: "M8 2v3" }], ["path", { d: "M16 2v3" }], ["rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }], ["path", { d: "M3 9h18" }], ["path", { d: "M8 13h.01" }], ["path", { d: "M12 13h.01" }], ["path", { d: "M16 13h.01" }], ["path", { d: "M8 17h.01" }], ["path", { d: "M12 17h.01" }], ["path", { d: "M16 17h.01" }] ],
62
66
  "graduation-cap": [ [ "path", { d: "M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0z" } ], ["path", { d: "M22 10v6" }], ["path", { d: "M6 12.5V16a6 3 0 0 0 12 0v-3.5" }] ],
63
67
  "calculator": [ ["rect", { width: "16", height: "20", x: "4", y: "2", rx: "2" }], ["line", { x1: "8", x2: "16", y1: "6", y2: "6" }], ["line", { x1: "16", x2: "16", y1: "14", y2: "18" }], ["path", { d: "M16 10h.01" }], ["path", { d: "M12 10h.01" }], ["path", { d: "M8 10h.01" }], ["path", { d: "M12 14h.01" }], ["path", { d: "M8 14h.01" }], ["path", { d: "M12 18h.01" }], ["path", { d: "M8 18h.01" }] ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mevebu",
3
- "version": "1.7.2",
3
+ "version": "1.7.3",
4
4
  "description": "Small tools that run in your browser. No accounts, no uploads, no tracking.",
5
5
  "license": "MIT",
6
6
  "type": "module",