From eba2d4486522e2ede93356de3b45b5ca338749ba Mon Sep 17 00:00:00 2001 From: Yan Stoianov <42742736+Nether0ne@users.noreply.github.com> Date: Sun, 25 Dec 2022 23:55:27 +0300 Subject: [PATCH] feat: stream card options and other improvements (#6) --- public/_locales/en/messages.json | 70 ++++++++++ public/_locales/ru/messages.json | 70 ++++++++++ public/_locales/uk/messages.json | 70 ++++++++++ src/background/actions/platform.ts | 1 - src/background/actions/streams.ts | 4 +- src/browser/common/hooks/platform.ts | 9 ++ src/browser/common/hooks/streams.ts | 52 +++++-- .../components/cards/platform/Platform.tsx | 9 +- .../platform/variants/auth/AuthPlatform.tsx | 18 +-- .../cards/stream/Details/Viewers.tsx | 6 +- .../components/cards/stream/Skeleton.tsx | 128 ++++++++++++++++++ .../components/cards/stream/Stream.tsx | 60 ++++---- .../components/modals/BackgroundReset.tsx | 8 +- src/browser/components/modals/Donate.tsx | 1 + .../components/modals/PlatformExpired.tsx | 93 +++++++++++++ .../components/pages/Settings/Extra.tsx | 2 +- .../components/pages/Settings/General.tsx | 2 +- .../pages/Settings/Notifications.tsx | 14 +- .../pages/Settings/StreamCardSettings.tsx | 90 ++++++++++++ .../pages/Settings/options/SettingLoading.tsx | 21 ++- .../pages/Settings/options/Switch.tsx | 4 +- .../components/pages/Streams/Settings.tsx | 6 +- .../pages/Streams/Settings/GroupBy.tsx | 29 ++-- .../pages/Streams/Settings/SortDirection.tsx | 17 ++- .../pages/Streams/Settings/SortField.tsx | 31 +++-- .../components/pages/Streams/StreamsGroup.tsx | 2 +- .../components/pages/Streams/StreamsList.tsx | 6 +- src/browser/pages/popup.tsx | 8 +- src/browser/views/Settings.tsx | 55 ++++---- src/common/types/settings.ts | 12 ++ src/common/types/stream.ts | 8 ++ yarn.lock | 98 ++++++-------- 32 files changed, 819 insertions(+), 185 deletions(-) create mode 100644 src/browser/components/cards/stream/Skeleton.tsx create mode 100644 src/browser/components/modals/PlatformExpired.tsx create mode 100644 src/browser/components/pages/Settings/StreamCardSettings.tsx diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 7d70751..ca7771f 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -57,6 +57,9 @@ "coinbase": { "message": "Coinbase" }, + "paypal": { + "message": "Paypal" + }, "generalSettings": { "message": "General settings" }, @@ -90,6 +93,27 @@ "badge": { "message": "Display badge on browser icon" }, + "customStreamCard": { + "message": "Custom stream card settings" + }, + "useCustomStreamCard": { + "message": "Use custom stream card settings" + }, + "useCustomThumbnail": { + "message": "Stream thumbnail" + }, + "useCustomPlatformIcon": { + "message": "Stream platform icon" + }, + "useCustomViewers": { + "message": "Stream current viewers" + }, + "useCustomTitle": { + "message": "Stream title" + }, + "useCustomCategory": { + "message": "Stream category" + }, "twitch": { "message": "Twitch" }, @@ -275,6 +299,22 @@ "search": { "message": "Search" }, + "asc": { + "message": "Sorted by $type$ ascending", + "placeholders": { + "type": { + "content": "$1" + } + } + }, + "desc": { + "message": "Sorted by $type$ descending", + "placeholders": { + "type": { + "content": "$1" + } + } + }, "viewersSortField": { "message": "Viewers" }, @@ -284,6 +324,14 @@ "userSortField": { "message": "Name" }, + "groupedBy": { + "message": "Streams are grouped by $group$", + "placeholders": { + "group": { + "content": "$1" + } + } + }, "noneGroupBy": { "message": "None" }, @@ -302,6 +350,9 @@ "rerun": { "message": "Rerun" }, + "noCategory": { + "message": "No category" + }, "openStream": { "message": "Open stream" }, @@ -387,5 +438,24 @@ }, "backgroundResetButton": { "message": "Reset application" + }, + "accessTokenExpired": { + "message": "$platform$ access token has expired", + "placeholders": { + "platform": { + "content": "$1" + } + } + }, + "renewAcessToken": { + "message": "Renew $platform$ access token", + "placeholders": { + "platform": { + "content": "$1" + } + } + }, + "forbidPlatform": { + "message": "Remove platform" } } diff --git a/public/_locales/ru/messages.json b/public/_locales/ru/messages.json index 1a8d95c..a279245 100644 --- a/public/_locales/ru/messages.json +++ b/public/_locales/ru/messages.json @@ -57,6 +57,9 @@ "coinbase": { "message": "Coinbase" }, + "paypal": { + "message": "Paypal" + }, "generalSettings": { "message": "Главные настройки" }, @@ -90,6 +93,27 @@ "badge": { "message": "Показывать значок с количеством активных стримов" }, + "customStreamCard": { + "message": "Собственные настройки карточки стрима" + }, + "useCustomStreamCard": { + "message": "Использовать собственные настройки карточки стрима" + }, + "useCustomThumbnail": { + "message": "Миниатюра стрима" + }, + "useCustomPlatformIcon": { + "message": "Иконка платформы стрима" + }, + "useCustomViewers": { + "message": "Количество зрителей стрима" + }, + "useCustomTitle": { + "message": "Название стрима" + }, + "useCustomCategory": { + "message": "Категория стрима" + }, "twitch": { "message": "Twitch" }, @@ -275,6 +299,22 @@ "search": { "message": "Поиск" }, + "asc": { + "message": "Отсортировано за {type} по возростанию", + "placeholders": { + "type": { + "content": "$1" + } + } + }, + "desc": { + "message": "Отсортировано за {type} по убыванию", + "placeholders": { + "type": { + "content": "$1" + } + } + }, "viewersSortField": { "message": "Зрители" }, @@ -284,6 +324,14 @@ "userSortField": { "message": "Имя" }, + "groupedBy": { + "message": "Стримы сгрупированны как $group$", + "placeholders": { + "group": { + "content": "$1" + } + } + }, "noneGroupBy": { "message": "Отсутствует" }, @@ -302,6 +350,9 @@ "rerun": { "message": "Повтор" }, + "noCategory": { + "message": "Без категории" + }, "openStream": { "message": "Открыть стрим" }, @@ -387,5 +438,24 @@ }, "backgroundResetButton": { "message": "Перезапустить приложение" + }, + "accessTokenExpired": { + "message": "Токен доступа $platform$ истек", + "placeholders": { + "platform": { + "content": "$1" + } + } + }, + "renewAcessToken": { + "message": "Обновить токен доступа $platform$", + "placeholders": { + "platform": { + "content": "$1" + } + } + }, + "forbidPlatform": { + "message": "Убрать платформу" } } diff --git a/public/_locales/uk/messages.json b/public/_locales/uk/messages.json index 41507dc..72e658e 100644 --- a/public/_locales/uk/messages.json +++ b/public/_locales/uk/messages.json @@ -57,6 +57,9 @@ "coinbase": { "message": "Coinbase" }, + "paypal": { + "message": "Paypal" + }, "generalSettings": { "message": "Основні налаштування" }, @@ -90,6 +93,27 @@ "badge": { "message": "Відображати значок з кількістю активних каналів" }, + "customStreamCard": { + "message": "Власні налаштування картки трансляції" + }, + "useCustomStreamCard": { + "message": "Використовувати власні налаштування картки трансляції" + }, + "useCustomThumbnail": { + "message": "Мініатюра трансляції" + }, + "useCustomPlatformIcon": { + "message": "Іконка платформи трансляції" + }, + "useCustomViewers": { + "message": "Кількість глядачів трансляції" + }, + "useCustomTitle": { + "message": "Назва трансляції" + }, + "useCustomCategory": { + "message": "Категорія трансляції" + }, "twitch": { "message": "Twitch" }, @@ -275,6 +299,22 @@ "search": { "message": "Пошук" }, + "asc": { + "message": "Відсортовано за {type} по зростанню", + "placeholders": { + "type": { + "content": "$1" + } + } + }, + "desc": { + "message": "Відсортовано за {type} по спаданню", + "placeholders": { + "type": { + "content": "$1" + } + } + }, "viewersSortField": { "message": "Глядачі" }, @@ -284,6 +324,14 @@ "userSortField": { "message": "Ім'я" }, + "groupedBy": { + "message": "Трансляції згруповані як $group$", + "placeholders": { + "group": { + "content": "$1" + } + } + }, "noneGroupBy": { "message": "Немає" }, @@ -302,6 +350,9 @@ "rerun": { "message": "Повтор" }, + "noCategory": { + "message": "Без категорії" + }, "openStream": { "message": "Відкрити стрим" }, @@ -387,5 +438,24 @@ }, "backgroundResetButton": { "message": "Перезапустити застосунок" + }, + "accessTokenExpired": { + "message": "Токен доступу $platform$ застарів", + "placeholders": { + "platform": { + "content": "$1" + } + } + }, + "renewAcessToken": { + "message": "Оновити токен $platform$", + "placeholders": { + "platform": { + "content": "$1" + } + } + }, + "forbidPlatform": { + "message": "Видалити платформу" } } diff --git a/src/background/actions/platform.ts b/src/background/actions/platform.ts index 845c1f6..cf7c234 100644 --- a/src/background/actions/platform.ts +++ b/src/background/actions/platform.ts @@ -67,7 +67,6 @@ export async function setupPlatform( platform.enabled = true; platform.accessToken = accessToken; await stores[`${platform.name}`].set(platform); - console.log(platform); return await updatePlatform(platform); } diff --git a/src/background/actions/streams.ts b/src/background/actions/streams.ts index 9e47b29..23c084c 100644 --- a/src/background/actions/streams.ts +++ b/src/background/actions/streams.ts @@ -108,7 +108,7 @@ const newStreamNotification = async ( createNotification([NotificationType.STREAM, JSON.stringify(stream)], { title: t("streamerOnline", [user, platform]), - message: game ?? "", + message: game ?? t("noCategory"), contextMessage: title, type: "basic", iconUrl: icon, @@ -127,7 +127,7 @@ const newCategoryNotification = async ( if (oldStream.game !== game) { createNotification([NotificationType.STREAM, JSON.stringify(newStream)], { title: t("streamerNewCategory", user), - message: t("streamerNewCategoryMessage", [oldStream.game, game]), + message: t("streamerNewCategoryMessage", [oldStream.game, game || t("noCategory")]), contextMessage: title, type: "basic", iconUrl: icon, diff --git a/src/browser/common/hooks/platform.ts b/src/browser/common/hooks/platform.ts index a99a612..4a99c9c 100644 --- a/src/browser/common/hooks/platform.ts +++ b/src/browser/common/hooks/platform.ts @@ -1,6 +1,7 @@ import { stores } from "@/common/store"; import { PlatformName } from "@/common/types/platform"; import { get } from "lodash-es"; +import { useMemo } from "react"; import { useStore } from "./store"; export function usePlatform(name: PlatformName) { @@ -18,3 +19,11 @@ export function useAllSetPlatforms() { return allSetProfiles; } + +export function useAllExpiredPlatforms() { + const [twitch] = usePlatform(PlatformName.TWITCH); + + return useMemo(() => { + return twitch.accessToken === undefined && twitch.enabled ? twitch : null; + }, [twitch]); +} diff --git a/src/browser/common/hooks/streams.ts b/src/browser/common/hooks/streams.ts index 6cbf3eb..d704135 100644 --- a/src/browser/common/hooks/streams.ts +++ b/src/browser/common/hooks/streams.ts @@ -35,19 +35,47 @@ export function useStreamsWithSettings() { sort = sortDirection === SortDirection.ASC ? SortDirection.DESC : SortDirection.ASC; } - setFilteredStreams( - groupItemsBy( - orderBy(data, [sortField], [sort]).filter((stream) => { - if (search !== undefined) { - return (stream.title.toLowerCase().includes(search.toLowerCase()) || - stream.user.toLowerCase().includes(search.toLowerCase()) || - stream.game?.toLowerCase().includes(search.toLowerCase())) as boolean; - } - return true; - }), - groupBy - ) + const groupedStreams = groupItemsBy( + orderBy(data, [sortField], [sort]).filter((stream) => { + if (search !== undefined) { + return (stream.title.toLowerCase().includes(search.toLowerCase()) || + stream.user.toLowerCase().includes(search.toLowerCase()) || + stream.game?.toLowerCase().includes(search.toLowerCase())) as boolean; + } + return true; + }), + groupBy ); + + const sortedGroupStreams = Object.entries(groupedStreams) + .sort(([a, aStreams], [b, bStreams]) => { + switch (sortField) { + case SortField.NAME: + return sort === SortDirection.ASC ? (a >= b ? -1 : 1) : a >= b ? 1 : 1; + case SortField.STARTED_AT: + const uptimeReducer = (total: number, stream: Stream) => + total + (new Date().getTime() - new Date(stream.startedAt || 0).getTime()); + return sort === SortDirection.ASC + ? aStreams.reduce(uptimeReducer, 0) >= bStreams.reduce(uptimeReducer, 0) + ? -1 + : 1 + : aStreams.reduce(uptimeReducer, 0) >= bStreams.reduce(uptimeReducer, 0) + ? 1 + : -1; + default: + const viewersReducer = (total: number, stream: Stream) => total + stream.viewers; + return sort === SortDirection.ASC + ? aStreams.reduce(viewersReducer, 0) >= bStreams.reduce(viewersReducer, 0) + ? 1 + : -1 + : aStreams.reduce(viewersReducer, 0) >= bStreams.reduce(viewersReducer, 0) + ? -1 + : 1; + } + }) + .reduce((o: Dictionary, [name, streams]) => ({ ...o, [name]: streams }), {}); + + setFilteredStreams(sortedGroupStreams); }, [data, search, groupBy, sortField, sortDirection]); const setStreamsSettings = (params: { diff --git a/src/browser/components/cards/platform/Platform.tsx b/src/browser/components/cards/platform/Platform.tsx index c0bcce1..11b24f6 100644 --- a/src/browser/components/cards/platform/Platform.tsx +++ b/src/browser/components/cards/platform/Platform.tsx @@ -9,11 +9,10 @@ interface PlatformProps { } const PlatformCard: FC = ({ platformName, platformType }) => { - return platformType === PlatformType.AUTH ? ( - - ) : ( - - ); + if (platformType === PlatformType.AUTH) { + return ; + } + return ; }; export default PlatformCard; diff --git a/src/browser/components/cards/platform/variants/auth/AuthPlatform.tsx b/src/browser/components/cards/platform/variants/auth/AuthPlatform.tsx index 12eb17d..8a5d856 100644 --- a/src/browser/components/cards/platform/variants/auth/AuthPlatform.tsx +++ b/src/browser/components/cards/platform/variants/auth/AuthPlatform.tsx @@ -10,16 +10,18 @@ interface AuthPlatformProps { } const AuthPlatform: FC = ({ platformName }) => { - const [platform, { isLoading }] = usePlatform(platformName); + const [platform, store] = usePlatform(platformName); const { data } = platform; - return isLoading ? ( - - ) : platform.enabled && data ? ( - - ) : ( - - ); + if (store.isLoading) { + return ; + } + + if (platform.enabled && data) { + return ; + } + + return ; }; export default AuthPlatform; diff --git a/src/browser/components/cards/stream/Details/Viewers.tsx b/src/browser/components/cards/stream/Details/Viewers.tsx index 9277f55..41e83cf 100644 --- a/src/browser/components/cards/stream/Details/Viewers.tsx +++ b/src/browser/components/cards/stream/Details/Viewers.tsx @@ -28,7 +28,11 @@ const Viewers: FC = ({ count, type }) => { const rerun = type === "rerun"; return ( - {!rerun ? t("live") : t("rerun")}} placement="left"> + {!rerun ? t("live") : t("rerun")}} + placement="left" + > {digitWithSpaces(count)} diff --git a/src/browser/components/cards/stream/Skeleton.tsx b/src/browser/components/cards/stream/Skeleton.tsx new file mode 100644 index 0000000..2a28fc8 --- /dev/null +++ b/src/browser/components/cards/stream/Skeleton.tsx @@ -0,0 +1,128 @@ +import { Box, Link, Skeleton, Tooltip, Typography } from "@mui/material"; +import { FC } from "react"; +import { getLinkForPlatform, t } from "@/common/helpers"; +import { LinkType } from "@/common/types/general"; +import useSettings from "@/browser/common/hooks/settings"; + +const styles = { + "& .stream": { + color: "inherit", + textDecoration: "inherit", + display: "flex", + flexDirection: "row", + p: 1, + px: 2, + transition: "background-color .5s ease-out", + "&:hover": { + backgroundColor: "background.paper", + transition: "background-color .5s ease-out", + }, + "& .thumbnail": { + display: "flex", + mr: "1rem", + alignSelf: "center", + "& .thumbnailWrapper": { + position: "relative", + overflow: "hidden", + borderRadius: ".25rem", + width: "6rem", + height: "3.35rem", + }, + "& .image": { + position: "absolute", + backgroundColor: "background.paper", + }, + }, + "& .uptime": { + color: "#D2D3D3", + position: "absolute", + right: 0, + bottom: 0, + borderTopLeftRadius: ".25rem", + backgroundColor: "RGB(0, 0, 0, 0.7)", + paddingLeft: ".25rem", + paddingRight: ".25rem", + }, + "& .info": { + display: "flex", + flexDirection: "column", + justifyContent: "center", + overflow: "hidden", + width: "100%", + gap: 0.5, + "& .mainWrapper": { + display: "flex", + justifyContent: "space-between", + "& .main": { + display: "flex", + alignItems: "center", + flexDirection: "row", + gap: 0.5, + "& svg": { + mr: ".5rem", + fontSize: "1rem", + }, + "& .name": { + fontWeight: 600, + maxWidth: "14rem", + }, + }, + }, + }, + "& .game": { + color: "#266798", + }, + }, +}; + +const StreamCardSkeleton: FC = () => { + const [ + { + general: { useCustomStreamCard, customStreamCard }, + }, + store, + ] = useSettings(); + + if (store.isLoading) { + return null; + } + + return ( + + + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.thumbnail)) && ( + + + + + + )} + + + + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.platformIcon)) && ( + + )} + + + + + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.viewers)) && ( + + )} + + + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.title)) && ( + + )} + + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.category)) && ( + + )} + + + + ); +}; + +export default StreamCardSkeleton; diff --git a/src/browser/components/cards/stream/Stream.tsx b/src/browser/components/cards/stream/Stream.tsx index f85d19b..d5f452a 100644 --- a/src/browser/components/cards/stream/Stream.tsx +++ b/src/browser/components/cards/stream/Stream.tsx @@ -6,8 +6,10 @@ import Image from "../../misc/Image"; import Viewers from "./details/Viewers"; import StreamContextMenu from "../../pages/Streams/ContextMenu"; import PlatformIcon from "../../misc/PlatformIcon"; -import { getLinkForPlatform } from "@/common/helpers"; +import { getLinkForPlatform, t } from "@/common/helpers"; import { LinkType } from "@/common/types/general"; +import useSettings from "@/browser/common/hooks/settings"; +import StreamCardSkeleton from "./Skeleton"; interface StreamCardProps { readonly stream: Stream; @@ -84,6 +86,16 @@ const styles = { const StreamCard: FC = ({ stream }) => { const { user, viewers, title, game, thumbnail, startedAt, type, platform } = stream; + const [ + { + general: { useCustomStreamCard, customStreamCard }, + }, + store, + ] = useSettings(); + + if (store.isLoading) { + return ; + } return ( @@ -94,50 +106,50 @@ const StreamCard: FC = ({ stream }) => { target="_blank" className="stream" > - - - {user} + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.thumbnail)) && ( + + + {user} - {startedAt && } + {startedAt && } + - - + )} - + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.platformIcon)) && ( + + )} {user} - + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.viewers)) && ( + + )} - {title}} - enterNextDelay={1000} - followCursor - arrow - > - - {title} - - - - {game && ( + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.title)) && ( {game}} + title={{title}} enterNextDelay={1000} followCursor arrow > - - {game} + + {title}  )} + + {(!useCustomStreamCard || (useCustomStreamCard && customStreamCard.category)) && ( + + {game || t("noCategory")}  + + )} diff --git a/src/browser/components/modals/BackgroundReset.tsx b/src/browser/components/modals/BackgroundReset.tsx index b79cb3f..a443628 100644 --- a/src/browser/components/modals/BackgroundReset.tsx +++ b/src/browser/components/modals/BackgroundReset.tsx @@ -32,20 +32,20 @@ const styles = { }; interface BackgroundResetProps { - readonly isOpen: boolean; + readonly open: boolean; } -const BackgroundReset: FC = ({ isOpen }) => { +const BackgroundReset: FC = ({ open }) => { return ( - + diff --git a/src/browser/components/modals/Donate.tsx b/src/browser/components/modals/Donate.tsx index ae96e38..8047818 100644 --- a/src/browser/components/modals/Donate.tsx +++ b/src/browser/components/modals/Donate.tsx @@ -66,6 +66,7 @@ const styles = { const links = [ { href: "https://nether0ne.github.io/#/r/streams-live-coinbase", label: t("coinbase") }, + { href: "https://nether0ne.github.io/#/r/streams-live-paypal", label: t("paypal") }, ]; const DonateModal: FC = ({ open, hide }) => { diff --git a/src/browser/components/modals/PlatformExpired.tsx b/src/browser/components/modals/PlatformExpired.tsx new file mode 100644 index 0000000..b14632c --- /dev/null +++ b/src/browser/components/modals/PlatformExpired.tsx @@ -0,0 +1,93 @@ +import { sendRuntimeMessage, t } from "@/common/helpers"; +import { + Fade, + Typography, + Portal, + Backdrop, + Dialog, + DialogTitle, + DialogContent, + DialogContentText, + Button, + DialogActions, + Box, +} from "@mui/material"; +import { FC } from "react"; +import { usePlatform } from "@/browser/common/hooks/platform"; +import { PlatformName } from "@/common/types/platform"; +import { stores } from "@/common/store"; + +interface PlatformExpiredModalProps { + readonly open: boolean; + readonly platformName: PlatformName; +} + +const styles = { + zIndex: 2000, + backdropFilter: "blur(2px)", + "& .header": { + padding: "1rem", + "& .text": { + px: "1rem", + }, + "& .actions": { + px: "1rem", + pb: ".75rem", + }, + }, +}; + +const PlatformExpiredModal: FC = ({ open, platformName }) => { + const [platform] = usePlatform(platformName); + + const handleUnset = async () => { + platform.enabled = false; + platform.data = { + id: null, + name: null, + avatar: null, + }; + platform.followedStreamers = []; + platform.accessToken = undefined; + await stores[platformName].set(platform); + sendRuntimeMessage("updateStreams", true); + }; + + const handleConfirm = () => sendRuntimeMessage("authInit", platformName); + + return ( + + + + + + {t("accessTokenExpired", [t(platformName)])} + + + + + + + + + + + ); +}; + +export default PlatformExpiredModal; diff --git a/src/browser/components/pages/Settings/Extra.tsx b/src/browser/components/pages/Settings/Extra.tsx index bf8b0cf..48c5c48 100644 --- a/src/browser/components/pages/Settings/Extra.tsx +++ b/src/browser/components/pages/Settings/Extra.tsx @@ -6,7 +6,7 @@ import ResetSetting from "./options/extra/Reset"; const ExtraSettings: FC = () => { return ( - + diff --git a/src/browser/components/pages/Settings/General.tsx b/src/browser/components/pages/Settings/General.tsx index 7e3bd6c..fe5b558 100644 --- a/src/browser/components/pages/Settings/General.tsx +++ b/src/browser/components/pages/Settings/General.tsx @@ -16,7 +16,7 @@ const GeneralSettings: FC = () => { const onBadgeChange = async () => await sendRuntimeMessage("updateBadge"); return ( - + { - const [{ notifications }] = useSettings(); + const [settings, store] = useSettings(); + const { notifications } = settings; const setPlatforms = useAllSetPlatforms(); + if (store.isLoading) { + return } sx={styles.loading} />; + } + return ( - + , + }, + platformIcon: { + id: "platformIcon", + label: t("useCustomPlatformIcon"), + icon: , + }, + viewers: { + id: "viewers", + label: t("useCustomViewers"), + icon: , + }, + title: { + id: "title", + label: t("useCustomTitle"), + icon: , + }, + category: { + id: "category", + label: t("useCustomCategory"), + icon: , + }, +}; + +const StreamCardSettings: FC = () => { + const [settings, store] = useSettings(); + const { general } = settings; + const { useCustomStreamCard } = general; + + if (store.isLoading) { + return } sx={styles.loading} />; + } + + return ( + + , + secondaryText: true, + setting: "general.useCustomStreamCard", + }} + /> + + + {Object.values(customStreamCardSettings).map(({ id, icon, label }) => ( + + ))} + + + ); +}; + +export default StreamCardSettings; diff --git a/src/browser/components/pages/Settings/options/SettingLoading.tsx b/src/browser/components/pages/Settings/options/SettingLoading.tsx index b232b50..9126d16 100644 --- a/src/browser/components/pages/Settings/options/SettingLoading.tsx +++ b/src/browser/components/pages/Settings/options/SettingLoading.tsx @@ -1,5 +1,5 @@ import { FC } from "react"; -import { Box, Skeleton, Switch } from "@mui/material"; +import { Box, Skeleton, Switch, SxProps } from "@mui/material"; const styles = { display: "flex", @@ -27,15 +27,17 @@ interface SettingLoadingProps { readonly icon?: JSX.Element; readonly secondaryText?: boolean; readonly withSwitch?: boolean; + readonly sx?: SxProps; } const SettingLoading: FC = ({ secondaryText = true, withSwitch = false, icon, + sx = {}, }) => { - return withSwitch ? ( - + return ( + {icon} @@ -43,14 +45,11 @@ const SettingLoading: FC = ({ {secondaryText && } - - - - - ) : ( - - - {secondaryText && } + {withSwitch && ( + + + + )} ); }; diff --git a/src/browser/components/pages/Settings/options/Switch.tsx b/src/browser/components/pages/Settings/options/Switch.tsx index 928934f..1dfa3ad 100644 --- a/src/browser/components/pages/Settings/options/Switch.tsx +++ b/src/browser/components/pages/Settings/options/Switch.tsx @@ -49,7 +49,7 @@ const SwitchSettings: FC = ({ const [settings, store] = useSettings(); const state = get(settings, setting); - const handleThemeDivClick = () => { + const handleSwitchChange = () => { set(settings, setting, !state); store.set({ @@ -60,7 +60,7 @@ const SwitchSettings: FC = ({ }; return ( - + {store.isLoading ? ( ) : ( diff --git a/src/browser/components/pages/Streams/Settings.tsx b/src/browser/components/pages/Streams/Settings.tsx index 59ad7d4..b62b73c 100644 --- a/src/browser/components/pages/Streams/Settings.tsx +++ b/src/browser/components/pages/Streams/Settings.tsx @@ -1,8 +1,8 @@ import { Box } from "@mui/material"; import { FC } from "react"; -import SortField from "./Settings/SortField"; -import SortDirection from "./Settings/SortDirection"; -import GroupBy from "./Settings/GroupBy"; +import SortField from "./settings/SortField"; +import SortDirection from "./settings/SortDirection"; +import GroupBy from "./settings/GroupBy"; const styles = { display: "flex", diff --git a/src/browser/components/pages/Streams/Settings/GroupBy.tsx b/src/browser/components/pages/Streams/Settings/GroupBy.tsx index f5d77be..f2665c9 100644 --- a/src/browser/components/pages/Streams/Settings/GroupBy.tsx +++ b/src/browser/components/pages/Streams/Settings/GroupBy.tsx @@ -1,7 +1,14 @@ import { ChangeEvent, FC, useContext } from "react"; import { StreamSettingsContext } from "@/browser/common/context/StreamsSettings"; import { GroupBy as GroupByEnum } from "@/common/types/settings"; -import { MenuItem, Skeleton, StandardTextFieldProps, TextField } from "@mui/material"; +import { + MenuItem, + Skeleton, + StandardTextFieldProps, + TextField, + Tooltip, + Typography, +} from "@mui/material"; import { t } from "@/common/helpers"; const loadingStyle = { @@ -54,13 +61,19 @@ const GroupBy: FC = () => { return settingsIsLoading ? ( ) : ( - - {groupByOptions.map((option) => ( - - {t(`${option}GroupBy`)} - - ))} - + {t("groupedBy", [t(`${groupBy}GroupBy`)])}} + placement="top" + > + + {groupByOptions.map((option) => ( + + {t(`${option}GroupBy`)} + + ))} + + ); }; diff --git a/src/browser/components/pages/Streams/Settings/SortDirection.tsx b/src/browser/components/pages/Streams/Settings/SortDirection.tsx index 7aa5fee..7d2fefd 100644 --- a/src/browser/components/pages/Streams/Settings/SortDirection.tsx +++ b/src/browser/components/pages/Streams/Settings/SortDirection.tsx @@ -1,8 +1,9 @@ import { FC, useContext } from "react"; -import { IconButton, Skeleton } from "@mui/material"; +import { IconButton, Skeleton, Tooltip, Typography } from "@mui/material"; import SortIcon from "@mui/icons-material/Sort"; import { StreamSettingsContext } from "@/browser/common/context/StreamsSettings"; import { SortDirection as SortDirectionEnum } from "@/common/types/settings"; +import { t } from "@/common/helpers"; const loadingStyle = { width: "0.75rem", @@ -24,7 +25,7 @@ const buttonStyle = { const SortDirection: FC = () => { const { streamSettings, setStreamsSettings, settingsIsLoading } = useContext(StreamSettingsContext); - const { sortDirection } = streamSettings; + const { sortDirection, sortField } = streamSettings; const changeSortDirection = () => setStreamsSettings({ @@ -35,9 +36,15 @@ const SortDirection: FC = () => { return settingsIsLoading ? ( ) : ( - - - + {t(sortDirection, [t(`${sortField}SortField`)])}} + placement="top" + > + + + + ); }; diff --git a/src/browser/components/pages/Streams/Settings/SortField.tsx b/src/browser/components/pages/Streams/Settings/SortField.tsx index be2a41b..db8257d 100644 --- a/src/browser/components/pages/Streams/Settings/SortField.tsx +++ b/src/browser/components/pages/Streams/Settings/SortField.tsx @@ -1,7 +1,14 @@ import { StreamSettingsContext } from "@/browser/common/context/StreamsSettings"; import { t } from "@/common/helpers"; import { SortField as SortFieldEnum } from "@/common/types/settings"; -import { MenuItem, Skeleton, StandardTextFieldProps, TextField } from "@mui/material"; +import { + MenuItem, + Skeleton, + StandardTextFieldProps, + TextField, + Tooltip, + Typography, +} from "@mui/material"; import { ChangeEvent, FC, useContext } from "react"; const loadingStyle = { @@ -41,7 +48,7 @@ const sortFieldOptions: SortFieldEnum[] = Object.values(SortFieldEnum); const SortField: FC = () => { const { streamSettings, setStreamsSettings, settingsIsLoading } = useContext(StreamSettingsContext); - const { sortField } = streamSettings; + const { sortField, sortDirection } = streamSettings; const changeSortField = (e: ChangeEvent) => setStreamsSettings({ sortField: e.target.value as SortFieldEnum }); @@ -49,13 +56,19 @@ const SortField: FC = () => { return settingsIsLoading ? ( ) : ( - - {sortFieldOptions.map((option) => ( - - {t(`${option}SortField`)} - - ))} - + {t(sortDirection, [t(`${sortField}SortField`)])}} + placement="top" + > + + {sortFieldOptions.map((option) => ( + + {t(`${option}SortField`)} + + ))} + + ); }; diff --git a/src/browser/components/pages/Streams/StreamsGroup.tsx b/src/browser/components/pages/Streams/StreamsGroup.tsx index c1bd09d..090b650 100644 --- a/src/browser/components/pages/Streams/StreamsGroup.tsx +++ b/src/browser/components/pages/Streams/StreamsGroup.tsx @@ -43,7 +43,7 @@ const StreamsGroup: FC = ({ key, group }) => { - {groupBy === GroupBy.PLATFORM ? t(key) : key} + {groupBy === GroupBy.PLATFORM ? t(key) : key || t("noCategory")} )} diff --git a/src/browser/components/pages/Streams/StreamsList.tsx b/src/browser/components/pages/Streams/StreamsList.tsx index 58855d5..23d9cde 100644 --- a/src/browser/components/pages/Streams/StreamsList.tsx +++ b/src/browser/components/pages/Streams/StreamsList.tsx @@ -4,6 +4,7 @@ import { Box, Typography } from "@mui/material"; import Loading from "../../layout/Loading/Loading"; import { StreamSettingsContext } from "@/browser/common/context/StreamsSettings"; import StreamsGroup from "./StreamsGroup"; +import useSettings from "@/browser/common/hooks/settings"; const styles = { display: "flex", @@ -25,10 +26,11 @@ const StreamsList: FC = () => { const { streamGroups, isLoading, settingsIsLoading, streamSettings } = useContext(StreamSettingsContext); const { search } = streamSettings; + const [, store] = useSettings(); return ( - {isLoading || settingsIsLoading ? ( + {isLoading || settingsIsLoading || store.isLoading ? ( ) : Object.keys(streamGroups).length ? ( Object.keys(streamGroups) @@ -39,7 +41,7 @@ const StreamsList: FC = () => { ) : ( - {search === undefined ? t("noStreams") : t("noFilteredStreams")} + {search === "" ? t("noStreams") : t("noFilteredStreams")} )} diff --git a/src/browser/pages/popup.tsx b/src/browser/pages/popup.tsx index 843c71e..da0b25f 100644 --- a/src/browser/pages/popup.tsx +++ b/src/browser/pages/popup.tsx @@ -10,6 +10,8 @@ import { usePingError } from "../common/hooks/pingError"; import BackgroundReset from "../components/modals/BackgroundReset"; import useSettings from "../common/hooks/settings"; import Loading from "../components/layout/Loading/Loading"; +import { useAllExpiredPlatforms } from "../common/hooks/platform"; +import PlatformExpiredModal from "../components/modals/PlatformExpired"; const styles = { height: "550px", @@ -20,6 +22,7 @@ const styles = { const Popup: FC = () => { const [, { isLoading }] = useSettings(); const [error] = usePingError(); + const expiredPlatform = useAllExpiredPlatforms(); return ( @@ -43,7 +46,10 @@ const Popup: FC = () => { - + + {expiredPlatform && ( + + )} )} diff --git a/src/browser/views/Settings.tsx b/src/browser/views/Settings.tsx index b01bb2f..a8e7553 100644 --- a/src/browser/views/Settings.tsx +++ b/src/browser/views/Settings.tsx @@ -5,6 +5,7 @@ import GeneralSettings from "../components/pages/Settings/General"; import NotificationsSettings from "../components/pages/Settings/Notifications"; import ExtraSettings from "../components/pages/Settings/Extra"; import PlatformsSettings from "../components/pages/Settings/Platforms"; +import StreamCardSettings from "../components/pages/Settings/StreamCardSettings"; const styles = { display: "flex", @@ -23,32 +24,40 @@ const styles = { }, }; +const settings = [ + { + label: t("generalSettings"), + component: , + }, + { + label: t("profileSettings"), + component: , + }, + { + label: t("customStreamCard"), + component: , + }, + { + label: t("notificationsSettings"), + component: , + }, + { + label: t("exportAndImportSettings"), + component: , + }, +]; + const Settings: FC = () => { return ( - - {t("generalSettings")} - - - - - - {t("profileSettings")} - - - - - - {t("notificationsSettings")} - - - - - - {t("exportAndImportSettings")} - - - + {settings.map(({ label, component }) => ( + <> + + {label} + + {component} + + ))} ); }; diff --git a/src/common/types/settings.ts b/src/common/types/settings.ts index 0ed138d..7e71f0b 100644 --- a/src/common/types/settings.ts +++ b/src/common/types/settings.ts @@ -1,3 +1,5 @@ +import { StreamCardSettings } from "./stream"; + export enum FontSize { SMALLEST = "smallest", SMALL = "small", @@ -31,6 +33,8 @@ export interface GeneralSettings { fontSize: FontSize; theme: Theme; badge: boolean; + useCustomStreamCard: boolean; + customStreamCard: StreamCardSettings; } export interface NotificationSettings { @@ -59,6 +63,14 @@ export const defaultSettings: Settings = { fontSize: FontSize.MEDIUM, theme: Theme.DARK, badge: true, + useCustomStreamCard: false, + customStreamCard: { + thumbnail: true, + platformIcon: true, + viewers: true, + title: true, + category: true, + }, }, notifications: { enabled: true, diff --git a/src/common/types/stream.ts b/src/common/types/stream.ts index 6619381..644f547 100644 --- a/src/common/types/stream.ts +++ b/src/common/types/stream.ts @@ -22,3 +22,11 @@ export interface StreamError { message: string; platform: PlatformName; } + +export interface StreamCardSettings { + thumbnail: boolean; + platformIcon: boolean; + viewers: boolean; + title: boolean; + category: boolean; +} diff --git a/yarn.lock b/yarn.lock index dee7dc3..74d679b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1196,33 +1196,46 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/gen-mapping@^0.3.0": - version "0.3.1" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz#cf92a983c83466b8c0ce9124fadeaf09f7c66ea9" - integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg== + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== dependencies: - "@jridgewell/set-array" "^1.0.0" + "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" "@jridgewell/resolve-uri@^3.0.3": - version "3.0.7" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe" - integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== "@jridgewell/set-array@^1.0.0": version "1.1.1" resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea" integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ== +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.13" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c" - integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w== + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== "@jridgewell/trace-mapping@^0.3.9": - version "0.3.13" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" - integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -2001,7 +2014,7 @@ balanced-match@^1.0.0: big.js@^5.2.2: version "5.2.2" - resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^2.0.0: @@ -2042,7 +2055,7 @@ browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.20.2, browserslist@^ buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== bytes@^3.0.0: @@ -2237,7 +2250,7 @@ colorette@^2.0.14, colorette@^2.0.16: commander@^2.20.0: version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commander@^7.0.0: @@ -2561,7 +2574,7 @@ emoji-regex@^9.2.2: emojis-list@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== enhanced-resolve@^5.9.2: @@ -3631,7 +3644,7 @@ json5@^1.0.1: json5@^2.1.2, json5@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== jsonfile@^6.0.1: @@ -3736,9 +3749,9 @@ loader-runner@^4.2.0: integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" - integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -3784,11 +3797,6 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - lodash.topath@^4.5.2: version "4.5.2" resolved "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz#3616351f3bba61994a0931989660bd03254fd009" @@ -4803,7 +4811,7 @@ source-map-js@^1.0.2: source-map-support@~0.5.20: version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" @@ -4824,13 +4832,6 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@~0.8.0-beta.0: - version "0.8.0-beta.0" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" - integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== - dependencies: - whatwg-url "^7.0.0" - sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" @@ -5050,13 +5051,13 @@ terser-webpack-plugin@^5.1.3: terser "^5.7.2" terser@^5.10.0, terser@^5.7.2: - version "5.13.1" - resolved "https://registry.npmjs.org/terser/-/terser-5.13.1.tgz#66332cdc5a01b04a224c9fad449fc1a18eaa1799" - integrity sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA== + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== dependencies: + "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" commander "^2.20.0" - source-map "~0.8.0-beta.0" source-map-support "~0.5.20" text-table@^0.2.0: @@ -5103,13 +5104,6 @@ toggle-selection@^1.0.6: resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI= -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= - dependencies: - punycode "^2.1.0" - ts-easing@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec" @@ -5258,11 +5252,6 @@ webextension-polyfill@^0.9.0: resolved "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.9.0.tgz#de6c1941d0ef1b0858b20e9c7b46bbc042c5a960" integrity sha512-LTtHb0yR49xa9irkstDxba4GATDAcDw3ncnFH9RImoFwDlW47U95ME5sn5IiQX2ghfaECaf6xyXM8yvClIBkkw== -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - webpack-cli@^4.9.2: version "4.9.2" resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d" @@ -5324,15 +5313,6 @@ webpack@^5.72.0: watchpack "^2.3.1" webpack-sources "^3.2.3" -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"