Ability to change title and icons

This commit is contained in:
Aimsucks
2022-06-07 00:07:56 +00:00
parent 7935fb6616
commit 6af5166aa5
7 changed files with 174 additions and 86 deletions

View File

@@ -0,0 +1,49 @@
import { TextInput, Group, Button } from '@mantine/core';
import { useState } from 'react';
import { useConfig } from '../../tools/state';
export default function TitleChanger() {
const { config, loadConfig, setConfig, getConfigs } = useConfig();
const [customTitle, setCustomTitle] = useState(config.title);
const [customLogo, setCustomLogo] = useState(config.logo);
const [customFavicon, setCustomFavicon] = useState(config.favicon);
const saveChanges = () => {
setConfig({
...config,
title: customTitle || "Homarr 🦞",
logo: customLogo || "/imgs/logo.png",
favicon: customFavicon || "/favicon.svg",
});
}
return (
<Group grow direction="column">
<TextInput
label="Page title"
defaultValue={config.title}
value={customTitle}
onChange={(event) => setCustomTitle(event.currentTarget.value)}
/>
<TextInput
label="Logo"
defaultValue={config.logo}
value={customLogo}
onChange={(event) => setCustomLogo(event.currentTarget.value)}
/>
<TextInput
label="Favicon"
defaultValue={config.favicon}
value={customFavicon}
onChange={(event) => setCustomFavicon(event.currentTarget.value)}
/>
<Button
variant="gradient"
gradient={{ from: 'red', to: 'orange' }}
onClick={() => saveChanges()}
>
Save
</Button>
</Group>
);
}

View File

@@ -8,6 +8,7 @@ import {
TextInput, TextInput,
Drawer, Drawer,
Anchor, Anchor,
Tabs
} from '@mantine/core'; } from '@mantine/core';
import { useColorScheme, useHotkeys } from '@mantine/hooks'; import { useColorScheme, useHotkeys } from '@mantine/hooks';
import { useState } from 'react'; import { useState } from 'react';
@@ -18,6 +19,7 @@ import { ColorSchemeSwitch } from '../ColorSchemeToggle/ColorSchemeSwitch';
import ConfigChanger from '../Config/ConfigChanger'; import ConfigChanger from '../Config/ConfigChanger';
import SaveConfigComponent from '../Config/SaveConfig'; import SaveConfigComponent from '../Config/SaveConfig';
import ModuleEnabler from './ModuleEnabler'; import ModuleEnabler from './ModuleEnabler';
import AdvancedSettings from './AdvancedSettings';
function SettingsMenu(props: any) { function SettingsMenu(props: any) {
const { config, setConfig } = useConfig(); const { config, setConfig } = useConfig();
@@ -37,95 +39,102 @@ function SettingsMenu(props: any) {
); );
return ( return (
<Group direction="column" grow> <Tabs>
<Group grow direction="column" spacing={0}> <Tabs.Tab label="Settings">
<Text>Search engine</Text> <Group direction="column" grow>
<SegmentedControl <Group grow direction="column" spacing={0}>
fullWidth <Text>Search engine</Text>
title="Search engine" <SegmentedControl
value={ fullWidth
// Match config.settings.searchUrl with a key in the matches array title="Search engine"
searchUrl value={
} // Match config.settings.searchUrl with a key in the matches array
onChange={ searchUrl
// Set config.settings.searchUrl to the value of the selected item }
(e) => { onChange={
setSearchUrl(e); // Set config.settings.searchUrl to the value of the selected item
setConfig({ (e) => {
...config, setSearchUrl(e);
settings: { setConfig({
...config.settings, ...config,
searchUrl: e, settings: {
}, ...config.settings,
}); searchUrl: e,
} },
} });
data={matches} }
/> }
{searchUrl === 'Custom' && ( data={matches}
<TextInput />
label="Query URL" {searchUrl === 'Custom' && (
placeholder="Custom query url" <TextInput
value={customSearchUrl} label="Query URL"
onChange={(event) => { placeholder="Custom query url"
setCustomSearchUrl(event.currentTarget.value); value={customSearchUrl}
setConfig({ onChange={(event) => {
...config, setCustomSearchUrl(event.currentTarget.value);
settings: { setConfig({
...config.settings, ...config,
searchUrl: event.currentTarget.value, settings: {
}, ...config.settings,
}); searchUrl: event.currentTarget.value,
}} },
/> });
)} }}
</Group> />
<ModuleEnabler /> )}
<ColorSchemeSwitch /> </Group>
<ConfigChanger /> <ModuleEnabler />
<SaveConfigComponent /> <ColorSchemeSwitch />
<Text <ConfigChanger />
style={{ <SaveConfigComponent />
alignSelf: 'center',
fontSize: '0.75rem',
textAlign: 'center',
color: 'gray',
}}
>
Tip: You can upload your config file by dragging and dropping it onto the page!
</Text>
<Group position="center" direction="row" mr="xs">
<Group spacing={0}>
<ActionIcon<'a'> component="a" href="https://github.com/ajnart/homarr" size="lg">
<BrandGithub size={18} />
</ActionIcon>
<Text <Text
style={{ style={{
position: 'relative', alignSelf: 'center',
fontSize: '0.90rem', fontSize: '0.75rem',
textAlign: 'center',
color: 'gray', color: 'gray',
}} }}
> >
{CURRENT_VERSION} Tip: You can upload your config file by dragging and dropping it onto the page!
</Text> </Text>
<Group position="center" direction="row" mr="xs">
<Group spacing={0}>
<ActionIcon<'a'> component="a" href="https://github.com/ajnart/homarr" size="lg">
<BrandGithub size={18} />
</ActionIcon>
<Text
style={{
position: 'relative',
fontSize: '0.90rem',
color: 'gray',
}}
>
{CURRENT_VERSION}
</Text>
</Group>
<Text
style={{
fontSize: '0.90rem',
textAlign: 'center',
color: 'gray',
}}
>
Made with by @
<Anchor
href="https://github.com/ajnart"
style={{ color: 'inherit', fontStyle: 'inherit', fontSize: 'inherit' }}
>
ajnart
</Anchor>
</Text>
</Group>
</Group> </Group>
<Text </Tabs.Tab>
style={{ <Tabs.Tab label="Advanced">
fontSize: '0.90rem', <AdvancedSettings />
textAlign: 'center', </Tabs.Tab>
color: 'gray', </Tabs>
}}
>
Made with by @
<Anchor
href="https://github.com/ajnart"
style={{ color: 'inherit', fontStyle: 'inherit', fontSize: 'inherit' }}
>
ajnart
</Anchor>
</Text>
</Group>
</Group>
); );
} }

