🚀 🔖 Release v0.3.0
13
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -1,12 +1,13 @@
|
||||
name: ✨ Feature Request
|
||||
description: Request a feature to help improve Homarr!
|
||||
title: '<title>'
|
||||
labels: ['✨ Feature']
|
||||
body:
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: Description
|
||||
description: Describe the feature you would like to see. Tell us how you imagine it and try to provide as much usefull information as possible. **PLEASE** use images or drawings or anything to image your thoughts. Also please do not say "Like X and Y do" as we sometimes don't know what X and Y are.
|
||||
description: Describe the feature you would like to see. Tell us how you imagine it and try to provide as much useful information as possible. **PLEASE** use images/screenshots, include details about X & Y when requesting changes like X & Y service does, make your description atleast 300 characters. Having an unclear issue with too little detail will result in your issue being marked as invalid and closed.
|
||||
placeholder: An outline of the feature you would like to see implemented, include as much detail as possible!
|
||||
validations:
|
||||
required: true
|
||||
@@ -21,3 +22,13 @@ body:
|
||||
- High (App breaking feature)
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: idiot-check
|
||||
attributes:
|
||||
label: Please tick the boxes
|
||||
description: Before submitting, please ensure that
|
||||
options:
|
||||
- label: You've read the [docs](https://github.com/ajnart/homarr#readme)
|
||||
required: true
|
||||
- label: You've checked for [duplicate issues](https://github.com/ajnart/homarr/issues)
|
||||
required: true
|
||||
|
||||
23
.github/ISSUE_TEMPLATE/idea.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: 🤔 Idea
|
||||
description: Tell us your idea! We may implement it.
|
||||
title: '<title>'
|
||||
labels: ['🤔 Idea']
|
||||
body:
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: Description
|
||||
description: Tell us your idea! Please add as much details as possible.
|
||||
placeholder: Maybe move ... to ...! Maybe add the version of Homarr somewhere...! Etc.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: idiot-check
|
||||
attributes:
|
||||
label: Please tick the boxes
|
||||
description: Before submitting, please ensure that
|
||||
options:
|
||||
- label: You've read the [docs](https://github.com/ajnart/homarr#readme)
|
||||
required: true
|
||||
- label: You've checked for [duplicate issues](https://github.com/ajnart/homarr/issues)
|
||||
required: true
|
||||
26
.github/workflows/docker.yml
vendored
@@ -1,18 +1,24 @@
|
||||
name: Build and publish Docker image
|
||||
name: Master docker CI
|
||||
# Workflow to build and publish docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
IMAGE_NAME: homarr
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
# Push image to GitHub Packages.
|
||||
# See also https://docs.docker.com/docker-hub/builds/
|
||||
build:
|
||||
yarn_install_and_build:
|
||||
# Will run yarn install && yarn build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup
|
||||
@@ -20,9 +26,11 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Get yarn cache directory path
|
||||
# to help speed up build times
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: Yarn cache
|
||||
# to help speed up build times
|
||||
uses: actions/cache@v3
|
||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||
with:
|
||||
@@ -43,6 +51,7 @@ jobs:
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn build
|
||||
- name: Cache build output
|
||||
# to copy needed files to docker build job
|
||||
uses: actions/cache@v2
|
||||
id: restore-build
|
||||
with:
|
||||
@@ -52,11 +61,11 @@ jobs:
|
||||
./public/
|
||||
./.next/static/
|
||||
./.next/standalone/
|
||||
./packages.jsan
|
||||
./packages.json
|
||||
key: ${{ github.sha }}
|
||||
|
||||
docker:
|
||||
needs: [build]
|
||||
docker_image_build_and_push:
|
||||
needs: [yarn_install_and_build]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
@@ -73,14 +82,14 @@ jobs:
|
||||
./public/
|
||||
./.next/static/
|
||||
./.next/standalone/
|
||||
./packages.jsan
|
||||
./packages.json
|
||||
key: ${{ github.sha }}
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
# generate Docker tags based on the following events/attributes
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
@@ -90,7 +99,6 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
|
||||
116
.github/workflows/docker_dev.yml
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
name: Development CI
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
on:
|
||||
push:
|
||||
branches: [dev]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tags:
|
||||
requierd: true
|
||||
description: 'Tags to deploy to'
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
# Push image to GitHub Packages.
|
||||
# See also https://docs.docker.com/docker-hub/builds/
|
||||
yarn_install_and_build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup
|
||||
uses: actions/setup-node@v3
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: Yarn cache
|
||||
uses: actions/cache@v3
|
||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: ${{ runner.os }}-yarn-
|
||||
- name: Nextjs cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
# See here for caching with `yarn` https://github.com/actions/cache/blob/main/examples.md#node---yarn or you can leverage caching with actions/setup-node https://github.com/actions/setup-node
|
||||
path: |
|
||||
~/.npm
|
||||
${{ github.workspace }}/.next/cache
|
||||
# Generate a new cache whenever packages or source files change.
|
||||
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
|
||||
# If source files changed but packages didn't, rebuild from a prior cache.
|
||||
restore-keys: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn build
|
||||
- name: Cache build output
|
||||
uses: actions/cache@v2
|
||||
id: restore-build
|
||||
with:
|
||||
path: |
|
||||
./next.config.js
|
||||
./pages/
|
||||
./public/
|
||||
./.next/static/
|
||||
./.next/standalone/
|
||||
./packages.json
|
||||
key: ${{ github.sha }}
|
||||
|
||||
docker_image_build_and_push:
|
||||
needs: [yarn_install_and_build]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: restore-build
|
||||
with:
|
||||
path: |
|
||||
./next.config.js
|
||||
./pages/
|
||||
./public/
|
||||
./.next/static/
|
||||
./.next/standalone/
|
||||
./packages.json
|
||||
key: ${{ github.sha }}
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
# generate Docker tags based on the following events/attributes
|
||||
tags: |
|
||||
type=ref,event=pr
|
||||
tpye=raw,value=dev,priority=1
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
stories: ['../components/**/*.story.mdx', '../components/**/*.story.*'],
|
||||
stories: ['../src/components/**/*.story.mdx', '../src/components/**/*.story.*'],
|
||||
addons: [
|
||||
'storybook-dark-mode',
|
||||
'@storybook/addon-links',
|
||||
|
||||
@@ -10,11 +10,10 @@ COPY /package.json ./package.json
|
||||
|
||||
# Automatically leverage output traces to reduce image size
|
||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||
COPY --chown=nextjs:nodejs /.next/standalone ./
|
||||
COPY --chown=nextjs:nodejs /.next/static ./.next/static
|
||||
COPY /.next/standalone ./
|
||||
COPY /.next/static ./.next/static
|
||||
|
||||
USER nextjs
|
||||
EXPOSE 7575
|
||||
ENV PORT 7575
|
||||
VOLUME /app/data/configs
|
||||
CMD ["node", "server.js"]
|
||||
CMD ["node", "server.js"]
|
||||
24
README.md
@@ -1,7 +1,17 @@
|
||||
|
||||
<h3 align="center">Homarr</h3>
|
||||
<br/>
|
||||
<p align="center">
|
||||
<a href="https://github.com/ajnart/homarr/actions/workflows/docker.yml">
|
||||
<img title="Docker CI Status" src="https://github.com/ajnart/homarr/actions/workflows/docker.yml/badge.svg" alt="CI Status"></a>
|
||||
<a href="https://github.com/ajnart/homarr/releases/latest">
|
||||
<img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/ajnart/homarr"></a>
|
||||
<a href="https://github.com/ajnart/homarr/pkgs/container/homarr">
|
||||
<img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/ajnart/homarr?label=Downloads%20"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<img align="end" width=500 src="https://user-images.githubusercontent.com/49837342/168315259-b778c816-10fe-44db-bd25-3eea6f31b233.png" />
|
||||
<a href="">
|
||||
<img align="end" width=600 src="https://user-images.githubusercontent.com/49837342/168315259-b778c816-10fe-44db-bd25-3eea6f31b233.png" />
|
||||
<a/>
|
||||
</p>
|
||||
<p align = "center">
|
||||
A homepage for <i>your</i> server.
|
||||
@@ -11,10 +21,11 @@
|
||||
<br />
|
||||
<i>Join the discord!</i>
|
||||
<br />
|
||||
<a href = "https://discord.gg/aCsmEV5RgA" > <img src="https://discordapp.com/api/guilds/972958686051962910/widget.png?style=shield" > </a>
|
||||
<a href = "https://discord.gg/aCsmEV5RgA" > <img title="Discord" src="https://discordapp.com/api/guilds/972958686051962910/widget.png?style=shield" > </a>
|
||||
<br/>
|
||||
<br/>
|
||||
</p>
|
||||
|
||||
|
||||
# 📃 Table of Contents
|
||||
- [📃 Table of Contents](#-table-of-contents)
|
||||
- [🚀 Getting Started](#-getting-started)
|
||||
@@ -34,11 +45,6 @@ Homarr is a simple and lightweight homepage for your server, that helps you easi
|
||||
|
||||
**[⤴️ Back to Top](#-table-of-contents)**
|
||||
|
||||
## 🐛 Known Issues
|
||||
|
||||
- Application cards not responsive https://github.com/ajnart/homarr/issues/47
|
||||
- Icon alignment out for specific icons https://github.com/ajnart/homarr/issues/82
|
||||
|
||||
## ⚡ Installation
|
||||
|
||||
### Deploying from Docker Image 🐳
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Text, AspectRatio, SimpleGrid, Card, Image, Group, Space } from '@mantine/core';
|
||||
import { useConfig } from '../../tools/state';
|
||||
import { serviceItem } from '../../tools/types';
|
||||
import AddItemShelfItem from './AddAppShelfItem';
|
||||
import { AppShelfItemWrapper } from './AppShelfItemWrapper';
|
||||
import AppShelfMenu from './AppShelfMenu';
|
||||
|
||||
const AppShelf = () => {
|
||||
const { config } = useConfig();
|
||||
|
||||
return (
|
||||
<SimpleGrid m="xl" cols={5} spacing="xl">
|
||||
{config.services.map((service) => (
|
||||
<AppShelfItem key={service.name} service={service} />
|
||||
))}
|
||||
<AddItemShelfItem />
|
||||
</SimpleGrid>
|
||||
);
|
||||
};
|
||||
|
||||
export function AppShelfItem(props: any) {
|
||||
const { service }: { service: serviceItem } = props;
|
||||
const [hovering, setHovering] = useState(false);
|
||||
return (
|
||||
<motion.div
|
||||
key={service.name}
|
||||
onHoverStart={() => {
|
||||
setHovering(true);
|
||||
}}
|
||||
onHoverEnd={() => {
|
||||
setHovering(false);
|
||||
}}
|
||||
>
|
||||
<AppShelfItemWrapper hovering={hovering}>
|
||||
<Card.Section>
|
||||
<Group position="apart" mx="lg">
|
||||
<Space />
|
||||
<Text
|
||||
// TODO: #1 Remove this hack to get the text to be centered.
|
||||
ml={15}
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
justifyItems: 'center',
|
||||
}}
|
||||
mt="sm"
|
||||
weight={500}
|
||||
>
|
||||
{service.name}
|
||||
</Text>
|
||||
<motion.div
|
||||
style={{
|
||||
alignSelf: 'flex-end',
|
||||
}}
|
||||
animate={{
|
||||
opacity: hovering ? 1 : 0,
|
||||
}}
|
||||
>
|
||||
<AppShelfMenu service={service} />
|
||||
</motion.div>
|
||||
</Group>
|
||||
</Card.Section>
|
||||
<Card.Section>
|
||||
<AspectRatio ratio={5 / 3} m="xl">
|
||||
<motion.i
|
||||
whileHover={{
|
||||
cursor: 'pointer',
|
||||
scale: 1.1,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
onClick={() => {
|
||||
window.open(service.url);
|
||||
}}
|
||||
style={{
|
||||
maxWidth: '50%',
|
||||
marginBottom: 10,
|
||||
}}
|
||||
src={service.icon}
|
||||
/>
|
||||
</motion.i>
|
||||
</AspectRatio>
|
||||
</Card.Section>
|
||||
</AppShelfItemWrapper>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AppShelf;
|
||||
@@ -1,7 +0,0 @@
|
||||
import { Welcome } from './Welcome';
|
||||
|
||||
export default {
|
||||
title: 'Welcome',
|
||||
};
|
||||
|
||||
export const Usage = () => <Welcome />;
|
||||
@@ -1,14 +0,0 @@
|
||||
import { createStyles } from '@mantine/core';
|
||||
|
||||
export default createStyles((theme) => ({
|
||||
title: {
|
||||
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
|
||||
fontSize: 100,
|
||||
fontWeight: 900,
|
||||
letterSpacing: -2,
|
||||
|
||||
[theme.fn.smallerThan('md')]: {
|
||||
fontSize: 50,
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -1,12 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { Welcome } from './Welcome';
|
||||
|
||||
describe('Welcome component', () => {
|
||||
it('has correct Next.js theming section link', () => {
|
||||
render(<Welcome />);
|
||||
expect(screen.getByText('this guide')).toHaveAttribute(
|
||||
'href',
|
||||
'https://mantine.dev/theming/next/'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,25 +0,0 @@
|
||||
import { Title, Text, Anchor } from '@mantine/core';
|
||||
import useStyles from './Welcome.styles';
|
||||
|
||||
export function Welcome() {
|
||||
const { classes } = useStyles();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title className={classes.title} align="center" mt={100}>
|
||||
Welcome to{' '}
|
||||
<Text inherit variant="gradient" component="span">
|
||||
Mantine
|
||||
</Text>
|
||||
</Title>
|
||||
<Text color="dimmed" align="center" size="lg" sx={{ maxWidth: 580 }} mx="auto" mt="xl">
|
||||
This starter Next.js project includes a minimal setup for server side rendering, if you want
|
||||
to learn more on Mantine + Next.js integration follow{' '}
|
||||
<Anchor href="https://mantine.dev/theming/next/" size="lg">
|
||||
this guide
|
||||
</Anchor>
|
||||
. To get started edit index.tsx file.
|
||||
</Text>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { Text } from '@mantine/core';
|
||||
import * as React from 'react';
|
||||
|
||||
export function Logo({ style }: any) {
|
||||
return (
|
||||
<Text
|
||||
sx={style}
|
||||
weight="bold"
|
||||
variant="gradient"
|
||||
gradient={{ from: 'red', to: 'orange', deg: 145 }}
|
||||
>
|
||||
Homarr
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
],
|
||||
"settings": {
|
||||
"searchBar": true,
|
||||
"searchUrl": "https://google.com/search?q=",
|
||||
"searchUrl": "https://duckduckgo.com/?q=",
|
||||
"enabledModules": []
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
export const REPO_URL = 'ajnart/homarr';
|
||||
export const CURRENT_VERSION = 'v0.2.0';
|
||||
export const CURRENT_VERSION = 'v0.3.0';
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
const nextJest = require('next/jest');
|
||||
|
||||
const createJestConfig = nextJest({
|
||||
dir: './',
|
||||
});
|
||||
|
||||
const customJestConfig = {
|
||||
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
|
||||
moduleNameMapper: {
|
||||
'^@/components/(.*)$': '<rootDir>/components/$1',
|
||||
'^@/pages/(.*)$': '<rootDir>/pages/$1',
|
||||
},
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
};
|
||||
|
||||
module.exports = createJestConfig(customJestConfig);
|
||||
@@ -1 +0,0 @@
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "homarr",
|
||||
"version": "0.1.6",
|
||||
"version": "0.3.0",
|
||||
"private": "false",
|
||||
"description": "Homarr - A homepage for your server.",
|
||||
"description": "Homarr - A homepage for your server.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ajnart/homarr"
|
||||
|
||||
BIN
public/favicon.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 14 KiB |
BIN
public/imgs/favicon.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
1
public/imgs/logo-color.svg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/imgs/logo.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
247
public/imgs/logo.svg
Normal file
@@ -0,0 +1,247 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1000.000000pt" height="1000.000000pt" viewBox="0 0 1000.000000 1000.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,1000.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M6470 9752 c-179 -11 -423 -57 -605 -113 -94 -29 -116 -37 -212 -73
|
||||
-381 -144 -693 -333 -1030 -621 -6 -5 -63 -61 -126 -123 l-114 -113 -179 88
|
||||
c-223 110 -305 143 -386 158 -12 3 -34 8 -48 11 -14 3 -100 8 -191 10 -154 4
|
||||
-171 3 -253 -21 -159 -46 -241 -93 -355 -201 -55 -53 -101 -100 -101 -104 0
|
||||
-10 76 18 110 41 39 26 206 108 253 124 61 20 202 42 294 44 56 1 105 -6 178
|
||||
-24 55 -15 110 -28 122 -31 76 -15 317 -112 410 -165 l52 -30 -78 -97 c-152
|
||||
-190 -244 -324 -230 -333 8 -5 17 -9 20 -9 4 0 12 -13 19 -30 18 -44 5 -139
|
||||
-39 -269 -20 -62 -34 -114 -31 -116 4 -2 24 14 45 35 22 22 43 40 49 40 5 0
|
||||
23 -10 40 -23 56 -42 210 -135 276 -167 36 -17 72 -35 80 -39 37 -20 139 -43
|
||||
187 -43 35 0 64 6 88 21 l36 21 57 -38 c31 -21 76 -46 100 -55 52 -21 149 -32
|
||||
188 -23 l28 7 -29 23 -29 24 54 34 c78 49 180 84 191 67 37 -57 119 -207 165
|
||||
-304 75 -157 122 -306 134 -421 16 -157 43 -193 152 -199 56 -4 62 -2 90 26
|
||||
29 29 30 33 25 89 -13 122 -191 536 -326 759 -53 87 -58 100 -41 102 6 1 13 2
|
||||
18 3 4 1 39 5 77 10 104 11 156 17 195 21 19 3 62 7 95 10 112 11 246 45 470
|
||||
120 370 124 716 314 905 497 278 269 418 532 380 714 l-12 58 -35 -43 c-48
|
||||
-57 -116 -90 -216 -102 -117 -15 -165 -29 -198 -56 -23 -19 -32 -22 -48 -14
|
||||
-51 27 -95 7 -160 -75 -30 -37 -60 -64 -73 -66 -13 -2 -50 2 -83 10 -79 17
|
||||
-112 10 -189 -43 -107 -73 -120 -78 -196 -70 -84 8 -97 2 -176 -82 -56 -59
|
||||
-63 -63 -94 -58 -18 3 -37 8 -41 11 -4 2 -25 7 -47 10 -37 5 -43 2 -111 -60
|
||||
l-71 -66 -65 0 c-90 0 -160 -28 -221 -90 -47 -47 -52 -50 -103 -50 -49 0 -57
|
||||
-3 -94 -41 -48 -47 -65 -57 -92 -53 -11 1 -39 6 -62 9 -29 4 -43 11 -43 21 0
|
||||
30 20 52 53 58 23 4 38 15 45 31 16 35 49 53 112 59 66 7 99 29 169 113 28 34
|
||||
60 67 72 73 11 6 55 14 97 16 84 5 91 9 133 71 20 29 40 45 65 52 35 10 47 9
|
||||
141 -10 61 -12 82 -4 163 65 57 49 103 62 173 52 41 -6 43 -5 85 44 68 79 92
|
||||
86 268 80 84 -3 113 9 175 75 95 100 156 119 227 73 44 -29 61 -28 110 6 57
|
||||
39 107 56 141 50 26 -6 38 1 92 49 72 66 120 79 184 53 21 -9 39 -15 40 -14 1
|
||||
2 9 14 18 28 51 75 -5 176 -155 283 -146 104 -224 134 -478 182 -61 11 -221
|
||||
34 -280 40 -69 8 -327 12 -400 7z"/>
|
||||
<path d="M8256 8794 c-3 -8 -3 -46 0 -82 4 -47 1 -86 -10 -128 -9 -34 -16 -93
|
||||
-16 -131 0 -44 -7 -92 -20 -128 -23 -66 -25 -108 -9 -186 9 -47 8 -60 -10
|
||||
-102 -26 -60 -26 -101 -1 -196 20 -74 20 -75 0 -145 -13 -48 -19 -102 -19
|
||||
-166 1 -135 -25 -322 -56 -403 -28 -75 -31 -112 -14 -185 13 -54 8 -78 -42
|
||||
-189 -23 -52 -23 -53 -5 -108 l17 -55 -35 -79 c-33 -71 -36 -87 -36 -168 0
|
||||
-122 -47 -273 -85 -273 -21 0 -19 21 14 138 17 57 32 131 36 165 3 34 17 104
|
||||
31 155 23 81 25 99 15 137 -17 67 -14 90 21 158 34 67 36 86 57 467 6 95 14
|
||||
160 25 190 19 49 15 93 -10 121 -15 16 -14 23 10 83 31 78 32 109 6 176 -27
|
||||
70 -25 89 15 146 40 56 46 111 19 189 -23 69 -21 113 9 188 26 62 27 74 21
|
||||
156 -6 80 -5 93 15 124 28 45 27 54 -10 73 -92 47 -184 -42 -338 -326 -161
|
||||
-298 -197 -386 -285 -705 -103 -375 -123 -584 -96 -1025 12 -204 25 -312 52
|
||||
-458 11 -62 18 -116 14 -119 -3 -3 -79 10 -168 30 -175 39 -357 74 -429 83
|
||||
-24 3 -51 7 -58 10 -24 8 -159 18 -241 19 l-75 0 -3 -81 c-4 -127 -9 -124 233
|
||||
-139 55 -3 111 -7 125 -10 14 -2 48 -6 77 -9 28 -3 77 -9 110 -15 32 -6 76
|
||||
-13 98 -16 22 -4 56 -10 75 -15 19 -5 51 -11 70 -14 47 -8 85 -15 148 -30 l32
|
||||
-8 0 -64 c0 -77 13 -110 75 -195 66 -90 81 -119 63 -130 -21 -14 -51 -10 -91
|
||||
11 -44 24 -45 20 -18 -71 45 -149 37 -167 -56 -132 -10 4 5 -19 34 -50 28 -32
|
||||
73 -92 99 -135 138 -222 189 -263 378 -302 107 -22 170 -49 187 -82 13 -23 14
|
||||
-73 3 -120 -5 -25 -3 -28 21 -28 34 0 52 10 136 75 73 56 115 70 181 60 68
|
||||
-11 138 46 104 84 -20 22 -21 18 62 191 35 74 80 183 100 242 l35 107 56 -40
|
||||
c74 -53 164 -142 201 -199 91 -142 192 -648 151 -754 -19 -47 -5 -41 24 11 58
|
||||
105 70 156 69 308 -1 121 -5 152 -27 226 -32 107 -94 250 -142 329 -45 75
|
||||
-166 204 -234 250 -28 19 -51 39 -51 44 0 5 29 99 65 210 35 111 73 235 84
|
||||
276 30 112 75 399 86 550 4 47 9 99 11 115 8 66 4 496 -6 593 -32 335 -162
|
||||
788 -297 1042 -130 243 -283 386 -487 456 -82 28 -82 28 -90 8z"/>
|
||||
<path d="M6300 7695 c-1 -143 -35 -481 -66 -659 -49 -276 -106 -466 -195 -644
|
||||
-56 -112 -56 -113 -35 -127 41 -29 54 -19 102 76 149 298 211 539 229 904 7
|
||||
142 -10 484 -25 499 -7 7 -10 -12 -10 -49z"/>
|
||||
<path d="M4095 7698 c-3 -7 -6 -56 -7 -108 -3 -89 -4 -95 -23 -92 -11 2 -35
|
||||
19 -52 39 -18 20 -34 34 -34 32 -1 -2 -3 -33 -4 -69 -4 -82 -13 -153 -27 -207
|
||||
l-10 -43 -46 40 c-24 22 -48 40 -52 40 -11 0 -24 -221 -17 -309 6 -83 37 -178
|
||||
66 -205 73 -66 245 -71 421 -12 58 19 130 45 160 56 30 12 69 26 86 31 31 9
|
||||
31 10 36 87 3 56 12 94 33 140 15 34 25 65 22 68 -3 4 -18 7 -32 7 -40 0 -35
|
||||
14 50 133 59 81 99 160 91 180 -3 8 -44 13 -123 17 -65 2 -127 7 -138 10 -127
|
||||
33 -204 66 -321 137 -74 45 -73 45 -79 28z"/>
|
||||
<path d="M3450 7544 c-123 -70 -410 -433 -412 -522 -2 -71 84 -177 137 -170
|
||||
19 3 41 40 96 158 9 19 31 61 48 93 22 38 36 81 42 127 10 68 62 184 136 303
|
||||
28 44 16 47 -47 11z"/>
|
||||
<path d="M4972 7109 c-21 -6 -32 -15 -29 -23 3 -6 13 -40 22 -75 17 -60 19
|
||||
-62 46 -56 15 3 45 2 66 -4 90 -23 132 -20 98 9 -33 28 -15 32 98 26 109 -7
|
||||
226 -20 273 -32 22 -6 24 -4 18 27 -4 19 -9 37 -13 41 -7 8 -256 73 -316 82
|
||||
-71 12 -229 14 -263 5z"/>
|
||||
<path d="M4810 7085 c-36 -7 -81 -18 -100 -24 -67 -21 -66 -18 -35 -135 15
|
||||
-58 33 -106 38 -106 14 0 135 68 142 80 3 5 26 12 50 16 25 3 45 8 45 11 0 3
|
||||
-6 31 -14 62 -8 31 -17 68 -20 84 -7 30 -9 31 -106 12z"/>
|
||||
<path d="M7315 6989 c-227 -53 -672 -275 -915 -457 -73 -55 -231 -196 -284
|
||||
-252 l-48 -53 26 -25 25 -25 83 84 c119 121 227 202 478 361 113 72 265 152
|
||||
437 232 216 100 260 123 268 136 7 12 -15 11 -70 -1z"/>
|
||||
<path d="M2974 6954 c-7 -29 1 -307 14 -484 10 -129 25 -174 70 -212 48 -40
|
||||
97 -53 127 -34 13 9 29 25 35 37 20 37 22 160 6 313 -9 82 -16 172 -16 202 l0
|
||||
53 -30 -9 c-17 -5 -33 -9 -35 -10 -32 -5 -130 93 -140 141 -8 36 -23 37 -31 3z"/>
|
||||
<path d="M2484 6858 c-73 -124 -162 -305 -184 -376 -24 -78 -17 -102 47 -142
|
||||
57 -36 90 -39 103 -7 17 41 49 232 59 359 6 69 13 131 16 139 11 30 22 109 15
|
||||
109 -4 0 -29 -37 -56 -82z"/>
|
||||
<path d="M4563 6824 c-64 -39 -317 -95 -423 -94 -96 0 -119 4 -180 25 l-42 15
|
||||
7 -28 c8 -32 34 -67 105 -142 28 -30 77 -84 108 -120 30 -36 89 -100 131 -142
|
||||
l76 -78 -63 0 c-34 0 -62 -3 -62 -7 0 -32 78 -102 230 -208 47 -33 135 -96
|
||||
195 -141 61 -44 120 -86 133 -93 29 -16 50 -4 127 69 33 31 80 70 105 86 25
|
||||
16 47 31 50 35 5 6 110 66 185 106 85 45 76 75 -57 189 -57 48 -208 192 -336
|
||||
318 -127 127 -235 232 -240 233 -4 1 -26 -9 -49 -23z"/>
|
||||
<path d="M5840 6684 c-30 -8 -82 -14 -115 -13 -33 0 -66 0 -73 0 -10 -1 -12
|
||||
-21 -10 -82 3 -75 5 -84 29 -101 49 -37 193 -36 216 1 14 23 29 211 17 210 -5
|
||||
-1 -34 -7 -64 -15z"/>
|
||||
<path d="M3914 6633 c-49 -114 -125 -336 -135 -397 -15 -86 -7 -135 27 -175
|
||||
46 -55 140 -50 163 7 5 15 11 59 13 97 3 56 13 91 51 179 26 60 47 114 47 122
|
||||
0 7 -20 36 -45 64 -25 28 -54 68 -65 90 -28 54 -37 56 -56 13z"/>
|
||||
<path d="M5620 6407 c-12 -34 -36 -88 -53 -120 -16 -31 -28 -60 -25 -62 3 -3
|
||||
41 3 84 13 43 11 112 20 153 21 41 1 78 4 81 6 4 3 10 30 14 60 3 31 13 72 21
|
||||
92 14 33 14 35 -3 28 -9 -4 -51 -9 -92 -11 -57 -2 -85 1 -117 16 l-41 18 -22
|
||||
-61z"/>
|
||||
<path d="M2257 6308 c7 -119 45 -313 89 -448 54 -167 71 -198 116 -202 42 -4
|
||||
98 9 120 29 22 20 19 36 -48 243 -61 190 -84 277 -84 314 0 17 -7 29 -17 32
|
||||
-46 15 -100 41 -134 66 -22 16 -40 28 -42 28 -2 0 -2 -28 0 -62z"/>
|
||||
<path d="M5935 6220 c-31 -44 -212 -222 -264 -259 -54 -38 -24 2 65 89 91 89
|
||||
149 158 141 167 -7 6 -266 -22 -357 -39 -225 -42 -501 -216 -745 -470 -199
|
||||
-206 -250 -272 -266 -349 -32 -150 60 -415 211 -604 152 -190 373 -343 525
|
||||
-361 161 -19 456 6 511 43 23 16 231 377 296 513 36 76 104 281 153 464 35
|
||||
128 30 177 -34 351 -69 185 -71 193 -71 248 0 44 -2 48 -16 36 -24 -20 -69
|
||||
-114 -108 -229 -43 -124 -64 -154 -35 -49 33 121 103 284 150 351 11 14 19 30
|
||||
19 35 0 5 -25 24 -55 42 -30 18 -59 39 -66 47 -17 21 -24 18 -54 -26z"/>
|
||||
<path d="M6446 6230 c-44 -16 -83 -35 -88 -42 -9 -14 -2 -158 11 -204 12 -45
|
||||
34 -52 78 -23 21 14 50 33 66 43 l27 17 -1 119 c0 66 -4 120 -7 119 -4 0 -43
|
||||
-13 -86 -29z"/>
|
||||
<path d="M3010 6219 c0 -59 289 -869 310 -869 4 0 14 24 20 53 25 105 54 140
|
||||
113 133 20 -2 37 -3 37 -1 0 1 -24 70 -54 152 -30 83 -83 241 -119 351 l-63
|
||||
200 -28 -34 c-23 -30 -33 -34 -72 -34 -53 0 -108 23 -129 54 -15 20 -15 20
|
||||
-15 -5z"/>
|
||||
<path d="M6244 6124 c-99 -79 -102 -86 -80 -181 10 -43 30 -114 43 -157 25
|
||||
-80 25 -80 38 -50 7 16 36 60 64 99 42 56 51 74 46 95 -4 14 -12 73 -19 133
|
||||
-7 59 -15 109 -17 112 -3 2 -36 -20 -75 -51z"/>
|
||||
<path d="M3980 6022 c0 -6 -14 -19 -32 -28 -32 -16 -118 -16 -161 1 -12 5 12
|
||||
-54 79 -191 53 -110 143 -298 201 -419 57 -121 111 -227 119 -235 13 -13 18
|
||||
-11 41 20 15 19 50 59 80 88 29 29 53 57 53 63 0 6 -63 122 -139 257 -77 136
|
||||
-162 294 -190 351 -28 57 -51 99 -51 93z"/>
|
||||
<path d="M6710 5911 c0 -5 20 -53 44 -107 73 -168 156 -442 156 -520 0 -45 4
|
||||
-55 27 -74 30 -23 30 -23 118 14 33 13 76 26 95 28 31 4 35 8 38 38 6 62 -52
|
||||
170 -92 170 -12 0 -14 -5 -6 -25 10 -25 4 -55 -10 -55 -4 0 -17 30 -29 68 -34
|
||||
105 -161 299 -270 415 -51 54 -71 68 -71 48z"/>
|
||||
<path d="M2571 5645 c-46 -37 -105 -47 -129 -23 -24 24 -11 -5 45 -100 127
|
||||
-218 184 -296 292 -402 58 -58 138 -126 176 -152 l70 -46 5 53 c5 56 23 85 72
|
||||
115 l28 17 -55 37 c-69 48 -253 262 -405 473 -25 34 -47 63 -50 63 -3 0 -25
|
||||
-16 -49 -35z"/>
|
||||
<path d="M3451 5493 c-38 -19 -78 -74 -87 -121 -6 -27 0 -40 35 -86 81 -105
|
||||
479 -476 511 -476 6 0 122 145 128 159 7 19 -301 349 -441 473 -42 37 -85 68
|
||||
-95 68 -9 0 -32 -8 -51 -17z"/>
|
||||
<path d="M6261 5478 c-5 -18 -26 -95 -46 -172 -43 -164 -75 -256 -122 -350
|
||||
-19 -37 -33 -69 -31 -70 87 -59 168 -125 365 -303 50 -44 100 -86 112 -92 18
|
||||
-10 21 -9 21 9 0 11 -9 38 -20 60 -35 69 -24 89 27 46 15 -13 96 -70 178 -127
|
||||
152 -105 292 -181 354 -193 l33 -6 -16 25 c-76 115 -126 250 -166 440 -12 61
|
||||
-31 146 -41 190 l-18 80 -88 83 c-47 46 -159 137 -247 203 -89 65 -187 139
|
||||
-218 164 -32 25 -59 45 -62 45 -2 0 -9 -15 -15 -32z"/>
|
||||
<path d="M4348 5238 c-144 -142 -397 -435 -508 -588 -30 -41 -57 -77 -61 -80
|
||||
-3 -3 -47 -66 -96 -140 -171 -258 -272 -462 -317 -640 -15 -63 -15 -69 5 -140
|
||||
25 -90 96 -235 155 -315 75 -101 203 -224 329 -313 233 -166 540 -300 669
|
||||
-293 26 1 149 124 355 352 192 213 185 205 287 334 298 379 438 604 535 862
|
||||
22 57 39 106 39 108 0 3 -10 0 -22 -6 -59 -31 -124 -39 -318 -35 -214 4 -266
|
||||
13 -379 68 -226 110 -420 341 -526 628 -25 66 -28 90 -29 192 -1 65 -2 118 -2
|
||||
118 -1 0 -53 -51 -116 -112z"/>
|
||||
<path d="M7119 5202 c-40 -20 -88 -35 -123 -39 l-58 -6 6 -30 c3 -16 6 -54 6
|
||||
-83 0 -70 22 -84 90 -59 25 9 71 25 103 34 32 9 62 23 66 29 8 13 -4 139 -17
|
||||
169 -6 17 -12 16 -73 -15z"/>
|
||||
<path d="M7547 5062 c-107 -101 -138 -112 -183 -67 -19 19 -25 35 -24 63 1 20
|
||||
2 41 1 45 -1 5 -19 -14 -41 -42 -25 -31 -60 -61 -91 -77 -55 -27 -60 -29 -159
|
||||
-49 -63 -13 -90 -32 -90 -64 0 -75 49 -233 138 -441 53 -125 57 -130 106 -130
|
||||
22 0 68 7 101 14 33 8 105 17 160 20 55 4 108 9 118 12 16 5 16 7 -3 31 -13
|
||||
17 -17 30 -11 36 5 5 76 16 158 24 81 7 159 16 173 19 l25 6 -22 18 c-13 10
|
||||
-23 22 -23 27 0 4 63 8 139 8 124 0 181 9 143 22 -31 11 -107 70 -110 84 -2
|
||||
10 16 31 46 53 28 20 53 43 56 51 17 46 -45 76 -176 85 -80 6 -105 12 -145 35
|
||||
-71 41 -115 93 -163 189 -23 47 -46 86 -52 86 -5 0 -37 -26 -71 -58z"/>
|
||||
<path d="M3110 5050 c-30 -32 -60 -89 -60 -113 0 -30 218 -189 335 -245 28
|
||||
-13 70 -34 95 -45 25 -12 83 -46 129 -76 l83 -54 19 24 c38 49 99 140 99 148
|
||||
0 7 -271 201 -294 210 -6 2 -38 23 -71 47 -94 65 -234 134 -273 134 -25 0 -41
|
||||
-8 -62 -30z"/>
|
||||
<path d="M6768 4376 c-23 -32 -125 -100 -168 -114 -19 -5 -61 -13 -94 -16 -32
|
||||
-4 -66 -11 -77 -16 -18 -10 -17 -11 3 -45 16 -29 19 -47 16 -93 -3 -31 -9 -65
|
||||
-13 -76 -8 -18 -4 -18 61 -11 90 9 200 47 272 92 31 20 91 69 132 111 69 68
|
||||
73 75 56 86 -11 6 -48 30 -84 54 -82 56 -84 56 -104 28z"/>
|
||||
<path d="M7617 4137 l-168 -258 19 -42 c29 -64 55 -82 118 -81 64 0 107 30
|
||||
167 114 45 64 47 78 8 51 -59 -42 -69 -12 -20 62 37 57 51 147 47 306 l-3 105
|
||||
-168 -257z"/>
|
||||
<path d="M5727 4246 c-18 -28 -87 -175 -87 -186 0 -10 16 -15 90 -29 142 -26
|
||||
251 -34 442 -35 240 -1 239 -2 245 86 5 62 -18 117 -57 135 -14 6 -63 14 -110
|
||||
18 -47 4 -98 9 -115 10 -39 4 -264 17 -337 20 -49 2 -60 -1 -71 -19z"/>
|
||||
<path d="M7380 3778 c-132 -121 -284 -208 -435 -248 -44 -12 -84 -26 -89 -31
|
||||
-12 -11 56 -94 103 -124 51 -34 83 -37 155 -15 61 19 75 27 181 101 28 19 86
|
||||
56 130 82 57 34 95 66 133 112 28 35 52 66 52 69 0 4 -18 3 -39 0 -51 -8 -98
|
||||
18 -120 68 l-16 36 -55 -50z"/>
|
||||
<path d="M5472 3742 c-73 -100 -95 -133 -91 -136 11 -10 139 -84 169 -98 83
|
||||
-39 250 -94 340 -113 8 -2 54 -12 101 -24 99 -24 102 -24 94 -11 -3 5 5 31 19
|
||||
57 23 45 32 58 91 124 l23 27 -96 36 c-272 104 -445 166 -472 171 -16 3 -40 9
|
||||
-54 15 -15 5 -26 7 -26 5 0 -2 -11 0 -24 5 -23 8 -29 3 -74 -58z"/>
|
||||
<path d="M3247 3598 c-86 -146 -197 -363 -197 -384 0 -31 93 -210 170 -329
|
||||
111 -171 289 -335 485 -450 61 -36 171 -90 205 -100 14 -4 30 -12 37 -17 6 -5
|
||||
34 -12 60 -15 l49 -5 175 150 c194 167 261 232 239 233 -16 1 -36 4 -90 15
|
||||
-19 4 -40 8 -47 10 -15 3 -103 30 -168 51 -27 9 -66 26 -85 37 -38 22 -192
|
||||
127 -200 136 -3 3 -36 31 -75 62 -150 119 -296 276 -368 395 -21 34 -59 116
|
||||
-86 183 l-48 122 -56 -94z"/>
|
||||
<path d="M6223 3515 c-36 -15 -91 -77 -99 -112 -9 -34 5 -72 36 -94 79 -58
|
||||
450 -92 655 -60 86 13 205 49 205 63 0 5 -4 7 -8 4 -5 -3 -31 5 -58 18 -57 26
|
||||
-130 103 -139 147 -4 16 -10 27 -14 25 -26 -16 -282 -25 -341 -12 -140 31
|
||||
-200 36 -237 21z"/>
|
||||
<path d="M5280 3493 c0 -4 -13 -24 -29 -43 -124 -152 -122 -149 -103 -167 10
|
||||
-10 60 -58 112 -107 52 -50 145 -138 205 -196 169 -162 200 -185 252 -185 39
|
||||
0 49 5 79 37 19 22 34 48 34 62 0 55 -269 393 -388 487 -94 75 -162 122 -162
|
||||
112z"/>
|
||||
<path d="M7664 3103 c-32 -43 -63 -83 -68 -89 -6 -6 -29 -31 -51 -55 -63 -68
|
||||
-155 -144 -205 -169 -113 -56 -129 -89 -73 -151 19 -21 51 -48 70 -60 l34 -21
|
||||
22 20 c12 11 39 25 59 31 32 11 108 79 108 98 0 4 -5 2 -12 -5 -18 -18 -38
|
||||
-15 -38 6 0 10 34 69 75 132 74 113 127 229 138 303 3 20 4 37 2 37 -2 0 -30
|
||||
-35 -61 -77z"/>
|
||||
<path d="M2978 3107 c-21 -34 -53 -87 -73 -116 -66 -103 -66 -103 10 -253 37
|
||||
-73 93 -169 124 -212 69 -96 201 -232 279 -284 125 -86 361 -182 444 -182 15
|
||||
0 47 16 75 36 53 40 173 154 173 166 0 3 -26 12 -57 18 -159 33 -220 63 -387
|
||||
189 -235 178 -341 305 -483 576 -35 69 -65 125 -66 125 -1 0 -19 -28 -39 -63z"/>
|
||||
<path d="M5845 2923 c28 -66 6 -126 -53 -142 -20 -6 -43 -11 -51 -11 -25 0 7
|
||||
-27 125 -106 208 -138 505 -293 577 -301 57 -7 65 7 28 50 -35 39 -53 80 -45
|
||||
101 3 8 21 20 41 27 20 6 39 21 45 35 13 28 4 42 -32 49 -44 8 -95 28 -145 55
|
||||
-90 49 -178 96 -320 170 -77 40 -144 77 -149 81 -17 15 -29 10 -21 -8z"/>
|
||||
<path d="M2810 2819 c0 -6 -41 -92 -91 -192 l-90 -182 80 -160 c44 -88 100
|
||||
-186 125 -217 98 -123 325 -272 503 -329 71 -22 72 -22 115 -4 28 13 87 63
|
||||
172 149 l130 130 -55 11 c-174 36 -347 131 -537 295 -107 92 -167 175 -260
|
||||
357 -70 139 -92 173 -92 142z"/>
|
||||
<path d="M7160 2680 c-33 -16 -114 -36 -305 -74 -88 -18 -270 -25 -297 -12
|
||||
-15 7 -18 3 -18 -20 0 -39 -12 -56 -51 -68 -18 -6 -34 -17 -37 -24 -6 -18 66
|
||||
-83 122 -111 55 -27 122 -24 310 13 321 64 429 96 464 139 11 12 7 16 -20 21
|
||||
-57 12 -118 81 -118 136 0 23 -4 24 -50 0z"/>
|
||||
<path d="M2517 2261 c-49 -79 -87 -151 -87 -165 0 -136 113 -336 251 -444 112
|
||||
-88 271 -171 355 -186 16 -3 40 -8 54 -11 106 -21 112 -20 169 31 29 26 75 80
|
||||
103 118 l50 71 -29 3 c-128 12 -337 119 -478 245 -87 78 -147 164 -231 334
|
||||
l-70 144 -87 -140z"/>
|
||||
<path d="M1575 2228 c-31 -18 -52 -48 -91 -126 -55 -113 -65 -150 -71 -254
|
||||
-10 -168 27 -325 92 -394 30 -31 38 -35 65 -29 71 16 287 113 626 281 l251
|
||||
125 -24 87 c-59 212 -46 189 -106 201 -28 6 -65 13 -82 16 -28 5 -46 8 -105
|
||||
20 -14 2 -41 7 -60 10 -19 3 -71 12 -115 20 -44 8 -96 17 -115 20 -19 3 -46 7
|
||||
-60 10 -117 21 -185 25 -205 13z"/>
|
||||
<path d="M2365 1759 c-44 -21 -168 -81 -275 -133 -240 -116 -441 -226 -497
|
||||
-272 l-42 -34 15 -53 c21 -69 86 -190 145 -269 96 -128 273 -278 329 -278 27
|
||||
0 34 8 165 175 52 66 277 383 375 529 l91 136 -102 120 c-56 66 -107 120 -113
|
||||
119 -6 0 -47 -18 -91 -40z"/>
|
||||
<path d="M2635 1413 c-44 -60 -136 -187 -205 -283 -69 -96 -147 -204 -172
|
||||
-240 -26 -36 -58 -79 -71 -95 -14 -17 -35 -47 -47 -68 -31 -53 -16 -84 71
|
||||
-147 96 -70 184 -113 294 -145 309 -90 341 -79 360 120 7 71 65 426 111 673
|
||||
13 73 24 140 24 148 0 8 -24 25 -52 38 -29 13 -92 42 -140 65 -48 22 -88 41
|
||||
-90 41 -2 0 -39 -48 -83 -107z"/>
|
||||
<path d="M3130 1390 c-14 -4 -39 -8 -57 -9 -17 -1 -34 -5 -37 -10 -22 -36
|
||||
-127 -689 -133 -833 -7 -162 -9 -160 106 -157 47 2 100 6 116 10 17 4 44 10
|
||||
60 12 86 13 298 79 368 114 66 33 74 54 47 134 -29 88 -159 348 -283 564 -95
|
||||
166 -105 180 -133 182 -16 1 -40 -2 -54 -7z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
@@ -10,6 +10,8 @@ import {
|
||||
Text,
|
||||
Card,
|
||||
LoadingOverlay,
|
||||
ActionIcon,
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { motion } from 'framer-motion';
|
||||
@@ -19,13 +21,42 @@ import { useConfig } from '../../tools/state';
|
||||
import { ServiceTypeList } from '../../tools/types';
|
||||
import { AppShelfItemWrapper } from './AppShelfItemWrapper';
|
||||
|
||||
export function AddItemShelfButton(props: any) {
|
||||
const [opened, setOpened] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
size="xl"
|
||||
radius="md"
|
||||
opened={props.opened || opened}
|
||||
onClose={() => setOpened(false)}
|
||||
title="Add a service"
|
||||
>
|
||||
<AddAppShelfItemForm setOpened={setOpened} />
|
||||
</Modal>
|
||||
<ActionIcon
|
||||
variant="default"
|
||||
radius="md"
|
||||
size="xl"
|
||||
color="blue"
|
||||
style={props.style}
|
||||
onClick={() => setOpened(true)}
|
||||
>
|
||||
<Tooltip label="Add a service">
|
||||
<Apps />
|
||||
</Tooltip>
|
||||
</ActionIcon>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AddItemShelfItem(props: any) {
|
||||
const [opened, setOpened] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
size="xl"
|
||||
radius="lg"
|
||||
radius="md"
|
||||
opened={props.opened || opened}
|
||||
onClose={() => setOpened(false)}
|
||||
title="Add a service"
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SimpleGrid } from '@mantine/core';
|
||||
import AppShelf, { AppShelfItem } from './AppShelf';
|
||||
|
||||
export default {
|
||||
@@ -16,3 +17,10 @@ export default {
|
||||
|
||||
export const Default = (args: any) => <AppShelf {...args} />;
|
||||
export const One = (args: any) => <AppShelfItem {...args} />;
|
||||
export const Ten = (args: any) => (
|
||||
<SimpleGrid>
|
||||
{Array.from(Array(10)).map((_, i) => (
|
||||
<AppShelfItem {...args} key={i} />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
);
|
||||
104
src/components/AppShelf/AppShelf.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Text, AspectRatio, SimpleGrid, Card, Image, useMantineTheme } from '@mantine/core';
|
||||
import { useConfig } from '../../tools/state';
|
||||
import { serviceItem } from '../../tools/types';
|
||||
import AppShelfMenu from './AppShelfMenu';
|
||||
|
||||
const AppShelf = () => {
|
||||
const { config } = useConfig();
|
||||
|
||||
return (
|
||||
<SimpleGrid
|
||||
cols={7}
|
||||
spacing="xl"
|
||||
breakpoints={[
|
||||
{ maxWidth: 2400, cols: 6, spacing: 'xl' },
|
||||
{ maxWidth: 1800, cols: 5, spacing: 'xl' },
|
||||
{ maxWidth: 1500, cols: 4, spacing: 'lg' },
|
||||
{ maxWidth: 800, cols: 3, spacing: 'md' },
|
||||
{ maxWidth: 400, cols: 3, spacing: 'sm' },
|
||||
{ maxWidth: 400, cols: 2, spacing: 'sm' },
|
||||
]}
|
||||
>
|
||||
{config.services.map((service) => (
|
||||
<AppShelfItem key={service.name} service={service} />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
);
|
||||
};
|
||||
|
||||
export function AppShelfItem(props: any) {
|
||||
const { service }: { service: serviceItem } = props;
|
||||
const [hovering, setHovering] = useState(false);
|
||||
const theme = useMantineTheme();
|
||||
return (
|
||||
<motion.div
|
||||
key={service.name}
|
||||
onHoverStart={() => {
|
||||
setHovering(true);
|
||||
}}
|
||||
onHoverEnd={() => {
|
||||
setHovering(false);
|
||||
}}
|
||||
>
|
||||
<Card
|
||||
style={{
|
||||
boxShadow: hovering ? '0px 0px 3px rgba(0, 0, 0, 0.5)' : '0px 0px 1px rgba(0, 0, 0, 0.5)',
|
||||
backgroundColor:
|
||||
theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[1],
|
||||
}}
|
||||
radius="md"
|
||||
>
|
||||
<Card.Section>
|
||||
<Text mt="sm" align="center" lineClamp={1} weight={500}>
|
||||
{service.name}
|
||||
</Text>
|
||||
<motion.div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 5,
|
||||
right: 5,
|
||||
alignSelf: 'flex-end',
|
||||
}}
|
||||
animate={{
|
||||
opacity: hovering ? 1 : 0,
|
||||
}}
|
||||
>
|
||||
<AppShelfMenu service={service} />
|
||||
</motion.div>
|
||||
</Card.Section>
|
||||
<Card.Section>
|
||||
<AspectRatio
|
||||
ratio={3 / 5}
|
||||
m="xl"
|
||||
style={{
|
||||
width: 150,
|
||||
height: 90,
|
||||
}}
|
||||
>
|
||||
<motion.i
|
||||
whileHover={{
|
||||
cursor: 'pointer',
|
||||
scale: 1.1,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
style={{
|
||||
maxWidth: 80,
|
||||
}}
|
||||
fit="contain"
|
||||
onClick={() => {
|
||||
window.open(service.url);
|
||||
}}
|
||||
src={service.icon}
|
||||
/>
|
||||
</motion.i>
|
||||
</AspectRatio>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AppShelf;
|
||||
@@ -8,10 +8,6 @@ export function AppShelfItemWrapper(props: any) {
|
||||
style={{
|
||||
boxShadow: hovering ? '0px 0px 3px rgba(0, 0, 0, 0.5)' : '0px 0px 1px rgba(0, 0, 0, 0.5)',
|
||||
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[1],
|
||||
|
||||
//TODO: #3 Fix this temporary fix and make the width and height dynamic / responsive
|
||||
width: 200,
|
||||
height: 180,
|
||||
}}
|
||||
radius="md"
|
||||
>
|
||||
@@ -22,6 +22,7 @@ export default function SearchBar(props: any) {
|
||||
|
||||
return (
|
||||
<Box
|
||||
mb={"xl"}
|
||||
style={{
|
||||
width: '100%',
|
||||
}}
|
||||
@@ -80,8 +81,7 @@ export default function SearchBar(props: any) {
|
||||
}
|
||||
>
|
||||
<Text>
|
||||
tip: You can prefix your querry with <b>!yt</b> or <b>!t</b> to research on youtube or
|
||||
for a torrent
|
||||
tip: Use the prefixes <b>!yt</b> and <b>!t</b> in front of your query to search on YouTube or for a Torrent respectively.
|
||||
</Text>
|
||||
</Popover>
|
||||
</form>
|
||||
@@ -9,11 +9,12 @@ import {
|
||||
SegmentedControl,
|
||||
Indicator,
|
||||
Alert,
|
||||
TextInput,
|
||||
} from '@mantine/core';
|
||||
import { useColorScheme } from '@mantine/hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { AlertCircle, Settings as SettingsIcon } from 'tabler-icons-react';
|
||||
import { CURRENT_VERSION, REPO_URL } from '../../data/constants';
|
||||
import { CURRENT_VERSION, REPO_URL } from '../../../data/constants';
|
||||
import { useConfig } from '../../tools/state';
|
||||
import { ColorSchemeSwitch } from '../ColorSchemeToggle/ColorSchemeSwitch';
|
||||
import ConfigChanger from '../Config/ConfigChanger';
|
||||
@@ -24,11 +25,19 @@ function SettingsMenu(props: any) {
|
||||
const { config, setConfig } = useConfig();
|
||||
const colorScheme = useColorScheme();
|
||||
const { current, latest } = props;
|
||||
|
||||
const matches = [
|
||||
{ label: 'Google', value: 'https://google.com/search?q=' },
|
||||
{ label: 'DuckDuckGo', value: 'https://duckduckgo.com/?q=' },
|
||||
{ label: 'Bing', value: 'https://bing.com/search?q=' },
|
||||
{ label: 'Custom', value: 'Custom' },
|
||||
];
|
||||
|
||||
const [customSearchUrl, setCustomSearchUrl] = useState(config.settings.searchUrl);
|
||||
const [searchUrl, setSearchUrl] = useState(
|
||||
matches.find((match) => match.value === config.settings.searchUrl)?.value ?? 'Custom'
|
||||
);
|
||||
|
||||
return (
|
||||
<Group direction="column" grow>
|
||||
<Alert
|
||||
@@ -37,29 +46,49 @@ function SettingsMenu(props: any) {
|
||||
radius="lg"
|
||||
hidden={current === latest}
|
||||
>
|
||||
Version {latest} is available. Current : {current}
|
||||
Version {latest} is available. Current: {current}
|
||||
</Alert>
|
||||
<Group>
|
||||
<Group grow direction="column" spacing={0}>
|
||||
<Text>Search engine</Text>
|
||||
<SegmentedControl
|
||||
fullWidth
|
||||
title="Search engine"
|
||||
value={
|
||||
// Match config.settings.searchUrl with a key in the matches array
|
||||
matches.find((match) => match.value === config.settings.searchUrl)?.value ?? 'Google'
|
||||
searchUrl
|
||||
}
|
||||
onChange={
|
||||
// Set config.settings.searchUrl to the value of the selected item
|
||||
(e) =>
|
||||
(e) => {
|
||||
setSearchUrl(e);
|
||||
setConfig({
|
||||
...config,
|
||||
settings: {
|
||||
...config.settings,
|
||||
searchUrl: e,
|
||||
},
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
data={matches}
|
||||
/>
|
||||
<Text>Search engine</Text>
|
||||
{searchUrl === 'Custom' && (
|
||||
<TextInput
|
||||
label="Querry URL"
|
||||
placeholder="Custom querry url"
|
||||
value={customSearchUrl}
|
||||
onChange={(event) => {
|
||||
setCustomSearchUrl(event.currentTarget.value);
|
||||
setConfig({
|
||||
...config,
|
||||
settings: {
|
||||
...config.settings,
|
||||
searchUrl: event.currentTarget.value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
<Group direction="column">
|
||||
<Switch
|
||||
@@ -122,7 +151,7 @@ export function SettingsMenuButton(props: any) {
|
||||
</Modal>
|
||||
<ActionIcon
|
||||
variant="default"
|
||||
radius="xl"
|
||||
radius="md"
|
||||
size="xl"
|
||||
color="blue"
|
||||
style={props.style}
|
||||
@@ -1,18 +1,22 @@
|
||||
import { Aside as MantineAside } from '@mantine/core';
|
||||
import { Aside as MantineAside, Group } from '@mantine/core';
|
||||
import { CalendarModule } from '../modules/calendar/CalendarModule';
|
||||
import ModuleWrapper from '../modules/moduleWrapper';
|
||||
|
||||
export default function Aside() {
|
||||
return (
|
||||
<MantineAside
|
||||
height="100%"
|
||||
hiddenBreakpoint="md"
|
||||
hidden
|
||||
style={{
|
||||
border: 'none',
|
||||
}}
|
||||
width={{
|
||||
base: 'auto',
|
||||
}}
|
||||
>
|
||||
<ModuleWrapper module={CalendarModule} />
|
||||
<Group mt="sm" direction="column">
|
||||
<ModuleWrapper module={CalendarModule} />
|
||||
</Group>
|
||||
</MantineAside>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,12 @@
|
||||
import React from 'react';
|
||||
import { createStyles, Anchor, Text, Group, ActionIcon } from '@mantine/core';
|
||||
import {
|
||||
createStyles,
|
||||
Anchor,
|
||||
Text,
|
||||
Group,
|
||||
ActionIcon,
|
||||
Footer as FooterComponent,
|
||||
} from '@mantine/core';
|
||||
import { BrandGithub } from 'tabler-icons-react';
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
@@ -48,34 +55,39 @@ export function Footer({ links }: FooterCenteredProps) {
|
||||
));
|
||||
|
||||
return (
|
||||
<Group
|
||||
sx={{
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
right: 15,
|
||||
}}
|
||||
direction="row"
|
||||
align="center"
|
||||
mb={15}
|
||||
>
|
||||
<Group className={classes.links}>{items}</Group>
|
||||
<Group spacing="xs" position="right" noWrap>
|
||||
<ActionIcon<'a'> component="a" href="https://github.com/ajnart/homarr" size="lg">
|
||||
<BrandGithub size={18} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: '0.75rem',
|
||||
textAlign: 'center',
|
||||
color: '#a0aec0',
|
||||
<FooterComponent height="auto" style={{ border: 'none' }}>
|
||||
<Group
|
||||
sx={{
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
right: 15,
|
||||
}}
|
||||
direction="row"
|
||||
align="center"
|
||||
mb={15}
|
||||
>
|
||||
Made with ❤️ by @
|
||||
<Anchor href="https://github.com/ajnart" style={{ color: 'inherit', fontStyle: 'inherit' }}>
|
||||
ajnart
|
||||
</Anchor>
|
||||
</Text>
|
||||
</Group>
|
||||
<Group className={classes.links}>{items}</Group>
|
||||
<Group spacing="xs" position="right" noWrap>
|
||||
<ActionIcon<'a'> component="a" href="https://github.com/ajnart/homarr" size="lg">
|
||||
<BrandGithub size={18} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: '0.90rem',
|
||||
textAlign: 'center',
|
||||
color: '#a0aec0',
|
||||
}}
|
||||
>
|
||||
Made with ❤️ by @
|
||||
<Anchor
|
||||
href="https://github.com/ajnart"
|
||||
style={{ color: 'inherit', fontStyle: 'inherit', fontSize: 'inherit' }}
|
||||
>
|
||||
ajnart
|
||||
</Anchor>
|
||||
</Text>
|
||||
</Group>
|
||||
</FooterComponent>
|
||||
);
|
||||
}
|
||||
@@ -1,18 +1,11 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
createStyles,
|
||||
Header as Head,
|
||||
Container,
|
||||
Group,
|
||||
Burger,
|
||||
Drawer,
|
||||
Center,
|
||||
} from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { createStyles, Header as Head, Group, Drawer, Center } from '@mantine/core';
|
||||
import { useBooleanToggle } from '@mantine/hooks';
|
||||
import { NextLink } from '@mantine/next';
|
||||
import { Logo } from './Logo';
|
||||
import { SettingsMenuButton } from '../Settings/SettingsMenu';
|
||||
import CalendarComponent from '../modules/calendar/CalendarModule';
|
||||
import { SettingsMenuButton } from '../Settings/SettingsMenu';
|
||||
import { AddItemShelfButton } from '../AppShelf/AddAppShelfItem';
|
||||
|
||||
const HEADER_HEIGHT = 60;
|
||||
|
||||
@@ -40,8 +33,6 @@ const useStyles = createStyles((theme) => ({
|
||||
|
||||
header: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
},
|
||||
|
||||
@@ -94,62 +85,33 @@ interface HeaderResponsiveProps {
|
||||
|
||||
export function Header({ links }: HeaderResponsiveProps) {
|
||||
const [opened, toggleOpened] = useBooleanToggle(false);
|
||||
const [active, setActive] = useState('/');
|
||||
const { classes, cx } = useStyles();
|
||||
|
||||
const items = (
|
||||
<>
|
||||
{links.map((link) => (
|
||||
<NextLink
|
||||
key={link.label}
|
||||
href={link.link}
|
||||
className={cx(classes.link, { [classes.linkActive]: active === link.link })}
|
||||
onClick={(event) => {
|
||||
setActive(link.link);
|
||||
toggleOpened(false);
|
||||
}}
|
||||
>
|
||||
{link.label}
|
||||
</NextLink>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<Head height={HEADER_HEIGHT} mb={10} className={classes.root}>
|
||||
<Container className={classes.header}>
|
||||
<Group>
|
||||
<NextLink style={{ textDecoration: 'none' }} href="/">
|
||||
<Logo style={{ fontSize: 22 }} />
|
||||
</NextLink>
|
||||
</Group>
|
||||
<Group spacing={5} className={classes.links}>
|
||||
{items}
|
||||
</Group>
|
||||
<Head height={HEADER_HEIGHT}>
|
||||
<Group direction="row" align="center" position="apart" className={classes.header} mx="xl">
|
||||
<NextLink style={{ textDecoration: 'none' }} href="/">
|
||||
<Logo style={{ fontSize: 22 }} />
|
||||
</NextLink>
|
||||
<Group>
|
||||
<SettingsMenuButton />
|
||||
|
||||
<Burger
|
||||
opened={opened}
|
||||
onClick={() => toggleOpened()}
|
||||
className={classes.burger}
|
||||
size="sm"
|
||||
/>
|
||||
<AddItemShelfButton />
|
||||
</Group>
|
||||
</Group>
|
||||
|
||||
<Drawer
|
||||
opened={opened}
|
||||
overlayOpacity={0.55}
|
||||
overlayBlur={3}
|
||||
onClose={() => toggleOpened()}
|
||||
position="right"
|
||||
>
|
||||
{opened ?? (
|
||||
<Center>
|
||||
<CalendarComponent />
|
||||
</Center>
|
||||
)}
|
||||
</Drawer>
|
||||
</Container>
|
||||
<Drawer
|
||||
opened={opened}
|
||||
overlayOpacity={0.55}
|
||||
overlayBlur={3}
|
||||
onClose={() => toggleOpened()}
|
||||
position="right"
|
||||
>
|
||||
{opened ?? (
|
||||
<Center>
|
||||
<CalendarComponent />
|
||||
</Center>
|
||||
)}
|
||||
</Drawer>
|
||||
</Head>
|
||||
);
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import Navbar from './Navbar';
|
||||
const useStyles = createStyles((theme) => ({
|
||||
main: {
|
||||
[theme.fn.largerThan('md')]: {
|
||||
width: 1200,
|
||||
maxWidth: 1500,
|
||||
},
|
||||
},
|
||||
}));
|
||||
40
src/components/layout/Logo.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Group, Image, Text } from '@mantine/core';
|
||||
import * as React from 'react';
|
||||
import { CURRENT_VERSION } from '../../../data/constants';
|
||||
|
||||
export function Logo({ style }: any) {
|
||||
return (
|
||||
<Group>
|
||||
<Image
|
||||
width={50}
|
||||
src="/imgs/logo.png"
|
||||
style={{
|
||||
position: 'relative',
|
||||
left: 15,
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
sx={style}
|
||||
weight="bold"
|
||||
variant="gradient"
|
||||
gradient={{ from: 'red', to: 'orange', deg: 145 }}
|
||||
>
|
||||
Homarr
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
position: 'relative',
|
||||
left: -14,
|
||||
bottom: -2,
|
||||
color: 'gray',
|
||||
fontStyle: 'inherit',
|
||||
fontSize: 'inherit',
|
||||
alignSelf: 'center',
|
||||
alignContent: 'center',
|
||||
}}
|
||||
>
|
||||
{CURRENT_VERSION}
|
||||
</Text>
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
@@ -1,18 +1,22 @@
|
||||
import { Navbar as MantineNavbar } from '@mantine/core';
|
||||
import { Group, Navbar as MantineNavbar } from '@mantine/core';
|
||||
import { DateModule } from '../modules/date/DateModule';
|
||||
import ModuleWrapper from '../modules/moduleWrapper';
|
||||
|
||||
export default function Navbar() {
|
||||
return (
|
||||
<MantineNavbar
|
||||
height="100%"
|
||||
hiddenBreakpoint="md"
|
||||
hiddenBreakpoint="lg"
|
||||
hidden
|
||||
style={{
|
||||
border: 'none',
|
||||
}}
|
||||
width={{
|
||||
base: 'auto',
|
||||
}}
|
||||
>
|
||||
<ModuleWrapper module={DateModule} />
|
||||
<Group mt="sm" direction="column">
|
||||
<ModuleWrapper module={DateModule} />
|
||||
</Group>
|
||||
</MantineNavbar>
|
||||
);
|
||||
}
|
||||
@@ -2,9 +2,8 @@
|
||||
import { Popover, Box, ScrollArea, Divider, Indicator } from '@mantine/core';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Calendar } from '@mantine/dates';
|
||||
import { CalendarIcon } from '@modulz/radix-icons';
|
||||
import { showNotification } from '@mantine/notifications';
|
||||
import { Check } from 'tabler-icons-react';
|
||||
import { Calendar as CalendarIcon, Check } from 'tabler-icons-react';
|
||||
import { RadarrMediaDisplay, SonarrMediaDisplay } from './MediaDisplay';
|
||||
import { useConfig } from '../../../tools/state';
|
||||
import { IModule } from '../modules';
|
||||
@@ -5,6 +5,7 @@ import { getCookie, setCookies } from 'cookies-next';
|
||||
import Head from 'next/head';
|
||||
import { MantineProvider, ColorScheme, ColorSchemeProvider } from '@mantine/core';
|
||||
import { NotificationsProvider } from '@mantine/notifications';
|
||||
import { useHotkeys } from '@mantine/hooks';
|
||||
import Layout from '../components/layout/Layout';
|
||||
import { ConfigProvider } from '../tools/state';
|
||||
import { theme } from '../tools/theme';
|
||||
@@ -18,6 +19,7 @@ export default function App(props: AppProps & { colorScheme: ColorScheme }) {
|
||||
setColorScheme(nextColorScheme);
|
||||
setCookies('color-scheme', nextColorScheme, { maxAge: 60 * 60 * 24 * 30 });
|
||||
};
|
||||
useHotkeys([['mod+J', () => toggleColorScheme()]]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -15,6 +15,6 @@
|
||||
"jsx": "preserve",
|
||||
"incremental": true
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "next.config.js"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||