Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/octokit/plugin-throt…
Browse files Browse the repository at this point in the history
…tling-9.4.0
  • Loading branch information
lucavallin authored Feb 19, 2025
2 parents 1008eab + 69b2136 commit 29b259c
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 66 deletions.
32 changes: 18 additions & 14 deletions components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import React from "react";
import React, { useMemo } from "react";
import { AppDataProvider } from "../context/AppDataContext";
import { Header } from "./Header";
import { Sidebar } from "./Sidebar";
Expand All @@ -9,16 +9,20 @@ type LayoutProps = {
children: React.ReactNode;
};

export const Layout = ({ children }: LayoutProps) => (
<div className="flex min-h-screen flex-col bg-black-400 text-silver-500 antialiased">
<AppDataProvider>
<Header />
<main className="flex flex-1">
<section className="container mx-auto flex flex-col items-center md:flex-row md:items-start lg:max-w-6xl">
<Sidebar />
{children}
</section>
</main>
</AppDataProvider>
</div>
);
export const Layout = ({ children }: LayoutProps) => {
const memoizedChildren = useMemo(() => children, [children]);

return (
<div className="flex min-h-screen flex-col bg-black-400 text-silver-500 antialiased">
<AppDataProvider>
<Header />
<main className="flex flex-1">
<section className="container mx-auto flex flex-col items-center md:flex-row md:items-start lg:max-w-6xl">
<Sidebar />
{memoizedChildren}
</section>
</main>
</AppDataProvider>
</div>
);
};
39 changes: 20 additions & 19 deletions components/Picker/LanguagePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { faChevronDown } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { CountableLanguage } from "../../types";
import { SectionTitle } from "../SectionTitle";
import ActiveTagButton from "./ActiveTagButton";
Expand All @@ -19,10 +19,13 @@ export const LanguagePicker = ({ activeTagId, languages, onLanguagePage }: Langu
setIsCollapsed(true);
}, [onLanguagePage, activeTagId]);

// Memoize the list of languages to prevent unnecessary re-rendering
const memoizedLanguages = useMemo(() => languages, [languages]);

// Toggle the collapsible sidebar
const toggleCollapsible = () => {
setIsCollapsed(!isCollapsed);
};
const toggleCollapsible = useCallback(() => {
setIsCollapsed((prev) => !prev);
}, []);

