diff --git a/.vscode/settings.json b/.vscode/settings.json index 25fa6215..6dd09e34 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "editor.defaultFormatter": "esbenp.prettier-vscode" } diff --git a/app/renderer/src/assets/audios/notification/clock-alarm.mp3 b/app/renderer/src/assets/audios/notification/clock-alarm.mp3 new file mode 100644 index 00000000..53c2713d Binary files /dev/null and b/app/renderer/src/assets/audios/notification/clock-alarm.mp3 differ diff --git a/app/renderer/src/assets/audios/notification/pomodoro.mp3 b/app/renderer/src/assets/audios/notification/pomodoro.mp3 new file mode 100644 index 00000000..c355ddb0 Binary files /dev/null and b/app/renderer/src/assets/audios/notification/pomodoro.mp3 differ diff --git a/app/renderer/src/assets/audios/notification/treasure.mp3 b/app/renderer/src/assets/audios/notification/treasure.mp3 new file mode 100644 index 00000000..ff101229 Binary files /dev/null and b/app/renderer/src/assets/audios/notification/treasure.mp3 differ diff --git a/app/renderer/src/assets/audios/notification/trumpets.mp3 b/app/renderer/src/assets/audios/notification/trumpets.mp3 new file mode 100644 index 00000000..68dad2d8 Binary files /dev/null and b/app/renderer/src/assets/audios/notification/trumpets.mp3 differ diff --git a/app/renderer/src/components/Collapse.tsx b/app/renderer/src/components/Collapse.tsx index 86d7f57e..6f8b39e7 100644 --- a/app/renderer/src/components/Collapse.tsx +++ b/app/renderer/src/components/Collapse.tsx @@ -1,16 +1,23 @@ +import { SVG } from "components"; import React, { useState } from "react"; import { StyledCollapse, - StyledCollapseHeading, StyledCollapseContent, + StyledCollapseContentResponsive, + StyledCollapseHeading, } from "styles"; -import { SVG } from "components"; type Props = { children?: React.ReactNode; + title?: string; + heightResponsive?: boolean; }; -const Collapse: React.FC = ({ children }) => { +const Collapse: React.FC = ({ + children, + title, + heightResponsive = false, +}) => { const [open, setOpen] = useState(false); const toggleCollapse = () => { @@ -19,17 +26,25 @@ const Collapse: React.FC = ({ children }) => { return ( - - Notification Types - - - {open && ( - {children} + {title && ( + + {title} + + )} + {open ? ( + heightResponsive ? ( + + {children} + + ) : ( + {children} + ) + ) : null} ); }; diff --git a/app/renderer/src/components/index.ts b/app/renderer/src/components/index.ts index fc701198..ac495b37 100644 --- a/app/renderer/src/components/index.ts +++ b/app/renderer/src/components/index.ts @@ -4,18 +4,18 @@ export { default as RangeLabel } from "./RangeLabel"; export { default as RangeSlider } from "./RangeSlider"; export { default as Time } from "./Time"; +export { default as Help } from "./Help"; +export { default as Shortcut } from "./Shortcut"; export * from "./Toggler"; export { default as Toggler } from "./Toggler"; -export { default as Shortcut } from "./Shortcut"; -export { default as Help } from "./Help"; export { default as Header } from "./Header"; export * from "./SVG"; export { default as SVG } from "./SVG"; -export { default as Portal } from "./Portal"; export { default as Dimmer } from "./Dimmer"; +export { default as Portal } from "./Portal"; export { default as Checkbox } from "./Checkbox"; export { default as Radio } from "./Radio"; @@ -23,8 +23,8 @@ export { default as Radio } from "./Radio"; export { default as Collapse } from "./Collapse"; export { default as Alert } from "./Alert"; -export { default as Updater } from "./Updater"; export { default as NavNotify } from "./NavNotify"; +export { default as Updater } from "./Updater"; export * from "./Popper"; export * from "./Preloader"; diff --git a/app/renderer/src/contexts/CounterContext.tsx b/app/renderer/src/contexts/CounterContext.tsx index 9e9f9c96..ba398359 100644 --- a/app/renderer/src/contexts/CounterContext.tsx +++ b/app/renderer/src/contexts/CounterContext.tsx @@ -1,8 +1,8 @@ -import React, { useState, useEffect, useCallback } from "react"; -import useStayAwake from "use-stay-awake"; -import { setRound, setTimerType, setPlay } from "store"; import { useNotification } from "hooks"; -import { padNum, isEqualToOne } from "utils"; +import React, { useCallback, useEffect, useState } from "react"; +import { setPlay, setRound, setTimerType } from "store"; +import useStayAwake from "use-stay-awake"; +import { isEqualToOne, padNum } from "utils"; import notificationIcon from "assets/logos/notification-dark.png"; @@ -44,6 +44,7 @@ const CounterProvider: React.FC = ({ children }) => { { icon: notificationIcon, mute: !settings.notificationSoundOn, + notificationSounds: settings.notificationSounds, }, settings.notificationType !== "none" ); @@ -106,72 +107,30 @@ const CounterProvider: React.FC = ({ children }) => { padNum(date.getHours()) + ":" + padNum(date.getMinutes()); if (timer.timerType !== TimerStatus.SPECIAL_BREAK) { - if (firstBreak && currentTime === firstBreak.fromTime) { - dispatch(setTimerType(TimerStatus.SPECIAL_BREAK)); - setTimerDuration(firstBreak.duration); - notification( - "Special break started.", - { - body: `Enjoy your ${firstBreak.duration} ${ - isEqualToOne(firstBreak.duration) - ? "minute" - : "minutes" - } special break.`, - }, - specialBreakStartedWav - ); - return; - } - - if (secondBreak && currentTime === secondBreak.fromTime) { - dispatch(setTimerType(TimerStatus.SPECIAL_BREAK)); - setTimerDuration(secondBreak.duration); - notification( - "Special break started.", - { - body: `Enjoy your ${secondBreak.duration} ${ - isEqualToOne(secondBreak.duration) - ? "minute" - : "minutes" - } special break.`, - }, - specialBreakStartedWav - ); - return; - } - - if (thirdBreak && currentTime === thirdBreak.fromTime) { - dispatch(setTimerType(TimerStatus.SPECIAL_BREAK)); - setTimerDuration(thirdBreak.duration); - notification( - "Special break started.", - { - body: `Enjoy your ${thirdBreak.duration} ${ - isEqualToOne(thirdBreak.duration) - ? "minute" - : "minutes" - } special break.`, - }, - specialBreakStartedWav - ); - return; - } - - if (fourthBreak && currentTime === fourthBreak.fromTime) { - dispatch(setTimerType(TimerStatus.SPECIAL_BREAK)); - setTimerDuration(fourthBreak.duration); - notification( - "Special break started.", - { - body: `Enjoy your ${fourthBreak.duration} ${ - isEqualToOne(fourthBreak.duration) - ? "minute" - : "minutes" - } special break.`, - }, - specialBreakStartedWav - ); - return; + const breaks = [ + firstBreak, + secondBreak, + thirdBreak, + fourthBreak, + ]; + + for (const breakTime of breaks) { + if (breakTime && currentTime === breakTime.fromTime) { + dispatch(setTimerType(TimerStatus.SPECIAL_BREAK)); + setTimerDuration(breakTime.duration); + notification( + "Special break started.", + { + body: `Enjoy your ${breakTime.duration} ${ + isEqualToOne(breakTime.duration) + ? "minute" + : "minutes" + } special break.`, + }, + specialBreakStartedWav + ); + return; + } } } else { return clearInterval(interval); @@ -225,27 +184,46 @@ const CounterProvider: React.FC = ({ children }) => { }, [timer.playing]); useEffect(() => { + const timerMessages = { + [TimerStatus.SHORT_BREAK]: + "Prepare yourself to stay focused again.", + [TimerStatus.LONG_BREAK]: + "Prepare yourself to stay focused again.", + [TimerStatus.SPECIAL_BREAK]: + "Prepare yourself to stay focused again.", + [TimerStatus.STAY_FOCUS]: + "Pause all media playing if there's one.", + }; + + const timerEndMessages = { + [TimerStatus.STAY_FOCUS]: { + message: "Focus time finished.", + nextType: TimerStatus.SHORT_BREAK, + sound: focusFinishedWav, + }, + [TimerStatus.SHORT_BREAK]: { + message: "Break time finished.", + nextType: TimerStatus.STAY_FOCUS, + sound: breakFinishedWav, + }, + [TimerStatus.LONG_BREAK]: { + message: "Break time finished.", + nextType: TimerStatus.STAY_FOCUS, + sound: breakFinishedWav, + }, + [TimerStatus.SPECIAL_BREAK]: { + message: "Break time finished.", + nextType: TimerStatus.STAY_FOCUS, + sound: sessionCompletedWav, + }, + }; if (settings.notificationType === "extra") { if (count === 61) { - if (timer.timerType === TimerStatus.SHORT_BREAK) { - notification( - "60 seconds left.", - { body: "Prepare yourself to stay focused again." }, - settings.enableVoiceAssistance && sixtySecondsLeftWav - ); - } else if (timer.timerType === TimerStatus.LONG_BREAK) { - notification( - "60 seconds left.", - { body: "Prepare yourself to stay focused again." }, - settings.enableVoiceAssistance && sixtySecondsLeftWav - ); - } else if (timer.timerType === TimerStatus.SPECIAL_BREAK) { - notification( - "60 seconds left.", - { body: "Prepare yourself to stay focused again." }, - settings.enableVoiceAssistance && sixtySecondsLeftWav - ); - } + notification( + "60 seconds left.", + { body: timerMessages[timer.timerType] }, + settings.enableVoiceAssistance && sixtySecondsLeftWav + ); } else if ( count === 31 && timer.timerType === TimerStatus.STAY_FOCUS @@ -259,110 +237,36 @@ const CounterProvider: React.FC = ({ children }) => { } if (count === 0) { - switch (timer.timerType) { - case TimerStatus.STAY_FOCUS: - if (timer.round < config.sessionRounds) { - setTimeout(() => { - notification( - "Focus time finished.", - { - body: `Enjoy your ${config.shortBreak} ${ - isEqualToOne(config.shortBreak) - ? "minute" - : "minutes" - } short break.`, - }, - settings.enableVoiceAssistance && focusFinishedWav - ); - - dispatch(setTimerType(TimerStatus.SHORT_BREAK)); - }, 1000); - } else { - setTimeout(() => { - notification( - "Session rounds completed.", - { - body: `Enjoy your ${config.longBreak} ${ - isEqualToOne(config.longBreak) - ? "minute" - : "minutes" - } long break.`, - }, - settings.enableVoiceAssistance && sessionCompletedWav - ); - - dispatch(setTimerType(TimerStatus.LONG_BREAK)); - }, 1000); - } - break; - - case TimerStatus.SHORT_BREAK: - setTimeout(() => { - notification( - "Break time finished.", - { - body: `Stay focused as much as possible for ${ - config.stayFocus - } ${ - isEqualToOne(config.stayFocus) ? "minute" : "minutes" - }.`, - }, - settings.enableVoiceAssistance && breakFinishedWav - ); - - dispatch(setTimerType(TimerStatus.STAY_FOCUS)); - dispatch(setRound(timer.round + 1)); - - if (!settings.autoStartWorkTime) { - dispatch(setPlay(false)); - } - }, 1000); - break; - - case TimerStatus.LONG_BREAK: - setTimeout(() => { - notification( - "Break time finished.", - { - body: `Stay focused as much as possible for ${ - config.stayFocus - } ${ - isEqualToOne(config.stayFocus) ? "minute" : "minutes" - }.`, - }, - settings.enableVoiceAssistance && breakFinishedWav - ); + const timerEndMessage = timerEndMessages[timer.timerType]; + if (timerEndMessage) { + setTimeout(() => { + notification( + timerEndMessage.message, + { + body: `Enjoy your ${config[timerEndMessage.nextType]} ${ + isEqualToOne(config[timerEndMessage.nextType]) + ? "minute" + : "minutes" + } ${timerEndMessage.nextType.replace("_", " ")}.`, + }, + settings.enableVoiceAssistance && timerEndMessage.sound + ); - dispatch(setTimerType(TimerStatus.STAY_FOCUS)); - dispatch(setRound(1)); + dispatch(setTimerType(timerEndMessage.nextType)); - if (!settings.autoStartWorkTime) { - dispatch(setPlay(false)); - } - }, 1000); - break; - - case TimerStatus.SPECIAL_BREAK: - setTimeout(() => { - notification( - "Break time finished.", - { - body: `Stay focused as much as possible for ${ - config.stayFocus - } ${ - isEqualToOne(config.stayFocus) ? "minute" : "minutes" - }.`, - }, - settings.enableVoiceAssistance && breakFinishedWav + if (timerEndMessage.nextType === TimerStatus.STAY_FOCUS) { + dispatch( + setRound( + timer.timerType === TimerStatus.SHORT_BREAK + ? timer.round + 1 + : 1 + ) ); - - dispatch(setTimerType(TimerStatus.STAY_FOCUS)); - if (!settings.autoStartWorkTime) { dispatch(setPlay(false)); } - }, 1000); - break; + } + }, 1000); } } }, [ @@ -379,6 +283,7 @@ const CounterProvider: React.FC = ({ children }) => { settings.notificationType, settings.autoStartWorkTime, settings.enableVoiceAssistance, + config, ]); useEffect(() => { diff --git a/app/renderer/src/hooks/useNotification.ts b/app/renderer/src/hooks/useNotification.ts index db3e22f2..bcc92696 100644 --- a/app/renderer/src/hooks/useNotification.ts +++ b/app/renderer/src/hooks/useNotification.ts @@ -1,7 +1,11 @@ import bell from "assets/audios/notification-bell.wav"; +import pomodoro from "assets/audios/notification/pomodoro.mp3"; +import trumpets from "assets/audios/notification/trumpets.mp3"; +import { NotificationSounds } from "store/settings/types"; type OptionProps = { mute?: boolean; + notificationSounds: NotificationSounds; } & NotificationOptions; export const useNotification = ( @@ -23,7 +27,20 @@ export const useNotification = ( // in all Operating System if (!constantOptions?.mute) { - new Audio(bell).play().catch((e) => { + let sound; + + switch (constantOptions?.notificationSounds) { + case NotificationSounds.MULTI: + sound = pomodoro; + break; + case NotificationSounds.CUSTOM: + sound = trumpets; + break; + default: + sound = bell; + } + + new Audio(sound).play().catch((e) => { console.warn("There was a problem playing sound", e); }); diff --git a/app/renderer/src/routes/Settings/FeatureSection.tsx b/app/renderer/src/routes/Settings/FeatureSection.tsx index 89bbf89e..154fc986 100644 --- a/app/renderer/src/routes/Settings/FeatureSection.tsx +++ b/app/renderer/src/routes/Settings/FeatureSection.tsx @@ -1,25 +1,30 @@ -import React, { useCallback, useContext } from "react"; +import { Collapse, Radio, Toggler, TogglerProps } from "components"; +import { ThemeContext } from "contexts"; import { useAppDispatch, useAppSelector } from "hooks/storeHooks"; +import React, { useCallback, useContext } from "react"; import { setAlwaysOnTop, - setEnableStrictMode, - setEnableProgressAnimation, - setNotificationType, - setEnableFullscreenBreak, - setUseNativeTitlebar, setAutoStartWorkTime, - setMinimizeToTray, setCloseToTray, - setEnableVoiceAssistance, setEnableCompactMode, + setEnableFullscreenBreak, + setEnableProgressAnimation, + setEnableStrictMode, + setEnableVoiceAssistance, + setMinimizeToTray, + setNotificationSounds, + setNotificationType, setOpenAtLogin, + setUseNativeTitlebar, } from "store"; -import { Toggler, TogglerProps, Collapse, Radio } from "components"; -import { ThemeContext } from "contexts"; -import SettingSection from "./SettingSection"; +import { + NotificationSounds, + NotificationTypes, +} from "store/settings/types"; import { detectOS } from "utils"; -import { NotificationTypes } from "store/settings/types"; +import SettingSection from "./SettingSection"; +import NotificationSoundsSetting from "./notficationSounds/NotificationSoundsSetting"; const FeatureSection: React.FC = () => { const settings = useAppSelector((state) => state.settings); @@ -149,6 +154,15 @@ const FeatureSection: React.FC = () => { [dispatch] ); + const onChangeNotificationSound = useCallback( + (e: React.ChangeEvent) => { + dispatch( + setNotificationSounds(e.target.value as NotificationSounds) + ); + }, + [dispatch] + ); + return ( {featureList.map( @@ -163,7 +177,7 @@ const FeatureSection: React.FC = () => { /> ) )} - + { onChange={onChangeNotificationProps} /> + ); }; diff --git a/app/renderer/src/routes/Settings/notficationSounds/NotificationSoundsSetting.tsx b/app/renderer/src/routes/Settings/notficationSounds/NotificationSoundsSetting.tsx new file mode 100644 index 00000000..7e72aabe --- /dev/null +++ b/app/renderer/src/routes/Settings/notficationSounds/NotificationSoundsSetting.tsx @@ -0,0 +1,67 @@ +import { Collapse, Radio } from "components"; +import { useAppDispatch, useAppSelector } from "hooks/storeHooks"; +import React, { useCallback } from "react"; +import { setNotificationSounds } from "store"; + +import { NotificationSounds } from "store/settings/types"; +import { + StyleSectionSubHeading, + StyledSectionSubSection, +} from "styles"; + +const NotificationSoundsSetting: React.FC = () => { + const settings = useAppSelector((state) => state.settings); + + const dispatch = useAppDispatch(); + + const onChangeNotificationSound = useCallback( + (e: React.ChangeEvent) => { + dispatch( + setNotificationSounds(e.target.value as NotificationSounds) + ); + }, + [dispatch] + ); + + return ( + + + + Notifcation Sounds Types + + + + + + + ); +}; + +export default NotificationSoundsSetting; diff --git a/app/renderer/src/routes/Timer/Control/Control.tsx b/app/renderer/src/routes/Timer/Control/Control.tsx index 6f1bb82a..bedfffd5 100644 --- a/app/renderer/src/routes/Timer/Control/Control.tsx +++ b/app/renderer/src/routes/Timer/Control/Control.tsx @@ -1,22 +1,22 @@ import WarningBell from "assets/audios/warning-bell.wav"; import { SVG } from "components"; -import React, { useCallback, useEffect, useState } from "react"; import { useAppDispatch, useAppSelector } from "hooks/storeHooks"; -import { TimerStatus } from "store/timer/types"; +import React, { useCallback, useEffect, useState } from "react"; import { setEnableCompactMode, setPlay, setRound, setTimerType, skipTimer, - toggleNotificationSound, + toggleNotificationSounds, } from "store"; +import { TimerStatus } from "store/timer/types"; import { StyledControl, StyledControlMain, + StyledControlSpacer, StyledStrictIndicator, StyledStrictSnackbar, - StyledControlSpacer, } from "styles"; import CompactModeButton from "./CompactModeButton"; import PlayButton from "./PlayButton"; @@ -77,7 +77,7 @@ const Control: React.FC = ({ resetTimerAction }) => { ]); const onNotifacationSoundCallback = useCallback(() => { - dispatch(toggleNotificationSound()); + dispatch(toggleNotificationSounds()); }, [dispatch]); const onToggleCompactCallback = useCallback(() => { diff --git a/app/renderer/src/store/settings/defaultSettings.ts b/app/renderer/src/store/settings/defaultSettings.ts index d8c2de55..f7575625 100644 --- a/app/renderer/src/store/settings/defaultSettings.ts +++ b/app/renderer/src/store/settings/defaultSettings.ts @@ -1,5 +1,9 @@ -import { NotificationTypes, SettingTypes } from "./types"; import { detectOS, isPreferredDark } from "utils"; +import { + NotificationSounds, + NotificationTypes, + SettingTypes, +} from "./types"; export const defaultSettings: Readonly = Object.freeze({ alwaysOnTop: false, @@ -12,6 +16,7 @@ export const defaultSettings: Readonly = Object.freeze({ enableVoiceAssistance: false, notificationSoundOn: true, notificationType: NotificationTypes.NONE, + notificationSounds: NotificationSounds.DEFAULT, closeToTray: true, minimizeToTray: false, autoStartWorkTime: false, diff --git a/app/renderer/src/store/settings/index.ts b/app/renderer/src/store/settings/index.ts index a7de5d0b..7ceb52ec 100644 --- a/app/renderer/src/store/settings/index.ts +++ b/app/renderer/src/store/settings/index.ts @@ -1,7 +1,7 @@ import { createSlice } from "@reduxjs/toolkit"; import { getFromStorage } from "utils"; -import { SettingTypes, SettingsPayload } from "./types"; import { defaultSettings } from "./defaultSettings"; +import { SettingTypes, SettingsPayload } from "./types"; export type { SettingTypes }; @@ -23,7 +23,7 @@ const settingsSlice = createSlice({ state.alwaysOnTop = action.payload; }, - toggleNotificationSound(state) { + toggleNotificationSounds(state) { state.notificationSoundOn = !state.notificationSoundOn; }, @@ -83,6 +83,13 @@ const settingsSlice = createSlice({ state.notificationType = action.payload; }, + setNotificationSounds( + state, + action: SettingsPayload<"notificationSounds"> + ) { + state.notificationSounds = action.payload; + }, + setCloseToTray(state, action: SettingsPayload<"closeToTray">) { state.closeToTray = action.payload; }, @@ -125,9 +132,10 @@ export const { setIgnoreUpdate, setMinimizeToTray, setNotificationType, + setNotificationSounds, setOpenAtLogin, setUseNativeTitlebar, - toggleNotificationSound, + toggleNotificationSounds, } = settingsSlice.actions; export default settingsSlice.reducer; diff --git a/app/renderer/src/store/settings/types.ts b/app/renderer/src/store/settings/types.ts index 90bf3443..2f008fca 100644 --- a/app/renderer/src/store/settings/types.ts +++ b/app/renderer/src/store/settings/types.ts @@ -15,9 +15,16 @@ export type SettingTypes = { minimizeToTray: boolean; autoStartWorkTime: boolean; notificationType: NotificationTypes; + notificationSounds: NotificationSounds; openAtLogin: boolean; }; +export const enum NotificationSounds { + DEFAULT = "default", // Windows sound.... + MULTI = "multi", + CUSTOM = "custom", +} + export const enum NotificationTypes { NONE = "none", NORMAL = "normal", diff --git a/app/renderer/src/styles/components/collapse.ts b/app/renderer/src/styles/components/collapse.ts index 50cc5cc8..43bfaa07 100644 --- a/app/renderer/src/styles/components/collapse.ts +++ b/app/renderer/src/styles/components/collapse.ts @@ -88,3 +88,9 @@ export const StyledCollapseContent = styled.div` } } `; + +export const StyledCollapseContentResponsive = styled( + StyledCollapseContent +)` + height: auto; +`; diff --git a/app/renderer/src/styles/components/index.ts b/app/renderer/src/styles/components/index.ts index c54af9da..e05c01f6 100644 --- a/app/renderer/src/styles/components/index.ts +++ b/app/renderer/src/styles/components/index.ts @@ -1,19 +1,19 @@ +export * from "./alert"; +export * from "./button"; +export * from "./checkbox"; +export * from "./collapse"; +export * from "./dimmer"; +export * from "./header"; +export * from "./help"; +export * from "./input"; export * from "./layout"; +export * from "./loaders"; export * from "./navigation"; -export * from "./svg"; -export * from "./titlebar"; +export * from "./popper"; export * from "./range"; -export * from "./time"; -export * from "./header"; -export * from "./toggler"; export * from "./shortcuts"; -export * from "./help"; -export * from "./button"; -export * from "./input"; +export * from "./svg"; export * from "./textarea"; -export * from "./dimmer"; -export * from "./checkbox"; -export * from "./popper"; -export * from "./loaders"; -export * from "./collapse"; -export * from "./alert"; +export * from "./time"; +export * from "./titlebar"; +export * from "./toggler"; diff --git a/app/renderer/src/styles/routes/settings.ts b/app/renderer/src/styles/routes/settings.ts index 6c0c5479..90f57a2a 100644 --- a/app/renderer/src/styles/routes/settings.ts +++ b/app/renderer/src/styles/routes/settings.ts @@ -1,7 +1,7 @@ import styled from "styled-components/macro"; -import { themes } from "styles/themes"; -import { StyledScrollbar } from "styles/mixins"; import { StyledButtonSecondary } from "styles"; +import { StyledScrollbar } from "styles/mixins"; +import { themes } from "styles/themes"; export const StyledSettings = styled.main` width: 100%; @@ -47,6 +47,15 @@ export const StyledSectionHeading = styled.h4` text-transform: uppercase; `; +export const StyleSectionSubHeading = styled.h5` + font-size: 0.9rem; + font-weight: 500; + + color: var(--color-disabled-text); + + text-transform: uppercase; +`; + export const StyledStarButton = styled(StyledButtonSecondary)` & > svg { margin-left: -1rem; @@ -72,3 +81,9 @@ export const StyledSectionSticky = styled.div` padding-top: 2rem; `; + +export const StyledSectionSubSection = styled.div` + display: flex; + flex-direction: column; + gap: 1rem; +`; diff --git a/app/renderer/src/typings.d.ts b/app/renderer/src/typings.d.ts index 71a8ca22..8373e06f 100644 --- a/app/renderer/src/typings.d.ts +++ b/app/renderer/src/typings.d.ts @@ -3,6 +3,7 @@ declare module "*.woff2"; declare module "*.png"; declare module "*.jpg"; declare module "*.wav"; +declare module "*.mp3"; declare module "*.mp4"; declare module "*.ogv"; declare module "*.webm";