Skip to content

Commit

Permalink
Merge pull request #44 from mnsinri/dev
Browse files Browse the repository at this point in the history
feat: setting menu
  • Loading branch information
mnsinri authored Sep 2, 2023
2 parents ccb0b82 + 3efe0d0 commit d007f36
Show file tree
Hide file tree
Showing 32 changed files with 622 additions and 123 deletions.
11 changes: 0 additions & 11 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,6 @@
<title>Vspo stream schedule</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
9 changes: 6 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
WindowSizeProvider,
ThemeProvider,
MainContainer,
ConfigProvider,
Background,
} from "./components";

Expand All @@ -12,9 +13,11 @@ export const App: React.FC = () => {
<WindowSizeProvider>
<ThemeProvider>
<Background>
<VspoStreamingProvider>
<MainContainer />
</VspoStreamingProvider>
<ConfigProvider>
<VspoStreamingProvider>
<MainContainer />
</VspoStreamingProvider>
</ConfigProvider>
</Background>
</ThemeProvider>
</WindowSizeProvider>
Expand Down
14 changes: 14 additions & 0 deletions src/colors/blue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const blue = {
50: "#ebeaf9",
100: "#ccc9ef",
200: "#aaa6e4",
300: "#8983d8",
400: "#7266cf", //vspo blue
500: "#5e49c5",
600: "#5840ba",
700: "#5035ad",
800: "#482aa2",
900: "#3d128b",
};

export default blue;
7 changes: 7 additions & 0 deletions src/colors/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// https://github.com/mui/material-ui/blob/master/packages/mui-material/src/colors/common.js
const common = {
black: "#000",
white: "#fff",
};

export default common;
19 changes: 19 additions & 0 deletions src/colors/grey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// https://github.com/mui/material-ui/blob/master/packages/mui-material/src/colors/grey.js
const grey = {
50: "#fafafa",
100: "#f5f5f5",
200: "#eeeeee",
300: "#e0e0e0",
400: "#bdbdbd",
500: "#9e9e9e",
600: "#757575",
700: "#616161",
800: "#424242",
900: "#212121",
A100: "#f5f5f5",
A200: "#eeeeee",
A400: "#bdbdbd",
A700: "#616161",
};

export default grey;
7 changes: 7 additions & 0 deletions src/colors/icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const icon = {
youtube: "#ff0000",
twitch: "#9146FF",
twitCasting: "#0092fa",
};

export default icon;
5 changes: 5 additions & 0 deletions src/colors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { default as common } from "./common";
export { default as grey } from "./grey";
export { default as pink } from "./pink";
export { default as blue } from "./blue";
export { default as icon } from "./icon";
14 changes: 14 additions & 0 deletions src/colors/pink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const pink = {
50: "#fee6ef",
100: "#fec1d8",
200: "#fe98be",
300: "#ff6fa4", //vspo pink
400: "#fe508e",
500: "#ff3679",
600: "#ed3375",
700: "#d52f6f",
800: "#c02b6a",
900: "#992462",
};

export default pink;
22 changes: 7 additions & 15 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import styled from "styled-components";
import { ThemeButton, GithubLinkButton } from "./buttons";
import { SettingMenu } from "./settingMenu";
import { breakpoints } from "../configs";
import logo from "../logo.png";
import { useWindowSize } from "../hooks";
Expand All @@ -19,11 +19,11 @@ const Container = styled.div`
`}
`;

const Title = styled.div`
flex-grow: 1;
const Title = styled.div<{ isPhone: boolean }>`
width: 100%;
display: flex;
justify-content: center;
margin-left: ${(p) => (p.isPhone ? "40px" : "0px")};
${breakpoints.mediaQueries.md`
justify-content: start;
Expand All @@ -49,29 +49,21 @@ const TitleText = styled.div`
`;

const Wrapper = styled.div`
width: 35px;
width: 40px;
display: flex;
justify-content: center;
${breakpoints.mediaQueries.md`
width: 120px;
justify-content: flex-end;
`}
justify-content: flex-end;
`;

