Skip to content

Commit

Permalink
Subscriptions to channels added
Browse files Browse the repository at this point in the history
Filter added that removes characters that Operating Systems don't allow in filenames when saving file

VideoList-styles.tsx uses Radio button instead of Checkbox for main page video/playlist filter

Video player has aspect ratio of 16 / 9, doesn't put controls over video, and removes controls if mouse exits video when in fullscreen (but only when playing for some reason)

Created new redux slice called settingsSlice.ts. It is used to store settings that are saved to disk automatically
  • Loading branch information
QortalSeth committed Feb 8, 2024
1 parent 5e5f190 commit 6fd206d
Show file tree
Hide file tree
Showing 21 changed files with 2,283 additions and 1,839 deletions.
496 changes: 338 additions & 158 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@mui/icons-material": "^5.11.11",
"@mui/lab": "^5.0.0-alpha.163",
"@mui/material": "^5.11.13",
"@reduxjs/toolkit": "^1.9.3",
"compressorjs": "^1.2.1",
Expand All @@ -29,6 +30,7 @@
"react-rnd": "^10.4.1",
"react-router-dom": "^6.9.0",
"react-toastify": "^9.1.2",
"redux-persist": "^6.0.0",
"short-unique-id": "^4.4.4",
"ts-key-enum": "^2.0.12"
},
Expand Down
36 changes: 22 additions & 14 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,36 @@ import { VideoContent } from "./pages/VideoContent/VideoContent";
import DownloadWrapper from "./wrappers/DownloadWrapper";
import { IndividualProfile } from "./pages/IndividualProfile/IndividualProfile";
import { PlaylistContent } from "./pages/PlaylistContent/PlaylistContent";
import { PersistGate } from "redux-persist/integration/react";
import { persistStore } from "redux-persist";

