📱 Make the design way more responsive for mobile
This commit is contained in:
@@ -167,7 +167,7 @@ function DayComponent(props: any) {
|
||||
/>
|
||||
)}
|
||||
<Popover
|
||||
position="left"
|
||||
position="bottom"
|
||||
radius="lg"
|
||||
shadow="xl"
|
||||
transition="pop"
|
||||
@@ -176,7 +176,7 @@ function DayComponent(props: any) {
|
||||
boxShadow: '0 0 14px 14px rgba(0, 0, 0, 0.1), 0 14px 11px rgba(0, 0, 0, 0.1)',
|
||||
},
|
||||
}}
|
||||
width={700}
|
||||
width="auto"
|
||||
onClose={() => setOpened(false)}
|
||||
opened={opened}
|
||||
target={day}
|
||||
@@ -197,12 +197,18 @@ function DayComponent(props: any) {
|
||||
{index < radarrFiltered.length - 1 && <Divider variant="dashed" my="xl" />}
|
||||
</React.Fragment>
|
||||
))}
|
||||
{sonarrFiltered.length > 0 && lidarrFiltered.length > 0 && (
|
||||
<Divider variant="dashed" my="xl" />
|
||||
)}
|
||||
{lidarrFiltered.map((media: any, index: number) => (
|
||||
<React.Fragment key={index}>
|
||||
<LidarrMediaDisplay media={media} />
|
||||
{index < lidarrFiltered.length - 1 && <Divider variant="dashed" my="xl" />}
|
||||
</React.Fragment>
|
||||
))}
|
||||
{lidarrFiltered.length > 0 && readarrFiltered.length > 0 && (
|
||||
<Divider variant="dashed" my="xl" />
|
||||
)}
|
||||
{readarrFiltered.map((media: any, index: number) => (
|
||||
<React.Fragment key={index}>
|
||||
<ReadarrMediaDisplay media={media} />
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import { Image, Group, Title, Badge, Text, ActionIcon, Anchor, ScrollArea } from '@mantine/core';
|
||||
import {
|
||||
Image,
|
||||
Group,
|
||||
Title,
|
||||
Badge,
|
||||
Text,
|
||||
ActionIcon,
|
||||
Anchor,
|
||||
ScrollArea,
|
||||
createStyles,
|
||||
} from '@mantine/core';
|
||||
import { IconLink as Link } from '@tabler/icons';
|
||||
import { useConfig } from '../../../tools/state';
|
||||
import { serviceItem } from '../../../tools/types';
|
||||
@@ -14,13 +24,31 @@ export interface IMedia {
|
||||
episodeNumber?: number;
|
||||
}
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
poster: {
|
||||
[theme.fn.smallerThan('sm')]: {
|
||||
maxWidth: '20%',
|
||||
},
|
||||
[theme.fn.largerThan('sm')]: {
|
||||
maxWidth: 300,
|
||||
},
|
||||
},
|
||||
overview: {
|
||||
[theme.fn.largerThan('sm')]: {
|
||||
width: 400,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export function MediaDisplay(props: { media: IMedia }) {
|
||||
const { media }: { media: IMedia } = props;
|
||||
const { classes, cx } = useStyles();
|
||||
return (
|
||||
<Group position="apart">
|
||||
<Text>
|
||||
{media.poster && (
|
||||
<Image
|
||||
className={classes.poster}
|
||||
style={{
|
||||
float: 'right',
|
||||
}}
|
||||
@@ -28,12 +56,10 @@ export function MediaDisplay(props: { media: IMedia }) {
|
||||
fit="cover"
|
||||
src={media.poster}
|
||||
alt={media.title}
|
||||
width={250}
|
||||
height={400}
|
||||
/>
|
||||
)}
|
||||
<Group direction="column">
|
||||
<Group noWrap mr="sm" style={{ minWidth: 400 }}>
|
||||
<Group noWrap mr="sm" className={classes.overview}>
|
||||
<Title order={3}>{media.title}</Title>
|
||||
{media.imdbId && (
|
||||
<Anchor href={`https://www.imdb.com/title/${media.imdbId}`} target="_blank">
|
||||
@@ -65,7 +91,7 @@ export function MediaDisplay(props: { media: IMedia }) {
|
||||
)}
|
||||
</Group>
|
||||
<Group direction="column" position="apart">
|
||||
<ScrollArea style={{ height: 250 }}>{media.overview}</ScrollArea>
|
||||
<ScrollArea style={{ maxHeight: 250, maxWidth: 700 }}>{media.overview}</ScrollArea>
|
||||
<Group align="center" position="center" spacing="xs">
|
||||
{media.genres.map((genre: string, i: number) => (
|
||||
<Badge size="sm" key={i}>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useEffect, useState } from 'react';
|
||||
import { IconClock as Clock } from '@tabler/icons';
|
||||
import { useConfig } from '../../../tools/state';
|
||||
import { IModule } from '../modules';
|
||||
import { useSetSafeInterval } from '../../../tools/hooks/useSetSafeInterval';
|
||||
|
||||
export const DateModule: IModule = {
|
||||
title: 'Date',
|
||||
@@ -20,13 +21,14 @@ export const DateModule: IModule = {
|
||||
|
||||
export default function DateComponent(props: any) {
|
||||
const [date, setDate] = useState(new Date());
|
||||
const setSafeInterval = useSetSafeInterval();
|
||||
const { config } = useConfig();
|
||||
const isFullTime = config?.modules?.[DateModule.title]?.options?.full?.value ?? false;
|
||||
const formatString = isFullTime ? 'HH:mm' : 'h:mm A';
|
||||
// Change date on minute change
|
||||
// Note: Using 10 000ms instead of 1000ms to chill a little :)
|
||||
useEffect(() => {
|
||||
setInterval(() => {
|
||||
setSafeInterval(() => {
|
||||
setDate(new Date());
|
||||
}, 1000 * 60);
|
||||
}, []);
|
||||
|
||||
@@ -6,6 +6,7 @@ import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
||||
import { IModule } from '../modules';
|
||||
import { useConfig } from '../../../tools/state';
|
||||
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
|
||||
import { useSetSafeInterval } from '../../../tools/hooks/useSetSafeInterval';
|
||||
|
||||
export const DownloadsModule: IModule = {
|
||||
title: 'Torrent',
|
||||
@@ -31,10 +32,10 @@ export default function DownloadComponent() {
|
||||
|
||||
const [delugeTorrents, setDelugeTorrents] = useState<NormalizedTorrent[]>([]);
|
||||
const [qBittorrentTorrents, setqBittorrentTorrents] = useState<NormalizedTorrent[]>([]);
|
||||
|
||||
const setSafeInterval = useSetSafeInterval();
|
||||
useEffect(() => {
|
||||
if (qBittorrentService) {
|
||||
setInterval(() => {
|
||||
setSafeInterval(() => {
|
||||
axios
|
||||
.post('/api/modules/downloads?dlclient=qbit', { ...qBittorrentService })
|
||||
.then((res) => {
|
||||
@@ -43,7 +44,7 @@ export default function DownloadComponent() {
|
||||
}, 3000);
|
||||
}
|
||||
if (delugeService) {
|
||||
setInterval(() => {
|
||||
setSafeInterval(() => {
|
||||
axios.post('/api/modules/downloads?dlclient=deluge', { ...delugeService }).then((res) => {
|
||||
setDelugeTorrents(res.data.torrents);
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ import { useListState } from '@mantine/hooks';
|
||||
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
|
||||
import { useConfig } from '../../../tools/state';
|
||||
import { IModule } from '../modules';
|
||||
import { useSetSafeInterval } from '../../../tools/hooks/useSetSafeInterval';
|
||||
|
||||
/**
|
||||
* Format bytes as human-readable text.
|
||||
@@ -74,9 +75,9 @@ export default function TotalDownloadsComponent() {
|
||||
|
||||
const totalDownloadSpeed = torrents.reduce((acc, torrent) => acc + torrent.downloadSpeed, 0);
|
||||
const totalUploadSpeed = torrents.reduce((acc, torrent) => acc + torrent.uploadSpeed, 0);
|
||||
|
||||
const setSafeInterval = useSetSafeInterval();
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setSafeInterval(() => {
|
||||
// Get the current download speed of qBittorrent.
|
||||
if (qBittorrentService) {
|
||||
axios
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import {
|
||||
Center,
|
||||
Group,
|
||||
RingProgress,
|
||||
Title,
|
||||
useMantineTheme,
|
||||
} from '@mantine/core';
|
||||
import { Center, Group, RingProgress, Title, useMantineTheme } from '@mantine/core';
|
||||
import { IconCpu } from '@tabler/icons';
|
||||
import { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import si from 'systeminformation';
|
||||
import { useListState } from '@mantine/hooks';
|
||||
import { IModule } from '../modules';
|
||||
import { useSetSafeInterval } from '../../../tools/hooks/useSetSafeInterval';
|
||||
|
||||
export const SystemModule: IModule = {
|
||||
title: 'System info',
|
||||
@@ -28,13 +23,13 @@ interface ApiResponse {
|
||||
|
||||
export default function SystemInfo(args: any) {
|
||||
const [data, setData] = useState<ApiResponse>();
|
||||
|
||||
const setSafeInterval = useSetSafeInterval();
|
||||
// Refresh data every second
|
||||
useEffect(() => {
|
||||
setInterval(() => {
|
||||
setSafeInterval(() => {
|
||||
axios.get('/api/modules/systeminfo').then((res) => setData(res.data));
|
||||
}, 1000);
|
||||
}, [args]);
|
||||
}, []);
|
||||
|
||||
// Update data every time data changes
|
||||
const [cpuLoadHistory, cpuLoadHistoryHandlers] =
|
||||
|
||||
Reference in New Issue
Block a user