Skip to content

Commit

Permalink
/sns page rework (#2350)
Browse files Browse the repository at this point in the history
* add chunked-parallel from events page branch

* feat: /sns page rework

* update sns share image

* add twitter links

* fix share image

* fix large card rounded image/video corners

* Minor copy Updates sns.tsx

* Edit from Lara sns.tsx

* update SNS page copy

* add to nav; fix conflict

---------

Co-authored-by: harpa12 <[email protected]>
  • Loading branch information
olaszakos and harpa12 authored Jan 22, 2024
1 parent e302231 commit 11d6c1f
Show file tree
Hide file tree
Showing 35 changed files with 1,011 additions and 527 deletions.
6 changes: 4 additions & 2 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const {
const fs = require("fs");
const validateShowcasePlugin = require("./plugins/validate-showcase.js");
const contentfulPlugin = require("./plugins/contentful");
const snsDataPlugin = require("./plugins/sns-data");
const airtablePlugin = require("./plugins/airtable");

const isDeployPreview = !!process.env.PREVIEW_CANISTER_ID;
Expand Down Expand Up @@ -256,8 +257,8 @@ const marketingNav = {
name: "Use cases",
items: [
{
name: "Open Internet Services",
href: "/ois",
name: "DAOs on ICP",
href: "/sns",
description: "Community-owned services",
},
{
Expand Down Expand Up @@ -494,6 +495,7 @@ const config = {
matomoPlugin,
blogPostsPlugin,
contentfulPlugin,
snsDataPlugin,
airtablePlugin,
validateShowcasePlugin,
externalRedirectsPlugin({
Expand Down
114 changes: 114 additions & 0 deletions plugins/sns-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const fetch = require("node-fetch-retry");
const logger = require("@docusaurus/logger");
const chunkedParallel = require("./utils/chunked-parallel");

function fetchAggregatorPage(page) {
return fetch(
`https://3r4gx-wqaaa-aaaaq-aaaia-cai.icp0.io/v1/sns/list/page/${page}/slow.json`
).then((res) => res.json());
}

/**
* Fetches all aggregator pages and returns a list of all dao data
* @returns {Promise<Array>}
*/
async function fetchAllAggregatorPages() {
const allDaos = [];
let page = 0;
while (true) {
try {
const pageData = await fetchAggregatorPage(page);
allDaos.push(...pageData);
if (pageData.length < 10) {
// reached end
break;
}
page++;
} catch {
// reached page which doesn't exist
break;
}
}
return allDaos;
}

/**
* Gets the number of proposals for a given SNS
* @param {string} root_canister_id
* @returns {Promise<number>}
*/
function getProposalCount(root_canister_id) {
return fetch(
`https://sns-api.internetcomputer.org/api/v1/snses/${root_canister_id}/proposals?limit=0`
)
.then((res) => res.json())
.then((res) => res.max_proposal_index);
}

function getBuyersFromSwapMetrics(swap_canister_id) {
return fetch(`https://${swap_canister_id}.raw.icp0.io/metrics`)
.then((res) => res.text())
.then((res) => +res.match(/sale_buyer_count (\d+)/)[1]);
}

/** @type {import('@docusaurus/types').PluginModule} */
const snsDataPlugin = async function (context, options) {
return {
name: "sns-data",
async loadContent() {
// get all sns daos from aggregator
const snsList = await fetchAllAggregatorPages();

// keep only launched daos
const completedDaos = snsList.filter(
(dao) => dao.lifecycle.lifecycle === 3
);

logger.info(
`Loaded ${snsList.length} daos from the aggregator, out of which ${completedDaos.length} are launched.`
);

const websiteDaoData = completedDaos.map((dao) => ({
name: dao.meta.name,
description: dao.meta.description,
url: dao.meta.url,
logo: dao.meta.logo,
rootCanisterId: dao.canister_ids.root_canister_id,
swapCanisterId: dao.canister_ids.swap_canister_id,
icpRaised: Math.floor(dao.derived_state.buyer_total_icp_e8s / 1e8),
participants: dao.derived_state.direct_participant_count,
proposalCount: 0,
}));

// some DAO's have missing sale participants, get those from swap canister metrics
const missingBuyersPromises = websiteDaoData
.filter((dao) => dao.participants === null)
.map(
(dao) => () =>
getBuyersFromSwapMetrics(dao.swapCanisterId).then(
(buyers) => (dao.participants = buyers)
)
);
await chunkedParallel(missingBuyersPromises, 5);

// get proposal count for all daos
const proposalFillPromises = websiteDaoData.map(
(dao) => () =>
getProposalCount(dao.rootCanisterId).then(
(count) => (dao.proposalCount = count)
)
);
await chunkedParallel(proposalFillPromises, 5);

return websiteDaoData;
},
async contentLoaded({ content, actions }) {
const { createData } = actions;
createData("sns-data.json", JSON.stringify(content, null, 2));
},
};
};

module.exports = snsDataPlugin;

// snsDataPlugin().then((r) => r.loadContent());
17 changes: 14 additions & 3 deletions src/components/Common/AnimateSpawn/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { useSpawnAnimation } from "@site/src/utils/use-spawn-animation";
import { ForwardRefComponent, motion, Variants } from "framer-motion";
import React from "react";
import React, { useEffect } from "react";

type Props<A, B> = {
el?: ForwardRefComponent<A, B>;
children?: React.ReactNode;
variants: Variants;
className?: string;
id?: string;

onShow?: () => void;
threshold?: number;
// todo: fix this hack
src?: string;
alt?: string;
Expand All @@ -19,10 +20,20 @@ function AnimateSpawn<A, B>({
children,
variants,
className,
onShow,
id,
threshold = 0,
...rest
}: Props<A, B>) {
const { controls, ref } = useSpawnAnimation();
const { controls, ref, inView } = useSpawnAnimation({ threshold });
const [started, setStarted] = React.useState(false);

useEffect(() => {
if (inView && !started) {
setStarted(true);
onShow?.();
}
}, [inView]);

const El = el as any; // todo: fix this hack

Expand Down
75 changes: 0 additions & 75 deletions src/components/Common/OpenChatCard/OpenChatCard.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions src/components/Common/RotatingStatsPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ const FadeInOutTitle: React.FC<{
};

const layoutClasses = {
2: "grid grid-cols-1 sm:grid-cols-2 md:justify-between gap-10",
3: "grid grid-cols-1 md:grid-cols-3 md:justify-between gap-10",
4: "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 md:justify-between gap-10",
2: "mt-20 grid grid-cols-1 sm:grid-cols-2 md:justify-between gap-10",
3: "mt-20 grid grid-cols-1 md:grid-cols-3 md:justify-between gap-10",
4: "mt-20 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 md:justify-between gap-10",
};

const RotatingStatPanel: React.FC<{
Expand Down
20 changes: 16 additions & 4 deletions src/components/Common/Stats/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const StatsPanel: React.FC<{
return (
<div
className={clsx(
"mt-20 backdrop-blur-md bg-white/80 border border-white border-solid rounded-xl py-12 px-6 md:px-20 ",
"backdrop-blur-md bg-white/80 border border-white border-solid rounded-xl py-12 px-6 md:px-20 ",
className
)}
>
Expand All @@ -35,11 +35,23 @@ export const StatsPanel: React.FC<{
export const Stat: React.FC<{
title: ReactNode;
value: ReactNode | null;
fallbackValue: string;
style?: React.CSSProperties;
fallbackValue?: string;
titleClassName?: string;
}> = ({ title, value, fallbackValue, titleClassName }) => {
className?: string;
}> = ({
title,
value,
fallbackValue = "",
titleClassName,
style = {},
className,
}) => {
return (
<figure className="m-0 flex flex-col gap-2 items-center">
<figure
className={clsx("m-0 flex flex-col gap-2 items-center", className)}
style={style}
>
{value !== null ? (
<span className="tw-heading-60 text-gradient">{value}</span>
) : (
Expand Down
6 changes: 4 additions & 2 deletions src/components/Common/VideoCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const ImageOnlyVideoCard: React.FC<{

const VideoCard: React.FC<{
title: string;
label: string;
label?: string;
description?: ReactNode;
image: string;
link: string;
Expand Down Expand Up @@ -61,7 +61,9 @@ const VideoCard: React.FC<{
</Link>
<div className="md:w-3/10 flex bg-white-80 border border-solid border-white md:rounded-tr-xl rounded-br-xl p-8 md:p-12 backdrop-blur-2xl">
<div className="self-end">
<h4 className="text-razzmatazz tw-heading-7 mb-0">{label}</h4>
{label && (
<h4 className="text-razzmatazz tw-heading-7 mb-0">{label}</h4>
)}
<p className="mb-0 tw-heading-6 md:tw-heading-5">{title}</p>
{description && (
<p className="text-black-60 tw-paragraph md:tw-lead-sm mb-0 mt-3">
Expand Down
19 changes: 16 additions & 3 deletions src/components/LandingPage/PreHero/Counters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,36 @@ export const SpringCounter: React.FC<{
format: (x: number) => string;
className?: string;
springConfig?: [friction: number, mass: number, tenstion: number];
enabled?: boolean;
delay?: number;
}> = ({
target,
initialTarget,
initialValue,
format,
className,
springConfig = [4, 3, 1],
enabled = true,
delay = 0,
}) => {
const ref = useRef<HTMLSpanElement>(null);
const spring = useRef<Spring | null>(null);
const startAt = useRef(Date.now());

useEffect(() => {
if (enabled) {
startAt.current = Date.now();
}
}, [enabled]);

useEffect(() => {
let lastHandle = -1;
let lastValue = "";
function paint() {
if (spring.current) {
spring.current.update(60);
if (spring.current && enabled) {
if (Date.now() - startAt.current > delay) {
spring.current.update(60);
}
const nextValue = format(spring.current.x);
if (lastValue !== nextValue) {
ref.current.innerText = format(spring.current.x);
Expand All @@ -39,7 +52,7 @@ export const SpringCounter: React.FC<{
return () => {
lastHandle >= 0 && cancelAnimationFrame(lastHandle);
};
}, [format, target, initialValue, initialTarget]);
}, [format, target, initialValue, initialTarget, enabled]);

useEffect(() => {
if (!spring.current) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/NodeProvidersPage/Stats/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const Stats: React.FC = () => {
);

return (
<StatsPanel className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 md:justify-between gap-10">
<StatsPanel className="mt-20 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 md:justify-between gap-10">
<Stat
title="Node providers"
value={
Expand Down
Loading

0 comments on commit 11d6c1f

Please sign in to comment.