diff --git a/README.md b/README.md index cc7ef10..65f6f84 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,9 @@ AniX is an unofficial web client for the Android application Anixart. It allows ## Changelog [RU] +- [3.7.0](./public/changelog/3.7.0.md) - [3.6.0](./public/changelog/3.6.0.md) - [3.5.0](./public/changelog/3.5.0.md) -- [3.4.0](./public/changelog/3.4.0.md) -- [3.3.0](./public/changelog/3.3.0.md) [other versions](./public/changelog) diff --git a/app/api/config.ts b/app/api/config.ts index 0746eb2..ec8fffd 100644 --- a/app/api/config.ts +++ b/app/api/config.ts @@ -1,4 +1,4 @@ -export const CURRENT_APP_VERSION = "3.6.0"; +export const CURRENT_APP_VERSION = "3.7.0"; export const API_URL = "https://api.anixart.tv"; export const API_PREFIX = "/api/proxy"; diff --git a/app/components/Comments/Comments.Comment.tsx b/app/components/Comments/Comments.Comment.tsx index 4b2953c..c19f561 100644 --- a/app/components/Comments/Comments.Comment.tsx +++ b/app/components/Comments/Comments.Comment.tsx @@ -84,9 +84,17 @@ export const CommentsComment = (props: { url += `&token=${props.token}`; } await fetch(url) - .then((res) => res.json()) + .then((res) => { + if (res.ok) { + return res.json(); + } else { + return { content: [] }; + } + }) .then((data) => { - setReplies(data.content); + if (data && data.content) { + setReplies(data.content); + } }); } if ( @@ -194,9 +202,9 @@ export const CommentsComment = (props: {

- {!props.comment.isDeleted - ? props.comment.message - : "Комментарий был удалён."} + {!props.comment.isDeleted ? + props.comment.message + : "Комментарий был удалён."}

{isHidden && ( - ) : ( - - )} + : }