export const Header: React.FC = () => {
const { isPhoneSize } = useWindowSize();
return (
<Container>
<Title>
<Title isPhone={isPhoneSize}>
<Icon src={logo} alt="logo" />
{!isPhoneSize && <TitleText>Vspo stream schedule</TitleText>}
</Title>
<Wrapper style={{ order: isPhoneSize ? -1 : 0 }}>
<GithubLinkButton />
</Wrapper>
<Wrapper>
<ThemeButton />
<SettingMenu />
</Wrapper>
</Container>
);
Expand Down
7 changes: 4 additions & 3 deletions src/components/MainContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import styled from "styled-components";
import { breakpoints } from "../configs";
import { StreamingTable } from "./StreamingTable";
import { DateBorder } from "./DateBorder";
import { useVspoStreams } from "../hooks";
import { useConfig, useVspoStreams } from "../hooks";
import { StreamInfo, StreamList } from "../types";
import { Header } from "./Header";

const Container = styled.div`
margin: 0 auto;
background: rgba(240, 240, 240, 0.08);
background: rgba(240, 240, 240, 0.03);
box-shadow: 0px 0px 4px 4px rgba(0, 0, 0, 0.2);
color: ${(p) => p.theme.text.primary};
transition: color 0.3s ease;
Expand Down Expand Up @@ -73,6 +73,7 @@ const TableContainer = styled.div`

export const MainContainer = React.memo(() => {
const streams = useVspoStreams();
const { config } = useConfig();

const parseToStreamList = (streams: StreamInfo[]): StreamList[] => {
const dateSet = new Set(streams.map((s) => s.scheduledDate));
Expand All @@ -85,7 +86,7 @@ export const MainContainer = React.memo(() => {
};

return (
<Container>
<Container ref={config.scrollContainerRef}>
<InnerContainer>
<Header />
{parseToStreamList(streams).map((s) => (
Expand Down
4 changes: 2 additions & 2 deletions src/components/buttons/ThemeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const Wrapper = styled(animated.div)`
export const ThemeButton: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({
...props
}) => {
const { themeType, toggleTheme } = useTheme();
const { themeType, setThemeDark } = useTheme();

const transitions = useTransition(themeType, {
from: { opacity: 0 },
Expand All @@ -23,7 +23,7 @@ export const ThemeButton: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({
});

return (
<BaseButton onClickHandler={toggleTheme} {...props}>
<BaseButton onClickHandler={() => setThemeDark(true)} {...props}>
{transitions((style, themeType) => (
<Wrapper style={style}>
{themeType === "dark" ? <IoMdSunny /> : <IoMdMoon />}
Expand Down
9 changes: 5 additions & 4 deletions src/components/card/ServiceIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { IconContext } from "react-icons";
import { FaYoutube, FaTwitch } from "react-icons/fa";
import { TbBroadcast } from "react-icons/tb";
import { useTheme, useWindowSize } from "../../hooks";
import { breakpoints, baseColors } from "../../configs";
import { breakpoints } from "../../configs";
import { icon } from "../../colors";
import { parseToJST } from "../../utils";

const Panel = styled(animated.div)`
Expand Down Expand Up @@ -71,11 +72,11 @@ export const ServiceIcon: React.FC<ServiceIconProps> = ({
const serviceColor = useMemo(() => {
switch (service) {
case "youtube":
return baseColors.logo.youtube;
return icon.youtube;
case "twitch":
return baseColors.logo.twitch;
return icon.twitch;
case "twitCasting":
return baseColors.logo.twitCasting;
return icon.twitCasting;
}
}, [service]);
const startDate = useMemo(() => new Date(startAt), [startAt]);
Expand Down
14 changes: 6 additions & 8 deletions src/components/card/StreamingCard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useMemo } from "react";
import React from "react";
import { StreamingCardProps } from "../../types";
import { ServiceIcon } from "./ServiceIcon";
import { ThumbnailBlock } from "./ThumbnailBlock";
import styled from "styled-components";
import { useHover, useWindowSize } from "../../hooks";
import { useConfig, useHover, useWindowSize } from "../../hooks";
import { animated } from "@react-spring/web";
import { breakpoints } from "../../configs";

Expand All @@ -27,11 +27,9 @@ export const StreamingCard = React.memo<StreamingCardProps>(
({ title, thumbnail, name, icon, service, url, startAt }) => {
const { hovered, hoverSpread } = useHover();
const { isMobile, isDesktopSize } = useWindowSize();
const { config } = useConfig();

const isHoverable = useMemo(
() => !isMobile && isDesktopSize,
[isMobile, isDesktopSize]
);
const isHoverable = !isMobile && isDesktopSize;

return (
<Container>
Expand All @@ -43,15 +41,15 @@ export const StreamingCard = React.memo<StreamingCardProps>(
<ServiceIcon
service={service}
startAt={startAt}
isExpand={!isHoverable || hovered}
isExpand={config.isExpandAlways || !isHoverable || hovered}
style={{ position: "absolute", top: 5, right: 5, zIndex: 10 }}
/>
<ThumbnailBlock
title={title}
thumbnail={thumbnail}
name={name}
icon={icon}
isExpand={!isHoverable || hovered}
isExpand={config.isExpandAlways || !isHoverable || hovered}
/>
</Card>
</Container>
Expand Down
11 changes: 8 additions & 3 deletions src/components/card/ThumbnailBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from "react";
import styled from "styled-components";
import { ThumbnailBlockProps } from "../../types";
import { animated, easings, useSpring } from "@react-spring/web";
import { breakpoints } from "../../configs";
import { useWindowSize } from "../../hooks";
import { useConfig, useWindowSize } from "../../hooks";
import { Marquee } from "../marquee";
import { ThumbnailBlockProps } from "../../types";

const Panel = styled(animated.div)`
width: 160px;
Expand Down Expand Up @@ -112,6 +112,8 @@ export const ThumbnailBlock: React.FC<ThumbnailBlockProps> = ({
...props
}) => {
const { isPhoneSize } = useWindowSize();
const { config } = useConfig();

const baseSpringConfig = {
height: isExpand ? "240px" : "180px",
borderRadius: isExpand ? "10px 10px 0px 0px" : "10px 10px 10px 10px",
Expand Down Expand Up @@ -156,7 +158,10 @@ export const ThumbnailBlock: React.FC<ThumbnailBlockProps> = ({
<Header>
<Icon src={icon} alt={name} style={{ filter: shadow }} loading="lazy" />
<Contents style={{ opacity }}>
<MarqueeTitle animate={isExpand} speed={isPhoneSize ? 0.04 : 0.05}>
<MarqueeTitle
animate={isExpand && config.isMarquee}
speed={isPhoneSize ? 0.03 : 0.05}
>
{title}
</MarqueeTitle>
<Name>{name}</Name>
Expand Down
9 changes: 1 addition & 8 deletions src/components/marquee/Marquee.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import React, {
useCallback,
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
} from "react";
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
import styled from "styled-components";
import { MarqueeProps } from "../../types";
import { animated, useSpring, useSpringRef } from "@react-spring/web";
Expand Down
57 changes: 57 additions & 0 deletions src/components/providers/ConfigProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { createContext, createRef } from "react";
import { ChildrenNode } from "../../types";
import { useBoolStateCache } from "../../hooks";

type ConfigSetter = {
setExpandAlways: React.Dispatch<React.SetStateAction<boolean>>;
setMarquee: React.Dispatch<React.SetStateAction<boolean>>;
};

type Config = {
scrollContainerRef: React.RefObject<HTMLDivElement>;
isExpandAlways: boolean;
isMarquee: boolean;
};

type ContextType = {
config: Config;
configSetter: ConfigSetter;
};

const initState = {
config: {
scrollContainerRef: null!,
isExpandAlways: true,
isMarquee: true,
},
configSetter: {
setExpandAlways: null!,
setMarquee: null!,
},
};

export const ConfigContext = createContext<ContextType>(initState);
const scrollContainerRef = createRef<HTMLDivElement>();

export const ConfigProvider: React.FC<ChildrenNode> = ({ children }) => {
const [isExpandAlways, setExpandAlways] = useBoolStateCache(
"isExpandAlways",
initState.config.isExpandAlways
);

const [isMarquee, setMarquee] = useBoolStateCache(
"isMarquee",
initState.config.isMarquee
);

return (
<ConfigContext.Provider
value={{
config: { scrollContainerRef, isExpandAlways, isMarquee },
configSetter: { setExpandAlways, setMarquee },
}}
>
{children}
</ConfigContext.Provider>
);
};
Loading

0 comments on commit d007f36

Please sign in to comment.