View File

@@ -0,0 +1,14 @@
import React from 'react';
import Head from 'next/head';
import { useConfig } from '../../tools/state';
export function HeaderConfig(props: any) {
const { config } = useConfig();
return (
<Head>
<title>{config.title ?? "Homarr 🦞"}</title>
<link rel="shortcut icon" href={config.favicon ?? "/favicon.svg"} />
</Head>
);
}

View File

@@ -1,13 +1,16 @@
import { Group, Image, Text } from '@mantine/core'; import { Group, Image, Text } from '@mantine/core';
import { NextLink } from '@mantine/next'; import { NextLink } from '@mantine/next';
import * as React from 'react'; import * as React from 'react';
import { useConfig } from '../../tools/state';
export function Logo({ style }: any) { export function Logo({ style }: any) {
const { config } = useConfig();
return ( return (
<Group spacing="xs"> <Group spacing="xs">
<Image <Image
width={50} width={50}
src="/imgs/logo.png" src={config.logo ?? "/imgs/logo.png"}
style={{ style={{
position: 'relative', position: 'relative',
}} }}
@@ -25,7 +28,8 @@ export function Logo({ style }: any) {
variant="gradient" variant="gradient"
gradient={{ from: 'red', to: 'orange', deg: 145 }} gradient={{ from: 'red', to: 'orange', deg: 145 }}
> >
Homarr {/* Added the .replace to remove emojis because they get screwed up by the gradient */}
{config.title.replace(/([\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g, '') ?? "Homarr"}
</Text> </Text>
</NextLink> </NextLink>
</Group> </Group>

View File

@@ -10,6 +10,9 @@ export function getConfig(name: string) {
configName: name, configName: name,
config: { config: {
name: name.toString(), name: name.toString(),
title: 'Homarr 🦞',
logo: '/imgs/logo.png',
favicon: '/favicon.svg',
services: [], services: [],
settings: { settings: {
searchUrl: 'https://www.google.com/search?q=', searchUrl: 'https://www.google.com/search?q=',

View File

@@ -15,14 +15,17 @@ type configContextType = {
const configContext = createContext<configContextType>({ const configContext = createContext<configContextType>({
config: { config: {
name: 'default', name: 'default',
title: 'Homarr 🦞',
logo: '/imgs/logo.png',
favicon: '/favicon.svg',
services: [], services: [],
settings: { settings: {
searchUrl: 'https://google.com/search?q=', searchUrl: 'https://google.com/search?q=',
}, },
modules: {}, modules: {},
}, },
setConfig: () => {}, setConfig: () => { },
loadConfig: async (name: string) => {}, loadConfig: async (name: string) => { },
getConfigs: async () => [], getConfigs: async () => [],
}); });
@@ -41,6 +44,9 @@ type Props = {
export function ConfigProvider({ children }: Props) { export function ConfigProvider({ children }: Props) {
const [config, setConfigInternal] = useState<Config>({ const [config, setConfigInternal] = useState<Config>({
name: 'default', name: 'default',
title: 'Homarr 🦞',
logo: '/imgs/logo.png',
favicon: '/favicon.svg',
services: [], services: [],
settings: { settings: {
searchUrl: 'https://www.google.com/search?q=', searchUrl: 'https://www.google.com/search?q=',

View File

@@ -6,6 +6,9 @@ export interface Settings {
export interface Config { export interface Config {
name: string; name: string;
title: string;
logo: string;
favicon: string;
services: serviceItem[]; services: serviceItem[];
settings: Settings; settings: Settings;
modules: { modules: {