mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-29 16:07:40 +01:00
caption keyboard shortcut + searchbar for captions + enabled toggle for keyboard + subtitle padding
Co-authored-by: Jip Frijlink <JipFr@users.noreply.github.com>
This commit is contained in:
parent
ca2bab30a4
commit
9ce0e6a099
6 changed files with 179 additions and 88 deletions
|
@ -1,17 +1,15 @@
|
||||||
import { ReactNode } from "react";
|
import Fuse from "fuse.js";
|
||||||
|
import { ReactNode, useState } from "react";
|
||||||
import { useAsync, useAsyncFn } from "react-use";
|
import { useAsync, useAsyncFn } from "react-use";
|
||||||
|
|
||||||
import {
|
import { languageIdToName } from "@/backend/helpers/subs";
|
||||||
downloadSrt,
|
|
||||||
languageIdToName,
|
|
||||||
searchSubtitles,
|
|
||||||
} from "@/backend/helpers/subs";
|
|
||||||
import { FlagIcon } from "@/components/FlagIcon";
|
import { FlagIcon } from "@/components/FlagIcon";
|
||||||
|
import { useCaptions } from "@/components/player/hooks/useCaptions";
|
||||||
import { Menu } from "@/components/player/internals/ContextMenu";
|
import { Menu } from "@/components/player/internals/ContextMenu";
|
||||||
|
import { Input } from "@/components/player/internals/ContextMenu/Input";
|
||||||
import { SelectableLink } from "@/components/player/internals/ContextMenu/Links";
|
import { SelectableLink } from "@/components/player/internals/ContextMenu/Links";
|
||||||
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
|
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
import { useSubtitleStore } from "@/stores/subtitles";
|
|
||||||
|
|
||||||
export function CaptionOption(props: {
|
export function CaptionOption(props: {
|
||||||
countryCode?: string;
|
countryCode?: string;
|
||||||
|
@ -48,40 +46,22 @@ export function CaptionOption(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO cache like everything in this view
|
// TODO cache like everything in this view
|
||||||
// TODO make quick settings for caption language
|
|
||||||
// TODO fix language names, some are unknown
|
// TODO fix language names, some are unknown
|
||||||
// TODO add search bar for languages
|
|
||||||
// TODO sort languages by common usage
|
// TODO sort languages by common usage
|
||||||
export function CaptionsView({ id }: { id: string }) {
|
export function CaptionsView({ id }: { id: string }) {
|
||||||
const router = useOverlayRouter(id);
|
const router = useOverlayRouter(id);
|
||||||
const setCaption = usePlayerStore((s) => s.setCaption);
|
|
||||||
const lang = usePlayerStore((s) => s.caption.selected?.language);
|
const lang = usePlayerStore((s) => s.caption.selected?.language);
|
||||||
const setLanguage = useSubtitleStore((s) => s.setLanguage);
|
const { search, download, disable } = useCaptions();
|
||||||
const meta = usePlayerStore((s) => s.meta);
|
|
||||||
|
|
||||||
const req = useAsync(async () => {
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
if (!meta) throw new Error("No meta");
|
|
||||||
return searchSubtitles(meta);
|
const req = useAsync(async () => search(), [search]);
|
||||||
}, [meta]);
|
|
||||||
|
|
||||||
const [downloadReq, startDownload] = useAsyncFn(
|
const [downloadReq, startDownload] = useAsyncFn(
|
||||||
async (subtitleId: string, language: string) => {
|
(subtitleId: string, language: string) => download(subtitleId, language),
|
||||||
const srtData = await downloadSrt(subtitleId);
|
[download]
|
||||||
setCaption({
|
|
||||||
language,
|
|
||||||
srtData,
|
|
||||||
url: "", // TODO remove url
|
|
||||||
});
|
|
||||||
setLanguage(language);
|
|
||||||
},
|
|
||||||
[setCaption, setLanguage]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
function disableCaption() {
|
|
||||||
setCaption(null);
|
|
||||||
setLanguage(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
let downloadProgress: ReactNode = null;
|
let downloadProgress: ReactNode = null;
|
||||||
if (downloadReq.loading) downloadProgress = <p>downloading...</p>;
|
if (downloadReq.loading) downloadProgress = <p>downloading...</p>;
|
||||||
else if (downloadReq.error) downloadProgress = <p>failed to download...</p>;
|
else if (downloadReq.error) downloadProgress = <p>failed to download...</p>;
|
||||||
|
@ -89,19 +69,43 @@ export function CaptionsView({ id }: { id: string }) {
|
||||||
let content: ReactNode = null;
|
let content: ReactNode = null;
|
||||||
if (req.loading) content = <p>loading...</p>;
|
if (req.loading) content = <p>loading...</p>;
|
||||||
else if (req.error) content = <p>errored!</p>;
|
else if (req.error) content = <p>errored!</p>;
|
||||||
else if (req.value)
|
else if (req.value) {
|
||||||
content = req.value.map((v) => (
|
const subs = req.value.map((v) => {
|
||||||
|
const languageName = languageIdToName(v.attributes.language) ?? "unknown";
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
languageName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let results = subs;
|
||||||
|
if (searchQuery.trim().length > 0) {
|
||||||
|
const fuse = new Fuse(subs, {
|
||||||
|
includeScore: true,
|
||||||
|
keys: ["languageName"],
|
||||||
|
});
|
||||||
|
|
||||||
|
results = fuse.search(searchQuery).map((res) => res.item);
|
||||||
|
}
|
||||||
|
|
||||||
|
content = results.map((v) => {
|
||||||
|
return (
|
||||||
<CaptionOption
|
<CaptionOption
|
||||||
key={v.id}
|
key={v.id}
|
||||||
countryCode={v.attributes.language}
|
countryCode={v.attributes.language}
|
||||||
selected={lang === v.attributes.language}
|
selected={lang === v.attributes.language}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
startDownload(v.attributes.legacy_subtitle_id, v.attributes.language)
|
startDownload(
|
||||||
|
v.attributes.legacy_subtitle_id,
|
||||||
|
v.attributes.language
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{languageIdToName(v.attributes.language) ?? "unknown"}
|
{v.languageName}
|
||||||
</CaptionOption>
|
</CaptionOption>
|
||||||
));
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -118,9 +122,10 @@ export function CaptionsView({ id }: { id: string }) {
|
||||||
>
|
>
|
||||||
Captions
|
Captions
|
||||||
</Menu.BackLink>
|
</Menu.BackLink>
|
||||||
<Menu.Section>
|
<Menu.Section className="pb-6">
|
||||||
|
<Input value={searchQuery} onInput={setSearchQuery} />
|
||||||
{downloadProgress}
|
{downloadProgress}
|
||||||
<CaptionOption onClick={() => disableCaption()} selected={!lang}>
|
<CaptionOption onClick={() => disable()} selected={!lang}>
|
||||||
Off
|
Off
|
||||||
</CaptionOption>
|
</CaptionOption>
|
||||||
{content}
|
{content}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { useMemo } from "react";
|
||||||
import { languageIdToName } from "@/backend/helpers/subs";
|
import { languageIdToName } from "@/backend/helpers/subs";
|
||||||
import { Toggle } from "@/components/buttons/Toggle";
|
import { Toggle } from "@/components/buttons/Toggle";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
|
import { useCaptions } from "@/components/player/hooks/useCaptions";
|
||||||
import { Menu } from "@/components/player/internals/ContextMenu";
|
import { Menu } from "@/components/player/internals/ContextMenu";
|
||||||
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
|
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
@ -13,27 +14,16 @@ import { providers } from "@/utils/providers";
|
||||||
export function SettingsMenu({ id }: { id: string }) {
|
export function SettingsMenu({ id }: { id: string }) {
|
||||||
const router = useOverlayRouter(id);
|
const router = useOverlayRouter(id);
|
||||||
const currentQuality = usePlayerStore((s) => s.currentQuality);
|
const currentQuality = usePlayerStore((s) => s.currentQuality);
|
||||||
const lastSelectedLanguage = useSubtitleStore((s) => s.lastSelectedLanguage);
|
|
||||||
const selectedCaptionLanguage = usePlayerStore(
|
const selectedCaptionLanguage = usePlayerStore(
|
||||||
(s) => s.caption.selected?.language
|
(s) => s.caption.selected?.language
|
||||||
);
|
);
|
||||||
const subtitlesEnabled = useSubtitleStore((s) => s.enabled);
|
const subtitlesEnabled = useSubtitleStore((s) => s.enabled);
|
||||||
const setSubtitleLanguage = useSubtitleStore((s) => s.setLanguage);
|
|
||||||
const currentSourceId = usePlayerStore((s) => s.sourceId);
|
const currentSourceId = usePlayerStore((s) => s.sourceId);
|
||||||
const setCaption = usePlayerStore((s) => s.setCaption);
|
|
||||||
const sourceName = useMemo(() => {
|
const sourceName = useMemo(() => {
|
||||||
if (!currentSourceId) return "...";
|
if (!currentSourceId) return "...";
|
||||||
return providers.getMetadata(currentSourceId)?.name ?? "...";
|
return providers.getMetadata(currentSourceId)?.name ?? "...";
|
||||||
}, [currentSourceId]);
|
}, [currentSourceId]);
|
||||||
|
const { toggleLastUsed } = useCaptions();
|
||||||
// TODO actually scrape subtitles to load
|
|
||||||
function toggleSubtitles() {
|
|
||||||
if (!subtitlesEnabled) setSubtitleLanguage(lastSelectedLanguage ?? "en");
|
|
||||||
else {
|
|
||||||
setSubtitleLanguage(null);
|
|
||||||
setCaption(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedLanguagePretty = selectedCaptionLanguage
|
const selectedLanguagePretty = selectedCaptionLanguage
|
||||||
? languageIdToName(selectedCaptionLanguage) ?? "unknown"
|
? languageIdToName(selectedCaptionLanguage) ?? "unknown"
|
||||||
|
@ -77,7 +67,7 @@ export function SettingsMenu({ id }: { id: string }) {
|
||||||
rightSide={
|
rightSide={
|
||||||
<Toggle
|
<Toggle
|
||||||
enabled={subtitlesEnabled}
|
enabled={subtitlesEnabled}
|
||||||
onClick={() => toggleSubtitles()}
|
onClick={() => toggleLastUsed().catch(() => {})}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
63
src/components/player/hooks/useCaptions.ts
Normal file
63
src/components/player/hooks/useCaptions.ts
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import { useCallback } from "react";
|
||||||
|
|
||||||
|
import { downloadSrt, searchSubtitles } from "@/backend/helpers/subs";
|
||||||
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
import { useSubtitleStore } from "@/stores/subtitles";
|
||||||
|
|
||||||
|
export function useCaptions() {
|
||||||
|
const setLanguage = useSubtitleStore((s) => s.setLanguage);
|
||||||
|
const enabled = useSubtitleStore((s) => s.enabled);
|
||||||
|
const setCaption = usePlayerStore((s) => s.setCaption);
|
||||||
|
const lastSelectedLanguage = useSubtitleStore((s) => s.lastSelectedLanguage);
|
||||||
|
const meta = usePlayerStore((s) => s.meta);
|
||||||
|
|
||||||
|
const download = useCallback(
|
||||||
|
async (subtitleId: string, language: string) => {
|
||||||
|
const srtData = await downloadSrt(subtitleId);
|
||||||
|
setCaption({
|
||||||
|
language,
|
||||||
|
srtData,
|
||||||
|
url: "", // TODO remove url
|
||||||
|
});
|
||||||
|
setLanguage(language);
|
||||||
|
},
|
||||||
|
[setCaption, setLanguage]
|
||||||
|
);
|
||||||
|
|
||||||
|
const search = useCallback(async () => {
|
||||||
|
if (!meta) throw new Error("No meta");
|
||||||
|
return searchSubtitles(meta);
|
||||||
|
}, [meta]);
|
||||||
|
|
||||||
|
const disable = useCallback(async () => {
|
||||||
|
setCaption(null);
|
||||||
|
setLanguage(null);
|
||||||
|
}, [setCaption, setLanguage]);
|
||||||
|
|
||||||
|
const downloadLastUsed = useCallback(async () => {
|
||||||
|
const language = lastSelectedLanguage ?? "en";
|
||||||
|
const searchResult = await search();
|
||||||
|
const languageResult = searchResult.find(
|
||||||
|
(v) => v.attributes.language === language
|
||||||
|
);
|
||||||
|
if (!languageResult) return false;
|
||||||
|
await download(
|
||||||
|
languageResult.attributes.legacy_subtitle_id,
|
||||||
|
languageResult.attributes.language
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}, [lastSelectedLanguage, search, download]);
|
||||||
|
|
||||||
|
const toggleLastUsed = useCallback(async () => {
|
||||||
|
if (!enabled) await downloadLastUsed();
|
||||||
|
else disable();
|
||||||
|
}, [downloadLastUsed, disable, enabled]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
download,
|
||||||
|
search,
|
||||||
|
disable,
|
||||||
|
downloadLastUsed,
|
||||||
|
toggleLastUsed,
|
||||||
|
};
|
||||||
|
}
|
21
src/components/player/internals/ContextMenu/Input.tsx
Normal file
21
src/components/player/internals/ContextMenu/Input.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
|
|
||||||
|
export function Input(props: {
|
||||||
|
value: string;
|
||||||
|
onInput: (str: string) => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="w-full relative mb-6">
|
||||||
|
<Icon
|
||||||
|
className="pointer-events-none absolute top-1/2 left-3 transform -translate-y-1/2 text-video-context-inputPlaceholder"
|
||||||
|
icon={Icons.SEARCH}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
placeholder="Search"
|
||||||
|
className="w-full py-2 px-3 pl-[calc(0.75rem+24px)] bg-video-context-inputBg rounded placeholder:text-video-context-inputPlaceholder"
|
||||||
|
value={props.value}
|
||||||
|
onInput={(e) => props.onInput(e.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
import { useCaptions } from "@/components/player/hooks/useCaptions";
|
||||||
import { useVolume } from "@/components/player/hooks/useVolume";
|
import { useVolume } from "@/components/player/hooks/useVolume";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
import { useEmpheralVolumeStore } from "@/stores/volume";
|
import { useEmpheralVolumeStore } from "@/stores/volume";
|
||||||
|
@ -10,6 +11,7 @@ export function KeyboardEvents() {
|
||||||
const time = usePlayerStore((s) => s.progress.time);
|
const time = usePlayerStore((s) => s.progress.time);
|
||||||
const { setVolume, toggleMute } = useVolume();
|
const { setVolume, toggleMute } = useVolume();
|
||||||
|
|
||||||
|
const { toggleLastUsed } = useCaptions();
|
||||||
const setShowVolume = useEmpheralVolumeStore((s) => s.setShowVolume);
|
const setShowVolume = useEmpheralVolumeStore((s) => s.setShowVolume);
|
||||||
|
|
||||||
const [isRolling, setIsRolling] = useState(false);
|
const [isRolling, setIsRolling] = useState(false);
|
||||||
|
@ -20,6 +22,7 @@ export function KeyboardEvents() {
|
||||||
setVolume,
|
setVolume,
|
||||||
toggleMute,
|
toggleMute,
|
||||||
setIsRolling,
|
setIsRolling,
|
||||||
|
toggleLastUsed,
|
||||||
display,
|
display,
|
||||||
mediaPlaying,
|
mediaPlaying,
|
||||||
isRolling,
|
isRolling,
|
||||||
|
@ -31,6 +34,7 @@ export function KeyboardEvents() {
|
||||||
setVolume,
|
setVolume,
|
||||||
toggleMute,
|
toggleMute,
|
||||||
setIsRolling,
|
setIsRolling,
|
||||||
|
toggleLastUsed,
|
||||||
display,
|
display,
|
||||||
mediaPlaying,
|
mediaPlaying,
|
||||||
isRolling,
|
isRolling,
|
||||||
|
@ -41,6 +45,7 @@ export function KeyboardEvents() {
|
||||||
setVolume,
|
setVolume,
|
||||||
toggleMute,
|
toggleMute,
|
||||||
setIsRolling,
|
setIsRolling,
|
||||||
|
toggleLastUsed,
|
||||||
display,
|
display,
|
||||||
mediaPlaying,
|
mediaPlaying,
|
||||||
isRolling,
|
isRolling,
|
||||||
|
@ -49,6 +54,9 @@ export function KeyboardEvents() {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const keyEventHandler = (evt: KeyboardEvent) => {
|
const keyEventHandler = (evt: KeyboardEvent) => {
|
||||||
|
if (evt.target && (evt.target as HTMLInputElement).nodeName === "INPUT")
|
||||||
|
return;
|
||||||
|
|
||||||
const k = evt.key;
|
const k = evt.key;
|
||||||
|
|
||||||
// Volume
|
// Volume
|
||||||
|
@ -83,6 +91,9 @@ export function KeyboardEvents() {
|
||||||
dataRef.current.mediaPlaying.isPaused ? "play" : "pause"
|
dataRef.current.mediaPlaying.isPaused ? "play" : "pause"
|
||||||
]();
|
]();
|
||||||
|
|
||||||
|
// captions
|
||||||
|
if (k === "c") dataRef.current.toggleLastUsed().catch(() => {}); // ignore errors
|
||||||
|
|
||||||
// Do a barrell roll!
|
// Do a barrell roll!
|
||||||
if (k === "r") {
|
if (k === "r") {
|
||||||
if (dataRef.current.isRolling || evt.ctrlKey || evt.metaKey) return;
|
if (dataRef.current.isRolling || evt.ctrlKey || evt.metaKey) return;
|
||||||
|
|
|
@ -26,23 +26,23 @@ module.exports = {
|
||||||
"ash-400": "#3D394D",
|
"ash-400": "#3D394D",
|
||||||
"ash-300": "#2C293A",
|
"ash-300": "#2C293A",
|
||||||
"ash-200": "#2B2836",
|
"ash-200": "#2B2836",
|
||||||
"ash-100": "#1E1C26",
|
"ash-100": "#1E1C26"
|
||||||
},
|
},
|
||||||
|
|
||||||
/* fonts */
|
/* fonts */
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
"open-sans": "'Open Sans'",
|
"open-sans": "'Open Sans'"
|
||||||
},
|
},
|
||||||
|
|
||||||
/* animations */
|
/* animations */
|
||||||
keyframes: {
|
keyframes: {
|
||||||
"loading-pin": {
|
"loading-pin": {
|
||||||
"0%, 40%, 100%": { height: "0.5em", "background-color": "#282336" },
|
"0%, 40%, 100%": { height: "0.5em", "background-color": "#282336" },
|
||||||
"20%": { height: "1em", "background-color": "white" },
|
"20%": { height: "1em", "background-color": "white" }
|
||||||
},
|
}
|
||||||
},
|
|
||||||
animation: { "loading-pin": "loading-pin 1.8s ease-in-out infinite" },
|
|
||||||
},
|
},
|
||||||
|
animation: { "loading-pin": "loading-pin 1.8s ease-in-out infinite" }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
require("tailwind-scrollbar"),
|
require("tailwind-scrollbar"),
|
||||||
|
@ -52,31 +52,31 @@ module.exports = {
|
||||||
colors: {
|
colors: {
|
||||||
// Branding
|
// Branding
|
||||||
pill: {
|
pill: {
|
||||||
background: "#1C1C36",
|
background: "#1C1C36"
|
||||||
},
|
},
|
||||||
|
|
||||||
// meta data for the theme itself
|
// meta data for the theme itself
|
||||||
global: {
|
global: {
|
||||||
accentA: "#505DBD",
|
accentA: "#505DBD",
|
||||||
accentB: "#3440A1",
|
accentB: "#3440A1"
|
||||||
},
|
},
|
||||||
|
|
||||||
// light bar
|
// light bar
|
||||||
lightBar: {
|
lightBar: {
|
||||||
light: "#2A2A71",
|
light: "#2A2A71"
|
||||||
},
|
},
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
buttons: {
|
buttons: {
|
||||||
toggle: "#8D44D6",
|
toggle: "#8D44D6",
|
||||||
toggleDisabled: "#202836",
|
toggleDisabled: "#202836"
|
||||||
},
|
},
|
||||||
|
|
||||||
// only used for body colors/textures
|
// only used for body colors/textures
|
||||||
background: {
|
background: {
|
||||||
main: "#0A0A10",
|
main: "#0A0A10",
|
||||||
accentA: "#6E3B80",
|
accentA: "#6E3B80",
|
||||||
accentB: "#1F1F50",
|
accentB: "#1F1F50"
|
||||||
},
|
},
|
||||||
|
|
||||||
// typography
|
// typography
|
||||||
|
@ -85,7 +85,7 @@ module.exports = {
|
||||||
text: "#73739D",
|
text: "#73739D",
|
||||||
dimmed: "#926CAD",
|
dimmed: "#926CAD",
|
||||||
divider: "#262632",
|
divider: "#262632",
|
||||||
secondary: "#64647B",
|
secondary: "#64647B"
|
||||||
},
|
},
|
||||||
|
|
||||||
// search bar
|
// search bar
|
||||||
|
@ -94,7 +94,7 @@ module.exports = {
|
||||||
focused: "#24243C",
|
focused: "#24243C",
|
||||||
placeholder: "#4A4A71",
|
placeholder: "#4A4A71",
|
||||||
icon: "#545476",
|
icon: "#545476",
|
||||||
text: "#FFFFFF",
|
text: "#FFFFFF"
|
||||||
},
|
},
|
||||||
|
|
||||||
// media cards
|
// media cards
|
||||||
|
@ -106,7 +106,7 @@ module.exports = {
|
||||||
barColor: "#4B4B63",
|
barColor: "#4B4B63",
|
||||||
barFillColor: "#BA7FD6",
|
barFillColor: "#BA7FD6",
|
||||||
badge: "#151522",
|
badge: "#151522",
|
||||||
badgeText: "#5F5F7A",
|
badgeText: "#5F5F7A"
|
||||||
},
|
},
|
||||||
|
|
||||||
// video player
|
// video player
|
||||||
|
@ -118,17 +118,17 @@ module.exports = {
|
||||||
error: "#E44F4F",
|
error: "#E44F4F",
|
||||||
success: "#40B44B",
|
success: "#40B44B",
|
||||||
loading: "#B759D8",
|
loading: "#B759D8",
|
||||||
noresult: "#64647B",
|
noresult: "#64647B"
|
||||||
},
|
},
|
||||||
|
|
||||||
progress: {
|
progress: {
|
||||||
background: "#8787A8",
|
background: "#8787A8",
|
||||||
preloaded: "#8787A8",
|
preloaded: "#8787A8",
|
||||||
watched: "#A75FC9",
|
watched: "#A75FC9"
|
||||||
},
|
},
|
||||||
|
|
||||||
audio: {
|
audio: {
|
||||||
set: "#A75FC9",
|
set: "#A75FC9"
|
||||||
},
|
},
|
||||||
|
|
||||||
buttons: {
|
buttons: {
|
||||||
|
@ -137,7 +137,7 @@ module.exports = {
|
||||||
secondaryHover: "#1B262E",
|
secondaryHover: "#1B262E",
|
||||||
primary: "#fff",
|
primary: "#fff",
|
||||||
primaryText: "#000",
|
primaryText: "#000",
|
||||||
primaryHover: "#dedede",
|
primaryHover: "#dedede"
|
||||||
},
|
},
|
||||||
|
|
||||||
context: {
|
context: {
|
||||||
|
@ -148,30 +148,31 @@ module.exports = {
|
||||||
buttonFocus: "#202836",
|
buttonFocus: "#202836",
|
||||||
flagBg: "#202836",
|
flagBg: "#202836",
|
||||||
inputBg: "#202836",
|
inputBg: "#202836",
|
||||||
|
inputPlaceholder: "#374A56",
|
||||||
cardBorder: "#1B262E",
|
cardBorder: "#1B262E",
|
||||||
slider: "#8787A8",
|
slider: "#8787A8",
|
||||||
sliderFilled: "#A75FC9",
|
sliderFilled: "#A75FC9",
|
||||||
|
|
||||||
download: {
|
download: {
|
||||||
button: "#6b298a",
|
button: "#6b298a",
|
||||||
hover: "#7f35a1",
|
hover: "#7f35a1"
|
||||||
},
|
},
|
||||||
|
|
||||||
buttons: {
|
buttons: {
|
||||||
list: "#161C26",
|
list: "#161C26",
|
||||||
active: "#0D1317",
|
active: "#0D1317"
|
||||||
},
|
},
|
||||||
|
|
||||||
type: {
|
type: {
|
||||||
main: "#617A8A",
|
main: "#617A8A",
|
||||||
secondary: "#374A56",
|
secondary: "#374A56",
|
||||||
accent: "#A570FA",
|
accent: "#A570FA"
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}),
|
})
|
||||||
],
|
]
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue