feat: remove cqmin system (#2407)
* feat: remove cqmin system * fix: improve weather widget --------- Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import { ActionIcon, Anchor, Avatar, Badge, Card, Group, Image, ScrollArea, Stac
|
||||
import { IconThumbDown, IconThumbUp } from "@tabler/icons-react";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useRequiredBoard } from "@homarr/boards/context";
|
||||
import { MediaAvailability, MediaRequestStatus } from "@homarr/integrations/types";
|
||||
import type { ScopedTranslationFunction } from "@homarr/translation";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
@@ -54,23 +55,23 @@ export default function MediaServerWidget({
|
||||
);
|
||||
|
||||
const { mutate: mutateRequestAnswer } = clientApi.widget.mediaRequests.answerRequest.useMutation();
|
||||
const board = useRequiredBoard();
|
||||
|
||||
if (mediaRequests.length === 0) throw new NoIntegrationDataError();
|
||||
|
||||
return (
|
||||
<ScrollArea
|
||||
className="mediaRequests-list-scrollArea"
|
||||
scrollbarSize="2cqmin"
|
||||
scrollbarSize="md"
|
||||
style={{ pointerEvents: isEditMode ? "none" : undefined }}
|
||||
>
|
||||
<Stack className="mediaRequests-list-list" gap="2cqmin" p="2cqmin">
|
||||
<Stack className="mediaRequests-list-list" gap="sm" p="sm">
|
||||
{mediaRequests.map((mediaRequest) => (
|
||||
<Card
|
||||
className={`mediaRequests-list-item-wrapper mediaRequests-list-item-${mediaRequest.type} mediaRequests-list-item-${mediaRequest.status}`}
|
||||
key={`${mediaRequest.integrationId}-${mediaRequest.id}`}
|
||||
h="20cqmin"
|
||||
radius="2cqmin"
|
||||
p="2cqmin"
|
||||
radius={board.itemRadius}
|
||||
p="sm"
|
||||
withBorder
|
||||
>
|
||||
<Image
|
||||
@@ -93,28 +94,24 @@ export default function MediaServerWidget({
|
||||
wrap="nowrap"
|
||||
gap={0}
|
||||
>
|
||||
<Group className="mediaRequests-list-item-left-side" h="100%" gap="4cqmin" wrap="nowrap" flex={1}>
|
||||
<Group className="mediaRequests-list-item-left-side" h="100%" gap="md" wrap="nowrap" flex={1}>
|
||||
<Image
|
||||
className="mediaRequests-list-item-poster"
|
||||
src={mediaRequest.posterImagePath}
|
||||
h="100%"
|
||||
w="10cqmin"
|
||||
radius="1cqmin"
|
||||
h={60}
|
||||
w="auto"
|
||||
radius={"md"}
|
||||
/>
|
||||
<Stack className="mediaRequests-list-item-media-infos" gap="1cqmin">
|
||||
<Group className="mediaRequests-list-item-info-first-line" gap="2cqmin" wrap="nowrap">
|
||||
<Text className="mediaRequests-list-item-media-year" size="3.5cqmin" pt="0.75cqmin">
|
||||
<Stack className="mediaRequests-list-item-media-infos" gap={0}>
|
||||
<Group className="mediaRequests-list-item-info-first-line" gap="sm" align={"end"} wrap="nowrap">
|
||||
<Text className="mediaRequests-list-item-media-year" size="md" pt="xs">
|
||||
{mediaRequest.airDate?.getFullYear() ?? t("toBeDetermined")}
|
||||
</Text>
|
||||
<Badge
|
||||
className="mediaRequests-list-item-media-status"
|
||||
color={getAvailabilityProperties(mediaRequest.availability, t).color}
|
||||
variant="light"
|
||||
fz="3.5cqmin"
|
||||
lh="4cqmin"
|
||||
size="5cqmin"
|
||||
pt="0.75cqmin"
|
||||
px="2cqmin"
|
||||
size="md"
|
||||
>
|
||||
{getAvailabilityProperties(mediaRequest.availability, t).label}
|
||||
</Badge>
|
||||
@@ -124,26 +121,27 @@ export default function MediaServerWidget({
|
||||
href={mediaRequest.href}
|
||||
c="var(--mantine-color-text)"
|
||||
target={options.linksTargetNewTab ? "_blank" : "_self"}
|
||||
fz="5cqmin"
|
||||
fz="md"
|
||||
fw={"bold"}
|
||||
lineClamp={1}
|
||||
>
|
||||
{mediaRequest.name || "unknown"}
|
||||
</Anchor>
|
||||
</Stack>
|
||||
</Group>
|
||||
<Stack className="mediaRequests-list-item-right-side" gap="1cqmin" align="end">
|
||||
<Group className="mediaRequests-list-item-request-user" gap="2cqmin" wrap="nowrap">
|
||||
<Stack className="mediaRequests-list-item-right-side" gap="xs" ms={"lg"} align="end">
|
||||
<Group className="mediaRequests-list-item-request-user" gap="sm" wrap="nowrap">
|
||||
<Avatar
|
||||
className="mediaRequests-list-item-request-user-avatar"
|
||||
src={mediaRequest.requestedBy?.avatar}
|
||||
size="6cqmin"
|
||||
size="sm"
|
||||
/>
|
||||
<Anchor
|
||||
className="mediaRequests-list-item-request-user-name"
|
||||
href={mediaRequest.requestedBy?.link}
|
||||
c="var(--mantine-color-text)"
|
||||
target={options.linksTargetNewTab ? "_blank" : "_self"}
|
||||
fz="5cqmin"
|
||||
fz="md"
|
||||
lineClamp={1}
|
||||
style={{ wordBreak: "break-all" }}
|
||||
>
|
||||
@@ -151,13 +149,14 @@ export default function MediaServerWidget({
|
||||
</Anchor>
|
||||
</Group>
|
||||
{mediaRequest.status === MediaRequestStatus.PendingApproval ? (
|
||||
<Group className="mediaRequests-list-item-pending-buttons" gap="2cqmin">
|
||||
<Group className="mediaRequests-list-item-pending-buttons" gap="sm">
|
||||
<Tooltip label={t("pending.approve")}>
|
||||
<ActionIcon
|
||||
className="mediaRequests-list-item-pending-button-approve"
|
||||
variant="light"
|
||||
color="green"
|
||||
size="5cqmin"
|
||||
size="md"
|
||||
radius={"md"}
|
||||
onClick={() => {
|
||||
mutateRequestAnswer({
|
||||
integrationId: mediaRequest.integrationId,
|
||||
@@ -166,7 +165,7 @@ export default function MediaServerWidget({
|
||||
});
|
||||
}}
|
||||
>
|
||||
<IconThumbUp size="4cqmin" />
|
||||
<IconThumbUp size={23} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Tooltip label={t("pending.decline")}>
|
||||
@@ -174,7 +173,8 @@ export default function MediaServerWidget({
|
||||
className="mediaRequests-list-item-pending-button-decline"
|
||||
variant="light"
|
||||
color="red"
|
||||
size="5cqmin"
|
||||
size="md"
|
||||
radius={"md"}
|
||||
onClick={() => {
|
||||
mutateRequestAnswer({
|
||||
integrationId: mediaRequest.integrationId,
|
||||
@@ -183,7 +183,7 @@ export default function MediaServerWidget({
|
||||
});
|
||||
}}
|
||||
>
|
||||
<IconThumbDown size="4cqmin" />
|
||||
<IconThumbDown size={23} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.gridElement:not(:nth-child(8n)) {
|
||||
border-right: 0.5cqmin solid var(--app-shell-border-color);
|
||||
[data-mantine-color-scheme="light"] .card {
|
||||
background-color: var(--mantine-color-gray-1);
|
||||
}
|
||||
|
||||
.gridElement:not(:nth-last-child(-n + 8)) {
|
||||
border-bottom: 0.5cqmin solid var(--app-shell-border-color);
|
||||
[data-mantine-color-scheme="dark"] .card {
|
||||
background-color: var(--mantine-color-dark-7);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
import combineClasses from "clsx";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useRequiredBoard } from "@homarr/boards/context";
|
||||
import type { RequestStats } from "@homarr/integrations/types";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
|
||||
@@ -42,9 +43,10 @@ export default function MediaServerWidget({
|
||||
|
||||
const { width, height, ref } = useElementSize();
|
||||
|
||||
const board = useRequiredBoard();
|
||||
|
||||
if (requestStats.users.length === 0 && requestStats.stats.length === 0) throw new NoIntegrationDataError();
|
||||
|
||||
//Add processing and available
|
||||
const data = [
|
||||
{
|
||||
name: "approved",
|
||||
@@ -93,37 +95,35 @@ export default function MediaServerWidget({
|
||||
className="mediaRequests-stats-layout"
|
||||
display="flex"
|
||||
h="100%"
|
||||
gap="2cqmin"
|
||||
p="2cqmin"
|
||||
gap="sm"
|
||||
p="sm"
|
||||
align="center"
|
||||
style={{ pointerEvents: isEditMode ? "none" : undefined }}
|
||||
>
|
||||
<Text className="mediaRequests-stats-stats-title" size="6.5cqmin">
|
||||
<Text className="mediaRequests-stats-stats-title" fw={"bold"} size="md">
|
||||
{t("titles.stats.main")}
|
||||
</Text>
|
||||
<Grid className="mediaRequests-stats-stats-grid" gutter={0} w="100%">
|
||||
<Grid className="mediaRequests-stats-stats-grid" gutter={10} w="100%">
|
||||
{data.map((stat) => (
|
||||
<Grid.Col
|
||||
className={combineClasses(
|
||||
classes.gridElement,
|
||||
"mediaRequests-stats-stat-wrapper",
|
||||
`mediaRequests-stats-stat-${stat.name}`,
|
||||
)}
|
||||
className={combineClasses("mediaRequests-stats-stat-wrapper", `mediaRequests-stats-stat-${stat.name}`)}
|
||||
key={stat.name}
|
||||
span={3}
|
||||
>
|
||||
<Tooltip label={t(`titles.stats.${stat.name}`)}>
|
||||
<Stack className="mediaRequests-stats-stat-stack" align="center" gap="2cqmin" p="2cqmin">
|
||||
<stat.icon className="mediaRequests-stats-stat-icon" size="7.5cqmin" />
|
||||
<Text className="mediaRequests-stats-stat-value" size="5cqmin">
|
||||
{stat.number}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Card p={0} radius={board.itemRadius} className={classes.card}>
|
||||
<Stack className="mediaRequests-stats-stat-stack" align="center" gap={0} p="xs">
|
||||
<stat.icon className="mediaRequests-stats-stat-icon" size={30} />
|
||||
<Text className="mediaRequests-stats-stat-value" size="md">
|
||||
{stat.number}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Tooltip>
|
||||
</Grid.Col>
|
||||
))}
|
||||
</Grid>
|
||||
<Text className="mediaRequests-stats-users-title" size="6.5cqmin">
|
||||
<Text className="mediaRequests-stats-users-title" fw={"bold"} size="md">
|
||||
{t("titles.users.main")}
|
||||
</Text>
|
||||
<Stack
|
||||
@@ -132,36 +132,34 @@ export default function MediaServerWidget({
|
||||
w="100%"
|
||||
ref={ref}
|
||||
display="flex"
|
||||
gap="2cqmin"
|
||||
style={{ overflow: "hidden" }}
|
||||
gap="sm"
|
||||
style={{ overflow: "hidden", justifyContent: "end" }}
|
||||
>
|
||||
{requestStats.users.slice(0, Math.max(Math.floor((height / width) * 5), 1)).map((user) => (
|
||||
<Card
|
||||
className={combineClasses(
|
||||
"mediaRequests-stats-users-user-wrapper",
|
||||
`mediaRequests-stats-users-user-${user.id}`,
|
||||
classes.card,
|
||||
)}
|
||||
key={user.id}
|
||||
withBorder
|
||||
p="2cqmin"
|
||||
flex={1}
|
||||
mah="38.5cqmin"
|
||||
radius="2.5cqmin"
|
||||
p="sm"
|
||||
radius={board.itemRadius}
|
||||
>
|
||||
<Group className="mediaRequests-stats-users-user-group" h="100%" p={0} gap="2cqmin" display="flex">
|
||||
<Group className="mediaRequests-stats-users-user-group" h="100%" p={0} gap="sm" display="flex">
|
||||
<Tooltip label={user.integration.name}>
|
||||
<Avatar
|
||||
className="mediaRequests-stats-users-user-avatar"
|
||||
size="12.5cqmin"
|
||||
size="md"
|
||||
src={user.avatar}
|
||||
bd={`0.5cqmin solid ${user.integration.kind === "overseerr" ? "#ECB000" : "#6677CC"}`}
|
||||
bd={`2px solid ${user.integration.kind === "overseerr" ? "#ECB000" : "#6677CC"}`}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Stack className="mediaRequests-stats-users-user-infos" gap="2cqmin">
|
||||
<Text className="mediaRequests-stats-users-user-userName" size="6cqmin">
|
||||
<Stack className="mediaRequests-stats-users-user-infos" gap={0}>
|
||||
<Text className="mediaRequests-stats-users-user-userName" fw={"bold"} size="md">
|
||||
{user.displayName}
|
||||
</Text>
|
||||
<Text className="mediaRequests-stats-users-user-request-count" size="4cqmin">
|
||||
<Text className="mediaRequests-stats-users-user-request-count" size="md">
|
||||
{`${t("titles.users.requests")}: ${user.requestCount}`}
|
||||
</Text>
|
||||
</Stack>
|
||||
@@ -170,11 +168,12 @@ export default function MediaServerWidget({
|
||||
className="mediaRequests-stats-users-user-link-button"
|
||||
variant="light"
|
||||
color="var(--mantine-color-text)"
|
||||
size="10cqmin"
|
||||
size={40}
|
||||
component="a"
|
||||
radius={board.itemRadius}
|
||||
href={user.link}
|
||||
>
|
||||
<IconExternalLink className="mediaRequests-stats-users-user-link-icon" size="7.5cqmin" />
|
||||
<IconExternalLink className="mediaRequests-stats-users-user-link-icon" size={25} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user