Skip to content

Commit

Permalink
implement simple search
Browse files Browse the repository at this point in the history
It's still very inaccessible. Just works by clicking.
  • Loading branch information
mrkvon committed Jul 22, 2021
1 parent 79e9ca1 commit 9ce310d
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 72 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
- [x] show also who knows this person
- [ ] login for different pod providers
- [x] faster (parallel) crawling
- [ ] search people
- [x] search people
- [ ] make it more accessible and easier to navigate
- [ ] highlight also people who know the person
- [ ] highlight people whose button is crawled in PersonList
- [ ] add custom starting point for crawling
Expand Down
114 changes: 51 additions & 63 deletions src/components/PersonCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,70 +10,58 @@ interface Props {

const PersonCard = ({ person, knows, known, onSelectPerson }: Props) => {
return (
<div
style={{
position: 'fixed',
width: '100%',
top: '0',
bottom: 0,
pointerEvents: 'none',
overflowY: 'auto',
overflowX: 'hidden',
}}
>
<div className="columns mr-1 mt-6">
<div className="column is-one-quarter is-offset-three-quarters">
<div
className="card"
style={{ pointerEvents: 'all', overflowX: 'auto', width: '100%' }}
>
<header className="card-header">
<a className="card-header-title" href={person.uri}>
{person.name || person.uri}
</a>
</header>
{person.photo && (
<div className="card-image">
<figure className="image">
<img src={person.photo} alt={person.name} />
</figure>
</div>
)}
<header className="card-header">
<p className="card-header-title">knows: {knows.length}</p>
</header>
<section className="card-content">
<ul className="buttons are-small">
{knows.map(friend => (
<li
onClick={() => onSelectPerson(friend.uri)}
key={friend.uri}
className="button is-link"
>
{friend.name}
</li>
))}
</ul>
</section>
<header className="card-header">
<p className="card-header-title">known by: {known.length}</p>
</header>
<section className="card-content">
<ul className="buttons are-small">
{known.map(friend => (
<li
onClick={() => onSelectPerson(friend.uri)}
key={friend.uri}
className="button is-link"
>
{friend.name}
</li>
))}
</ul>
</section>
</div>
<div className="card">
<header className="card-header">
<p className="card-header-title">
<a href={person.uri}>{person.name || person.uri}</a>
</p>
<button
className="card-header-icon"
aria-label="close"
onClick={() => onSelectPerson('')}
>
close
</button>
</header>
{person.photo && (
<div className="card-image">
<figure className="image">
<img src={person.photo} alt={person.name} />
</figure>
</div>
</div>
)}
<header className="card-header">
<p className="card-header-title">knows: {knows.length}</p>
</header>
<section className="card-content">
<ul className="buttons are-small">
{knows.map(friend => (
<li
onClick={() => onSelectPerson(friend.uri)}
key={friend.uri}
className="button is-link"
>
{friend.name}
</li>
))}
</ul>
</section>
<header className="card-header">
<p className="card-header-title">known by: {known.length}</p>
</header>
<section className="card-content">
<ul className="buttons are-small">
{known.map(friend => (
<li
onClick={() => onSelectPerson(friend.uri)}
key={friend.uri}
className="button is-link"
>
{friend.name}
</li>
))}
</ul>
</section>
</div>
)
}
Expand Down
37 changes: 37 additions & 0 deletions src/components/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'

interface Props {
onChange: (text: string) => void
onSelect: (text: string) => void
value: string
options: { value: string; label: string }[]
}

const Search: React.FC<Props> = ({
onChange,
onSelect,
value,
options,
...props
}: Props) => (
<div {...props} className="box p-0">
<input
type="text"
className="input"
placeholder="Search"
value={value}
onChange={e => onChange(e.target.value)}
/>
<div className="menu">
<ul className="menu-list">
{options.map(({ value, label }) => (
<li key={value} title={value}>
<a onClick={() => onSelect(value)}>{label}</a>
</li>
))}
</ul>
</div>
</div>
)

export default Search
69 changes: 61 additions & 8 deletions src/components/VisualizationContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Vector } from '../helpers/draw'
import { Grid } from '../helpers/draw'
import numeric from 'numeric'
import PersonCard from './PersonCard'
import Search from './Search'
import { withRouter, RouteComponentProps } from 'react-router-dom'
import { PeopleContext, Person } from './DataContainer'
import { IriString } from '@inrupt/solid-client'
Expand All @@ -24,6 +25,31 @@ const transform = (matrix: number[][], vector: Vector): Vector => {
return [x, y]
}

interface ICProps {
children: React.ReactNode
}
const InfoContainer = ({ children }: ICProps) => (
<div
style={{
position: 'fixed',
width: '100%',
top: 0,
bottom: 0,
pointerEvents: 'none',
overflowY: 'auto',
overflowX: 'hidden',
}}
>
<div className="columns mr-1 mt-6">
<div className="column is-one-quarter is-offset-three-quarters">
<div style={{ pointerEvents: 'all', overflowX: 'auto', width: '100%' }}>
{children}
</div>
</div>
</div>
</div>
)

type VisualizationNode = {
x: number
y: number
Expand Down Expand Up @@ -154,6 +180,8 @@ const VisualizationContainer: React.FC<RouteComponentProps> = ({
links: [],
})

const [search, setSearch] = useState<string>('')

const [highlightedNode, setHighlightedNode] = useState<string | undefined>()

const people = useContext(PeopleContext)
Expand Down Expand Up @@ -268,16 +296,41 @@ const VisualizationContainer: React.FC<RouteComponentProps> = ({
</title>
</Helmet>

{person && knows && known && (
<PersonCard
person={person}
knows={knows}
known={known}
onSelectPerson={selectNode}
/>
)}
<InfoContainer>
{person && knows && known ? (
<PersonCard
person={person}
knows={knows}
known={known}
onSelectPerson={selectNode}
/>
) : (
<Search
value={search}
onChange={setSearch}
options={selectSearchOptions(search, people)}
onSelect={selectNode}
/>
)}
</InfoContainer>
</>
)
}

export default withRouter(VisualizationContainer)

const selectSearchOptions = (
query: string,
people: PeopleGraph,
): { value: string; label: string }[] => {
if (query.length < 2) return []
return Object.values(people)
.filter(
({ name, uri }) =>
name.toLowerCase().includes(query.toLowerCase()) ||
uri.toLowerCase().includes(query.toLowerCase()),
)
.sort(({ known: a }, { known: b }) => (b?.size ?? 0) - (a?.size ?? 0))
.map(({ name, uri }) => ({ value: uri, label: name || uri }))
.slice(0, 10)
}
1 change: 1 addition & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@import '~bulma/sass/elements/button.sass';
@import '~bulma/sass/grid/columns.sass';
@import '~bulma/sass/components/card.sass';
@import '~bulma/sass/components/menu.sass';

// You can use Bulma variables from here on

Expand Down

0 comments on commit 9ce310d

Please sign in to comment.