mirror of
				https://github.com/karl0ss/homepage.git
				synced 2025-11-04 08:20:58 +00:00 
			
		
		
		
	Feature: add category icons (#301)
* Update setting.yaml mapping * Implement adding icon to categoryTitle * Move resolveIcon func to utils for reusability * Turn off default export eslint rule * Fix util typo * Revert "Turn off default export eslint rule" This reverts commit e8dd853ba6fac1d33253667ffe9e02010a8dcfd6. * fix resolveIcon export * Revert "Update setting.yaml mapping" This reverts commit 78c947766951e14d1f6db290c0ab03ccc8f1ebc3. * Revert "Implement adding icon to categoryTitle" * Use settings layout for group icon * Revert "Fix util typo" This reverts commit ab49b426ec6d925d7938c3ddec753a0e7c8759af. * ResolvedIcon component Co-authored-by: Mindfreak9100 <dhoom_rik@yahoo.com> Co-authored-by: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									bfd4e7e890
								
							
						
					
					
						commit
						71faaa56dc
					
				@ -2,7 +2,7 @@ import { useTranslation } from "react-i18next";
 | 
				
			|||||||
import { useEffect, useState, useRef, useCallback, useContext } from "react";
 | 
					import { useEffect, useState, useRef, useCallback, useContext } from "react";
 | 
				
			||||||
import classNames from "classnames";
 | 
					import classNames from "classnames";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { resolveIcon } from "./services/item";
 | 
					import ResolvedIcon from "./resolvedicon";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { SettingsContext } from "utils/contexts/settings";
 | 
					import { SettingsContext } from "utils/contexts/settings";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -135,7 +135,7 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
 | 
				
			|||||||
                    )} onClick={handleItemClick}>
 | 
					                    )} onClick={handleItemClick}>
 | 
				
			||||||
                    <div className="flex flex-row items-center mr-4 pointer-events-none">
 | 
					                    <div className="flex flex-row items-center mr-4 pointer-events-none">
 | 
				
			||||||
                      <div className="w-5 text-xs mr-4">
 | 
					                      <div className="w-5 text-xs mr-4">
 | 
				
			||||||
                        {r.icon && resolveIcon(r.icon)}
 | 
					                        {r.icon && <ResolvedIcon icon={r.icon} />}
 | 
				
			||||||
                        {r.abbr && r.abbr}
 | 
					                        {r.abbr && r.abbr}
 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
                      <div className="flex flex-col md:flex-row text-left items-baseline mr-4 pointer-events-none">
 | 
					                      <div className="flex flex-col md:flex-row text-left items-baseline mr-4 pointer-events-none">
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										35
									
								
								src/components/resolvedicon.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/components/resolvedicon.jsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					import Image from "next/future/image";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function ResolvedIcon({ icon }) {
 | 
				
			||||||
 | 
					  // direct or relative URLs
 | 
				
			||||||
 | 
					  if (icon.startsWith("http") || icon.startsWith("/")) {
 | 
				
			||||||
 | 
					    return <Image src={`${icon}`} width={32} height={32} alt="logo" />;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // mdi- prefixed, material design icons
 | 
				
			||||||
 | 
					  if (icon.startsWith("mdi-")) {
 | 
				
			||||||
 | 
					    const iconName = icon.replace("mdi-", "").replace(".svg", "");
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        style={{
 | 
				
			||||||
 | 
					          width: 32,
 | 
				
			||||||
 | 
					          height: 32,
 | 
				
			||||||
 | 
					          background: "linear-gradient(180deg, rgb(var(--color-logo-start)), rgb(var(--color-logo-stop)))",
 | 
				
			||||||
 | 
					          mask: `url(https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/${iconName}.svg) no-repeat center / contain`,
 | 
				
			||||||
 | 
					          WebkitMask: `url(https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/${iconName}.svg) no-repeat center / contain`,
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // fallback to dashboard-icons
 | 
				
			||||||
 | 
					  const iconName = icon.replace(".png", "");
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Image
 | 
				
			||||||
 | 
					      src={`https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${iconName}.png`}
 | 
				
			||||||
 | 
					      width={32}
 | 
				
			||||||
 | 
					      height={32}
 | 
				
			||||||
 | 
					      alt="logo"
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
import classNames from "classnames";
 | 
					import classNames from "classnames";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import List from "components/services/list";
 | 
					import List from "components/services/list";
 | 
				
			||||||
 | 
					import ResolvedIcon from "components/resolvedicon";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function ServicesGroup({ services, layout }) {
 | 
					export default function ServicesGroup({ services, layout }) {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -11,7 +12,14 @@ export default function ServicesGroup({ services, layout }) {
 | 
				
			|||||||
        "flex-1 p-1"
 | 
					        "flex-1 p-1"
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{services.name}</h2>
 | 
					      <div className="flex select-none items-center">
 | 
				
			||||||
 | 
					        {layout?.icon &&
 | 
				
			||||||
 | 
					          <div className="flex-shrink-0 mr-2 w-7 h-7">
 | 
				
			||||||
 | 
					            <ResolvedIcon icon={layout.icon} />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        <h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{services.name}</h2>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
      <List services={services.services} layout={layout} />
 | 
					      <List services={services.services} layout={layout} />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
import Image from "next/future/image";
 | 
					 | 
				
			||||||
import classNames from "classnames";
 | 
					import classNames from "classnames";
 | 
				
			||||||
import { useContext, useState } from "react";
 | 
					import { useContext, useState } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -7,40 +6,7 @@ import Widget from "./widget";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import Docker from "widgets/docker/component";
 | 
					import Docker from "widgets/docker/component";
 | 
				
			||||||
import { SettingsContext } from "utils/contexts/settings";
 | 
					import { SettingsContext } from "utils/contexts/settings";
 | 
				
			||||||
 | 
					import ResolvedIcon from "components/resolvedicon";
 | 
				
			||||||
export function resolveIcon(icon) {
 | 
					 | 
				
			||||||
  // direct or relative URLs
 | 
					 | 
				
			||||||
  if (icon.startsWith("http") || icon.startsWith("/")) {
 | 
					 | 
				
			||||||
    return <Image src={`${icon}`} width={32} height={32} alt="logo" />;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // mdi- prefixed, material design icons
 | 
					 | 
				
			||||||
  if (icon.startsWith("mdi-")) {
 | 
					 | 
				
			||||||
    const iconName = icon.replace("mdi-", "").replace(".svg", "");
 | 
					 | 
				
			||||||
    return (
 | 
					 | 
				
			||||||
      <div
 | 
					 | 
				
			||||||
        style={{
 | 
					 | 
				
			||||||
          width: 32,
 | 
					 | 
				
			||||||
          height: 32,
 | 
					 | 
				
			||||||
          background: "linear-gradient(180deg, rgb(var(--color-logo-start)), rgb(var(--color-logo-stop)))",
 | 
					 | 
				
			||||||
          mask: `url(https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/${iconName}.svg) no-repeat center / contain`,
 | 
					 | 
				
			||||||
          WebkitMask: `url(https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/${iconName}.svg) no-repeat center / contain`,
 | 
					 | 
				
			||||||
        }}
 | 
					 | 
				
			||||||
      />
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // fallback to dashboard-icons
 | 
					 | 
				
			||||||
  const iconName = icon.replace(".png", "");
 | 
					 | 
				
			||||||
  return (
 | 
					 | 
				
			||||||
    <Image
 | 
					 | 
				
			||||||
      src={`https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${iconName}.png`}
 | 
					 | 
				
			||||||
      width={32}
 | 
					 | 
				
			||||||
      height={32}
 | 
					 | 
				
			||||||
      alt="logo"
 | 
					 | 
				
			||||||
    />
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Item({ service }) {
 | 
					export default function Item({ service }) {
 | 
				
			||||||
  const hasLink = service.href && service.href !== "#";
 | 
					  const hasLink = service.href && service.href !== "#";
 | 
				
			||||||
@ -75,10 +41,12 @@ export default function Item({ service }) {
 | 
				
			|||||||
                rel="noreferrer"
 | 
					                rel="noreferrer"
 | 
				
			||||||
                className="flex-shrink-0 flex items-center justify-center w-12 "
 | 
					                className="flex-shrink-0 flex items-center justify-center w-12 "
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                {resolveIcon(service.icon)}
 | 
					                <ResolvedIcon icon={service.icon} />
 | 
				
			||||||
              </a>
 | 
					              </a>
 | 
				
			||||||
            ) : (
 | 
					            ) : (
 | 
				
			||||||
              <div className="flex-shrink-0 flex items-center justify-center w-12 ">{resolveIcon(service.icon)}</div>
 | 
					              <div className="flex-shrink-0 flex items-center justify-center w-12 ">
 | 
				
			||||||
 | 
					                <ResolvedIcon icon={service.icon} />
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
            ))}
 | 
					            ))}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          {hasLink ? (
 | 
					          {hasLink ? (
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user