Skip to content

Commit

Permalink
feat(home): add extra video actions to the display options
Browse files Browse the repository at this point in the history
  • Loading branch information
AXeL-dev committed Oct 1, 2022
1 parent 13589d4 commit c675ca8
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 82 deletions.
1 change: 1 addition & 0 deletions src/store/reducers/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const defaultSettings = {
},
homeDisplayOptions: {
hiddenViews: [],
extraVideoActions: [],
},
enableNotifications: true,
queryTimeout: 10000,
Expand Down
21 changes: 20 additions & 1 deletion src/store/selectors/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ViewFilters,
RecentViewFilters,
WatchLaterViewFilters,
ExtraVideoAction,
} from 'types';
import { defaultSettings } from 'store/reducers/settings';

Expand Down Expand Up @@ -62,9 +63,27 @@ export const selectViewSorting = (view: HomeView) =>

export const selectHomeDisplayOptions = createSelector(
selectSettings,
(settings) => settings.homeDisplayOptions,
(settings) => ({
...defaultSettings.homeDisplayOptions,
...settings.homeDisplayOptions,
}),
);

export const selectHiddenViews = createSelector(
selectHomeDisplayOptions,
(options) => options.hiddenViews,
);

export const selectExtraVideoActions = createSelector(
selectHomeDisplayOptions,
(options) => options.extraVideoActions,
);

export const selectHasExtraVideoAction = (action: ExtraVideoAction) =>
createSelector(selectHomeDisplayOptions, (options) =>
options.extraVideoActions.includes(action),
);

export const selectRecentVideosSeniority = createSelector(
selectSettings,
(settings) => settings.recentVideosSeniority,
Expand Down
5 changes: 5 additions & 0 deletions src/types/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ export interface Settings {
queryTimeout: number;
}

export enum ExtraVideoAction {
CopyLink = 'copy-link',
}

export interface HomeDisplayOptions {
hiddenViews: HomeView[];
extraVideoActions: ExtraVideoAction[];
}

export interface ViewSorting {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React, { useState } from 'react';
import { Grow, IconButton, Tooltip } from '@mui/material';
import { Video } from 'types';
import { ExtraVideoAction, Video } from 'types';
import LinkIcon from '@mui/icons-material/Link';
import CheckIcon from '@mui/icons-material/Check';
import copy from 'copy-to-clipboard';
import { useAppSelector } from 'store';
import { selectHasExtraVideoAction } from 'store/selectors/settings';

interface CopyLinkActionProps {
video: Video;
Expand All @@ -13,6 +15,9 @@ function CopyLinkAction(props: CopyLinkActionProps) {
const { video } = props;
const [isShown, setIsShown] = useState(true);
const [copied, setCopied] = useState(false);
const enabled = useAppSelector(
selectHasExtraVideoAction(ExtraVideoAction.CopyLink),
);

const handleClick = () => {
if (copied) return;
Expand All @@ -23,7 +28,7 @@ function CopyLinkAction(props: CopyLinkActionProps) {
}, 1000);
};

return (
return enabled ? (
<Grow in={isShown}>
<Tooltip
title={copied ? 'Copied!' : 'Copy link to clipboard'}
Expand All @@ -50,7 +55,7 @@ function CopyLinkAction(props: CopyLinkActionProps) {
</IconButton>
</Tooltip>
</Grow>
);
) : null;
}

export default CopyLinkAction;
102 changes: 102 additions & 0 deletions src/ui/components/pages/Home/DisplayOptionsDialog/ActiveViews.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React, { forwardRef, useImperativeHandle, useState } from 'react';
import {
FormControl,
FormControlLabel,
FormGroup,
FormLabel,
Switch,
} from '@mui/material';
import { useAppSelector } from 'store';
import { selectHiddenViews } from 'store/selectors/settings';
import { HomeView } from 'types';

interface ActiveViewsProps {}

interface View {
label: string;
value: HomeView;
hidden: boolean;
}

export interface ActiveViewsRef {
reset: () => void;
getViews: () => View[];
setViews: (views: View[]) => void;
}

const ActiveViews = forwardRef<ActiveViewsRef, ActiveViewsProps>(
(props, ref) => {
const hiddenViews = useAppSelector(selectHiddenViews);
const initialViews: View[] = [
{
label: 'All',
value: HomeView.All,
hidden: hiddenViews.includes(HomeView.All),
},
{
label: 'Recent',
value: HomeView.Recent,
hidden: hiddenViews.includes(HomeView.Recent),
},
{
label: 'Watch Later',
value: HomeView.WatchLater,
hidden: hiddenViews.includes(HomeView.WatchLater),
},
];
const [views, setViews] = useState(initialViews);

useImperativeHandle(
ref,
() => ({
reset: () => setViews(initialViews),
getViews: () => views,
setViews,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[views],
);

const handleToggle = (target: View) => {
setViews((state) =>
state.map((view) =>
view.value === target.value
? {
...view,
hidden: !view.hidden,
}
: view,
),
);
};

return (
<FormControl
component="fieldset"
variant="standard"
focused={false}
fullWidth
>
<FormLabel component="legend">Active views</FormLabel>
<FormGroup>
{views.map((view) => (
<FormControlLabel
onClick={() => handleToggle(view)}
key={view.value}
control={
<Switch
color="secondary"
checked={!view.hidden}
name={view.value}
/>
}
label={view.label}
/>
))}
</FormGroup>
</FormControl>
);
},
);

export default ActiveViews;
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React, { forwardRef, useImperativeHandle, useState } from 'react';
import {
FormControl,
FormControlLabel,
FormGroup,
FormLabel,
Switch,
} from '@mui/material';
import { useAppSelector } from 'store';
import { selectExtraVideoActions } from 'store/selectors/settings';
import { ExtraVideoAction } from 'types';

interface ExtraVideoActionsProps {}

interface Action {
label: string;
value: ExtraVideoAction;
active: boolean;
}

export interface ExtraVideoActionsRef {
reset: () => void;
getActions: () => Action[];
setActions: (actions: Action[]) => void;
}

const ExtraVideoActions = forwardRef<
ExtraVideoActionsRef,
ExtraVideoActionsProps
>((props, ref) => {
const extraVideoActions = useAppSelector(selectExtraVideoActions);
const initialActions: Action[] = [
{
label: 'Copy link to clipboard',
value: ExtraVideoAction.CopyLink,
active: extraVideoActions.includes(ExtraVideoAction.CopyLink),
},
];
const [actions, setActions] = useState(initialActions);

useImperativeHandle(
ref,
() => ({
reset: () => setActions(initialActions),
getActions: () => actions,
setActions,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[actions],
);

const handleToggle = (target: Action) => {
setActions((state) =>
state.map((action) =>
action.value === target.value
? {
...action,
active: !action.active,
}
: action,
),
);
};

return (
<FormControl
component="fieldset"
variant="standard"
focused={false}
fullWidth
>
<FormLabel component="legend">Extra video actions</FormLabel>
<FormGroup>
{actions.map((action) => (
<FormControlLabel
onClick={() => handleToggle(action)}
key={action.value}
control={
<Switch
color="secondary"
checked={action.active}
name={action.value}
/>
}
label={action.label}
/>
))}
</FormGroup>
</FormControl>
);
});

export default ExtraVideoActions;
Loading

0 comments on commit c675ca8

Please sign in to comment.