Skip to content

Commit

Permalink
feat: replace TwitterFeed with SlippiStore upsell banner (#420)
Browse files Browse the repository at this point in the history
* chore: replace twitter feed with shop upsell

* chore: switch to stylex

* use stylex

* add countdown

* clear countdown on shop closure

* why am i such a derp

* remove seconds from countdown

* dont memoize countdown

* define interval before checkTime

* only show seconds when theres less than an hour left

---------

Co-authored-by: Vince Au <vinceau09@gmail.com>
  • Loading branch information
JLaferri and vinceau authored Feb 15, 2024
1 parent 5a32466 commit 8d2c16e
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 38 deletions.
20 changes: 20 additions & 0 deletions src/renderer/lib/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,23 @@ export function convertFrameCountToDurationString(frameCount: number, format: "s
export function monthDayHourFormat(date: Date): string {
return format(date, "PP · p");
}

const formatDistanceLocale: Record<string, string> = {
xYears: "{{count}} yrs",
xMonths: "{{count}} months",
xWeeks: "{{count}} weeks",
xDays: "{{count}} days",
xHours: "{{count}} hrs",
xMinutes: "{{count}} mins",
xSeconds: "{{count}} secs",
};

export const shortEnLocale = {
formatDistance: (token: string, count: number) => {
const replacement = formatDistanceLocale[token];
if (replacement) {
return replacement.replace("{{count}}", count.toString());
}
return "";
},
};
4 changes: 2 additions & 2 deletions src/renderer/pages/home/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from "@emotion/styled";

import { SlippiStore } from "./slippi_store";
import { TournamentLinks } from "./tournament_links";
import { TwitterFeed } from "./twitter_feed";

const Outer = styled.div`
display: flex;
Expand All @@ -13,7 +13,7 @@ const Outer = styled.div`
export const Sidebar = () => {
return (
<Outer>
<TwitterFeed />
<SlippiStore />
<TournamentLinks />
</Outer>
);
Expand Down
102 changes: 102 additions & 0 deletions src/renderer/pages/home/sidebar/slippi_store.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { Button, Typography } from "@mui/material";
import * as stylex from "@stylexjs/stylex";
import type { Duration } from "date-fns";
import { formatDuration, intervalToDuration, isBefore } from "date-fns";
import React from "react";

import { ExternalLink } from "@/components/external_link";
import { shortEnLocale } from "@/lib/time";
import shopImage from "@/styles/images/shop-image.png";

const SHOP_CLOSES_AT = new Date("2024-02-28T08:00:00.000Z");

const styles = stylex.create({
container: {
position: "relative",
flex: "1",
overflow: "hidden",
backgroundColor: "#21ba44",
},
image: {
position: "absolute",
width: "100%",
objectFit: "cover",
},
buttonContainer: {
position: "absolute",
top: "150px",
left: "40px",
width: "220px !important",
},
closeDate: {
position: "absolute",
fontWeight: "bold",
top: "200px",
width: "100%",
color: "white",
fontSize: 15,
textAlign: "center",
},
});

const InternalSlippiStore = ({ shopOpen, countdown }: { shopOpen: boolean; countdown: string }) => {
const buttonText = shopOpen ? "Click to Shop" : "Shop closed";
return (
<div {...stylex.props(styles.container)}>
<img src={shopImage} {...stylex.props(styles.image)} />
<div {...stylex.props(styles.buttonContainer)}>
<Button
variant="contained"
sx={{ color: "white", textTransform: "uppercase" }}
color="secondary"
fullWidth={true}
LinkComponent={ExternalLink}
href="https://start.gg/slippi/shop"
disabled={!shopOpen}
>
{buttonText}
</Button>
</div>
{countdown && (
<div {...stylex.props(styles.closeDate)}>
<Typography variant="overline" sx={{ lineHeight: "initial" }}>
Shop closes in
</Typography>
<Typography fontWeight="bold">{countdown}</Typography>
</div>
)}
</div>
);
};

export const SlippiStore = React.memo(function SlippiStore() {
const [shopOpen, setShopOpen] = React.useState(true);
const [countdown, setCountdown] = React.useState<string>("");

React.useEffect(() => {
const endDate = SHOP_CLOSES_AT;

// eslint-disable-next-line prefer-const
let interval: number | undefined;
const checkTime = () => {
const now = new Date();
const duration = intervalToDuration({ start: now, end: endDate });

if (isBefore(endDate, now)) {
setShopOpen(false);
setCountdown("");
window.clearInterval(interval);
} else {
const format: (keyof Duration)[] =
(duration.hours ?? 0) < 1 ? ["minutes", "seconds"] : ["days", "hours", "minutes"];
setCountdown(formatDuration(duration, { format, locale: shortEnLocale }));
}
};
checkTime();

interval = window.setInterval(checkTime, 1000);
return () => window.clearInterval(interval);
}, []);

return <InternalSlippiStore shopOpen={shopOpen} countdown={countdown} />;
});
36 changes: 0 additions & 36 deletions src/renderer/pages/home/sidebar/twitter_feed.tsx

This file was deleted.

Binary file added src/renderer/styles/images/shop-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8d2c16e

Please sign in to comment.