return (
<div className="pt-6">
Expand All @@ -47,21 +50,19 @@ export const LanguagePicker = ({ activeTagId, languages, onLanguagePage }: Langu
isCollapsed ? "max-h-0" : "max-h-96"
} ${isCollapsed ? "sm:max-h-full" : ""}`}
>
{languages.map((language) => {
return (
<PickerItem
className={`group m-1 inline-block rounded-sm border px-2 py-1 ${
onLanguagePage && language.id === activeTagId
? "active-pill"
: "border-silver-100 transition-all hover:border-primary hover:text-primary"
}`}
href={`/language/${language.id}`}
key={language.id}
text={language.display}
totalOccurrences={language.count}
/>
);
})}
{memoizedLanguages.map((language) => (
<PickerItem
className={`group m-1 inline-block rounded-sm border px-2 py-1 ${
onLanguagePage && language.id === activeTagId
? "active-pill"
: "border-silver-100 transition-all hover:border-primary hover:text-primary"
}`}
href={`/language/${language.id}`}
key={language.id}
text={language.display}
totalOccurrences={language.count}
/>
))}
</div>
</div>
);
Expand Down
27 changes: 16 additions & 11 deletions components/Picker/TagPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { faChevronDown } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { CountableTag } from "../../types";
import { ShowMoreButton } from "../Button/ShowMoreButton";
import { SectionTitle } from "../SectionTitle";
Expand Down Expand Up @@ -28,16 +28,21 @@ export const TagPicker = ({ tags, activeTagId, onTagPage }: TagPickerProps) => {
setIsCollapsed(true);
}, [activeTagId]);

const toggleCollapsible = () => {
setIsCollapsed(!isCollapsed);
};
// Memoize the tags array to avoid unnecessary recalculations on each render
const memoizedTags = useMemo(() => tags, [tags]);

const handleShowMore = () => {
setLimit((limit) => limit + limitStep);
};
const handleShowLess = () => {
const toggleCollapsible = useCallback(() => {
setIsCollapsed((prev) => !prev);
}, []);

// Memoize the showMore and showLess handlers
const handleShowMore = useCallback(() => {
setLimit((prev) => prev + limitStep);
}, [limitStep]);

const handleShowLess = useCallback(() => {
setLimit(limitStep);
};
}, [limitStep]);

return (
<div className="pt-6">
Expand Down Expand Up @@ -65,13 +70,13 @@ export const TagPicker = ({ tags, activeTagId, onTagPage }: TagPickerProps) => {
{activeTagId && isCollapsed && <ActiveTagButton data={activeTagId} />}
</div>
<div
className={` ${
className={`${
isShowLessVisible && "overflow-y-scroll"
} overflow-hidden duration-300 ease-in-out md:max-h-[50dvh] ${
isCollapsed ? "max-h-0" : "max-h-96"
} ${isCollapsed ? "sm:max-h-full" : ""}`}
>
{tags.slice(0, limit).map((tag) => {
{memoizedTags.slice(0, limit).map((tag) => {
return (
<PickerItem
className={`group m-1 inline-block rounded-sm border px-2 py-1 text-sm ${
Expand Down
21 changes: 13 additions & 8 deletions components/Repository/RepositoryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { faCircleNotch } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useState } from "react";
import { useMemo, useState } from "react";
import InfiniteScroll from "react-infinite-scroll-component";

import { Repository } from "types";
Expand Down Expand Up @@ -35,15 +35,20 @@ export const RepositoryList = ({ languageId, tagId }: RepositoryListProps) => {
filterRepositoriesByTag,
filterRepositoriesByLanguage
} = useAppData();
let repos: Repository[] = repositories;
// Memoizing the filtered repositories based on languageId and tagId
const repos: Repository[] = useMemo(() => {
let filteredRepos = repositories;

if (languageId) {
repos = filterRepositoriesByLanguage(languageId);
}
if (languageId) {
filteredRepos = filterRepositoriesByLanguage(languageId);
}

if (tagId) {
repos = filterRepositoriesByTag(tagId);
}
if (tagId) {
filteredRepos = filterRepositoriesByTag(tagId);
}

return filteredRepos;
}, [repositories, languageId, tagId, filterRepositoriesByLanguage, filterRepositoriesByTag]);

return (
<main className="grow md:max-w-sm lg:max-w-none">
Expand Down
15 changes: 10 additions & 5 deletions components/Repository/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
// searchbar.tsx
"use client";

import { faSearch } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useState } from "react";
import { useCallback, useState } from "react";
import { useAppData } from "../../hooks/useAppData";

export const SearchBar = () => {
const [query, setQuery] = useState("");
const { filterRepositoriesByQuery } = useAppData();

const handleSearch = (searchQuery: string) => {
setQuery(searchQuery);
filterRepositoriesByQuery(searchQuery);
};
const handleSearch = useCallback(
(searchQuery: string) => {
setQuery(searchQuery);
filterRepositoriesByQuery(searchQuery);
},
[filterRepositoriesByQuery]
);

return (
<div className="relative mt-4 flex rounded-md">
Expand Down
16 changes: 7 additions & 9 deletions components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { faGithub } from "@fortawesome/free-brands-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import { useParams, usePathname } from "next/navigation";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { useAppData } from "../hooks/useAppData";
import { AboutSection } from "./AboutSection";
import { LinkButton } from "./Button/LinkButton";
Expand All @@ -19,7 +19,10 @@ export const Sidebar = () => {

const { languages, tags } = useAppData();

// State variable to track whether the user has scrolled to a minimum height of 702 pixels vertically.
// Memoize languages and tags to avoid unnecessary re-renders
const memoizedLanguages = useMemo(() => languages, [languages]);
const memoizedTags = useMemo(() => tags, [tags]);

const [scrollHeightReached, setScrollHeightReached] = useState(false);
const [showUpArrow, setShowUpArrow] = useState(false);

Expand All @@ -30,20 +33,15 @@ export const Sidebar = () => {
scrollTarget?.scrollIntoView({ behavior: "smooth" });
}

// Handle scroll events and set "scrollHeightReached" & "showUpArrow" to True, when the user scrolls to 702 pixels vertically.
const handleScroll = () => {
setScrollHeightReached(window.scrollY >= 702);
setShowUpArrow(window.scrollY > 702);
};

// Add the scroll event listener
window.addEventListener("scroll", handleScroll);

// Remove the scroll event listener when the component unmounts
return () => window.removeEventListener("scroll", handleScroll);
}, [pageType]);

// Function to scroll to the top of the page
const handleScrollToTop = () => window.scrollTo({ top: 0, behavior: "smooth" });

return (
Expand Down Expand Up @@ -74,11 +72,11 @@ export const Sidebar = () => {
}`}
>
<LanguagePicker
languages={languages}
languages={memoizedLanguages}
activeTagId={activeLanguageId}
onLanguagePage={pageType == "language"}
/>
<TagPicker tags={tags} activeTagId={activeTagId} onTagPage={pageType == "tag"} />
<TagPicker tags={memoizedTags} activeTagId={activeTagId} onTagPage={pageType == "tag"} />
</div>
{showUpArrow && <ScrollToTop handleOnClick={handleScrollToTop} />}
</section>
Expand Down

0 comments on commit 29b259c

Please sign in to comment.