Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,10 @@ const config = {
label: '市场',
position: 'left',
},

{
type: 'search',
position: 'right',
},
{
type: 'localeDropdown',
position: 'right',
Expand All @@ -180,6 +183,33 @@ const config = {
darkTheme: darkCodeTheme,
additionalLanguages: ['shell-session', 'http', 'protobuf', 'rust'],
},
algolia: {
// The application ID provided by Algolia
appId: 'E5GVH515OK',

// Public API key: it is safe to commit it
apiKey: '06b2d0933abc228a5979d16d1af26c0b',

// 默认 index 是简体中文,其它语言需要动态切 indexName,逻辑在 SearchBar.tsx
indexName: 'open-longportapp',

// Optional: see doc section below
contextualSearch: true,

// Optional: Replace parts of the item URLs from Algolia. Useful when using the same search index for multiple deployments using a different baseUrl. You can use regexp or string in the `from` param. For example: localhost:3000 vs myCompany.com/docs
// replaceSearchResultPathname: {
// from: '/docs/', // or as RegExp: /\/docs\//
// to: '/',
// },

// Optional: Algolia search parameters
searchParameters: {},

// Optional: path for search page that enabled by default (`false` to disable it)
searchPagePath: 'search',

//... other Algolia params
},
}),
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/dropdown/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $border-color: #eeeeee;
--dropdown-hover-bg: #{$hover-bg};
--dropdown-border-color: #{$border-color};
--dropdown-brand-color: #{$brand-color};
@apply relative text-sm;
@apply relative text-sm mr-[50px] md:mr-auto;
:global(.trigger) {
@apply cursor-pointer py-1 px-2 rounded-full text-base font-medium;
&:hover {
Expand Down
192 changes: 192 additions & 0 deletions src/theme/SearchBar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import React, { useCallback, useMemo, useRef, useState } from 'react'
import { DocSearchButton, useDocSearchKeyboardEvents } from '@docsearch/react'
import Head from '@docusaurus/Head'
import Link from '@docusaurus/Link'
import { useHistory } from '@docusaurus/router'
import { isRegexpStringMatch, useSearchLinkCreator } from '@docusaurus/theme-common'
import { useAlgoliaContextualFacetFilters, useSearchResultUrlProcessor } from '@docusaurus/theme-search-algolia/client'
import Translate from '@docusaurus/Translate'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
import { createPortal } from 'react-dom'
import translations from '@theme/SearchTranslations'

let DocSearchModal = null

function Hit({ hit, children }) {
return <Link to={hit.url}>{children}</Link>
}

function ResultsFooter({ state, onClose }) {
const createSearchLink = useSearchLinkCreator()
return (
<Link to={createSearchLink(state.query)} onClick={onClose}>
<Translate id="theme.SearchBar.seeAll" values={{ count: state.context.nbHits }}>
{'See all {count} results'}
</Translate>
</Link>
)
}

function mergeFacetFilters(f1, f2) {
const normalize = (f) => (typeof f === 'string' ? [f] : f)
return [...normalize(f1), ...normalize(f2)]
}

function DocSearch({ contextualSearch, externalUrlRegex, ...props }) {
const { siteMetadata, i18n } = useDocusaurusContext()
const processSearchResultUrl = useSearchResultUrlProcessor()
const contextualSearchFacetFilters = useAlgoliaContextualFacetFilters()
const configFacetFilters = props.searchParameters?.facetFilters ?? []
const facetFilters = contextualSearch
? // Merge contextual search filters with config filters
mergeFacetFilters(contextualSearchFacetFilters, configFacetFilters)
: // ... or use config facetFilters
configFacetFilters
// We let user override default searchParameters if she wants to
const searchParameters = {
...props.searchParameters,
facetFilters,
}
const history = useHistory()
const searchContainer = useRef(null)
const searchButtonRef = useRef(null)
const [isOpen, setIsOpen] = useState(false)
const [initialQuery, setInitialQuery] = useState(undefined)
const importDocSearchModalIfNeeded = useCallback(() => {
if (DocSearchModal) {
return Promise.resolve()
}
return Promise.all([
import('@docsearch/react/modal'),
import('@docsearch/react/style'),
import('./styles.css'),
]).then(([{ DocSearchModal: Modal }]) => {
DocSearchModal = Modal
})
}, [])
const onOpen = useCallback(() => {
importDocSearchModalIfNeeded().then(() => {
searchContainer.current = document.createElement('div')
document.body.insertBefore(searchContainer.current, document.body.firstChild)
setIsOpen(true)
})
}, [importDocSearchModalIfNeeded, setIsOpen])
const onClose = useCallback(() => {
setIsOpen(false)
searchContainer.current?.remove()
}, [setIsOpen])
const onInput = useCallback(
(event) => {
importDocSearchModalIfNeeded().then(() => {
setIsOpen(true)
setInitialQuery(event.key)
})
},
[importDocSearchModalIfNeeded, setIsOpen, setInitialQuery]
)
const navigator = useRef({
navigate({ itemUrl }) {
// Algolia results could contain URL's from other domains which cannot
// be served through history and should navigate with window.location
if (isRegexpStringMatch(externalUrlRegex, itemUrl)) {
window.location.href = itemUrl
} else {
history.push(itemUrl)
}
},
}).current
const transformItems = useRef((items) =>
props.transformItems
? // Custom transformItems
props.transformItems(items)
: // Default transformItems
items.map((item) => ({
...item,
url: processSearchResultUrl(item.url),
}))
).current
const resultsFooterComponent = useMemo(
() =>
// eslint-disable-next-line react/no-unstable-nested-components
(footerProps) => <ResultsFooter {...footerProps} onClose={onClose} />,
[onClose]
)
const transformSearchClient = useCallback(
(searchClient) => {
searchClient.addAlgoliaAgent('docusaurus', siteMetadata.docusaurusVersion)
return searchClient
},
[siteMetadata.docusaurusVersion]
)
useDocSearchKeyboardEvents({
isOpen,
onOpen,
onClose,
onInput,
searchButtonRef,
})

const indexName = useMemo(() => {
switch (i18n.currentLocale) {
case 'en':
return 'open-longportapp-en'
break
case 'zh-HK':
return 'open-longportapp-zh-HK'
break
default:
return 'open-longportapp'
}
}, [i18n.currentLocale])

console.log('DocSearch-142', i18n.currentLocale, indexName)

return (
<>
<Head>
{/* This hints the browser that the website will load data from Algolia,
and allows it to preconnect to the DocSearch cluster. It makes the first
query faster, especially on mobile. */}
<link rel="preconnect" href={`https://${props.appId}-dsn.algolia.net`} crossOrigin="anonymous" />
</Head>

<DocSearchButton
onTouchStart={importDocSearchModalIfNeeded}
onFocus={importDocSearchModalIfNeeded}
onMouseOver={importDocSearchModalIfNeeded}
onClick={onOpen}
ref={searchButtonRef}
translations={translations.button}
/>

{isOpen &&
DocSearchModal &&
searchContainer.current &&
createPortal(
<DocSearchModal
onClose={onClose}
initialScrollY={window.scrollY}
initialQuery={initialQuery}
navigator={navigator}
transformItems={transformItems}
hitComponent={Hit}
transformSearchClient={transformSearchClient}
{...(props.searchPagePath && {
resultsFooterComponent,
})}
{...props}
indexName={indexName}
searchParameters={searchParameters}
placeholder={translations.placeholder}
translations={translations.modal}
/>,
searchContainer.current
)}
</>
)
}

export default function SearchBar() {
const { siteConfig } = useDocusaurusContext()
return <DocSearch {...siteConfig.themeConfig.algolia} />
}
21 changes: 21 additions & 0 deletions src/theme/SearchBar/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

:root {
--docsearch-primary-color: var(--ifm-color-primary);
--docsearch-text-color: var(--ifm-font-color-base);
}

.DocSearch-Button {
margin: 0;
transition: all var(--ifm-transition-fast)
var(--ifm-transition-timing-default);
}

.DocSearch-Container {
z-index: calc(var(--ifm-z-index-fixed) + 1);
}