From 2354399117ec2c71cda90757fbf5d0230f1aa2b3 Mon Sep 17 00:00:00 2001 From: ajnart Date: Thu, 1 Dec 2022 00:54:35 +0900 Subject: [PATCH 1/5] Ping module rework --- package.json | 2 ++ src/pages/api/modules/ping.ts | 31 +++++++++++++------------------ yarn.lock | 28 +++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index bef8a0f18..8f72efb94 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "next": "12.2.0", "next-i18next": "^11.3.0", "nzbget-api": "^0.0.3", + "ping": "^0.4.2", "prism-react-renderer": "^1.3.5", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -75,6 +76,7 @@ "@next/eslint-plugin-next": "^12.1.4", "@types/dockerode": "^3.3.9", "@types/node": "17.0.1", + "@types/ping": "^0.4.1", "@types/react": "17.0.1", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^5.30.7", diff --git a/src/pages/api/modules/ping.ts b/src/pages/api/modules/ping.ts index de5dcc79d..1ac40498b 100644 --- a/src/pages/api/modules/ping.ts +++ b/src/pages/api/modules/ping.ts @@ -1,26 +1,21 @@ -import axios from 'axios'; -import https from 'https'; +import ping from 'ping'; import { NextApiRequest, NextApiResponse } from 'next'; async function Get(req: NextApiRequest, res: NextApiResponse) { // Parse req.body as a ServiceItem const { url } = req.query; - const agent = new https.Agent({ rejectUnauthorized: false }); - await axios - .get(url as string, { httpsAgent: agent }) - .then((response) => { - res.status(response.status).json(response.statusText); - }) - .catch((error) => { - if (error.response) { - res.status(error.response.status).json(error.response.statusText); - } else { - res.status(500).json('Server Error'); - } - }); - // // Make a request to the URL - // const response = await axios.get(url); - // // Return the response + // Parse url as URL object + const parsedUrl = new URL(url as string); + // Ping the URL + const response = await ping.promise.probe(parsedUrl.hostname, { + timeout: 1, + }); + // Return 200 if the alive property is true + if (response.alive) { + return res.status(200).end(); + } + // Return 404 if the alive property is false + return res.status(404).end(); } export default async (req: NextApiRequest, res: NextApiResponse) => { diff --git a/yarn.lock b/yarn.lock index 87dd94f19..ea55cdc95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2179,6 +2179,13 @@ __metadata: languageName: node linkType: hard +"@types/ping@npm:^0.4.1": + version: 0.4.1 + resolution: "@types/ping@npm:0.4.1" + checksum: 9b94837fe66df70558c5a42b0e0c8371b4950ab56b96c42c8df809ff2cf52477dd0a7e01d2e6b38af8bb6683b3dcb54587960b96b4b1f3d40fdb529aea348ad0 + languageName: node + linkType: hard + "@types/prettier@npm:^2.1.5": version: 2.6.3 resolution: "@types/prettier@npm:2.6.3" @@ -4843,6 +4850,7 @@ __metadata: "@tanstack/react-query": ^4.2.1 "@types/dockerode": ^3.3.9 "@types/node": 17.0.1 + "@types/ping": ^0.4.1 "@types/react": 17.0.1 "@types/uuid": ^8.3.4 "@typescript-eslint/eslint-plugin": ^5.30.7 @@ -4874,6 +4882,7 @@ __metadata: next: 12.2.0 next-i18next: ^11.3.0 nzbget-api: ^0.0.3 + ping: ^0.4.2 prettier: ^2.7.1 prism-react-renderer: ^1.3.5 react: ^18.2.0 @@ -6897,6 +6906,16 @@ __metadata: languageName: node linkType: hard +"ping@npm:^0.4.2": + version: 0.4.2 + resolution: "ping@npm:0.4.2" + dependencies: + q: 1.x + underscore: ^1.12.0 + checksum: 43992c76fb3294734248753f2028d9fab3b919dbfae79a5ea6df7e81fc2d6d555dd0b195d6c3dbc5c89aa9dba1cd8eb58d5ecedad103ecfee64df516e5f3665b + languageName: node + linkType: hard + "pirates@npm:^4.0.4": version: 4.0.5 resolution: "pirates@npm:4.0.5" @@ -7064,7 +7083,7 @@ __metadata: languageName: node linkType: hard -"q@npm:^1.4.1": +"q@npm:1.x, q@npm:^1.4.1": version: 1.5.1 resolution: "q@npm:1.5.1" checksum: 147baa93c805bc1200ed698bdf9c72e9e42c05f96d007e33a558b5fdfd63e5ea130e99313f28efc1783e90e6bdb4e48b67a36fcc026b7b09202437ae88a1fb12 @@ -8177,6 +8196,13 @@ __metadata: languageName: node linkType: hard +"underscore@npm:^1.12.0": + version: 1.13.6 + resolution: "underscore@npm:1.13.6" + checksum: d5cedd14a9d0d91dd38c1ce6169e4455bb931f0aaf354108e47bd46d3f2da7464d49b2171a5cf786d61963204a42d01ea1332a903b7342ad428deaafaf70ec36 + languageName: node + linkType: hard + "unique-filename@npm:^1.1.1": version: 1.1.1 resolution: "unique-filename@npm:1.1.1" From b2f51495274d27da44394de4e829619cfac512ff Mon Sep 17 00:00:00 2001 From: ajnart Date: Thu, 1 Dec 2022 01:35:17 +0900 Subject: [PATCH 2/5] Ping module overall Removed useless code leftover --- .../en/layout/add-service-app-shelf.json | 6 ---- src/components/AppShelf/AddAppShelfItem.tsx | 34 ++----------------- src/modules/ping/PingModule.tsx | 4 +-- src/tools/types.ts | 22 ------------ 4 files changed, 4 insertions(+), 62 deletions(-) diff --git a/public/locales/en/layout/add-service-app-shelf.json b/public/locales/en/layout/add-service-app-shelf.json index 735110906..ee5d2676e 100644 --- a/public/locales/en/layout/add-service-app-shelf.json +++ b/public/locales/en/layout/add-service-app-shelf.json @@ -113,12 +113,6 @@ "advancedOptions": { "title": "Advanced options", "form": { - "httpStatusCodes": { - "label": "HTTP Status Codes", - "placeholder": "Select valid status codes", - "clearButtonLabel": "Clear selection", - "nothingFound": "Nothing found" - }, "openServiceInNewTab": { "label": "Open service in new tab" }, diff --git a/src/components/AppShelf/AddAppShelfItem.tsx b/src/components/AppShelf/AddAppShelfItem.tsx index 01dd3da81..3b89d1c85 100644 --- a/src/components/AppShelf/AddAppShelfItem.tsx +++ b/src/components/AppShelf/AddAppShelfItem.tsx @@ -7,7 +7,6 @@ import { Image, LoadingOverlay, Modal, - MultiSelect, PasswordInput, Select, Space, @@ -25,7 +24,7 @@ import { useTranslation } from 'next-i18next'; import { useEffect, useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { useConfig } from '../../tools/state'; -import { tryMatchPort, ServiceTypeList, StatusCodes, Config } from '../../tools/types'; +import { tryMatchPort, ServiceTypeList, Config } from '../../tools/types'; import apiKeyPaths from './apiKeyPaths.json'; import Tip from '../layout/Tip'; @@ -121,7 +120,6 @@ export function AddAppShelfItemForm(props: AddAppShelfItemFormProps) { password: props.password ?? undefined, openedUrl: props.openedUrl ?? undefined, ping: props.ping ?? true, - status: props.status ?? ['200'], newTab: props.newTab ?? true, }, validate: { @@ -139,12 +137,6 @@ export function AddAppShelfItemForm(props: AddAppShelfItemFormProps) { } return null; }, - status: (value: string[]) => { - if (!value.length) { - return t('modal.form.validation.noStatusCodeSelected'); - } - return null; - }, }, }); @@ -190,12 +182,6 @@ export function AddAppShelfItemForm(props: AddAppShelfItemFormProps) { if (newForm.openedUrl === '') newForm.openedUrl = undefined; if (newForm.category === null) newForm.category = undefined; if (newForm.ping === true) newForm.ping = undefined; - if ( - (newForm.status.length === 1 && newForm.status[0] === '200') || - newForm.ping === false - ) { - delete newForm.status; - } // If service already exists, update it. if (config.services && config.services.find((s) => s.id === newForm.id)) { setConfig({ @@ -451,26 +437,10 @@ export function AddAppShelfItemForm(props: AddAppShelfItemFormProps) { - {form.values.ping && ( - - )} @@ -78,7 +78,7 @@ export default function PingComponent(props: any) { } > {null} diff --git a/src/tools/types.ts b/src/tools/types.ts index 68d8d75e7..83f5b24de 100644 --- a/src/tools/types.ts +++ b/src/tools/types.ts @@ -35,28 +35,6 @@ interface ConfigModule { }; } -export const StatusCodes = [ - { value: '200', label: '200 - OK', group: 'Sucessful responses' }, - { value: '204', label: '204 - No Content', group: 'Sucessful responses' }, - { value: '301', label: '301 - Moved Permanently', group: 'Redirection responses' }, - { value: '302', label: '302 - Found / Moved Temporarily', group: 'Redirection responses' }, - { value: '304', label: '304 - Not Modified', group: 'Redirection responses' }, - { value: '307', label: '307 - Temporary Redirect', group: 'Redirection responses' }, - { value: '308', label: '308 - Permanent Redirect', group: 'Redirection responses' }, - { value: '400', label: '400 - Bad Request', group: 'Client error responses' }, - { value: '401', label: '401 - Unauthorized', group: 'Client error responses' }, - { value: '403', label: '403 - Forbidden', group: 'Client error responses' }, - { value: '404', label: '404 - Not Found', group: 'Client error responses' }, - { value: '405', label: '405 - Method Not Allowed', group: 'Client error responses' }, - { value: '408', label: '408 - Request Timeout', group: 'Client error responses' }, - { value: '410', label: '410 - Gone', group: 'Client error responses' }, - { value: '429', label: '429 - Too Many Requests', group: 'Client error responses' }, - { value: '500', label: '500 - Internal Server Error', group: 'Server error responses' }, - { value: '502', label: '502 - Bad Gateway', group: 'Server error responses' }, - { value: '503', label: '503 - Service Unavailable', group: 'Server error responses' }, - { value: '054', label: '504 - Gateway Timeout Error', group: 'Server error responses' }, -]; - export const Targets = [ { value: '_blank', label: 'New Tab' }, { value: '_top', label: 'Same Window' }, From cabbf8f90d86ac1098daec6c30d78ef50dfab123 Mon Sep 17 00:00:00 2001 From: ajnart Date: Sat, 10 Dec 2022 23:31:22 +0900 Subject: [PATCH 3/5] Working on new update indicator --- data/constants.ts | 2 +- src/components/Settings/SettingsMenu.tsx | 108 ++++++++++++++++------- src/components/layout/Footer.tsx | 74 ---------------- src/components/layout/Layout.tsx | 2 - src/pages/api/modules/ping.ts | 4 +- 5 files changed, 78 insertions(+), 112 deletions(-) delete mode 100644 src/components/layout/Footer.tsx diff --git a/data/constants.ts b/data/constants.ts index 8ca22cd0b..db44a4c1e 100644 --- a/data/constants.ts +++ b/data/constants.ts @@ -1,2 +1,2 @@ export const REPO_URL = 'ajnart/homarr'; -export const CURRENT_VERSION = 'v0.10.7'; +export const CURRENT_VERSION = 'v0.10.6'; diff --git a/src/components/Settings/SettingsMenu.tsx b/src/components/Settings/SettingsMenu.tsx index 903989a10..b97bc00a1 100644 --- a/src/components/Settings/SettingsMenu.tsx +++ b/src/components/Settings/SettingsMenu.tsx @@ -1,39 +1,80 @@ -import { ActionIcon, Title, Tooltip, Drawer, Tabs, ScrollArea } from '@mantine/core'; -import { useHotkeys } from '@mantine/hooks'; -import { useState } from 'react'; -import { IconSettings } from '@tabler/icons'; +import { + ActionIcon, + Title, + Tooltip, + Drawer, + Tabs, + ScrollArea, + Indicator, + Alert, + Notification, +} from '@mantine/core'; +import { useElementSize, useHotkeys, useViewportSize } from '@mantine/hooks'; +import { useEffect, useState } from 'react'; +import { IconInfoCircle, IconSettings } from '@tabler/icons'; import { useTranslation } from 'next-i18next'; import AdvancedSettings from './AdvancedSettings'; import CommonSettings from './CommonSettings'; import Credits from './Credits'; +import { CURRENT_VERSION, REPO_URL } from '../../../data/constants'; -function SettingsMenu(props: any) { +function SettingsMenu({ newVersionAvailable }: { newVersionAvailable: string }) { const { t } = useTranslation('settings/common'); + const { height, width } = useViewportSize(); return ( - - - {t('tabs.common')} - {t('tabs.customizations')} - - - - - - - - - - - - + <> + } + disallowClose + color="teal" + radius="md" + title="New update available" + hidden={newVersionAvailable === ''} + > + { + //TODO: Translate and add link to release page} + } + Version {newVersionAvailable} is available, update now! + + + + + {t('tabs.common')} + {t('tabs.customizations')} + + + + + + + + + + + + + + + ); } export function SettingsMenuButton(props: any) { useHotkeys([['ctrl+L', () => setOpened(!opened)]]); const { t } = useTranslation('settings/common'); + const [newVersionAvailable, setNewVersionAvailable] = useState(''); + useEffect(() => { + // Fetch Data here when component first mounted + fetch(`https://api.github.com/repos/${REPO_URL}/releases/latest`).then((res) => { + res.json().then((data) => { + if (data.tag_name > CURRENT_VERSION) { + setNewVersionAvailable(data.tag_name); + } + }); + }); + }, [CURRENT_VERSION]); const [opened, setOpened] = useState(false); @@ -47,20 +88,21 @@ export function SettingsMenuButton(props: any) { opened={props.opened || opened} onClose={() => setOpened(false)} > - - + - setOpened(true)} - > - - + + setOpened(true)} + > + + + ); diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx deleted file mode 100644 index f1b58cd2a..000000000 --- a/src/components/layout/Footer.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import React, { useEffect } from 'react'; -import { createStyles, Footer as FooterComponent } from '@mantine/core'; -import { showNotification } from '@mantine/notifications'; -import { IconAlertCircle as AlertCircle } from '@tabler/icons'; -import { CURRENT_VERSION, REPO_URL } from '../../../data/constants'; - -const useStyles = createStyles((theme) => ({ - footer: { - borderTop: `1px solid ${ - theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[2] - }`, - }, - - inner: { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - padding: `${theme.spacing.md}px ${theme.spacing.md}px`, - - [theme.fn.smallerThan('sm')]: { - flexDirection: 'column', - }, - }, - - links: { - [theme.fn.smallerThan('sm')]: { - marginTop: theme.spacing.lg, - marginBottom: theme.spacing.sm, - }, - }, -})); - -interface FooterCenteredProps { - links: { link: string; label: string }[]; -} - -export function Footer({ links }: FooterCenteredProps) { - useEffect(() => { - // Fetch Data here when component first mounted - fetch(`https://api.github.com/repos/${REPO_URL}/releases/latest`).then((res) => { - res.json().then((data) => { - if (data.tag_name > CURRENT_VERSION) { - showNotification({ - color: 'yellow', - autoClose: false, - title: 'New version available', - icon: , - message: `Version ${data.tag_name} is available, update now!`, - }); - } else if (data.tag_name < CURRENT_VERSION) { - showNotification({ - color: 'orange', - autoClose: 5000, - title: 'You are using a development version', - icon: , - message: 'This version of Homarr is still in development! Bugs are expected 🐛', - }); - } - }); - }); - }, []); - - return ( - - ); -} diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 5e8f074e0..db29e482a 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -1,6 +1,5 @@ import { AppShell, createStyles } from '@mantine/core'; import { Header } from './header/Header'; -import { Footer } from './Footer'; import Aside from './Aside'; import Navbar from './Navbar'; import { HeaderConfig } from './header/HeaderConfig'; @@ -30,7 +29,6 @@ export default function Layout({ children, style }: any) { header={
} navbar={widgetPosition ? : undefined} aside={widgetPosition ? undefined :