diff --git a/src/core/components/App.tsx b/src/core/components/App.tsx index 29e010d..5be0e47 100644 --- a/src/core/components/App.tsx +++ b/src/core/components/App.tsx @@ -5,8 +5,6 @@ import { useParams } from "../hooks/useParams" import { FADE_TRANSITION_MS, MINIMUM_SCREEN_TIME } from "../constants" import { Content } from "./Content" import { getTheme } from "../../mood/helpers/getTheme" -import { getPhaseOfDay } from "../../mood/helpers/getPhaseOfDay" -import { OSLO_COORDINATES } from "../../mood/constants" import { useSchedule } from "../useSchedule" import { DevPanel } from "./DevPanel" import { AppContext, type AppContextT, type AppState } from "./AppContext.tsx" @@ -49,7 +47,7 @@ const LoadingDiv = styled.div` ` export function App() { - const theme = getTheme(getPhaseOfDay(new Date(), ...OSLO_COORDINATES)) + const theme = getTheme("noon") //getPhaseOfDay(new Date(), ...OSLO_COORDINATES)) const { loading } = useSchedule() const [state, setState] = useState("idle") diff --git a/src/core/components/Background.tsx b/src/core/components/Background.tsx index 879bedf..d30f0a2 100644 --- a/src/core/components/Background.tsx +++ b/src/core/components/Background.tsx @@ -1,12 +1,10 @@ import { getMoodVideo } from "../../mood/helpers/getMoodVideo" import { RESOLUTION, URL_PREFIX } from "../constants" -import { getPhaseOfDay } from "../../mood/helpers/getPhaseOfDay" -import { OSLO_COORDINATES } from "../../mood/constants" const [width, height] = RESOLUTION -const src = getMoodVideo(getPhaseOfDay(new Date(), ...OSLO_COORDINATES)) +const src = getMoodVideo("noon") //getPhaseOfDay(new Date(), ...OSLO_COORDINATES)) export function Background() { const renderSource = (ext: string, mime: string) => ( diff --git a/src/core/components/Card.tsx b/src/core/components/Card.tsx index 59edaea..796992c 100644 --- a/src/core/components/Card.tsx +++ b/src/core/components/Card.tsx @@ -1,6 +1,5 @@ import * as stylex from "@stylexjs/stylex" import { theme } from "../../theme.stylex.ts" -import { ComponentPropsWithoutRef, forwardRef } from "react" // Define the basic card style export const cardStyle = stylex.create({ @@ -12,16 +11,3 @@ export const cardStyle = stylex.create({ backdropFilter: "blur(30px)", }, }) - -/** - * This is here for styled-component backwards compatibility. - */ -export const Card = forwardRef>( - ({ children, ...props }, ref) => { - return ( -
- {children} -
- ) - }, -) diff --git a/src/core/components/Clock.tsx b/src/core/components/Clock.tsx index 5e862ac..edfaf19 100644 --- a/src/core/components/Clock.tsx +++ b/src/core/components/Clock.tsx @@ -8,7 +8,7 @@ const drawRoundRect = ( y: number, width: number, height: number, - radius: number + radius: number, ) => { context.beginPath() context.arc(x + radius, y + radius, radius, Math.PI, Math.PI + Math.PI / 2) @@ -28,8 +28,7 @@ export type ClockProps = { size: number } -export function Clock(props: ClockProps) { - const { size } = props +export function Clock({ size }: ClockProps) { const theme = useTheme() const [handleRef, canvas] = useCanvasAnimation((context) => { @@ -56,7 +55,7 @@ export function Clock(props: ClockProps) { time: number, thickness: number, length: number, - color = theme.fontColor.normal + color = theme.fontColor.normal, ) => { context.save() const width = thickness diff --git a/src/core/components/Content.tsx b/src/core/components/Content.tsx index 1e8f2b9..38c0010 100644 --- a/src/core/components/Content.tsx +++ b/src/core/components/Content.tsx @@ -21,7 +21,7 @@ const Container = styled.div<{ keyed: boolean }>` position: relative; overflow: hidden; - background: ${({ keyed }) => (keyed ? "transparent" : "black")}; + background: transparent; ` const Inner = styled.div<{ visible: boolean }>` diff --git a/src/core/components/DevPanel.tsx b/src/core/components/DevPanel.tsx index aa34841..aff47e0 100644 --- a/src/core/components/DevPanel.tsx +++ b/src/core/components/DevPanel.tsx @@ -1,6 +1,7 @@ import styled from "@emotion/styled" import { RESOLUTION } from "../constants" import { Content } from "./Content" +import { useState } from "react" const DevContainerDiv = styled.div` display: flex; flex-direction: column; @@ -45,16 +46,28 @@ const DevPanelButtons = styled.div` } } ` -export const DevPanel = () => ( - -
-

Frikanalen sendegrafikk

- - -

Events

- - -
-
-
-) +export const DevPanel = () => { + const [show, setShow] = useState(true) + const reset = () => { + setShow(false) + setTimeout(() => { + setShow(true) + window.play() + }, 100) + } + + return ( + +
+

Frikanalen sendegrafikk

+ {show && } + + +

Events

+ + +
+
+
+ ) +} diff --git a/src/core/components/IntroView.tsx b/src/core/components/IntroView.tsx index 096d07a..91e248e 100644 --- a/src/core/components/IntroView.tsx +++ b/src/core/components/IntroView.tsx @@ -1,10 +1,9 @@ -import styled from "@emotion/styled" -import { css, keyframes } from "@emotion/react" -import { cardStyle } from "./Card" import { Logo } from "./Logo" import { TransitionStatus } from "react-transition-group" import { SequenceEntry } from "../../sequencing/components/ViewSequence" import stylex from "@stylexjs/stylex" +import { theme } from "../../theme.stylex.ts" +import { cardStyle } from "./Card.tsx" const ENTER_MS = 1200 const EXIT_MS = 700 @@ -16,108 +15,107 @@ export const INTRO_VIEW_SEQUENCE_ENTRY: SequenceEntry = { overlay: false, } -const CardFall = keyframes` - 0% {} - - 100% { - transform: rotate(10deg) translateY(60%); - } -` - -const Container = styled.div<{ status: TransitionStatus }>` - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 100; - - display: flex; - align-items: center; - justify-content: center; - - color: ${(props) => props.theme.fontColor.normal}; - &:before { - content: ""; - position: absolute; - - height: 200%; - width: 200%; - - top: 0; - right: 0; - - transform: rotate(10deg) translateY(-220px); - - ${(props) => { - if (props.status === "exiting") - return css` - animation: ${CardFall} ${EXIT_MS}ms ease-in-out forwards; - ` - }} - } -` - -const LogoUnblur = keyframes` - 0% { - filter: blur(120px); - opacity: 0; - } - - 100% { - opacity: 1; - } -` - -const LogoFall = keyframes` - 0% {} - - 50% { - opacity: 0; - } - - 100% { - transform: translateY(800px); - opacity: 0; - } -` - -const LogoContainer = styled.div<{ status: TransitionStatus }>` - width: 600px; - - position: relative; - z-index: 1; - - animation: ${(props) => { - if (props.status === "entering") { - return css` - ${LogoUnblur} ${ENTER_MS}ms ease-in-out forwards; - animation-delay: 200ms; - - opacity: 0; - ` - } - - if (props.status === "exiting") { - return css` - ${LogoFall} ${EXIT_MS}ms ease-in-out forwards - ` - } - }}; -` +const CardFall = stylex.keyframes({ + from: {}, + to: { transform: "rotate(10deg) translateY(60%)" }, +}) + +const LogoUnblur = stylex.keyframes({ + from: { + filter: "blur(120px)", + opacity: 0, + }, + to: { opacity: 1 }, +}) + +const LogoFall = stylex.keyframes({ + from: {}, + "50%": { opacity: 0 }, + to: { + transform: "translateY(800px)", + opacity: 0, + }, +}) + +const backdropStyle = stylex.create({ + base: { + position: "absolute", + width: "200%", + height: "200%", + top: 0, + right: 0, + transform: "rotate(10deg) translateY(-220px)", + content: "", + }, + exiting: { + animationName: CardFall, + animationDuration: `${EXIT_MS}ms`, + animationFillMode: "forwards", + }, +}) + +const containerStyle = stylex.create({ + base: { + display: "flex", + alignItems: "center", + justifyContent: "center", + position: "absolute", + top: 0, + right: 0, + bottom: 0, + left: 0, + zIndex: 100, + color: theme.fontColorNormal, + }, +}) + +const logoContainerStyles = stylex.create({ + base: { + width: 600, // Assuming you want to set width to 600px + position: "relative", + zIndex: 1, + animationTimingFunction: "ease-in-out", + }, + entering: { + animationName: LogoUnblur, + animationDuration: `${ENTER_MS}ms`, // ENTER_MS should be a predefined constant + animationDelay: "200ms", + opacity: 0, + animationFillMode: "forwards", + }, + exiting: { + animationName: LogoFall, + animationFillMode: "forwards", + animationDuration: `${EXIT_MS}ms`, // EXIT_MS should be a predefined constant + }, +}) export type IntroView = { status: TransitionStatus } -export function IntroView(props: IntroView) { - const { status } = props - +export const IntroView = ({ status }: IntroView) => { + console.log(status) return ( - - - - - +
+
+
+
+ +
+
+
) } diff --git a/src/isDark.ts b/src/isDark.ts new file mode 100644 index 0000000..e3d9440 --- /dev/null +++ b/src/isDark.ts @@ -0,0 +1,6 @@ +import { getPhaseOfDay } from "./mood/helpers/getPhaseOfDay.ts" +import { OSLO_COORDINATES } from "./mood/constants.ts" + +export const isDark = ["sunset", "dusk", "night"].includes( + getPhaseOfDay(new Date(), ...OSLO_COORDINATES), +) diff --git a/src/schedule/components/ScheduleView.tsx b/src/schedule/components/ScheduleView.tsx index 6967d99..ff2234c 100644 --- a/src/schedule/components/ScheduleView.tsx +++ b/src/schedule/components/ScheduleView.tsx @@ -1,53 +1,27 @@ -import { css, keyframes } from "@emotion/react" +import { keyframes } from "@emotion/react" import styled from "@emotion/styled" import { darken } from "polished" import { TransitionStatus } from "react-transition-group" -import { Card, cardStyle } from "../../core/components/Card" +import { cardStyle } from "../../core/components/Card" import { Clock } from "../../core/components/Clock" import { Logo } from "../../core/components/Logo" - import { ScheduleItemSummary } from "./ScheduleItemSummary" import { useSchedule } from "../../core/useSchedule" import * as stylex from "@stylexjs/stylex" - -// Define the keyframe animations -const slideIn = stylex.keyframes({ - from: { transform: "translateX(-700px)" }, - to: { transform: "translateY(0)" }, -}) - -const slideOut = stylex.keyframes({ - from: { transform: "translateY(0)" }, - to: { transform: "translateX(-700px)" }, -}) - -const SlideFadeTransition = (px: number, reversed: boolean) => keyframes` - ${reversed ? "0%" : "100%"} { - opacity: 0; - transform: translateX(${px}px); - } - - ${reversed ? "100%" : "0%"} { - transform: translateY(0px); - opacity: 1; - } -` - -const slideFade = (px: number) => (props: { status: TransitionStatus }) => { - const { status } = props - - return css` - animation-name: ${SlideFadeTransition(px, status !== "exiting")}; - ` -} +import { + scheduleStyles, + slideStyles, + titleStyle, +} from "./scheduleAnimations.ts" const ContainerTransition = (reversed: boolean) => keyframes` - ${reversed ? "0%" : "100%"} { - opacity: 0; - transform: rotate(10deg) translateY(-90px) translateX(200px); - } + ${reversed ? "0%" : "100%"} { + opacity: 0; + transform: rotate(10deg) translateY(-90px) translateX(200px); + } - ${reversed ? "100%" : "0%"} {} + ${reversed ? "100%" : "0%"} { + } ` const Container = styled.div<{ status: TransitionStatus }>` @@ -76,21 +50,14 @@ const Container = styled.div<{ status: TransitionStatus }>` } ` -const Body = styled.div` - display: flex; - flex: 1; - - position: relative; - z-index: 1; -` - const FooterTransition = (reversed: boolean) => keyframes` -${reversed ? "0%" : "100%"} { - opacity: 0; - transform: translateY(200px); -} + ${reversed ? "0%" : "100%"} { + opacity: 0; + transform: translateY(200px); + } -${reversed ? "100%" : "0%"} {} + ${reversed ? "100%" : "0%"} { + } ` const Footer = styled.div<{ status: TransitionStatus }>` @@ -108,48 +75,9 @@ const Footer = styled.div<{ status: TransitionStatus }>` z-index: 1; ` -const Content = styled.div` - max-width: 590px; - flex: 1; -` - -const styles = stylex.create({ - entering: { - animationName: slideIn, - animationDuration: "1000ms", - animationFillMode: "both", - animationTimingFunction: "ease", - }, - exiting: { - animationName: slideOut, - animationDuration: "1000ms", - animationFillMode: "both", - animationTimingFunction: "ease", - }, - nextCardBase: { - marginTop: "24px", - marginBottom: "42px", - }, - laterListCardBase: { - marginTop: "24px", - animationDelay: "100ms", - }, -}) - -const Aside = styled.div` - flex: 1; - - display: flex; - flex-direction: column; - align-items: center; -` - const SizedLogo = styled(Logo)` width: 450px; color: ${(props) => props.theme.fontColor.normal}; - - animation: 500ms ease both; - ${slideFade(50)} ` const ClockContainer = styled.div` @@ -157,25 +85,7 @@ const ClockContainer = styled.div` display: flex; align-items: center; - animation: 500ms ease both; animation-delay: 100ms; - ${slideFade(50)} -` - -const HeadingTransition = (reversed: boolean) => keyframes` - ${reversed ? "0%" : "100%"} { - opacity: 0; - } - - ${reversed ? "100%" : "0%"} {} -` - -const Heading = styled.h1<{ status: TransitionStatus }>` - transition: all 500ms ease; - - color: ${(props) => props.theme.fontColor.normal}; - animation: ${(props) => HeadingTransition(props.status !== "exiting")} 500ms - ease forwards; ` export type ScheduleViewProps = { @@ -191,38 +101,64 @@ export function ScheduleView(props: ScheduleViewProps) { return ( - - - Neste program - +
+

+ Neste program +

+
{next ? : null} - - Senere +
+

+ Senere +

{scheduleItems.slice(0, 3).map((item) => ( ))}
- -
+
+ + - - +
+