prepare search modal, refactor search fetch, handle intersection, etc.
This commit is contained in:
parent
d5fa4ed034
commit
cf7aec3e1c
|
@ -335,6 +335,7 @@
|
||||||
"This post has not been rated yet": "This post has not been rated yet",
|
"This post has not been rated yet": "This post has not been rated yet",
|
||||||
"This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted": "This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted",
|
"This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted": "This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted",
|
||||||
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "This way you ll be able to subscribe to authors, interesting topics and customize your feed",
|
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "This way you ll be able to subscribe to authors, interesting topics and customize your feed",
|
||||||
|
"To find publications, art, comments, authors and topics of interest to you, just start typing your query": "To find publications, art, comments, authors and topics of interest to you, just start typing your query",
|
||||||
"To leave a comment please": "To leave a comment please",
|
"To leave a comment please": "To leave a comment please",
|
||||||
"To write a comment, you must": "To write a comment, you must",
|
"To write a comment, you must": "To write a comment, you must",
|
||||||
"Top authors": "Authors rating",
|
"Top authors": "Authors rating",
|
||||||
|
|
|
@ -353,6 +353,7 @@
|
||||||
"This post has not been rated yet": "Эту публикацию еще пока никто не оценил",
|
"This post has not been rated yet": "Эту публикацию еще пока никто не оценил",
|
||||||
"This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted": "Так мы поймем, что вы реальный человек, и учтем ваш голос. А вы увидите, как проголосовали другие",
|
"This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted": "Так мы поймем, что вы реальный человек, и учтем ваш голос. А вы увидите, как проголосовали другие",
|
||||||
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "Так вы сможете подписаться на авторов, интересные темы и настроить свою ленту",
|
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "Так вы сможете подписаться на авторов, интересные темы и настроить свою ленту",
|
||||||
|
"To find publications, art, comments, authors and topics of interest to you, just start typing your query": "Для поиска публикаций, искусства, комментариев, интересных вам авторов и тем, просто начните вводить ваш запрос",
|
||||||
"To leave a comment please": "Чтобы оставить комментарий, необходимо",
|
"To leave a comment please": "Чтобы оставить комментарий, необходимо",
|
||||||
"To write a comment, you must": "Чтобы написать комментарий, необходимо",
|
"To write a comment, you must": "Чтобы написать комментарий, необходимо",
|
||||||
"Top authors": "Рейтинг авторов",
|
"Top authors": "Рейтинг авторов",
|
||||||
|
|
|
@ -161,13 +161,13 @@ export const ArticleCard = (props: ArticleCardProps) => {
|
||||||
<a href={`/${props.article.slug || ''}`}>
|
<a href={`/${props.article.slug || ''}`}>
|
||||||
<div class={styles.shoutCardTitle}>
|
<div class={styles.shoutCardTitle}>
|
||||||
<span class={styles.shoutCardLinkWrapper}>
|
<span class={styles.shoutCardLinkWrapper}>
|
||||||
<span class={styles.shoutCardLinkContainer}>{title}</span>
|
<span class={styles.shoutCardLinkContainer} innerHTML={title} />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when={!props.settings?.nosubtitle && subtitle}>
|
<Show when={!props.settings?.nosubtitle && subtitle}>
|
||||||
<div class={styles.shoutCardSubtitle}>
|
<div class={styles.shoutCardSubtitle}>
|
||||||
<span class={styles.shoutCardLinkContainer}>{subtitle}</span>
|
<span class={styles.shoutCardLinkContainer} innerHTML={subtitle} />
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
@mixin searchFilterControl {
|
@mixin searchFilterControl {
|
||||||
|
@include font-size(1.4rem);
|
||||||
|
|
||||||
|
height: 4rem;
|
||||||
|
|
||||||
|
padding: 0 2rem;
|
||||||
|
|
||||||
background: rgb(64 64 64 / 0.5);
|
background: rgb(64 64 64 / 0.5);
|
||||||
border-radius: 10rem;
|
border-radius: 10rem;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@include font-size(1.4rem);
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
height: 4rem;
|
|
||||||
padding: 0 2rem;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -17,42 +20,50 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchForm {
|
.searchContainer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchInput {
|
||||||
|
@include font-size(4.8rem);
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
padding: 0 0 0.5rem;
|
||||||
|
|
||||||
.searchField {
|
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
border-bottom: 2px solid #fff;
|
border-bottom: 2px solid #fff;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@include font-size(4.8rem);
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
outline: none;
|
outline: none;
|
||||||
padding: 0 0 0.5rem;
|
|
||||||
|
|
||||||
&::placeholder {
|
&::placeholder {
|
||||||
color: rgb(255 255 255 / 0.32);
|
color: rgb(255 255 255 / 0.32);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(:placeholder-shown) + .submitControl {
|
&:not(:placeholder-shown) + .searchButton img {
|
||||||
display: block;
|
filter: invert(1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.submitControl {
|
.searchButton {
|
||||||
display: none;
|
|
||||||
filter: invert(1);
|
|
||||||
height: 3.2rem;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 2rem;
|
top: 2rem;
|
||||||
|
|
||||||
width: 3.2rem;
|
width: 3.2rem;
|
||||||
|
height: 3.2rem;
|
||||||
|
|
||||||
|
& img {
|
||||||
|
filter: invert(0.4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchDescription {
|
.searchDescription {
|
||||||
color: rgb(255 255 255 / 0.64);
|
|
||||||
@include font-size(1.6rem);
|
@include font-size(1.6rem);
|
||||||
|
|
||||||
|
color: rgb(255 255 255 / 0.64);
|
||||||
}
|
}
|
||||||
|
|
||||||
.topicsList {
|
.topicsList {
|
||||||
|
@ -60,6 +71,7 @@
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|
||||||
margin-top: 9.6rem !important;
|
margin-top: 9.6rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +102,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|
||||||
margin: 6.4rem 0;
|
margin: 6.4rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,47 +1,103 @@
|
||||||
import { hideModal } from '../../../stores/ui'
|
|
||||||
import { useLocalize } from '../../../context/localize'
|
|
||||||
import { Button } from '../../_shared/Button'
|
|
||||||
import styles from './SearchModal.module.scss'
|
|
||||||
import { Icon } from '../../_shared/Icon'
|
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
|
import { createSignal, Show, For } from 'solid-js'
|
||||||
|
|
||||||
|
import { ArticleCard } from '../../Feed/ArticleCard'
|
||||||
|
import { Button } from '../../_shared/Button'
|
||||||
|
import { Icon } from '../../_shared/Icon'
|
||||||
|
|
||||||
|
// import { PRERENDERED_ARTICLES_COUNT } from '../../Views/Home'
|
||||||
|
|
||||||
|
// import { restoreScrollPosition, saveScrollPosition } from '../../../utils/scroll'
|
||||||
|
|
||||||
|
import type { Shout } from '../../../graphql/types.gen'
|
||||||
|
import { useLocalize } from '../../../context/localize'
|
||||||
|
|
||||||
|
import styles from './SearchModal.module.scss'
|
||||||
|
|
||||||
|
// @@TODO implement search
|
||||||
|
// @@TODO implement throttling
|
||||||
|
|
||||||
|
// @@TODO implement load more (await ...({ filters: { .. }, limit: .., offset: .. }))
|
||||||
|
// @@TODO implement modal hiding on article click
|
||||||
|
// @@TODO search url as const
|
||||||
|
// @@TODO refactor switcher, filters, topics
|
||||||
|
|
||||||
|
const getSearchCoincidences = ({ str, intersection }) =>
|
||||||
|
`<span>${str.replace(
|
||||||
|
new RegExp(intersection, 'g'),
|
||||||
|
`<span class="blackModeIntersection">${intersection}</span>`
|
||||||
|
)}</span>`
|
||||||
|
|
||||||
export const SearchModal = () => {
|
export const SearchModal = () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
|
||||||
const action = '/search'
|
const searchInputRef: { current: HTMLInputElement } = { current: null }
|
||||||
const method = 'get'
|
|
||||||
let msgElement: HTMLTextAreaElement | undefined
|
const [isSearching, setIsSearching] = createSignal(false)
|
||||||
let contactElement: HTMLInputElement | undefined
|
const [searchResultsList, setSearchResultsList] = createSignal([])
|
||||||
const submit = async () => {
|
// const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
await fetch(action, {
|
|
||||||
method,
|
const handleSearch = async () => {
|
||||||
|
const searchValue = searchInputRef.current?.value || ''
|
||||||
|
|
||||||
|
if (Boolean(searchValue)) {
|
||||||
|
await fetch(`https://search.discours.io/search?q=${searchValue}`, {
|
||||||
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
accept: 'application/json',
|
accept: 'application/json',
|
||||||
'content-type': 'application/json; charset=utf-8'
|
'content-type': 'application/json; charset=utf-8'
|
||||||
},
|
}
|
||||||
body: JSON.stringify({ contact: contactElement?.value, message: msgElement?.textContent })
|
|
||||||
})
|
})
|
||||||
// hideModal()
|
.then((data) => data.json())
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
// if (data.length) {
|
||||||
|
// const preparedSearchResultsList = [].map((article) => ({
|
||||||
|
// ...article,
|
||||||
|
// title: getSearchCoincidences({
|
||||||
|
// str: article.title,
|
||||||
|
// intersection: searchInputRef.current?.value || ''
|
||||||
|
// }),
|
||||||
|
// subtitle: getSearchCoincidences({
|
||||||
|
// str: article.subtitle,
|
||||||
|
// intersection: searchInputRef.current?.value || ''
|
||||||
|
// })
|
||||||
|
// }))
|
||||||
|
// setSearchResultsList(preparedSearchResultsList)
|
||||||
|
// } else {
|
||||||
|
// // @@TODO handle no search results notice
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log('search request failed', error)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form method={method} action={action} onSubmit={submit} class={styles.searchForm}>
|
<div class={styles.searchContainer}>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="search"
|
||||||
name="contact"
|
|
||||||
placeholder={t('Site search')}
|
placeholder={t('Site search')}
|
||||||
ref={contactElement}
|
ref={(el) => (searchInputRef.current = el)}
|
||||||
class={styles.searchField}
|
class={styles.searchInput}
|
||||||
|
onInput={handleSearch}
|
||||||
|
onFocusIn={() => setIsSearching(true)}
|
||||||
|
onFocusOut={() => setIsSearching(false)}
|
||||||
/>
|
/>
|
||||||
<button type={submit} class={styles.submitControl}>
|
|
||||||
<Icon name="search" />
|
|
||||||
</button>
|
|
||||||
<p class={styles.searchDescription}>
|
|
||||||
Для поиска публикаций, искусства, комментариев, интересных вам авторов и тем, просто начните
|
|
||||||
вводить ваш запрос
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul class={clsx('view-switcher', styles.filterSwitcher)}>
|
<Button class={styles.searchButton} onClick={handleSearch} value={<Icon name="search" />} />
|
||||||
|
|
||||||
|
<p
|
||||||
|
class={styles.searchDescription}
|
||||||
|
innerHTML={t(
|
||||||
|
'To find publications, art, comments, authors and topics of interest to you, just start typing your query'
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* @@TODO handle switcher */}
|
||||||
|
{/* <ul class={clsx('view-switcher', styles.filterSwitcher)}>
|
||||||
<li class="view-switcher__item view-switcher__item--selected">
|
<li class="view-switcher__item view-switcher__item--selected">
|
||||||
<button type="button">Все</button>
|
<button type="button">Все</button>
|
||||||
</li>
|
</li>
|
||||||
|
@ -51,95 +107,83 @@ export const SearchModal = () => {
|
||||||
<li class="view-switcher__item">
|
<li class="view-switcher__item">
|
||||||
<button type="button">Темы</button>
|
<button type="button">Темы</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul> */}
|
||||||
|
|
||||||
|
{/* @@TODO handle filter */}
|
||||||
|
{/* <Show when={FILTERS.length}>
|
||||||
<div class={styles.filterResults}>
|
<div class={styles.filterResults}>
|
||||||
<button type="button" class={styles.filterResultsControl}>
|
<For each={FILTERS}>
|
||||||
|
{(filter) => (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class={styles.filterResultsControl}
|
||||||
|
onClick={() => setActiveFilter(filter)}
|
||||||
|
>
|
||||||
Период времени
|
Период времени
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class={styles.filterResultsControl}>
|
)}
|
||||||
Рейтинг
|
</For>
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.filterResultsControl}>
|
|
||||||
Тип постов
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.filterResultsControl}>
|
|
||||||
Темы
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.filterResultsControl}>
|
|
||||||
Авторы
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.filterResultsControl}>
|
|
||||||
Сообщества
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
</Show> */}
|
||||||
|
|
||||||
<div class="container-xl">
|
{/* <Show when={searchResultsList().length}> */}
|
||||||
|
<Show when={true}>
|
||||||
|
{/* <For each={searchResultsList()}> */}
|
||||||
|
<For
|
||||||
|
each={[
|
||||||
|
{
|
||||||
|
body: 'body',
|
||||||
|
cover: 'production/image/bbad6b10-9b44-11ee-bdef-5758f9198f7d.png',
|
||||||
|
createdAt: '12',
|
||||||
|
id: 12,
|
||||||
|
slug: '/',
|
||||||
|
authors: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'author',
|
||||||
|
slug: '/'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: '',
|
||||||
|
subtitle: '',
|
||||||
|
topics: []
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{(article: Shout) => (
|
||||||
|
<ArticleCard
|
||||||
|
article={article}
|
||||||
|
settings={{
|
||||||
|
isFloorImportant: true,
|
||||||
|
isSingle: true,
|
||||||
|
nodate: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
|
||||||
|
{/* @@TODO handle load more */}
|
||||||
|
{/* <Show when={isLoadMoreButtonVisible()}>
|
||||||
|
<p class="load-more-container">
|
||||||
|
<button class="button" onClick={loadMore}>
|
||||||
|
{t('Load more')}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</Show> */}
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
{/* @@TODO handle topics */}
|
||||||
|
{/* <div class="container-xl">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class={clsx('col-md-18 offset-md-2', styles.topicsList)}>
|
<div class={clsx('col-md-18 offset-md-2', styles.topicsList)}>
|
||||||
|
{topics.map((topic) => (
|
||||||
<button type="button" class={styles.topTopic}>
|
<button type="button" class={styles.topTopic}>
|
||||||
За месяц
|
{topic.name}
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#репортажи
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#интервью
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#культура
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#поэзия
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#теории
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#война в украине
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#общество
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#Экспериментальная Музыка
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
Рейтинг 300+
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#Протесты
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
Музыка
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#За линией Маннергейма
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
Тесты
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
Коллективные истории
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#личный опыт
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
Тоня Самсонова
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#личный опыт
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
#Секс
|
|
||||||
</button>
|
|
||||||
<button type="button" class={styles.topTopic}>
|
|
||||||
Молоко Plus
|
|
||||||
</button>
|
</button>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1036,3 +1036,8 @@ iframe {
|
||||||
.cursorPointer {
|
.cursorPointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blackModeIntersection {
|
||||||
|
color: var(--default-color);
|
||||||
|
background: #fef2f2;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user