Skip to content

Commit

Permalink
Final updates to new Q-Tube 2.0 release
Browse files Browse the repository at this point in the history
settingsSlice.ts renamed to persistentSlice, it is only used to store persistent data.

reset button no longer changes video type from "playlist" to "video".

Subscriptions are now stored as list of objects that have the name of the user and the name of the channel that is followed.

When the application starts in App.tsx the subscription list is filtered by the user's name, so they only see channels by the name they have subscribed to.

Edits to QuickMythril's bounty commits (showing home page stats and publish video form displaying supported codecs) to improve visibility and readability.
  • Loading branch information
QortalSeth committed Feb 14, 2024
1 parent f0b89f0 commit 1a4dc83
Show file tree
Hide file tree
Showing 15 changed files with 564 additions and 382 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "qtube",
"private": true,
"version": "0.0.0",
"version": "2.0.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
48 changes: 45 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useState } from "react";
import { Routes, Route } from "react-router-dom";
import { useEffect, useState } from "react";
import { Route, Routes } from "react-router-dom";
import { ThemeProvider } from "@mui/material/styles";
import { CssBaseline } from "@mui/material";
import { lightTheme, darkTheme } from "./styles/theme";
import { darkTheme, lightTheme } from "./styles/theme";
import { store } from "./state/store";
import { Provider } from "react-redux";
import GlobalWrapper from "./wrappers/GlobalWrapper";
Expand All @@ -14,13 +14,55 @@ import { IndividualProfile } from "./pages/IndividualProfile/IndividualProfile";
import { PlaylistContent } from "./pages/PlaylistContent/PlaylistContent";
import { PersistGate } from "redux-persist/integration/react";
import { persistStore } from "redux-persist";
import { setFilteredSubscriptions } from "./state/features/videoSlice.ts";
import { SubscriptionObject } from "./state/features/persistSlice.ts";

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

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

const filterVideosByName = (
subscriptionList: SubscriptionObject[],
userName: string
) => {
return subscriptionList.filter(item => {
return item.userName === userName;
});
};

const getUserName = async () => {
const account = await qortalRequest({
action: "GET_USER_ACCOUNT",
});
const nameData = await qortalRequest({
action: "GET_ACCOUNT_NAMES",
address: account.address,
});

if (nameData?.length > 0) return nameData[0].name;
else return "";
};

const subscriptionListFilter = async () => {
const subscriptionList = store.getState().persist.subscriptionList;
const filterByUserName =
store.getState().persist.subscriptionListFilter === "currentNameOnly";
const userName = await getUserName();

if (filterByUserName && userName) {
return filterVideosByName(subscriptionList, userName);
} else return subscriptionList;
};

useEffect(() => {
const subscriptionList = store.getState().persist.subscriptionList;
subscriptionListFilter().then(filteredList => {
store.dispatch(setFilteredSubscriptions(filteredList));
});
}, []);

return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
Expand Down
29 changes: 15 additions & 14 deletions src/components/PublishVideo/PublishVideo-styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Rating,
TextField,
Typography,
Select
Select,
} from "@mui/material";
import AddPhotoAlternateIcon from "@mui/icons-material/AddPhotoAlternate";
import { TimesSVG } from "../../assets/svgs/TimesSVG";
Expand Down Expand Up @@ -51,6 +51,9 @@ export const CreateContainer = styled(Box)(({ theme }) => ({
borderRadius: "50%",
}));

