From 72ac411bc42acb39acf6d568d772e3eff75c934c Mon Sep 17 00:00:00 2001 From: Dan BROOKS Date: Mon, 25 Jul 2022 21:54:39 -0700 Subject: [PATCH] feat(Next > useSearch): Index search keywords to aid user with searching --- next/__tests__/hooks/useSearch.jsx | 14 +++++++------- next/pages/[gallery].jsx | 7 ++++--- next/pages/[gallery]/[album].jsx | 9 ++++++--- next/pages/[gallery]/all.jsx | 7 ++++--- next/pages/[gallery]/today.jsx | 8 +++++--- next/public/galleries/demo/sample.xml | 7 +++++-- next/src/components/AlbumPage/index.jsx | 4 ++-- next/src/hooks/useSearch.jsx | 3 ++- next/src/lib/search.js | 18 ++++++++++++++++++ public/galleries/demo/sample.xml | 7 +++++-- 10 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 next/src/lib/search.js diff --git a/next/__tests__/hooks/useSearch.jsx b/next/__tests__/hooks/useSearch.jsx index 2fa777fe3..501a00968 100644 --- a/next/__tests__/hooks/useSearch.jsx +++ b/next/__tests__/hooks/useSearch.jsx @@ -13,7 +13,7 @@ describe('Query string', () => { query: { keyword: '' }, })) const items = [{ corpus: 'apple' }, { corpus: 'banana' }, { corpus: 'cherry' }] - const { result } = renderHook(() => useSearch(items)) + const { result } = renderHook(() => useSearch({ items })) expect(result.current.filtered).toBe(items) expect(result.current.keyword).toBe('') @@ -25,7 +25,7 @@ describe('Query string', () => { query: { keyword: 'app' }, })) const items = [{ corpus: 'apple' }, { corpus: 'banana' }, { corpus: 'cherry' }] - const { result } = renderHook(() => useSearch(items)) + const { result } = renderHook(() => useSearch({ items })) expect(result.current.filtered).toBe(items) expect(result.current.keyword).toBe('') @@ -36,7 +36,7 @@ describe('Query string', () => { const keyword = 'app' useRouter.mockImplementation(() => ({ isReady: true, asPath: '', query: { keyword } })) const items = [{ corpus: 'apple' }, { corpus: 'banana' }, { corpus: 'cherry' }] - const { result } = renderHook(() => useSearch(items)) + const { result } = renderHook(() => useSearch({ items })) expect(result.current.filtered).toStrictEqual([items[0]]) expect(result.current.keyword).toBe(keyword) @@ -45,7 +45,7 @@ describe('Query string', () => { const keyword = 'ban' useRouter.mockImplementation(() => ({ isReady: true, asPath: '', query: { keyword } })) const items = [{ corpus: 'apple' }, { corpus: 'bañana' }, { corpus: 'cherry' }] - const { result } = renderHook(() => useSearch(items)) + const { result } = renderHook(() => useSearch({ items })) expect(result.current.filtered).toStrictEqual([items[1]]) expect(result.current.keyword).toBe(keyword) @@ -54,7 +54,7 @@ describe('Query string', () => { const keyword = 'ban||che' useRouter.mockImplementation(() => ({ isReady: true, asPath: '', query: { keyword } })) const items = [{ corpus: 'apple' }, { corpus: 'bañana' }, { corpus: 'cherry' }] - const { result } = renderHook(() => useSearch(items)) + const { result } = renderHook(() => useSearch({ items })) expect(result.current.filtered).toStrictEqual([items[1], items[2]]) expect(result.current.keyword).toBe(keyword) @@ -63,7 +63,7 @@ describe('Query string', () => { const keyword = 'ban&&che' useRouter.mockImplementation(() => ({ isReady: true, asPath: '', query: { keyword } })) const items = [{ corpus: 'ban' }, { corpus: 'cherrished bañana' }, { corpus: 'cherry' }] - const { result } = renderHook(() => useSearch(items)) + const { result } = renderHook(() => useSearch({ items })) expect(result.current.filtered).toStrictEqual([items[1]]) expect(result.current.keyword).toBe(keyword) @@ -77,7 +77,7 @@ describe('Search box component', () => { useRouter.mockImplementation(() => ({ isReady: true, asPath: '', query: { keyword } })) const items = [{ corpus: 'apple' }, { corpus: 'banana' }, { corpus: 'cherry' }] function Dan() { - const { searchBox } = useSearch(items) + const { searchBox } = useSearch({ items }) return searchBox } const { getByText } = render() diff --git a/next/pages/[gallery].jsx b/next/pages/[gallery].jsx index c7af4b2c4..5a6a00645 100644 --- a/next/pages/[gallery].jsx +++ b/next/pages/[gallery].jsx @@ -3,6 +3,7 @@ import styled, { css } from 'styled-components' import { get as getAlbums } from '../src/lib/albums' import { get as getGalleries } from '../src/lib/galleries' +import { indexKeywords } from '../src/lib/search' import Image from '../src/components/Img' import Link from '../src/components/Link' @@ -15,7 +16,7 @@ export async function getStaticProps({ params: { gallery } }) { corpus: [album.h1, album.h2, album.year].join(' '), })) return { - props: { gallery, albums: preparedAlbums }, + props: { gallery, albums: preparedAlbums, ...indexKeywords(albums) }, } } @@ -55,11 +56,11 @@ const AlbumYear = styled.h3` color: #8B5A2B; ` -function AlbumsPage({ gallery, albums }) { +function AlbumsPage({ gallery, albums, indexedKeywords }) { const { filtered, searchBox, - } = useSearch(albums) + } = useSearch({ items: albums, indexedKeywords }) const AlbumSet = () => filtered.map((album, i) => ( +function AlbumPage({ items = [], meta, indexedKeywords }) { + return } export default AlbumPage diff --git a/next/pages/[gallery]/all.jsx b/next/pages/[gallery]/all.jsx index 5ad533287..9a4f98d10 100644 --- a/next/pages/[gallery]/all.jsx +++ b/next/pages/[gallery]/all.jsx @@ -4,6 +4,7 @@ import { useMemo, useState, useRef } from 'react' import { get as getAlbum } from '../../src/lib/album' import { get as getAlbums } from '../../src/lib/albums' import { get as getGalleries } from '../../src/lib/galleries' +import { indexKeywords } from '../../src/lib/search' import AlbumContext from '../../src/components/Context' import Img from '../../src/components/Img' @@ -29,7 +30,7 @@ export async function getStaticProps({ params: { gallery } }) { }, Promise.resolve([])) return { - props: { items: allItems }, + props: { items: allItems, ...indexKeywords(allItems) }, } } @@ -43,14 +44,14 @@ export async function getStaticPaths() { } } -function AllPage({ items = [] }) { +function AllPage({ items = [], indexedKeywords }) { const refImageGallery = useRef(null) const [memoryIndex, setMemoryIndex] = useState(0) const { filtered, keyword, searchBox, - } = useSearch(items, setMemoryIndex) + } = useSearch({ items, setMemoryIndex, indexedKeywords }) const { setViewed, memoryHtml, viewedList } = useMemory(filtered, refImageGallery) const showThumbnail = (kw = '') => kw.length > 2 diff --git a/next/pages/[gallery]/today.jsx b/next/pages/[gallery]/today.jsx index 58e60c5f5..16162fd4c 100644 --- a/next/pages/[gallery]/today.jsx +++ b/next/pages/[gallery]/today.jsx @@ -1,6 +1,8 @@ import { get as getGalleries } from '../../src/lib/galleries' import { get as getAlbums } from '../../src/lib/albums' import { get as getAlbum } from '../../src/lib/album' +import { indexKeywords } from '../../src/lib/search' + import AlbumPageComponent from '../../src/components/AlbumPage' export async function getStaticProps({ params: { gallery } }) { @@ -19,7 +21,7 @@ export async function getStaticProps({ params: { gallery } }) { }, Promise.resolve([])) return { - props: { items: allItems }, + props: { items: allItems, ...indexKeywords(allItems) }, } } @@ -33,8 +35,8 @@ export async function getStaticPaths() { } } -function Today({ items }) { - return +function Today({ items, indexedKeywords }) { + return } export default Today diff --git a/next/public/galleries/demo/sample.xml b/next/public/galleries/demo/sample.xml index 6dca01f88..3699c5311 100644 --- a/next/public/galleries/demo/sample.xml +++ b/next/public/galleries/demo/sample.xml @@ -4,7 +4,7 @@ demo sample - 2.0 + 2.2 11 @@ -29,6 +29,7 @@ Dining Room Gingerbread Gingerbread persons + best^, baked goods, house 2005-07-30-01.jpg @@ -56,6 +57,7 @@ 49.25 -123.1 + 10 @@ -67,7 +69,7 @@ Vancouver International Airport, BC YVR Airport - + aerodrome, airdrome Vancouver_International_Airport wikipedia @@ -83,6 +85,7 @@ Brass Fish Tavern Tavern Located in the iconic art deco Marine building + best^ Marine_Building wikipedia diff --git a/next/src/components/AlbumPage/index.jsx b/next/src/components/AlbumPage/index.jsx index e3c788ce9..d839ecabe 100644 --- a/next/src/components/AlbumPage/index.jsx +++ b/next/src/components/AlbumPage/index.jsx @@ -13,13 +13,13 @@ const Wrapper = styled.ul` padding-left: 2px; ` -function AlbumPage({ items = [], meta }) { +function AlbumPage({ items = [], meta, indexedKeywords }) { const refImageGallery = useRef(null) const [memoryIndex, setMemoryIndex] = useState(0) const { filtered, searchBox, - } = useSearch(items, setMemoryIndex) + } = useSearch({ items, setMemoryIndex, indexedKeywords }) const { setViewed, memoryHtml, viewedList } = useMemory(filtered, refImageGallery) function selectThumb(index) { diff --git a/next/src/hooks/useSearch.jsx b/next/src/hooks/useSearch.jsx index 1d3b6efc9..1535b8428 100644 --- a/next/src/hooks/useSearch.jsx +++ b/next/src/hooks/useSearch.jsx @@ -1,9 +1,10 @@ import { useRouter } from 'next/router' import { useEffect, useState } from 'react' -const useSearch = (items, setMemoryIndex) => { +const useSearch = ({ items, setMemoryIndex, indexedKeywords }) => { const router = useRouter() const [keyword, setKeyword] = useState(router.query.keyword || '') + console.log('indexedKeywords', indexedKeywords) const getShareUrlStem = () => { if (router.asPath.includes('keyword=')) { diff --git a/next/src/lib/search.js b/next/src/lib/search.js new file mode 100644 index 000000000..c202dc708 --- /dev/null +++ b/next/src/lib/search.js @@ -0,0 +1,18 @@ +/** + * Index search keywords from search xml element and dedupe + * + * @param {Object[]} items + * @returns {{ indexedKeywords }} + */ +function indexKeywords(items) { + const indexedKeywords = items.reduce((out, item) => { + item?.search?.split(', ').forEach((i) => out.add(i)) + return out + }, new Set()) + + return { indexedKeywords: Array.from(indexedKeywords) } +} + +module.exports = { + indexKeywords, +} diff --git a/public/galleries/demo/sample.xml b/public/galleries/demo/sample.xml index 6dca01f88..3699c5311 100644 --- a/public/galleries/demo/sample.xml +++ b/public/galleries/demo/sample.xml @@ -4,7 +4,7 @@ demo sample - 2.0 + 2.2 11 @@ -29,6 +29,7 @@ Dining Room Gingerbread Gingerbread persons + best^, baked goods, house 2005-07-30-01.jpg @@ -56,6 +57,7 @@ 49.25 -123.1 + 10 @@ -67,7 +69,7 @@ Vancouver International Airport, BC YVR Airport - + aerodrome, airdrome Vancouver_International_Airport wikipedia @@ -83,6 +85,7 @@ Brass Fish Tavern Tavern Located in the iconic art deco Marine building + best^ Marine_Building wikipedia