From 7a0c465b67c4daf6a337d5551c7f02ab2882de4e Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 20 Feb 2025 15:17:07 -0800 Subject: [PATCH 1/6] refactor theme --- src/Utils/Theme/constants.js | 37 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/Utils/Theme/constants.js b/src/Utils/Theme/constants.js index c81a07f99..7a1650ed0 100644 --- a/src/Utils/Theme/constants.js +++ b/src/Utils/Theme/constants.js @@ -200,6 +200,20 @@ const newSemanticColors = { dark: newColors.green200, }, }, + successSecondary: { + main: { + light: undefined, + dark: "#073C2D", + }, + contrastText: { + light: undefined, + dark: "#34D399", + }, + lowContrast: { + light: undefined, + dark: "#094434", + }, + }, warning: { main: { light: newColors.orange700, @@ -267,29 +281,6 @@ const newSemanticColors = { }, }, - distributedStatusHeader: { - up: { - light: "#073C2D", - dark: "#073C2D", - }, - down: { - light: newColors.red700, - dark: newColors.red700, - }, - textPrimary: { - light: "#34D399", - dark: "#34D399", - }, - textPrimaryBackground: { - light: "#094434", - dark: "#094434", - }, - textSecondary: { - light: "#22946C", - dark: "#22946C", - }, - }, - chatbot: { background: { light: "#112B2B", From 0433c2ee880ff24abe29f9a15e9894aac0d86247 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 20 Feb 2025 15:17:32 -0800 Subject: [PATCH 2/6] add html2canvas --- package-lock.json | 50 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 51 insertions(+) diff --git a/package-lock.json b/package-lock.json index 00df0a9bf..395458288 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "axios": "^1.7.4", "dayjs": "1.11.13", "flag-icons": "7.3.2", + "html2canvas": "1.4.1", "i18next": "^24.2.2", "immutability-helper": "^3.1.1", "joi": "17.13.3", @@ -9384,6 +9385,15 @@ "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==", "license": "MIT" }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -10446,6 +10456,15 @@ "tiny-invariant": "^1.0.6" } }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -12444,6 +12463,19 @@ "void-elements": "3.1.0" } }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -17888,6 +17920,15 @@ "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -18418,6 +18459,15 @@ "node": ">= 0.4.0" } }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", diff --git a/package.json b/package.json index 9df235cdd..5072650b8 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "axios": "^1.7.4", "dayjs": "1.11.13", "flag-icons": "7.3.2", + "html2canvas": "1.4.1", "i18next": "^24.2.2", "immutability-helper": "^3.1.1", "joi": "17.13.3", From 8e23f35e76b4338800edc5c36d20347101b75927 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 20 Feb 2025 15:17:47 -0800 Subject: [PATCH 3/6] Add sharing component --- src/Components/ShareComponent/index.jsx | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/Components/ShareComponent/index.jsx diff --git a/src/Components/ShareComponent/index.jsx b/src/Components/ShareComponent/index.jsx new file mode 100644 index 000000000..9c52756f3 --- /dev/null +++ b/src/Components/ShareComponent/index.jsx @@ -0,0 +1,67 @@ +import html2canvas from "html2canvas"; +import ShareIcon from "@mui/icons-material/Share"; +import { Button } from "@mui/material"; +import { useTheme } from "@emotion/react"; + +const ShareComponent = ({ elementToCapture, fileName }) => { + const theme = useTheme(); + const captureAndShare = async () => { + try { + // Temporarily apply styles directly to the element + const originalBackground = elementToCapture.current.style.background; + const originalPadding = elementToCapture.current.style.padding; + + elementToCapture.current.style.background = `radial-gradient(circle, ${theme.palette.gradient.color1}, ${theme.palette.gradient.color2}, ${theme.palette.gradient.color3}, ${theme.palette.gradient.color4}, ${theme.palette.gradient.color5})`; + elementToCapture.current.style.padding = `${theme.spacing(20)}`; + + // Capture the element directly + const canvas = await html2canvas(elementToCapture.current, { + useCORS: true, + scale: 2, + allowTaint: true, + backgroundColor: null, + }); + + // Restore original styles + elementToCapture.current.style.background = originalBackground; + elementToCapture.current.style.padding = originalPadding; + + const imageBlob = await new Promise((resolve) => + canvas.toBlob(resolve, "image/png") + ); + + const file = new File([imageBlob], `${fileName}.png`, { + type: "image/png", + }); + + if (navigator.share) { + await navigator.share({ + files: [file], + title: "Screenshot", + text: "Check out this screenshot!", + }); + } else { + const url = URL.createObjectURL(imageBlob); + const a = document.createElement("a"); + a.href = url; + a.download = `${fileName}.png`; + a.click(); + URL.revokeObjectURL(url); + } + } catch (error) { + console.error(error); + } + }; + return ( + + ); +}; + +export default ShareComponent; From aa1cd5313e69527f242e4fbb4b309ec656c8a881 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 20 Feb 2025 15:18:03 -0800 Subject: [PATCH 4/6] set button height --- src/Utils/Theme/globalTheme.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index c521cb117..66631edec 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -118,6 +118,7 @@ const baseTheme = (palette) => ({ }, }, ], + height: 34, fontWeight: 400, borderRadius: 4, boxShadow: "none", From b0cadf66bf08a1e00d6f226f0187a1712e19d3dc Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 20 Feb 2025 15:18:14 -0800 Subject: [PATCH 5/6] add sharing feature --- .../Components/DistributedUptimeMap/index.jsx | 6 +- .../Details/Components/StatusHeader/index.jsx | 71 ++++++++++--------- .../DistributedUptimeStatus/Status/index.jsx | 9 ++- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/Pages/DistributedUptime/Details/Components/DistributedUptimeMap/index.jsx b/src/Pages/DistributedUptime/Details/Components/DistributedUptimeMap/index.jsx index 940b59351..7617666eb 100644 --- a/src/Pages/DistributedUptime/Details/Components/DistributedUptimeMap/index.jsx +++ b/src/Pages/DistributedUptime/Details/Components/DistributedUptimeMap/index.jsx @@ -5,7 +5,6 @@ import { useTheme } from "@mui/material/styles"; import maplibregl from "maplibre-gl"; import { useSelector } from "react-redux"; import buildStyle from "./buildStyle"; -import { ColContainer } from "../../../../../Components/StandardContainer"; const DistributedUptimeMap = ({ width = "100%", checks }) => { const mapContainer = useRef(null); @@ -29,12 +28,17 @@ const DistributedUptimeMap = ({ width = "100%", checks }) => { useEffect(() => { if (mapContainer.current && !map.current) { const initialStyle = buildStyle(initialTheme.current, initialMode.current); + map.current = new maplibregl.Map({ container: mapContainer.current, style: initialStyle, center: [0, 20], zoom: 0.8, attributionControl: false, + canvasContextAttributes: { + antialias: true, + preserveDrawingBuffer: true, + }, }); } map.current.on("load", () => { diff --git a/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx b/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx index c5a861fca..0e9b9bd20 100644 --- a/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx +++ b/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx @@ -4,19 +4,17 @@ import { Stack, Typography } from "@mui/material"; import PulseDot from "../../../../../Components/Animated/PulseDot"; import LastUpdate from "../LastUpdate"; import ChatBot from "../Chatbot"; +import ShareComponent from "../../../../../Components/ShareComponent"; // Utils import { useTheme } from "@emotion/react"; import PropTypes from "prop-types"; -const StatusHeader = ({ monitor, connectionStatus }) => { - console.log(monitor); - +const StatusHeader = ({ monitor, connectionStatus, elementToCapture }) => { const theme = useTheme(); - const COLOR_MAP = { - up: theme.palette.distributedStatusHeader.up, - down: theme.palette.distributedStatusHeader.down, + up: theme.palette.successSecondary.main, + down: theme.palette.error.lowContrast, }; const MSG_MAP = { @@ -35,43 +33,48 @@ const StatusHeader = ({ monitor, connectionStatus }) => { - - - - + + + - {MSG_MAP[connectionStatus]} - + + {MSG_MAP[connectionStatus]} + + + Uptime: {(monitor.totalUptime * 100).toFixed(2)}% + + - Uptime: {(monitor.totalUptime * 100).toFixed(2)}% + Last updated{" "} + - - Last updated{" "} - - + diff --git a/src/Pages/DistributedUptimeStatus/Status/index.jsx b/src/Pages/DistributedUptimeStatus/Status/index.jsx index a714f6976..a1c6b473f 100644 --- a/src/Pages/DistributedUptimeStatus/Status/index.jsx +++ b/src/Pages/DistributedUptimeStatus/Status/index.jsx @@ -19,7 +19,7 @@ import StatusHeader from "../../DistributedUptime/Details/Components/StatusHeade //Utils import { useTheme } from "@mui/material/styles"; -import { useState } from "react"; +import { useState, useRef } from "react"; import { useParams } from "react-router-dom"; import { useSubscribeToDetails } from "../../DistributedUptime/Details/Hooks/useSubscribeToDetails"; import { useStatusPageFetchByUrl } from "./Hooks/useStatusPageFetchByUrl"; @@ -31,6 +31,7 @@ const DistributedUptimeStatus = () => { const location = useLocation(); const isPublic = location.pathname.startsWith("/status/distributed/public"); + const elementToCapture = useRef(null); // Local State const [dateRange, setDateRange] = useState("day"); const [isDeleteOpen, setIsDeleteOpen] = useState(false); @@ -135,9 +136,12 @@ const DistributedUptimeStatus = () => { return ( {!isPublic && } { Date: Thu, 20 Feb 2025 15:20:17 -0800 Subject: [PATCH 6/6] add default filename, use monitor name for filename --- src/Components/ShareComponent/index.jsx | 2 +- .../Details/Components/StatusHeader/index.jsx | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Components/ShareComponent/index.jsx b/src/Components/ShareComponent/index.jsx index 9c52756f3..073ed2243 100644 --- a/src/Components/ShareComponent/index.jsx +++ b/src/Components/ShareComponent/index.jsx @@ -3,7 +3,7 @@ import ShareIcon from "@mui/icons-material/Share"; import { Button } from "@mui/material"; import { useTheme } from "@emotion/react"; -const ShareComponent = ({ elementToCapture, fileName }) => { +const ShareComponent = ({ elementToCapture, fileName = "screenshot" }) => { const theme = useTheme(); const captureAndShare = async () => { try { diff --git a/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx b/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx index 0e9b9bd20..5db44a559 100644 --- a/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx +++ b/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx @@ -74,7 +74,10 @@ const StatusHeader = ({ monitor, connectionStatus, elementToCapture }) => { - +