function App() {
// const themeColor = window._qdnTheme

const [theme, setTheme] = useState("dark");
let persistor = persistStore(store);

return (
<Provider store={store}>
<ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
<Notification />
<DownloadWrapper>
<GlobalWrapper setTheme={(val: string) => setTheme(val)}>
<CssBaseline />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/video/:name/:id" element={<VideoContent />} />
<Route path="/playlist/:name/:id" element={<PlaylistContent />} />
<Route path="/channel/:name" element={<IndividualProfile />} />
</Routes>
</GlobalWrapper>
</DownloadWrapper>
</ThemeProvider>
<PersistGate loading={null} persistor={persistor}>
<ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
<Notification />
<DownloadWrapper>
<GlobalWrapper setTheme={(val: string) => setTheme(val)}>
<CssBaseline />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/video/:name/:id" element={<VideoContent />} />
<Route
path="/playlist/:name/:id"
element={<PlaylistContent />}
/>
<Route path="/channel/:name" element={<IndividualProfile />} />
</Routes>
</GlobalWrapper>
</DownloadWrapper>
</ThemeProvider>
</PersistGate>
</Provider>
);
}
Expand Down
30 changes: 26 additions & 4 deletions src/components/common/SubscribeButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
import { Button, ButtonProps } from "@mui/material";
import { MouseEvent } from "react";
import { MouseEvent, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../state/store.ts";
import { subscribe, unSubscribe } from "../../state/features/videoSlice.ts";

interface SubscribeButtonProps extends ButtonProps {
name: string;
}

const isSubscribed = false;
export const SubscribeButton = ({ name, ...props }: SubscribeButtonProps) => {
const dispatch = useDispatch();
const select = useSelector((state: RootState) => {
return state.video;
});
const [isSubscribed, setIsSubscribed] = useState<boolean>(false);

useEffect(() => {
setIsSubscribed(select.subscriptionList.includes(name));
}, []);

const subscribeToRedux = () => {
dispatch(subscribe(name));
setIsSubscribed(true);
};
const unSubscribeFromRedux = () => {
dispatch(unSubscribe(name));
setIsSubscribed(false);
};

const manageSubscription = (e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
e.stopPropagation();
console.log("subscribed to: ", name);
isSubscribed ? unSubscribeFromRedux() : subscribeToRedux();
};

const verticalPadding = "3px";
const horizontalPadding = "8px";
const buttonStyle = {
Expand All @@ -23,7 +45,7 @@ export const SubscribeButton = ({ name, ...props }: SubscribeButtonProps) => {
paddingLeft: horizontalPadding,
paddingRight: horizontalPadding,
borderRadius: 28,
display: "none",
height: "40px",
};
return (
<Button
Expand Down
32 changes: 32 additions & 0 deletions src/components/common/VideoPlayer/VideoPlayer-styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { styled } from "@mui/system";
import { Box } from "@mui/material";

export const VideoContainer = styled(Box)`
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
max-height: 70vh;
`;

export const VideoElement = styled("video")`
width: 100%;
background: rgb(33, 33, 33);
max-height: 70vh;
`;

export const ControlsContainer = styled(Box)`
position: absolute;
display: flex;
align-items: center;
justify-content: space-between;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.6);
`;
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,20 @@ import {
VolumeOff,
} from "@mui/icons-material";
import { styled } from "@mui/system";
import { MyContext } from "../../wrappers/DownloadWrapper";
import { MyContext } from "../../../wrappers/DownloadWrapper.tsx";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../state/store";
import { RootState } from "../../../state/store.ts";
import { Refresh } from "@mui/icons-material";

import { Menu, MenuItem } from "@mui/material";
import { MoreVert as MoreIcon } from "@mui/icons-material";
import { setVideoPlaying } from "../../state/features/globalSlice";
const VideoContainer = styled(Box)`
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
max-height: 70vh;
`;

const VideoElement = styled("video")`
width: 100%;
height: auto;
background: rgb(33, 33, 33);
max-height: 70vh;
`;

const ControlsContainer = styled(Box)`
position: absolute;
display: flex;
align-items: center;
justify-content: space-between;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.6);
`;
import { setVideoPlaying } from "../../../state/features/globalSlice.ts";
import {
ControlsContainer,
VideoContainer,
VideoElement,
} from "./VideoPlayer-styles.ts";
import CSS from "csstype";

interface VideoPlayerProps {
src?: string;
Expand All @@ -65,6 +41,7 @@ interface VideoPlayerProps {
nextVideo?: any;
onEnd?: () => void;
autoPlay?: boolean;
style?: CSS.Properties;
}

export const VideoPlayer: React.FC<VideoPlayerProps> = ({
Expand All @@ -80,6 +57,7 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
nextVideo,
onEnd,
autoPlay,
style = {},
}) => {
const dispatch = useDispatch();
const videoRef = useRef<HTMLVideoElement | null>(null);
Expand All @@ -94,16 +72,21 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
const [isMobileView, setIsMobileView] = useState(false);
const [playbackRate, setPlaybackRate] = useState(1);
const [anchorEl, setAnchorEl] = useState(null);
const [showControlsFullScreen, setShowControlsFullScreen] =
useState<boolean>(true);
const videoPlaying = useSelector(
(state: RootState) => state.global.videoPlaying
);
const settingsState = useSelector((state: RootState) => state.settings);
const { downloads } = useSelector((state: RootState) => state.global);

const reDownload = useRef<boolean>(false);
const reDownloadNextVid = useRef<boolean>(false);

const isFetchingProperties = useRef<boolean>(false);

const status = useRef<null | string>(null);
const { downloads } = useSelector((state: RootState) => state.global);

const download = useMemo(() => {
if (!downloads || !identifier) return {};
const findDownload = downloads[identifier];
Expand Down Expand Up @@ -678,6 +661,7 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
onKeyDown={keyboardShortcutsDown}
style={{
padding: from === "create" ? "8px" : 0,
...customStyle,
}}
>
{isLoading && (
Expand Down Expand Up @@ -781,28 +765,31 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
onEnded={handleEnded}
// onLoadedMetadata={handleLoadedMetadata}
onCanPlay={handleCanPlay}
onMouseEnter={e => {
setShowControlsFullScreen(true);
console.log("entering video, fullscreen is: ", isFullscreen);
}}
onMouseLeave={e => {
setShowControlsFullScreen(false);
console.log("leaving video, fullscreen is: ", isFullscreen);
}}
preload="metadata"
style={
startPlay
? {
...customStyle,
objectFit: "fill",
objectFit: settingsState.stretchVideoSetting,
height: "calc(100% - 80px)",
}
: { ...customStyle }
: { ...customStyle, height: "100%" }
}
/>

<ControlsContainer
style={
startPlay
? {
bottom: from === "create" ? "15px" : 0,
padding: "8px",
}
: { bottom: from === "create" ? "15px" : 0, padding: "0px" }
}
style={{ bottom: from === "create" ? "15px" : 0, padding: "0px" }}
display={showControlsFullScreen ? "flex" : "none"}
>
{isMobileView && canPlay ? (
{isMobileView && canPlay && showControlsFullScreen ? (
<>
<IconButton
sx={{
Expand Down
Loading

0 comments on commit 6fd206d

Please sign in to comment.