export const CodecTypography = styled(Typography)(({ theme }) => ({
fontSize: "18px",
}));
export const ModalBody = styled(Box)(({ theme }) => ({
position: "absolute",
backgroundColor: theme.palette.background.default,
Expand Down Expand Up @@ -159,8 +162,6 @@ export const CustomInputField = styled(TextField)(({ theme }) => ({
},
}));



export const CrowdfundTitle = styled(Typography)(({ theme }) => ({
fontFamily: "Copse",
letterSpacing: "1px",
Expand Down Expand Up @@ -539,8 +540,8 @@ export const NoReviewsFont = styled(Typography)(({ theme }) => ({

export const StyledButton = styled(Button)(({ theme }) => ({
fontWeight: 600,
color: theme.palette.text.primary
}))
color: theme.palette.text.primary,
}));

export const CustomSelect = styled(Select)(({ theme }) => ({
fontFamily: "Mulish",
Expand All @@ -549,34 +550,34 @@ export const CustomSelect = styled(Select)(({ theme }) => ({
fontWeight: 400,
color: theme.palette.text.primary,
backgroundColor: theme.palette.background.default,
'& .MuiSelect-select': {
padding: '12px',
"& .MuiSelect-select": {
padding: "12px",
fontFamily: "Mulish",
fontSize: "19px",
letterSpacing: "0px",
fontWeight: 400,
borderRadius: theme.shape.borderRadius, // Match border radius
},
'&:before': {
"&:before": {
// Underline style
borderBottomColor: theme.palette.mode === "light" ? "#B2BAC2" : "#c9cccf",
},
'&:after': {
"&:after": {
// Underline style when focused
borderBottomColor: theme.palette.secondary.main,
},
'& .MuiOutlinedInput-root': {
'& fieldset': {
"& .MuiOutlinedInput-root": {
"& fieldset": {
borderColor: "#E0E3E7",
},
'&:hover fieldset': {
"&:hover fieldset": {
borderColor: "#B2BAC2",
},
'&.Mui-focused fieldset': {
"&.Mui-focused fieldset": {
borderColor: "#6F7E8C",
},
},
'& .MuiInputBase-root': {
"& .MuiInputBase-root": {
fontFamily: "Mulish",
fontSize: "19px",
letterSpacing: "0px",
Expand Down
27 changes: 18 additions & 9 deletions src/components/PublishVideo/PublishVideo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Compressor from "compressorjs";
import {
AddCoverImageButton,
AddLogoIcon,
CodecTypography,
CoverImagePreview,
CrowdfundActionButton,
CrowdfundActionButtonRow,
Expand Down Expand Up @@ -713,15 +714,23 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
</Typography>
</Box>
<Box>
<Typography sx={{fontSize: "14px"}}>
Supported File Containers: MP4, Ogg, WebM, WAV
</Typography>
<Typography sx={{fontSize: "14px"}}>
Audio Codecs: FLAC, MP3, Opus, PCM (8/16/32-bit, μ-law), Vorbis
</Typography>
<Typography sx={{fontSize: "14px"}}>
Video Codecs: AV1, VP8, VP9
</Typography>
<CodecTypography>
Supported File Containers:{" "}
<span style={{ fontWeight: "bold" }}>MP4</span>, Ogg, WebM,
WAV
</CodecTypography>
<CodecTypography>
Audio Codecs: <span style={{ fontWeight: "bold" }}>Opus</span>
, MP3, FLAC, PCM (8/16/32-bit, μ-law), Vorbis
</CodecTypography>
<CodecTypography>
Video Codecs: <span style={{ fontWeight: "bold" }}>AV1</span>,
VP8, VP9, H.264
</CodecTypography>
<CodecTypography sx={{ fontWeight: "800", color: "red" }}>
Using unsupported Codecs may result in video or audio not
working properly
</CodecTypography>
</Box>

<Box
Expand Down
44 changes: 36 additions & 8 deletions src/components/common/SubscribeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,57 @@ import { Button, ButtonProps } from "@mui/material";
import { MouseEvent, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../state/store.ts";
import { subscribe, unSubscribe } from "../../state/features/persistSlice.ts";
import {
resetSubscriptions,
subscribe,
unSubscribe,
} from "../../state/features/persistSlice.ts";
import { setFilteredSubscriptions } from "../../state/features/videoSlice.ts";

interface SubscribeButtonProps extends ButtonProps {
name: string;
subscriberName: string;
}

export const SubscribeButton = ({ name, ...props }: SubscribeButtonProps) => {
export const SubscribeButton = ({
subscriberName,
...props
}: SubscribeButtonProps) => {
const dispatch = useDispatch();
const persistSelector = useSelector((state: RootState) => {
return state.persist;
const filteredSubscriptionList = useSelector((state: RootState) => {
return state.video.filteredSubscriptionList;
});
const userName = useSelector((state: RootState) => state.auth.user?.name);
const [isSubscribed, setIsSubscribed] = useState<boolean>(false);

useEffect(() => {
setIsSubscribed(persistSelector.subscriptionList.includes(name));
const isSubscribedToName =
filteredSubscriptionList.find(item => {
return item.subscriberName === subscriberName;
}) !== undefined;

setIsSubscribed(isSubscribedToName);
}, []);

const subscriptionData = {
userName: userName,
subscriberName: subscriberName,
};
const subscribeToRedux = () => {
dispatch(subscribe(name));
dispatch(subscribe(subscriptionData));
dispatch(
setFilteredSubscriptions([...filteredSubscriptionList, subscriptionData])
);
setIsSubscribed(true);
};
const unSubscribeFromRedux = () => {
dispatch(unSubscribe(name));
dispatch(unSubscribe(subscriptionData));
dispatch(
setFilteredSubscriptions(
filteredSubscriptionList.filter(
item => item.subscriberName !== subscriptionData.subscriberName
)
)
);
setIsSubscribed(false);
};

Expand Down
32 changes: 24 additions & 8 deletions src/hooks/useFetchVideos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
QTUBE_VIDEO_BASE,
} from "../constants/Identifiers.ts";
import { allTabValue, subscriptionTabValue } from "../constants/Misc.ts";
import { persistReducer } from "redux-persist";

export const useFetchVideos = () => {
const dispatch = useDispatch();
Expand All @@ -48,9 +49,7 @@ export const useFetchVideos = () => {
(state: RootState) => state.video.filteredVideos
);

const subscriptions = useSelector(
(state: RootState) => state.persist.subscriptionList
);
const videoReducer = useSelector((state: RootState) => state.video);

const checkAndUpdateVideo = React.useCallback(
(video: Video) => {
Expand Down Expand Up @@ -189,22 +188,38 @@ export const useFetchVideos = () => {
}
}, [videos, hashMapVideos]);

type FilterType = {
name?: string;
category?: string;
subcategory?: string;
keywords?: string;
type?: string;
};

const emptyFilters = {
name: "",
category: "",
subcategory: "",
keywords: "",
type: "",
};
const getVideos = React.useCallback(
async (
filters = {},
filters = emptyFilters,
reset?: boolean,
resetFilters?: boolean,
limit?: number,
listType = allTabValue
) => {
emptyFilters.type = filters.type;
try {
const {
name = "",
category = "",
subcategory = "",
keywords = "",
type = "",
}: any = resetFilters ? {} : filters;
type = filters.type,
}: FilterType = resetFilters ? emptyFilters : filters;
let offset = videos.length;
if (reset) {
offset = 0;
Expand All @@ -217,8 +232,9 @@ export const useFetchVideos = () => {
defaultUrl = defaultUrl + `&name=${name}`;
}
if (listType === subscriptionTabValue) {
subscriptions.map(sub => {
defaultUrl += `&name=${sub}`;
const filteredSubscribeList = videoReducer.filteredSubscriptionList;
filteredSubscribeList.map(sub => {
defaultUrl += `&name=${sub.subscriberName}`;
});
}

Expand Down
18 changes: 9 additions & 9 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
import { BrowserRouter } from 'react-router-dom'
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
import { BrowserRouter } from "react-router-dom";
interface CustomWindow extends Window {
_qdnBase: string
_qdnBase: string;
}

const customWindow = window as unknown as CustomWindow
const customWindow = window as unknown as CustomWindow;

const baseUrl = customWindow?._qdnBase || ''
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
const baseUrl = customWindow?._qdnBase || "";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<BrowserRouter basename={baseUrl}>
<App />
<div id="modal-root" />
</BrowserRouter>
)
);
Loading

0 comments on commit 1a4dc83

Please sign in to comment.