
= (
+ props
+) => {
+ return (
+
+
+
+
+
+

+
+
+
+ );
+};
+
+export const UseCaseSection: Component = () => {
+ return (
+
+ );
+};
diff --git a/src/components/home/VideoSection.tsx b/src/components/home/VideoSection.tsx
index fe2a65e..564387f 100644
--- a/src/components/home/VideoSection.tsx
+++ b/src/components/home/VideoSection.tsx
@@ -14,7 +14,12 @@ import { PlayIcon } from "../../components/commons/icons/PlayIcon";
import { getContentSize } from "../../utils/dom";
import { Typography } from "../commons/Typography";
-const videos = [
+interface Video {
+ src: string;
+ thumbnail: string;
+}
+
+const videos: Video[] = [
{
src: "https://www.youtube-nocookie.com/embed/2JqAj1_KYXU",
thumbnail: "https://i.ytimg.com/vi/2JqAj1_KYXU/hqdefault.jpg",
@@ -140,13 +145,12 @@ const VideoControl: Component<{
export const VideoSection: Component = () => {
const [currentVideo, setCurrentVideo] = createSignal(videos[0]);
const [autoplay, setAutoplay] = createSignal(false);
- const [videosContainerSize, setVideosContainerSize] =
- createSignal
(null);
- const [videosScrollSize, setVideosScrollSize] = createSignal(null);
+ const [videosContainerSize, setVideosContainerSize] = createSignal();
+ const [videosScrollSize, setVideosScrollSize] = createSignal();
const [videosScroll, setVideosScroll] = createSignal(0);
- let videosContainerRef: HTMLDivElement;
- let videosScrollRef: HTMLDivElement;
- let resizeObserver;
+ let videosContainerRef!: HTMLDivElement;
+ let videosScrollRef!: HTMLDivElement;
+ let resizeObserver: ResizeObserver;
const shouldShowNext = createMemo(() => {
const containerSize = videosContainerSize();
@@ -167,13 +171,13 @@ export const VideoSection: Component = () => {
const scrollNext = () => {
videosScrollRef.scrollBy({
- left: videosContainerSize().width / videos.length,
+ left: videosContainerSize()!.width / videos.length,
});
};
const scrollPrev = () => {
videosScrollRef.scrollBy({
- left: -videosContainerSize().width / videos.length,
+ left: -videosContainerSize()!.width / videos.length,
});
};
@@ -205,7 +209,7 @@ export const VideoSection: Component = () => {
}
});
- const openVideo = (video) => {
+ const openVideo = (video: Video) => {
batch(() => {
setAutoplay(true);
setCurrentVideo(video);
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index 6470678..5f912d3 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -1,54 +1,17 @@
import { Link, Meta } from "@solidjs/meta";
-import { A, useLocation } from "@solidjs/router";
-import { Component, ParentProps, createEffect } from "solid-js";
+import { useLocation } from "@solidjs/router";
+import { createEffect } from "solid-js";
import { AppTitle } from "~/components/AppTitle";
-import { Container } from "~/components/commons/Container";
-import { Typography } from "~/components/commons/Typography";
import { DownloadSection } from "~/components/home/DownloadSection";
import { HeroSection } from "~/components/home/HeroSection";
import { QASection } from "~/components/home/QASection";
+import { UseCaseSection } from "~/components/home/UseCaseSection";
import { VideoSection } from "~/components/home/VideoSection";
import { Section } from "~/components/Section";
import { MainLayout } from "~/layouts/MainLayout";
import { scrollToSection } from "~/utils/dom";
-const UseCaseCard: Component<{ title: string; image: string; desc: string }> = (
- props
-) => {
- return (
-
-
-
-
-
-

-
-
-
- );
-};
-
-export default function HomePage(props: ParentProps) {
+export default function HomePage() {
const location = useLocation();
// scroll to a section after navigation (for dom.ts#scrollToSection)
@@ -94,39 +57,16 @@ export default function HomePage(props: ParentProps) {
-
-
+
+
diff --git a/src/routes/privacy.tsx b/src/routes/privacy.tsx
index 3440e25..2ad0997 100644
--- a/src/routes/privacy.tsx
+++ b/src/routes/privacy.tsx
@@ -1,6 +1,5 @@
import { Link, Meta } from "@solidjs/meta";
import remarkGfm from "remark-gfm";
-import { ParentProps } from "solid-js";
import { SolidMarkdown } from "solid-markdown";
import { AppTitle } from "~/components/AppTitle";
import { Container } from "~/components/commons/Container";
@@ -8,7 +7,7 @@ import { MarkdownLink } from "~/components/commons/Markdown";
import { Section } from "~/components/Section";
import { MainLayout } from "~/layouts/MainLayout";
-export default function PrivacyPage(props: ParentProps) {
+export default function PrivacyPage() {
return (
diff --git a/src/routes/team.tsx b/src/routes/team.tsx
index ca957c5..94dbc5d 100644
--- a/src/routes/team.tsx
+++ b/src/routes/team.tsx
@@ -8,14 +8,17 @@ import {
createSignal,
onCleanup,
onMount,
- ParentProps,
} from "solid-js";
import { AppTitle } from "~/components/AppTitle";
import { Button } from "~/components/commons/Button";
import { Container } from "~/components/commons/Container";
import { ShuffleIcon } from "~/components/commons/icons/ShuffleIcon";
import { Typography } from "~/components/commons/Typography";
-import { Contributor, contributors } from "~/components/contributors";
+import {
+ Contributor,
+ ContributorDisplay,
+ contributors,
+} from "~/components/contributors";
import { Card } from "~/components/contributors/Card";
import { SearchBox } from "~/components/contributors/SearchBox";
import { Sponsor, SponsorCard, PastSponsorAvatar } from "~/components/sponsors";
@@ -28,6 +31,7 @@ import { PeopleIcon } from "~/components/commons/icons/PeopleIcon";
import CircularIcon from "~/components/contributors/CircularIcon";
import { useI18n } from "~/i18n";
import { setScroll } from "~/utils/scrollbar";
+import { getCardIndex, getCardName } from "~/utils/dom";
// constants
const MAX_SHINY = 5;
@@ -57,7 +61,11 @@ const socialsPriority = [
const sortedContribs = contributors
.slice()
// sort alphabetically by name
- .sort((a, b) => a.name.localeCompare(b.name))
+ .sort((a, b) => {
+ const nameA = getCardName(a.display).toLowerCase();
+ const nameB = getCardName(b.display).toLowerCase();
+ return nameA.localeCompare(nameB);
+ })
.map((contributor) => {
if (contributor.socials) {
// sort socials by priority
@@ -198,7 +206,11 @@ const imageCache = new Map<
string,
{ src: string; classes: string; error: boolean }
>();
-const preloadImage = (name: string, classes?: string): Promise => {
+const preloadImage = (
+ name: string,
+ display: ContributorDisplay[],
+ classes?: string
+): Promise => {
return new Promise((resolve) => {
if (imageCache.has(name)) {
resolve();
@@ -206,7 +218,14 @@ const preloadImage = (name: string, classes?: string): Promise => {
}
const image = new Image();
- image.src = `/images/contributors/${name.toLowerCase()}.webp`;
+
+ if (display.length > 1) {
+ const i = getCardIndex(display.length) - 1;
+ image.src = display[i].src;
+ } else {
+ image.src = display[0].src;
+ }
+
image.onload = () => {
imageCache.set(name, {
src: image.src,
@@ -220,7 +239,7 @@ const preloadImage = (name: string, classes?: string): Promise => {
};
image.onerror = () => {
imageCache.set(name, {
- src: `/images/contributors/jovannmc.webp`, // fallback
+ src: `/images/contributors/jovannmc-1.webp`, // fallback
classes:
"object-contain w-[calc(100%+16px)] scale-[103%] no-interact brightness-[0.01]",
error: true,
@@ -254,7 +273,7 @@ function shuffle() {
}, SHUFFLE_INTERVAL);
}
-export default function TeamPage(props: ParentProps) {
+export default function TeamPage() {
const { translator } = useI18n();
const [focusedCard, setFocusedCard] = createSignal(null);
@@ -267,9 +286,11 @@ export default function TeamPage(props: ParentProps) {
const pastCount = createMemo(() => pastSponsors().length);
const shinyContribs = createMemo(() => getShinyContribs(sortedContribs));
const filteredContribs = createMemo(() =>
- finalContribs().filter((contrib) =>
- contrib.name.toLowerCase().includes(searchTerm().toLowerCase())
- )
+ finalContribs().filter((contrib) => {
+ const search = searchTerm().toLowerCase();
+ const name = getCardName(contrib.display).toLowerCase();
+ return name.toLowerCase().includes(search);
+ })
);
const handleCardClick = (contributorName: string) => {
@@ -308,7 +329,7 @@ export default function TeamPage(props: ParentProps) {
// preload all contributor images
sortedContribs.forEach((contrib) => {
- preloadImage(contrib.name, contrib.classes);
+ preloadImage(contrib.name, contrib.display, contrib.classes);
});
});
@@ -327,7 +348,7 @@ export default function TeamPage(props: ParentProps) {
rel="preload"
fetchpriority="high"
as="image"
- href="/images/contributors/jovannmc.webp"
+ href="/images/contributors/jovannmc-1.webp"
type="image/webp"
/>
{/* contributors section */}
@@ -422,7 +443,6 @@ export default function TeamPage(props: ParentProps) {
(s) => s.name === contrib.name
);
const cachedImage = imageCache.get(contrib.name);
-
return (
diff --git a/src/utils/dom.ts b/src/utils/dom.ts
index 9a25f88..29f86e4 100644
--- a/src/utils/dom.ts
+++ b/src/utils/dom.ts
@@ -16,3 +16,15 @@ export const scrollToSection = (
// use location.state to pass scrollTo
navigate("/", { state: { scrollTo: sectionId } });
};
+
+export const getCardIndex = (index: number) => {
+ const periodDays = 3; // change image every 3 days
+ const period = Math.floor(Date.now() / (1000 * 60 * 60 * 24 * periodDays));
+ const i = (period % index) + 1;
+ return i;
+};
+
+export const getCardName = (display: { name: string }[]) => {
+ const i = getCardIndex(display.length) - 1;
+ return i >= 0 ? display[i].name : display[0].name;
+};