From b1b3e128114dd5214b83c97ab580794ae9054491 Mon Sep 17 00:00:00 2001 From: tonyrewin Date: Thu, 17 Nov 2022 20:20:19 +0300 Subject: [PATCH 1/4] abc sort fix --- src/components/Views/AllAuthors.tsx | 15 ++++----------- src/components/Views/AllTopics.tsx | 10 ++++------ 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/components/Views/AllAuthors.tsx b/src/components/Views/AllAuthors.tsx index 487ee161..be42b8ff 100644 --- a/src/components/Views/AllAuthors.tsx +++ b/src/components/Views/AllAuthors.tsx @@ -8,6 +8,7 @@ import { useRouter } from '../../stores/router' import styles from '../../styles/AllTopics.module.scss' import { clsx } from 'clsx' import { useSession } from '../../context/session' +import { locale } from '../../stores/ui' type AllAuthorsPageSearchParams = { by: '' | 'name' | 'shouts' | 'rating' @@ -35,18 +36,10 @@ export const AllAuthorsView = (props: Props) => { const byLetter = createMemo<{ [letter: string]: Author[] }>(() => { return sortedAuthors().reduce((acc, author) => { - if (!author.name) { - // name === null for new users - return acc - } - - const letter = author.name[0].toUpperCase() - if (!acc[letter]) { - acc[letter] = [] - } - + let letter = author.name.trim().split(' ').pop().at(0).toUpperCase() + if (!/[а-яА-Я]/i.test(letter) && locale() == 'ru') letter = '#' + if (!acc[letter]) acc[letter] = [] acc[letter].push(author) - return acc }, {} as { [letter: string]: Author[] }) }) diff --git a/src/components/Views/AllTopics.tsx b/src/components/Views/AllTopics.tsx index 57e8b6ca..f015d772 100644 --- a/src/components/Views/AllTopics.tsx +++ b/src/components/Views/AllTopics.tsx @@ -8,6 +8,7 @@ import { TopicCard } from '../Topic/Card' import styles from '../../styles/AllTopics.module.scss' import { clsx } from 'clsx' import { useSession } from '../../context/session' +import { locale } from '../../stores/ui' type AllTopicsPageSearchParams = { by: 'shouts' | 'authors' | 'title' | '' @@ -37,13 +38,10 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { const byLetter = createMemo<{ [letter: string]: Topic[] }>(() => { return sortedTopics().reduce((acc, topic) => { - const letter = topic.title[0].toUpperCase() - if (!acc[letter]) { - acc[letter] = [] - } - + let letter = topic.title[0].toUpperCase() + if (!/[а-яА-Я]/i.test(letter) && locale() == 'ru') letter = '#' + if (!acc[letter]) acc[letter] = [] acc[letter].push(topic) - return acc }, {} as { [letter: string]: Topic[] }) }) From 2f65142236eb7625a28d86b9febc076a61355d13 Mon Sep 17 00:00:00 2001 From: tonyrewin Date: Thu, 17 Nov 2022 20:32:21 +0300 Subject: [PATCH 2/4] linter-pass-sort-fix --- src/components/Views/AllAuthors.tsx | 2 +- src/components/Views/AllTopics.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Views/AllAuthors.tsx b/src/components/Views/AllAuthors.tsx index be42b8ff..2f051787 100644 --- a/src/components/Views/AllAuthors.tsx +++ b/src/components/Views/AllAuthors.tsx @@ -37,7 +37,7 @@ export const AllAuthorsView = (props: Props) => { const byLetter = createMemo<{ [letter: string]: Author[] }>(() => { return sortedAuthors().reduce((acc, author) => { let letter = author.name.trim().split(' ').pop().at(0).toUpperCase() - if (!/[а-яА-Я]/i.test(letter) && locale() == 'ru') letter = '#' + if (!/[а-яА-Я]/i.test(letter) && locale() === 'ru') letter = '#' if (!acc[letter]) acc[letter] = [] acc[letter].push(author) return acc diff --git a/src/components/Views/AllTopics.tsx b/src/components/Views/AllTopics.tsx index f015d772..f4c3224a 100644 --- a/src/components/Views/AllTopics.tsx +++ b/src/components/Views/AllTopics.tsx @@ -39,7 +39,7 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { const byLetter = createMemo<{ [letter: string]: Topic[] }>(() => { return sortedTopics().reduce((acc, topic) => { let letter = topic.title[0].toUpperCase() - if (!/[а-яА-Я]/i.test(letter) && locale() == 'ru') letter = '#' + if (!/[а-яА-Я]/i.test(letter) && locale() === 'ru') letter = '#' if (!acc[letter]) acc[letter] = [] acc[letter].push(topic) return acc From a8247bafd63b0ba309251d083277daae092f6537 Mon Sep 17 00:00:00 2001 From: tonyrewin Date: Thu, 17 Nov 2022 23:08:12 +0300 Subject: [PATCH 3/4] need some cosmetics --- src/components/Topic/Card.tsx | 10 -- src/components/Views/AllAuthors.tsx | 2 +- src/components/Views/AllTopics.tsx | 181 +++++++++++++++++++--------- src/styles/AllTopics.module.scss | 5 + 4 files changed, 127 insertions(+), 71 deletions(-) diff --git a/src/components/Topic/Card.tsx b/src/components/Topic/Card.tsx index 2f18162a..8067171e 100644 --- a/src/components/Topic/Card.tsx +++ b/src/components/Topic/Card.tsx @@ -120,15 +120,6 @@ export const TopicCard = (props: TopicProps) => { {/* */} {/**/} - - {/* - - {subscribers().toString() + ' ' + t('follower') + plural( - subscribers(), - locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's'] - )} - -*/} @@ -136,7 +127,6 @@ export const TopicCard = (props: TopicProps) => { class={styles.controlContainer} classList={{ 'col-md-3': !props.compact && !props.subscribeButtonBottom }} > - {} { const byLetter = createMemo<{ [letter: string]: Author[] }>(() => { return sortedAuthors().reduce((acc, author) => { let letter = author.name.trim().split(' ').pop().at(0).toUpperCase() - if (!/[а-яА-Я]/i.test(letter) && locale() === 'ru') letter = '#' + if (!/[а-яА-Я]/i.test(letter) && locale() === 'ru') letter = '@' if (!acc[letter]) acc[letter] = [] acc[letter].push(author) return acc diff --git a/src/components/Views/AllTopics.tsx b/src/components/Views/AllTopics.tsx index f4c3224a..4e2fe920 100644 --- a/src/components/Views/AllTopics.tsx +++ b/src/components/Views/AllTopics.tsx @@ -1,14 +1,15 @@ -import { createEffect, createMemo, createSignal, For, Show } from 'solid-js' +import { createEffect, createMemo, createSignal, For, onMount, Show } from 'solid-js' import type { Topic } from '../../graphql/types.gen' import { Icon } from '../_shared/Icon' import { t } from '../../utils/intl' import { setTopicsSort, useTopicsStore } from '../../stores/zine/topics' import { useRouter } from '../../stores/router' import { TopicCard } from '../Topic/Card' -import styles from '../../styles/AllTopics.module.scss' import { clsx } from 'clsx' import { useSession } from '../../context/session' import { locale } from '../../stores/ui' +import { translit } from '../../utils/ru2en' +import styles from '../../styles/AllTopics.module.scss' type AllTopicsPageSearchParams = { by: 'shouts' | 'authors' | 'title' | '' @@ -55,66 +56,77 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { const subscribed = (s) => Boolean(session()?.news?.topics && session()?.news?.topics?.includes(s || '')) const showMore = () => setLimit((oldLimit) => oldLimit + PAGE_SIZE) + let searchEl: HTMLInputElement + const [searchResults, setSearchResults] = createSignal([]) + const searchTopics = (ev) => { + /* very stupid search algorithm with no deps */ + let q = searchEl.value.toLowerCase() + if (q.length > 0) { + console.debug(q) + setSearchResults([]) + if (locale() === 'ru') q = translit(q, 'ru') + let ttt: Topic[] = [] + sortedTopics().forEach((t: Topic) => { + let flag = false + t.slug.split('-').forEach((w) => { + if (w.startsWith(q)) flag = true + }) + + if (!flag) { + let wrds: string = t.title.toLowerCase() + if (locale() === 'ru') wrds = translit(wrds, 'ru') + wrds.split(' ').forEach((w: string) => { + if (w.startsWith(q)) flag = true + }) + } + + if (flag && !ttt.includes(t)) ttt.push(t) + }) + + setSearchResults((sr: Topic[]) => [...sr, ...ttt]) + changeSearchParam('by', '') + } + } + createEffect(() => {}) + const AllTopicsHead = () => ( +
+
+

{t('Topics')}

+

{t('Subscribe what you like to tune your personal feed')}

+ + +
+
+ ) return (
- 0}> -
- - - ( - <> - - {(topic) => ( - - )} - - limit()}> -
-
- -
-
-
- - )} - > +
+ 0 || searchResults().length > 0}> + {(letter) => (
@@ -140,8 +152,57 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { )} -
-
+ + 1}> + + {(topic) => ( + + )} + + + + + + {(topic) => ( + + )} + + + + + + {(topic) => ( + + )} + + + + limit()}> +
+
+ +
+
+
+
+
) } diff --git a/src/styles/AllTopics.module.scss b/src/styles/AllTopics.module.scss index 976dec91..da4a4bb2 100644 --- a/src/styles/AllTopics.module.scss +++ b/src/styles/AllTopics.module.scss @@ -27,6 +27,11 @@ .container { width: auto; + + .search-input { + display: inline-block; + width: 100px !important; + } } } From e39414d975b82ddd963f4147b41085c87fe636a8 Mon Sep 17 00:00:00 2001 From: tonyrewin Date: Fri, 18 Nov 2022 02:20:40 +0300 Subject: [PATCH 4/4] search-wip, bio fix --- src/components/Author/Card.tsx | 6 +++- src/components/Views/Search.tsx | 59 ++++++++++++++++++++++++--------- src/locales/ru.json | 3 +- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/components/Author/Card.tsx b/src/components/Author/Card.tsx index 7cd3131a..670ddcbe 100644 --- a/src/components/Author/Card.tsx +++ b/src/components/Author/Card.tsx @@ -30,7 +30,11 @@ export const AuthorCard = (props: AuthorCardProps) => { () => session()?.news?.authors?.some((u) => u === props.author.slug) || false ) const canFollow = createMemo(() => !props.hideFollow && session()?.user?.slug !== props.author.slug) - const bio = () => props.author.bio || t('Our regular contributor') + const bio = () => { + const d = document.createElement('div') + d.innerHTML = props.author.bio + return d.innerText || t('Our regular contributor') + } const name = () => { return props.author.name === 'Дискурс' && locale() !== 'ru' ? 'Discours' diff --git a/src/components/Views/Search.tsx b/src/components/Views/Search.tsx index a3bbfd1f..062076c9 100644 --- a/src/components/Views/Search.tsx +++ b/src/components/Views/Search.tsx @@ -4,6 +4,7 @@ import type { Shout } from '../../graphql/types.gen' import { ArticleCard } from '../Feed/Card' import { t } from '../../utils/intl' import { useArticlesStore, loadShoutsBy } from '../../stores/zine/articles' +import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll' import { useRouter } from '../../stores/router' type SearchPageSearchParams = { @@ -15,31 +16,49 @@ type Props = { results: Shout[] } +const LOAD_MORE_PAGE_SIZE = 50 + export const SearchView = (props: Props) => { const { sortedArticles } = useArticlesStore({ shouts: props.results }) - const [getQuery, setQuery] = createSignal(props.query) + const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) + const [query, setQuery] = createSignal(props.query) + const [offset, setOffset] = createSignal(0) const { searchParams, handleClientRouteLinkClick } = useRouter() - - const handleQueryChange = (ev) => { - setQuery(ev.target.value) + let searchEl: HTMLInputElement + const handleQueryChange = (_ev) => { + setQuery(searchEl.value) } - const handleSubmit = (_ev) => { - // TODO page - // TODO sort - loadShoutsBy({ by: { title: getQuery(), body: getQuery() }, limit: 50 }) + const loadMore = async () => { + saveScrollPosition() + const { hasMore } = await loadShoutsBy({ + by: { + title: query(), + body: query() + }, + offset: offset(), + limit: LOAD_MORE_PAGE_SIZE + }) + setIsLoadMoreButtonVisible(hasMore) + setOffset(offset() + LOAD_MORE_PAGE_SIZE) + restoreScrollPosition() } return (
- {/*FIXME t*/} - +
-
@@ -51,14 +70,18 @@ export const SearchView = (props: Props) => { selected: searchParams().by === 'relevance' }} > - {t('By relevance')} + + {t('By relevance')} +
  • - {t('Top rated')} + + {t('Top rated')} +
  • @@ -83,9 +106,13 @@ export const SearchView = (props: Props) => {
    -

    {t('Topics')}

    - -

    {t('Authors')}

    + +

    + +

    +
    ) diff --git a/src/locales/ru.json b/src/locales/ru.json index 900d6684..b71cdec3 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -176,5 +176,6 @@ "Video": "Видео", "Literature": "Литература", "We can't find you, check email or": "Не можем вас найти, проверьте адрес электронной почты или", - "register": "зарегистрируйтесь" + "register": "зарегистрируйтесь", + "Enter text": "Введите текст" }