0 - ? "text-green-500 dark:text-green-400" - : likes < 0 - ? "text-red-500 dark:text-red-400" - : "text-gray-500 dark:text-gray-400" + likes > 0 ? "text-green-500 dark:text-green-400" + : likes < 0 ? "text-red-500 dark:text-red-400" + : "text-gray-500 dark:text-gray-400" }`} > {likes} @@ -282,9 +286,9 @@ export const CommentsComment = (props: { > diff --git a/app/components/Comments/Comments.Main.tsx b/app/components/Comments/Comments.Main.tsx index 3411918..c4c1ec3 100644 --- a/app/components/Comments/Comments.Main.tsx +++ b/app/components/Comments/Comments.Main.tsx @@ -41,7 +41,7 @@ export const CommentsMain = (props: {

- {props.comments.map((comment: any) => ( + {props.comments && props.comments.map((comment: any) => ( { - let anonEpisodesWatched = getAnonEpisodesWatched( - props.release_id, - props.source.id, - props.voiceover.id - ); - anonEpisodesWatched = - anonEpisodesWatched[props.release_id][props.source.id][props.voiceover.id]; - - async function saveEpisodeToHistory(episode: Episode) { - if (episode && props.token) { - fetch( - `${ENDPOINTS.statistic.addHistory}/${props.release_id}/${props.source.id}/${episode.position}?token=${props.token}` - ); - fetch( - `${ENDPOINTS.statistic.markWatched}/${props.release_id}/${props.source.id}/${episode.position}?token=${props.token}` - ); - } - } - - return ( -
- - {props.availableEpisodes.map((episode: Episode) => ( - - - - ))} - -
- ); -}; diff --git a/app/components/ReleasePlayer/EpisodeSelectorMenu.tsx b/app/components/ReleasePlayer/EpisodeSelectorMenu.tsx new file mode 100644 index 0000000..ab03540 --- /dev/null +++ b/app/components/ReleasePlayer/EpisodeSelectorMenu.tsx @@ -0,0 +1,133 @@ +"use client"; + +import { ENDPOINTS } from "#/api/config"; +import { useEffect, useState } from "react"; +import { _fetchAPI } from "./PlayerParsing"; + +import { Voiceover } from "./VoiceoverSelectorMenu"; +import { Source } from "./SourceSelectorMenu"; +import { getAnonEpisodesWatched } from "./ReleasePlayer"; + +export interface Episode { + position: number; + name: string; + is_watched: boolean; +} +interface EpisodeSelectorMenuProps { + release_id: number; + voiceover: Voiceover; + source: Source; + token: string | null; + setEpisode: (state) => void; + episode: Episode; + episodeList: Episode[]; + setPlayerError: (state) => void; +} + +export const EpisodeSelectorMenu = ({ + release_id, + token, + voiceover, + source, + setEpisode, + episode, + episodeList, + setPlayerError, +}: EpisodeSelectorMenuProps) => { + const [watchedEpisodes, setWatchedEpisodes] = useState([]); + useEffect(() => { + const __getInfo = async () => { + let url = `${ENDPOINTS.release.episode}/${release_id}/${voiceover.id}/${source.id}`; + if (token) { + url += `?token=${token}`; + } + const episodes = await _fetchAPI( + url, + "Не удалось получить информацию о эпизодах", + setPlayerError + ); + if (episodes) { + let anonEpisodesWatched = getAnonEpisodesWatched( + release_id, + source.id, + voiceover.id + ); + let lastEpisodeWatched = Math.max.apply( + 0, + Object.keys(anonEpisodesWatched[release_id][source.id][voiceover.id]) + ); + let selectedEpisode = + episodes.episodes.find( + (episode: Episode) => episode.position == lastEpisodeWatched + ) || episodes.episodes[0]; + + setEpisode({ + selected: selectedEpisode, + available: episodes.episodes, + }); + } + }; + if (source) { + __getInfo(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [source]); + + useEffect(() => { + if (release_id && source && voiceover) { + const anonEpisodesWatched = getAnonEpisodesWatched( + release_id, + source.id, + voiceover.id + ); + setWatchedEpisodes( + anonEpisodesWatched[release_id][source.id][voiceover.id] + ); + } + }, [release_id, source, voiceover]); + + if (!voiceover || !source || !episode) return <> + + return ( +
+

Эпизод

+
+ {episodeList && episodeList.length > 0 ? + episodeList.map((epis: Episode) => { + return ( + + ); + }) + : ""} +
+
+ ); +}; diff --git a/app/components/ReleasePlayer/MediaPlayer.module.css b/app/components/ReleasePlayer/MediaPlayer.module.css new file mode 100644 index 0000000..28b47a9 --- /dev/null +++ b/app/components/ReleasePlayer/MediaPlayer.module.css @@ -0,0 +1,630 @@ +.media-controller { + --_primary-color: var(--media-primary-color, #fff); + --_secondary-color: var(--media-secondary-color, transparent); + --_accent-color: var(--media-accent-color, #fff); + + --base: 18px; + + font-size: calc(0.75 * var(--base)); + font-family: Roboto, Arial, sans-serif; + --media-font-family: Roboto, helvetica neue, segoe ui, arial, sans-serif; + -webkit-font-smoothing: antialiased; + + --media-primary-color: #fff; + --media-secondary-color: transparent; + --media-menu-background: rgba(28, 28, 28, 0.8); + --media-text-color: var(--_primary-color); + --media-control-hover-background: var(--media-secondary-color); + + --media-range-track-height: calc(0.125 * var(--base)); + --media-range-thumb-height: var(--base); + --media-range-thumb-width: var(--base); + --media-range-thumb-border-radius: var(--base); + + --media-control-height: calc(2 * var(--base)); +} + +.media-controller[breakpointmd] { + --base: 20px; +} + +/* The biggest size controller is tied to going fullscreen + instead of a player width */ +.media-controller[mediaisfullscreen] { + --base: 24px; +} + +.media-controller:not([mediaisfullscreen]) { + border-radius: 8px; +} + +.media-control-bar { + position: absolute; + height: calc(2 * var(--base)); + line-height: calc(2 * var(--base)); + bottom: calc(1 * var(--base)); + left: var(--base); + right: var(--base); +} + +.media-button { + --media-control-hover-background: var(--_secondary-color); + --media-tooltip-background: rgb(28 28 28 / 0.24); + --media-text-content-height: 1.2; + --media-tooltip-padding: 0.7em 1em; + --media-tooltip-distance: 8px; + --media-tooltip-container-margin: 18px; + position: relative; + padding: 0; + opacity: 0.9; + transition: opacity 0.1s cubic-bezier(0.4, 0, 1, 1); +} + +.svg { + fill: none; + stroke: var(--_primary-color, #fff); + stroke-width: 1; + stroke-linecap: "round"; + stroke-linejoin: "round"; +} + +.svg .svg-shadow { + stroke: #000; + stroke-opacity: 0.15; + stroke-width: 2px; + fill: none; +} + +.media-gradient-bottom { + position: absolute; + bottom: 0; + width: 100%; + height: calc(12 * var(--base)); + pointer-events: none; +} + +.media-gradient-bottom::before { + content: ""; + --gradient-steps: + hsl(0 0% 0% / 0) 0%, hsl(0 0% 0% / 0.013) 8.1%, hsl(0 0% 0% / 0.049) 15.5%, + hsl(0 0% 0% / 0.104) 22.5%, hsl(0 0% 0% / 0.175) 29%, + hsl(0 0% 0% / 0.259) 35.3%, hsl(0 0% 0% / 0.352) 41.2%, + hsl(0 0% 0% / 0.45) 47.1%, hsl(0 0% 0% / 0.55) 52.9%, + hsl(0 0% 0% / 0.648) 58.8%, hsl(0 0% 0% / 0.741) 64.7%, + hsl(0 0% 0% / 0.825) 71%, hsl(0 0% 0% / 0.896) 77.5%, + hsl(0 0% 0% / 0.951) 84.5%, hsl(0 0% 0% / 0.987) 91.9%, hsl(0 0% 0%) 100%; + + position: absolute; + inset: 0; + opacity: 0.7; + background: linear-gradient(to bottom, var(--gradient-steps)); +} + +.media-gradient-top { + position: absolute; + top: 0; + width: 100%; + height: calc(8 * var(--base)); + pointer-events: none; +} + +.media-gradient-top::before { + content: ""; + --gradient-steps: + hsl(0 0% 0% / 0) 0%, hsl(0 0% 0% / 0.013) 8.1%, hsl(0 0% 0% / 0.049) 15.5%, + hsl(0 0% 0% / 0.104) 22.5%, hsl(0 0% 0% / 0.175) 29%, + hsl(0 0% 0% / 0.259) 35.3%, hsl(0 0% 0% / 0.352) 41.2%, + hsl(0 0% 0% / 0.45) 47.1%, hsl(0 0% 0% / 0.55) 52.9%, + hsl(0 0% 0% / 0.648) 58.8%, hsl(0 0% 0% / 0.741) 64.7%, + hsl(0 0% 0% / 0.825) 71%, hsl(0 0% 0% / 0.896) 77.5%, + hsl(0 0% 0% / 0.951) 84.5%, hsl(0 0% 0% / 0.987) 91.9%, hsl(0 0% 0%) 100%; + + position: absolute; + inset: 0; + opacity: 0.7; + background: linear-gradient(to top, var(--gradient-steps)); +} + +.anime-title { + position: absolute; + height: calc(2 * var(--base)); + top: calc(0.5 * var(--base)); + left: var(--base); + right: var(--base); +} + +.media-settings-menu { + --media-menu-icon-height: 20px; + --media-menu-item-icon-height: 20px; + --media-settings-menu-min-width: calc(10 * var(--base)); + --media-menu-transform-in: translateY(0) scale(1); + --media-menu-transform-out: translateY(20px) rotate(3deg) scale(1); + padding-block: calc(0.15 * var(--base)); + margin-right: 10px; + margin-bottom: 17px; + border-radius: 8px; + z-index: 2; + user-select: none; +} + +.media-source-dialog { + --media-menu-icon-height: 20px; + --media-menu-item-icon-height: 20px; + --media-settings-menu-min-width: calc(10 * var(--base)); + --media-settings-menu-min-height: calc(2 * var(--base)); + --media-menu-transform-in: translateY(0) scale(1); + --media-menu-transform-out: translateY(20px) rotate(3deg) scale(1); + background: rgba(28, 28, 28, 0.8); + min-width: var(--media-settings-menu-min-width, 170px); + min-height: var(--media-settings-menu-min-height, 170px); + position: absolute; + right: 10px; + bottom: calc(3 * var(--base)); + padding: 0; + padding-block: calc(0.15 * var(--base)); + padding-inline: calc(0.6 * var(--base)); + margin-right: 10px; + margin-bottom: 17px; + border-radius: 8px; + user-select: none; + width: fit-content; + max-height: fit-content; + z-index: 5; +} + +@media (min-width: 640px) { + .media-source-dialog { + max-height: 50%; + } +} + +@media (min-width: 1280px) { + .media-controller[mediaisfullscreen] .media-source-dialog { + max-height: 30%; + } +} + +.media-controller media-chrome-dialog > div { + word-wrap: normal !important; +} + +.media-settings-menu[hidden] { + display: block; + visibility: visible; + opacity: 0; +} + +.media-settings-menu-item, +.media-controller [role="menu"]::part(menu-item) { + --media-icon-color: var(--_primary-color); + margin-inline: calc(0.45 * var(--base)); + height: calc(1.6 * var(--base)); + font-size: calc(0.7 * var(--base)); + font-weight: 400; + padding: 0; + padding-left: calc(0.4 * var(--base)); + padding-right: calc(0.1 * var(--base)); + border-radius: 6px; + text-shadow: none; +} + +.media-controller [slot="submenu"]::part(back button) { + font-size: calc(0.7 * var(--base)); +} + +.media-settings-menu-item:hover { + --media-icon-color: #000; + color: #000; + background-color: #fff; +} + +.media-settings-menu-item:hover [slot="submenu"]::part(menu-item), +.media-controller [slot="submenu"]::part(back indicator) { + --media-icon-color: var(--_primary-color); +} + +.media-settings-menu-item:hover [slot="submenu"]::part(menu-item):hover { + --media-icon-color: #000; + color: #000; + background-color: #fff; +} + +.media-settings-menu-item[submenusize="0"] { + display: none; +} + +.quality-settings[submenusize="1"] { + display: none; +} + +@keyframes bounce-scale-play { + 0% { + transform: scale(0.75, 0.75); + } + 50% { + transform: scale(115%, 115%); + } + 100% { + transform: scale(1, 1); + } +} + +.media-button { + border-radius: 25%; + backdrop-filter: blur(10px) invert(15%) brightness(80%) opacity(0); + -webkit-backdrop-filter: blur(10px) invert(15%) brightness(80%) opacity(0); + transition: + backdrop-filter 0.3s, + -webkit-backdrop-filter 0.3s, + box-shadow 0.3s; +} + +.media-button:hover { + /* background-color: rgba(0, 0, 0, 0.05); */ + box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 5px; + /* hue-rotate(120deg) */ + backdrop-filter: blur(10px) invert(15%) brightness(80%) opacity(1); + -webkit-backdrop-filter: blur(10px) invert(15%) brightness(80%) opacity(1); + transition: + backdrop-filter 0.3s, + -webkit-backdrop-filter 0.3s; +} + +.media-play-button .icon-play { + opacity: 0; + transform-box: view-box; + transform-origin: center center; + transform: scale(0.5, 0.5); + transition: all 0.5s; +} + +.media-play-button[mediapaused] .icon-play { + opacity: 1; + transform: scale(1, 1); + animation: 0.35s bounce-scale-play ease-in-out; +} + +@keyframes bounce-pause-left { + 0% { + font-size: 10px; + } + 50% { + font-size: 3px; + } + 100% { + font-size: 4px; + } +} + +@keyframes bounce-pause-right { + 0% { + font-size: 10px; + transform: translateX(-8px); + } + 50% { + font-size: 3px; + transform: translateX(1px); + } + 100% { + font-size: 4px; + transform: translateX(0); + } +} + +.media-play-button .pause-left, +.media-play-button .pause-right { + font-size: 4px; + opacity: 1; + transform: translateX(0); + transform-box: view-box; +} + +.media-play-button:not([mediapaused]) .pause-left { + animation: 0.3s bounce-pause-left ease-out; +} + +.media-play-button:not([mediapaused]) .pause-right { + animation: 0.3s bounce-pause-right ease-out; +} + +.media-play-button[mediapaused] .pause-left, +.media-play-button[mediapaused] .pause-right { + opacity: 0; + font-size: 10px; +} + +.media-play-button[mediapaused] .pause-right { + transform-origin: right center; + transform: translateX(-8px); +} + +.media-settings-menu-button svg { + transition: transform 0.1s cubic-bezier(0.4, 0, 1, 1); + transform: rotateZ(0deg); +} +.media-settings-menu-button[aria-expanded="true"] svg { + transform: rotateZ(30deg); +} + +.media-time-display { + position: relative; + padding: calc(0.5 * var(--base)); + font-size: calc(0.7 * var(--base)); + border-radius: calc(0.5 * var(--base)); +} + +.media-controller[breakpointmd] .media-time-display:not([showduration]) { + display: none; +} + +.media-controller:not([breakpointmd]) .media-time-display[showduration] { + display: none; +} + +.media-time-range { + height: calc(2 * var(--base)); + border-radius: calc(0.25 * var(--base)); + + --media-range-track-backdrop-filter: invert(10%) blur(5px) brightness(110%); + --media-range-track-background: rgba(255, 255, 255, 0.2); + --media-range-track-pointer-background: rgba(255, 255, 255, 0.5); + --media-range-track-border-radius: calc(0.25 * var(--base)); + + --media-time-range-buffered-color: rgba(255, 255, 255, 0.4); + --media-range-bar-color: var(--media-accent-color); + + --media-range-thumb-background: var(--media-accent-color); + --media-range-thumb-transition: opacity 0.1s linear; + --media-range-thumb-opacity: 0; + + --media-preview-thumbnail-border: calc(0.125 * var(--base)) solid #fff; + --media-preview-thumbnail-border-radius: calc(0.5 * var(--base)); + --media-preview-thumbnail-min-width: calc(8 * var(--base)); + --media-preview-thumbnail-max-width: calc(10 * var(--base)); + --media-preview-thumbnail-min-height: calc(5 * var(--base)); + --media-preview-thumbnail-max-height: calc(7 * var(--base)); + --media-preview-box-margin: 0 0 -10px; +} +.media-time-range:hover { + --media-range-thumb-opacity: 1; + --media-range-track-height: calc(0.25 * var(--base)); +} + +.media-preview-time-display { + font-size: calc(0.65 * var(--base)); + padding-top: 0; +} + +.media-mute-button { + position: relative; + opacity: 1; +} + +.media-mute-button .muted-path { + transition: clip-path 0.2s ease-out; +} + +.media-mute-button .muted-path-2 { + transition-delay: 0.2s; +} + +.media-mute-button .muted-path { + clip-path: inset(0); +} + +.media-mute-button:not([mediavolumelevel="off"]) .muted-path-1 { + clip-path: inset(0 0 100% 0); +} + +.media-mute-button:not([mediavolumelevel="off"]) .muted-path-2 { + clip-path: inset(0 0 100% 0); +} + +.media-mute-button .muted-path { + opacity: 0; +} + +.media-mute-button[mediavolumelevel="off"] .muted-path { + opacity: 1; +} + +.media-mute-button .vol-path { + opacity: 1; + transition: opacity 0.4s; +} + +.media-mute-button[mediavolumelevel="off"] .vol-path { + opacity: 0; +} + +.media-mute-button[mediavolumelevel="low"] .vol-high-path, +.media-mute-button[mediavolumelevel="medium"] .vol-high-path { + opacity: 0; +} + +.media-volume-range { + --media-range-track-background: rgba(255, 255, 255, 0.2); + --media-range-thumb-opacity: 0; +} + +@keyframes volume-in { + 0% { + visibility: hidden; + opacity: 0; + transform: translateY(50%) rotate(1deg); + } + 50% { + visibility: visible; + opacity: 1; + transform: rotate(-2deg); + } + 100% { + visibility: visible; + opacity: 1; + transform: translateY(0) rotate(0deg); + } +} + +@keyframes volume-out { + 0% { + visibility: visible; + opacity: 1; + transform: translateY(0) rotate(0deg); + } + 50% { + opacity: 1; + transform: rotate(0deg); + } + 100% { + visibility: hidden; + opacity: 0; + transform: translateY(50%) rotate(1deg); + } +} + +.media-volume-range-wrapper { + opacity: 0; + visibility: hidden; + + position: absolute; + top: -100%; + left: calc(4 * var(--base)); + + width: calc(10 * var(--base)); + height: calc(2.5 * var(--base)); + transform-origin: center left; +} + +.media-volume-range { + /* + Hide range and animation until mediavolume attribute is set. + visibility didn't work, hovering over media-volume-range-wrapper + caused it to show. Should require mute-button:hover. + */ + opacity: 0; + transition: opacity 0s 1s; + + width: calc(10 * var(--base)); + height: var(--base); + padding: 0; + border-radius: calc(0.25 * var(--base)); + overflow: hidden; + background: rgba(0, 0, 0, 0.2); + + --media-range-bar-color: var(--media-accent-color); + + --media-range-padding-left: 0; + --media-range-padding-right: 0; + + --media-range-track-width: calc(10 * var(--base)); + --media-range-track-height: var(--base); + --media-range-track-border-radius: calc(0.25 * var(--base)); + --media-range-track-backdrop-filter: blur(10px) brightness(80%); + + /* This makes zero volume still show some of the bar. + I can't make the bar have curved corners otherwise though. */ + --media-range-thumb-width: var(--base); + --media-range-thumb-border-radius: calc(0.25 * var(--base)); + + /* The Sutro design has a gradient like this, but not sure I like it */ + /* --media-range-thumb-box-shadow: 10px 0px 20px rgba(255, 255, 255, 0.5); */ +} + +.media-volume-range[mediavolume] { + opacity: 1; +} + +.media-controller[keyboardcontrol] .media-volume-range:focus { + /* TODO: This appears to be creating a think outline */ + outline: 1px solid rgba(27, 127, 204, 0.9); +} + +.media-mute-button:hover + .media-volume-range-wrapper, +.media-mute-button:focus + .media-volume-range-wrapper, +.media-mute-button:focus-within + .media-volume-range-wrapper, +.media-volume-range-wrapper:hover, +.media-volume-range-wrapper:focus, +.media-volume-range-wrapper:focus-within { + animation: 0.3s volume-in forwards ease-out; +} + +.media-volume-range-wrapper:not(:hover, :focus-within) { + animation: 0.3s volume-out ease-out; +} + +/* When keyboard navigating the volume range and wrapper need to always be visible + otherwise focus state can't land on it. This is ok when keyboard navigating because + the hovering issues aren't a concern, unless you happen to be keyboard AND mouse navigating. + */ +.media-controller[keyboardcontrol] .media-volume-range-wrapper, +.media-controller[keyboardcontrol] .media-volume-range-wrapper:focus-within, +.media-controller[keyboardcontrol] + .media-volume-range-wrapper:focus-within + .media-volume-range { + visibility: visible; +} + +/* Having trouble getting @property to work in the shadow dom + to clean this up. Like https://codepen.io/luwes/pen/oNRyZyx */ + +.media-fullscreen-button .fs-arrow { + translate: 0% 0%; +} +.media-fullscreen-button:hover .fs-arrow { + animation: 0.35s up-left-bounce cubic-bezier(0.34, 1.56, 0.64, 1); +} +.media-fullscreen-button:hover .fs-enter-top, +.media-fullscreen-button:hover .fs-exit-bottom { + animation-name: up-right-bounce; +} + +.media-fullscreen-button:hover .fs-enter-bottom, +.media-fullscreen-button:hover .fs-exit-top { + animation-name: down-left-bounce; +} + +@keyframes up-left-bounce { + 0% { + translate: 0 0; + } + 50% { + translate: -4% -4%; + } +} +@keyframes up-right-bounce { + 0% { + translate: 0 0; + } + 50% { + translate: 4% -4%; + } +} +@keyframes down-left-bounce { + 0% { + translate: 0 0; + } + 50% { + translate: -4% 4%; + } +} +@keyframes down-right-bounce { + 0% { + translate: 0 0; + } + 50% { + translate: 4% 4%; + } +} + +.media-controller:not([breakpointmd]) .media-pip-button { + display: none; +} + +.media-controller media-rendition-menu[mediarenditionunavailable], +.media-controller media-volume-range[mediavolumeunavailable], +.media-controller media-airplay-button[mediaairplayunavailable], +.media-controller media-fullscreen-button[mediafullscreenunavailable], +.media-controller media-cast-button[mediacastunavailable], +.media-controller media-pip-button[mediapipunavailable] { + display: none; +} diff --git a/app/components/ReleasePlayer/MediaThemeSutro.tsx b/app/components/ReleasePlayer/MediaThemeSutro.tsx deleted file mode 100644 index 7ebb900..0000000 --- a/app/components/ReleasePlayer/MediaThemeSutro.tsx +++ /dev/null @@ -1,760 +0,0 @@ -import "media-chrome/react"; -import "media-chrome/react/menu"; -import { MediaTheme } from "media-chrome/react/media-theme"; - -export default function Page(props: { children: any, className?: string }) { - return ( - <> -