Merge branch 'main' into main

This commit is contained in:
shamoon 2022-10-08 13:20:09 -07:00 committed by GitHub
commit 1249ecaa68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 557 additions and 29 deletions

View file

@ -3,9 +3,11 @@ import List from "components/bookmarks/list";
export default function BookmarksGroup({ group }) {
return (
<div key={group.name} className="basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4 flex-1 p-1">
<div key={group.name} className="basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4 flex-1">
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{group.name}</h2>
<ErrorBoundary><List bookmarks={group.bookmarks} /></ErrorBoundary>
<ErrorBoundary>
<List bookmarks={group.bookmarks} />
</ErrorBoundary>
</div>
);
}

114
src/components/favicon.jsx Normal file
View file

@ -0,0 +1,114 @@
/* eslint-disable @next/next/no-img-element */
/* eslint-disable jsx-a11y/alt-text */
import { useRef, useEffect, useContext } from "react";
import themes from "utils/styles/themes";
import { ColorContext } from "utils/contexts/color";
export function Svg({ svgRef = null }) {
const { color } = useContext(ColorContext);
const { iconStart, iconEnd } = themes[color];
return (
<svg
ref={svgRef}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
style={{
enableBackground: "new 0 0 1024 1024",
}}
xmlSpace="preserve"
className="w-full h-full"
>
<style>
{
".st0{display:none}.st3{stroke-linecap:square}.st3,.st4{fill:none;stroke:#fff;stroke-miterlimit:10}.st6{display:inline;fill:#333}.st7{fill:#fff}"
}
</style>
<g id="Icon">
<path
d="M771.9 191c27.7 0 50.1 26.5 50.1 59.3v186.4l-100.2.3V250.3c0-32.8 22.4-59.3 50.1-59.3z"
style={{
fill: iconStart,
}}
/>
<linearGradient
id="homepage_favicon_gradient"
gradientUnits="userSpaceOnUse"
x1={200.746}
y1={225.015}
x2={764.986}
y2={789.255}
>
<stop
offset={0}
style={{
stopColor: iconStart,
}}
/>
<stop
offset={1}
style={{
stopColor: iconEnd,
}}
/>
</linearGradient>
<path
d="M721.8 250.3c0-32.7 22.4-59.3 50.1-59.3H253.1c-27.7 0-50.1 26.5-50.1 59.3v582.2l90.2-75.7-.1-130.3H375v61.8l88-73.8 258.8 217.9V250.6"
style={{
fill: "url(#homepage_favicon_gradient})",
}}
/>
</g>
</svg>
);
}
export default function Favicon() {
const svgRef = useRef();
const imgRef = useRef();
const canvasRef = useRef();
useEffect(() => {
const svg = svgRef.current;
const img = imgRef.current;
const canvas = canvasRef.current;
if (!svg || !img || !canvas) {
return;
}
const xml = new XMLSerializer().serializeToString(svg);
const svg64 = Buffer.from(xml).toString("base64");
const b64Start = "data:image/svg+xml;base64,";
// prepend a "header"
const image64 = b64Start + svg64;
// set it as the source of the img element
img.onload = () => {
// draw the image onto the canvas
canvas.getContext("2d").drawImage(img, 0, 0);
// canvas.width = 256;
// canvas.height = 256;
const link = window.document.createElement("link");
link.type = "image/x-icon";
link.rel = "shortcut icon";
link.href = canvas.toDataURL("image/x-icon");
document.getElementsByTagName("head")[0].appendChild(link);
};
img.src = image64;
}, []);
return (
<div className="hidden">
<Svg svgRef={svgRef} />
<img width={64} height={64} ref={imgRef} />
<canvas width={64} height={64} ref={canvasRef} />
</div>
);
}

View file

@ -0,0 +1,56 @@
export default function Logo() {
return (
<div className="w-12 h-12 flex flex-row items-center align-middle mr-3 self-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024"
style={{
enableBackground: "new 0 0 1024 1024",
}}
xmlSpace="preserve"
className="w-full h-full"
>
<style>
{
".st0{display:none}.st3{stroke-linecap:square}.st3,.st4{fill:none;stroke:#fff;stroke-miterlimit:10}.st6{display:inline;fill:#333}.st7{fill:#fff}"
}
</style>
<g id="Icon">
<path
d="M771.9 191c27.7 0 50.1 26.5 50.1 59.3v186.4l-100.2.3V250.3c0-32.8 22.4-59.3 50.1-59.3z"
style={{
fill: "rgba(var(--color-logo-start))",
}}
/>
<linearGradient
id="homepage_logo_gradient"
gradientUnits="userSpaceOnUse"
x1={200.746}
y1={225.015}
x2={764.986}
y2={789.255}
>
<stop
offset={0}
style={{
stopColor: "rgba(var(--color-logo-start))",
}}
/>
<stop
offset={1}
style={{
stopColor: "rgba(var(--color-logo-stop))",
}}
/>
</linearGradient>
<path
d="M721.8 250.3c0-32.7 22.4-59.3 50.1-59.3H253.1c-27.7 0-50.1 26.5-50.1 59.3v582.2l90.2-75.7-.1-130.3H375v61.8l88-73.8 258.8 217.9V250.6"
style={{
fill: "url(#homepage_logo_gradient)",
}}
/>
</g>
</svg>
</div>
);
}

