Skip to content

Commit

Permalink
fixing search
Browse files Browse the repository at this point in the history
  • Loading branch information
ganesshkumar committed Dec 28, 2024
1 parent dc6f84f commit 2dd9876
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 76 deletions.
45 changes: 13 additions & 32 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const customTheme: CustomFlowbiteTheme['footer'] = {
};

const AppFooter = () => {
const footerLinkClass = 'text-gray-900 underline';
return (
<section className="w-full bg-gray-200 mt-16 border-b-8 border-b-violet-800">
<Footer
Expand All @@ -28,47 +29,30 @@ const AppFooter = () => {
<div>
<Footer.Title className="text-gray-900" title="Plugins" />
<Footer.LinkGroup col>
<Footer.Link className="underline text-gray-900" href="/new">
<Footer.Link className={footerLinkClass} href="/plugins">
All Plugins
</Footer.Link>
<Footer.Link className={footerLinkClass} href="/new">
New Plugins
</Footer.Link>
<Footer.Link
className="underline text-gray-900"
href="/updates"
>
<Footer.Link className={footerLinkClass} href="/updates">
Latest Updates
</Footer.Link>
<Footer.Link
className="underline text-gray-900"
href="/most-downloaded"
>
<Footer.Link className={footerLinkClass} href="/most-downloaded">
Most Downloaded
</Footer.Link>
</Footer.LinkGroup>
</div>
<div>
<Footer.LinkGroup col>
<Footer.Title className="" title="" />
<Footer.Link
className="underline text-gray-900"
href="/plugins"
>
All Plugins
</Footer.Link>
<Footer.Link className="underline text-gray-900" href="/tags">
<Footer.Link className={footerLinkClass} href="/tags">
Tags
</Footer.Link>
<Footer.Link
className="underline text-gray-900"
href="/trending"
>
<Footer.Link className={footerLinkClass} href="/trending">
Trending
</Footer.Link>
</Footer.LinkGroup>
</div>
<div>
<Footer.Title className="text-gray-900" title="Posts" />
<Footer.LinkGroup col>
<Footer.Link className="underline text-gray-900" href="/posts">
<Footer.Link className={footerLinkClass} href="/posts">
All Posts
</Footer.Link>
</Footer.LinkGroup>
Expand All @@ -77,12 +61,9 @@ const AppFooter = () => {
</div>
<Footer.Divider className="border-gray-300" />
<div className="w-full items-center justify-between">
<Footer.Copyright
href="/"
by={`${Constants.AppName}™`}
year={new Date().getFullYear()}
className="text-center text-gray-900"
/>
<div className="text-sm text-gray-900 text-center">
© 2022-{new Date().getFullYear()} <a href="/" className="hover:underline">Obsidian Plugin Stats</a>. All rights reserved.
</div>
<div className="my-2 text-sm dark:text-gray-400 text-center">
Made with 💜 by{' '}
<a className="underline" href="https://twitter.com/ganesshkumar">
Expand Down
68 changes: 45 additions & 23 deletions components/InfoBar.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,50 @@
const InfoBar = ({ title }) => {
return (
<h1
className="group relative z-20 scroll-mt-20 text-3xl font-bold text-gray-800 dark:text-white capitalize my-4"
id="default-table"
interface IInfoBarProps {
title: string;
as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
};

const Content = ({ title }) => (
<>
<a
aria-hidden="true"
tabIndex={-1}
target="_blank"
rel="noreferrer"
href="#default-table"
className="text-gray-800"
>
<a
aria-hidden="true"
tabIndex={-1}
target="_blank"
rel="noreferrer"
href="#default-table"
>
{title}
</a>
{title}
</a>

<a
href="#"
aria-label=""
className="ml-2 text-violet-900 opacity-0 transition-opacity group-hover:opacity-100 dark:text-primary-500"
>
#
</a>
</>
);

const className = "group relative z-20 scroll-mt-20 text-3xl font-bold text-gray-800 dark:text-white capitalize my-4";
const id = "default-table";

<a
href="#"
aria-label=""
className="ml-2 text-violet-900 opacity-0 transition-opacity group-hover:opacity-100 dark:text-primary-500"
>
#
</a>
</h1>
);
const InfoBar = ({ title, as = "h1" }: IInfoBarProps) => {
switch (as) {
case "h6":
return <h6 id={id} className={className}><Content title={title} /></h6>;
case "h5":
return <h5 id={id} className={className}><Content title={title} /></h5>;
case "h4":
return <h4 id={id} className={className}><Content title={title} /></h4>;
case "h3":
return <h3 id={id} className={className}><Content title={title} /></h3>;
case "h2":
return <h2 id={id} className={className}><Content title={title} /></h2>;
case "h1":
default:
return <h1 id={id} className={className}><Content title={title} /></h1>;
}
};

export default InfoBar;
14 changes: 7 additions & 7 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ const Home = (props) => {
{/* Most Downloaded */}
<div className="bg-transparent mt-32">
<div className="max-w-6xl mx-auto px-2">
<InfoBar title="Most Downloaded" />
<InfoBar title="Most Downloaded" as="h2"/>
<div>
Here are the 25 most downloaded plugins ever since the beginning of
Obsidian Editor.
Expand Down Expand Up @@ -161,7 +161,7 @@ const Home = (props) => {
{/* FAQ */}
<div className="bg-transparent">
<div className="max-w-6xl mx-auto px-2">
<InfoBar title="FAQ for plugin developers" />
<InfoBar title="FAQ for plugin developers" as="h2"/>
<div className="mt-4">
<Faq />
</div>
Expand All @@ -179,7 +179,7 @@ const NewPluginsSection = ({ newPlugins }) => {
return (
<div className="bg-transparent mt-16">
<div className="max-w-6xl mx-auto px-2">
<InfoBar title="New Plugins" />
<InfoBar title="New Plugins" as="h2"/>
<div>
There are {newPlugins?.length || 0} new plugins from the last 10 days
</div>
Expand Down Expand Up @@ -256,7 +256,7 @@ const NewVersionsSection = ({ newReleases }) => {
return (
<main className="bg-transparent">
<div className="max-w-6xl mx-auto px-2">
<InfoBar title="New Versions" />
<InfoBar title="New Versions" as="h2" />
<div>
There are {sortedNewReleases?.length || 0} new plugins from the last 10 days
</div>
Expand Down Expand Up @@ -351,7 +351,7 @@ const TrendingPlugins = ({plugins}) => {

return (
<div className='max-w-6xl mx-auto px-2 w-full text-gray-800'>
<InfoBar title="Trending Plugins" />
<InfoBar title="Trending Plugins" as="h2" />
<div style={scrollContainerStyle} className="mb-6">
<motion.div
style={{
Expand Down Expand Up @@ -407,7 +407,7 @@ const PostIcon = (props) => {
const NewPosts = ({posts}) => {
return (
<div className="max-w-6xl mx-auto px-2">
<InfoBar title="Posts" />
<InfoBar title="Posts" as="h2" />
<ul className="flex flex-col divide-y mb-4">
{posts.map((post) => (
<li key={post.id}>
Expand Down Expand Up @@ -468,7 +468,7 @@ export const getStaticProps = async () => {
.forEach((tag) => tags.add(tag));
});

const newPosts = getSortedPostsData().slice(0, 10);
const newPosts = getSortedPostsData().slice(0, 5);

const totalPluginsCount = plugins.length;
const newPluginsCount = newPlugins.length;
Expand Down
87 changes: 78 additions & 9 deletions pages/plugins/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useEffect, useMemo, useState } from 'react';
import Header from '../../components/HeaderAll';
import Navbar from '../../components/Navbar';

import { PrismaClient } from '@prisma/client';
import Footer from '../../components/Footer';
import { setupFavorites } from '../../utils/favorites';
import AllPluginsList from '../../components/AllPluinsList';
Expand All @@ -15,6 +14,7 @@ const sortByOptions = {
createdAt_desc: 'Newest Plugins',
//date_desc: 'Date (Newest)',
downloaded_desc: 'Most Downloaded',
relevance: 'Relevance',
};

const filterCategoryOptions = {
Expand All @@ -35,6 +35,61 @@ const filterCategoryOptions = {
uncategorized: 'Uncategorized',
};

const exactMatch = (query: string, text: string) => {
if (!query || !text) {
return false;
}
const regex = new RegExp(`\\b${query}\\b`, "i");
return regex.test(text);
};

const queryPlugins = (
query: string,
plugins: any[] = [],
): any[] => {
if (!query) {
return plugins;
}

const result = [];
const helperSet = new Set();

const addToResult = (plugins) => {
plugins.forEach((plugin) => {
if (!helperSet.has(plugin.pluginId)) {
helperSet.add(plugin.pluginId);
result.push(plugin);
}
});
};

addToResult(plugins.filter((plugin) => {
return exactMatch(query, plugin.name);
}));
addToResult(plugins.filter((plugin) => {
return exactMatch(query, plugin.description);
}));

const queryParts = query.split(" ").filter((part) => !!part);
addToResult(queryParts
.map((part) => plugins.filter((plugin) => exactMatch(part, plugin.name)))
.flat()
);
addToResult(queryParts
.map((part) => plugins.filter((plugin) => exactMatch(part, plugin.description)))
.flat()
);

addToResult(plugins
.filter((plugin) => plugin.name?.toLowerCase().split(" ").some((part) => part.startsWith(query.toLowerCase())))
);
addToResult(plugins
.filter((plugin) => plugin.description?.toLowerCase().split(" ").some((part) => part.startsWith(query.toLowerCase())))
);

return result;
};

const Plugins = (props) => {
const [filter, setFilter] = useState('');
const [favoritesFilter, setFavoritesFilter] = useState(false);
Expand All @@ -48,7 +103,7 @@ const Plugins = (props) => {

const filteredPlugins = useMemo(() => {
const filterLowerCase = filter.toLowerCase();
const plugins = [...props.plugins]
const favAndCategoryFilteredPlugins = [...props.plugins]
.filter((plugin) =>
favoritesFilter ? favorites.includes(plugin.pluginId) : true
)
Expand All @@ -58,15 +113,19 @@ const Plugins = (props) => {
}
return plugin.aiCategories === filterCategoryOptions[filterCategory];
})
.filter((plugin) => {
return (
plugin.name.toLowerCase().includes(filterLowerCase) ||
plugin.description.toLowerCase().includes(filterLowerCase)
);
});
// .filter((plugin) => {
// return (
// plugin.name.toLowerCase().includes(filterLowerCase) ||
// plugin.description.toLowerCase().includes(filterLowerCase)
// );
// });

const plugins = queryPlugins(filterLowerCase, favAndCategoryFilteredPlugins);

plugins.sort((a, b) => {
switch (sortby) {
case 'relevance':
return 0;
case 'alphabet_asc':
return a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1;
case 'alphabet_desc':
Expand Down Expand Up @@ -118,7 +177,12 @@ const Plugins = (props) => {
placeholder="Search for plugins"
color="purple"
shadow
onChange={(e) => setFilter(e.target.value)}
onChange={(e) => {
if (filter.length === 0 && e.target.value.length === 1) {
setSortby('relevance');
}
setFilter(e.target.value)
}}
/>
</div>
<div className="pl-2 mb-4 bg-white flex justify-between">
Expand Down Expand Up @@ -248,6 +312,11 @@ const Plugins = (props) => {
inline
size="sm"
>
{sortby === 'relevance' &&
<Dropdown.Item disabled>
{sortByOptions['relevance']}
</Dropdown.Item>
}
<Dropdown.Item onClick={() => setSortby('alphabet_asc')}>
{sortByOptions['alphabet_asc']}
</Dropdown.Item>
Expand Down
5 changes: 2 additions & 3 deletions pages/tags/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Link from 'next/link';
import Footer from '../../components/Footer';
import { sanitizeTag, tagDenyList } from '../../utils/plugins';
import { PluginsCache } from '../../cache/plugins-cache';
import InfoBar from '../../components/InfoBar';

const Tags = (props) => {
return (
Expand All @@ -18,9 +19,7 @@ const Tags = (props) => {
{/* New Plugins */}
<div className="bg-white pt-5">
<div className="max-w-6xl mx-auto px-2">
<div className="text-3xl py-5 pl-5 text-bold text-violet-900">
☁️ Tags {props.tags && `(${props.tags.length})`}
</div>
<InfoBar title={`Tags ${props.tags && `(${props.tags.length})`}`} />
<div className="flex flex-wrap bg-white px-5 py-5">
{props.tags.sort().map((tag) => {
return (
Expand Down
6 changes: 4 additions & 2 deletions pages/updates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import moment from 'moment';
import Favorites from '../components/Favorites';
import showdown from 'showdown';
import { PluginsCache } from '../cache/plugins-cache';
import InfoBar from '../components/InfoBar';

const mdConverter = new showdown.Converter();
mdConverter.setFlavor('github');
Expand All @@ -32,9 +33,10 @@ const Updates = (props) => {
<div>
<Navbar current="updates" />
</div>
{/* New Plugins */}
{/* New Releases */}
<div className="bg-white pt-5">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<InfoBar title={`New Releases ${props.newReleases && `(${props.newReleases.length})`}`} />
<List
unstyled
className="w-full divide-y divide-gray-200 dark:divide-gray-700"
Expand Down

0 comments on commit 2dd9876

Please sign in to comment.