View file

@ -16,9 +16,9 @@ function Widget({ options }) {
if (error || data?.cod === 401 || data?.error) {
return (
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-col justify-center first:ml-auto ml-4 mr-2">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<div className="hidden sm:flex flex-col items-center">
<BiError className="w-8 h-8 text-theme-800 dark:text-theme-200" />
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">{t("widget.api_error")}</span>
@ -32,9 +32,9 @@ function Widget({ options }) {
if (!data) {
return (
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-col justify-center first:ml-auto ml-4 mr-2">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<div className="hidden sm:flex flex-col items-center">
<WiCloudDown className="w-8 h-8 text-theme-800 dark:text-theme-200" />
</div>
<div className="flex flex-col ml-3 text-left">
@ -49,9 +49,9 @@ function Widget({ options }) {
const unit = options.units === "metric" ? "celsius" : "fahrenheit";
return (
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-col justify-center first:ml-auto ml-2 mr-2">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<div className="hidden sm:flex flex-col items-center">
<Icon
condition={data.weather[0].id}
timeOfDay={data.dt > data.sys.sunrise && data.dt < data.sys.sundown ? "day" : "night"}
@ -102,9 +102,13 @@ export default function OpenWeatherMap({ options }) {
if (!location) {
return (
<button type="button" onClick={() => requestLocation()} className="flex flex-col justify-center first:ml-0 ml-4">
<button
type="button"
onClick={() => requestLocation()}
className="flex flex-col justify-center first:ml-auto ml-4 mr-2"
>
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<div className="hidden sm:flex flex-col items-center">
{requesting ? (
<MdLocationSearching className="w-6 h-6 text-theme-800 dark:text-theme-200 animate-pulse" />
) : (

View file

@ -5,7 +5,7 @@ import Memory from "./memory";
export default function Resources({ options }) {
const { expanded } = options;
return (
<div className="flex flex-col max-w:full sm:basis-auto self-center m-auto flex-wrap">
<div className="flex flex-col max-w:full sm:basis-auto self-center grow-0 flex-wrap">
<div className="flex flex-row self-center flex-wrap justify-between">
{options.cpu && <Cpu expanded={expanded} />}
{options.memory && <Memory expanded={expanded} />}

View file

@ -56,7 +56,7 @@ export default function Search({ options }) {
}
return (
<form className="flex-col relative h-8 my-4 min-w-full md:min-w-fit grow first:ml-0 ml-4" onSubmit={handleSubmit}>
<form className="flex-col relative h-8 my-4 min-w-fit grow first:ml-0 ml-4" onSubmit={handleSubmit}>
<div className="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none w-full text-theme-800 dark:text-white" />
<input
type="text"

View file

@ -16,7 +16,7 @@ function Widget({ options }) {
if (error || data?.error) {
return (
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-col justify-center first:ml-0 ml-4 mr-2">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<BiError className="w-8 h-8 text-theme-800 dark:text-theme-200" />
@ -32,7 +32,7 @@ function Widget({ options }) {
if (!data) {
return (
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-col justify-center first:ml-0 ml-4 mr-2">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<WiCloudDown className="w-8 h-8 text-theme-800 dark:text-theme-200" />
@ -49,7 +49,7 @@ function Widget({ options }) {
const unit = options.units === "metric" ? "celsius" : "fahrenheit";
return (
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-col justify-center first:ml-0 ml-4 mr-2">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<Icon condition={data.current.condition.code} timeOfDay={data.current.is_day ? "day" : "night"} />
@ -103,7 +103,11 @@ export default function WeatherApi({ options }) {
if (!location) {
return (
<button type="button" onClick={() => requestLocation()} className="flex flex-col justify-center first:ml-0 ml-4">
<button
type="button"
onClick={() => requestLocation()}
className="flex flex-col justify-center first:ml-0 ml-4 mr-2"
>
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
{requesting ? (

View file

@ -9,6 +9,7 @@ const widgetMappings = {
search: dynamic(() => import("components/widgets/search/search")),
greeting: dynamic(() => import("components/widgets/greeting/greeting")),
datetime: dynamic(() => import("components/widgets/datetime/datetime")),
logo: dynamic(() => import("components/widgets/logo/logo"), { ssr: false }),
unifi_console: dynamic(() => import("components/widgets/unifi_console/unifi_console")),
};