This commit is contained in:
parent
605d510e54
commit
14e59690bc
|
@ -30,6 +30,7 @@
|
||||||
"All articles": "Все материалы",
|
"All articles": "Все материалы",
|
||||||
"All authors": "Все авторы",
|
"All authors": "Все авторы",
|
||||||
"All posts": "Все публикации",
|
"All posts": "Все публикации",
|
||||||
|
"All posts rating": "Рейтинг всех постов",
|
||||||
"All topics": "Все темы",
|
"All topics": "Все темы",
|
||||||
"Almost done! Check your email.": "Почти готово! Осталось подтвердить вашу почту.",
|
"Almost done! Check your email.": "Почти готово! Осталось подтвердить вашу почту.",
|
||||||
"Are you sure you want to delete this comment?": "Уверены, что хотите удалить этот комментарий?",
|
"Are you sure you want to delete this comment?": "Уверены, что хотите удалить этот комментарий?",
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { Author, Reaction, ReactionKind } from '../../../graphql/schema/core.gen
|
||||||
import { router } from '../../../stores/router'
|
import { router } from '../../../stores/router'
|
||||||
import { Icon } from '../../_shared/Icon'
|
import { Icon } from '../../_shared/Icon'
|
||||||
import { ShowIfAuthenticated } from '../../_shared/ShowIfAuthenticated'
|
import { ShowIfAuthenticated } from '../../_shared/ShowIfAuthenticated'
|
||||||
import { AuthorLink } from '../../Author/AhtorLink'
|
import { AuthorLink } from '../../Author/AuthorLink'
|
||||||
import { Userpic } from '../../Author/Userpic'
|
import { Userpic } from '../../Author/Userpic'
|
||||||
import { CommentDate } from '../CommentDate'
|
import { CommentDate } from '../CommentDate'
|
||||||
import { CommentRatingControl } from '../CommentRatingControl'
|
import { CommentRatingControl } from '../CommentRatingControl'
|
||||||
|
|
|
@ -11,9 +11,12 @@ import { Button } from '../../_shared/Button'
|
||||||
import { CheckButton } from '../../_shared/CheckButton'
|
import { CheckButton } from '../../_shared/CheckButton'
|
||||||
import { Icon } from '../../_shared/Icon'
|
import { Icon } from '../../_shared/Icon'
|
||||||
import { Userpic } from '../Userpic'
|
import { Userpic } from '../Userpic'
|
||||||
|
import { translit } from '../../../utils/ru2en'
|
||||||
|
|
||||||
import styles from './AuthorBadge.module.scss'
|
import styles from './AuthorBadge.module.scss'
|
||||||
import stylesButton from '../../_shared/Button/Button.module.scss'
|
import stylesButton from '../../_shared/Button/Button.module.scss'
|
||||||
|
import { capitalize } from '../../../utils/capitalize'
|
||||||
|
import { isCyrillic } from '../../../utils/cyrillic'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
author: Author
|
author: Author
|
||||||
|
@ -30,7 +33,7 @@ export const AuthorBadge = (props: Props) => {
|
||||||
actions: { loadSubscriptions, requireAuthentication },
|
actions: { loadSubscriptions, requireAuthentication },
|
||||||
} = useSession()
|
} = useSession()
|
||||||
const { changeSearchParams } = useRouter()
|
const { changeSearchParams } = useRouter()
|
||||||
const { t, formatDate } = useLocalize()
|
const { t, formatDate, lang } = useLocalize()
|
||||||
const subscribed = createMemo(() =>
|
const subscribed = createMemo(() =>
|
||||||
subscriptions().authors.some((a: Author) => a.slug === props.author.slug),
|
subscriptions().authors.some((a: Author) => a.slug === props.author.slug),
|
||||||
)
|
)
|
||||||
|
@ -60,19 +63,27 @@ export const AuthorBadge = (props: Props) => {
|
||||||
}, 'discussions')
|
}, 'discussions')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const name = createMemo(() =>
|
||||||
|
capitalize(
|
||||||
|
lang() === 'en' && isCyrillic(props.author.name)
|
||||||
|
? translit(props.author.name)
|
||||||
|
: props.author.name || '',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={clsx(styles.AuthorBadge, { [styles.nameOnly]: props.nameOnly })}>
|
<div class={clsx(styles.AuthorBadge, { [styles.nameOnly]: props.nameOnly })}>
|
||||||
<div class={styles.basicInfo}>
|
<div class={styles.basicInfo}>
|
||||||
<Userpic
|
<Userpic
|
||||||
hasLink={true}
|
hasLink={true}
|
||||||
size={'M'}
|
size={'M'}
|
||||||
name={props.author.name}
|
name={name()}
|
||||||
userpic={props.author.pic}
|
userpic={props.author.pic}
|
||||||
slug={props.author.slug}
|
slug={props.author.slug}
|
||||||
/>
|
/>
|
||||||
<a href={`/author/${props.author.slug}`} class={styles.info}>
|
<a href={`/author/${props.author.slug}`} class={styles.info}>
|
||||||
<div class={styles.name}>
|
<div class={styles.name}>
|
||||||
<span>{props.author.name}</span>
|
<span>{name()}</span>
|
||||||
</div>
|
</div>
|
||||||
<Show when={!props.nameOnly}>
|
<Show when={!props.nameOnly}>
|
||||||
<Switch
|
<Switch
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { Userpic } from '../Userpic'
|
||||||
|
|
||||||
import styles from './AuthorCard.module.scss'
|
import styles from './AuthorCard.module.scss'
|
||||||
import stylesButton from '../../_shared/Button/Button.module.scss'
|
import stylesButton from '../../_shared/Button/Button.module.scss'
|
||||||
|
import { isCyrillic } from '../../../utils/cyrillic'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
author: Author
|
author: Author
|
||||||
|
@ -60,7 +61,7 @@ export const AuthorCard = (props: Props) => {
|
||||||
const isProfileOwner = createMemo(() => author()?.slug === props.author.slug)
|
const isProfileOwner = createMemo(() => author()?.slug === props.author.slug)
|
||||||
|
|
||||||
const name = createMemo(() => {
|
const name = createMemo(() => {
|
||||||
if (lang() !== 'ru') {
|
if (lang() !== 'ru' && isCyrillic(props.author.name)) {
|
||||||
if (props.author.name === 'Дискурс') {
|
if (props.author.name === 'Дискурс') {
|
||||||
return 'Discours'
|
return 'Discours'
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { isCyrillic } from '../../../utils/cyrillic'
|
||||||
import { Userpic } from '../Userpic'
|
import { Userpic } from '../Userpic'
|
||||||
|
|
||||||
import styles from './AhtorLink.module.scss'
|
import styles from './AhtorLink.module.scss'
|
||||||
|
import { translit } from '../../../utils/ru2en'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
author: Author
|
author: Author
|
||||||
|
@ -20,7 +21,7 @@ export const AuthorLink = (props: Props) => {
|
||||||
const { lang } = useLocalize()
|
const { lang } = useLocalize()
|
||||||
const name = createMemo(() => {
|
const name = createMemo(() => {
|
||||||
return lang() === 'en' && isCyrillic(props.author.name)
|
return lang() === 'en' && isCyrillic(props.author.name)
|
||||||
? capitalize(props.author.slug.replace(/-/, ' '))
|
? translit(capitalize(props.author.name))
|
||||||
: props.author.name
|
: props.author.name
|
||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
|
@ -30,7 +31,7 @@ export const AuthorLink = (props: Props) => {
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<a class={styles.link} href={`/author/${props.author.slug}`}>
|
<a class={styles.link} href={`/author/${props.author.slug}`}>
|
||||||
<Userpic size={props.size ?? 'M'} name={props.author.name} userpic={props.author.pic} />
|
<Userpic size={props.size ?? 'M'} name={name()} userpic={props.author.pic} />
|
||||||
<div class={styles.name}>{name()}</div>
|
<div class={styles.name}>{name()}</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
|
@ -15,7 +15,7 @@ import { Popover } from '../../_shared/Popover'
|
||||||
import { CoverImage } from '../../Article/CoverImage'
|
import { CoverImage } from '../../Article/CoverImage'
|
||||||
import { getShareUrl, SharePopup } from '../../Article/SharePopup'
|
import { getShareUrl, SharePopup } from '../../Article/SharePopup'
|
||||||
import { ShoutRatingControl } from '../../Article/ShoutRatingControl'
|
import { ShoutRatingControl } from '../../Article/ShoutRatingControl'
|
||||||
import { AuthorLink } from '../../Author/AhtorLink'
|
import { AuthorLink } from '../../Author/AuthorLink'
|
||||||
import { CardTopic } from '../CardTopic'
|
import { CardTopic } from '../CardTopic'
|
||||||
import { FeedArticlePopup } from '../FeedArticlePopup'
|
import { FeedArticlePopup } from '../FeedArticlePopup'
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ import { SearchField } from '../_shared/SearchField'
|
||||||
import { AuthorBadge } from '../Author/AuthorBadge'
|
import { AuthorBadge } from '../Author/AuthorBadge'
|
||||||
|
|
||||||
import styles from './AllAuthors.module.scss'
|
import styles from './AllAuthors.module.scss'
|
||||||
|
import { isCyrillic } from '../../utils/cyrillic'
|
||||||
|
import { capitalize } from '../../utils/capitalize'
|
||||||
|
|
||||||
type AllAuthorsPageSearchParams = {
|
type AllAuthorsPageSearchParams = {
|
||||||
by: '' | 'name' | 'shouts' | 'followers'
|
by: '' | 'name' | 'shouts' | 'followers'
|
||||||
|
@ -26,10 +28,11 @@ type Props = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const PAGE_SIZE = 20
|
const PAGE_SIZE = 20
|
||||||
const ALPHABET = [...'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ@']
|
|
||||||
|
|
||||||
export const AllAuthorsView = (props: Props) => {
|
export const AllAuthorsView = (props: Props) => {
|
||||||
const { t, lang } = useLocalize()
|
const { t, lang } = useLocalize()
|
||||||
|
const ALPHABET =
|
||||||
|
lang() === 'ru' ? [...'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ@'] : [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ@']
|
||||||
const [offsetByShouts, setOffsetByShouts] = createSignal(0)
|
const [offsetByShouts, setOffsetByShouts] = createSignal(0)
|
||||||
const [offsetByFollowers, setOffsetByFollowers] = createSignal(0)
|
const [offsetByFollowers, setOffsetByFollowers] = createSignal(0)
|
||||||
const { searchParams, changeSearchParams } = useRouter<AllAuthorsPageSearchParams>()
|
const { searchParams, changeSearchParams } = useRouter<AllAuthorsPageSearchParams>()
|
||||||
|
@ -73,20 +76,24 @@ export const AllAuthorsView = (props: Props) => {
|
||||||
shouts: loadMoreByShouts,
|
shouts: loadMoreByShouts,
|
||||||
followers: loadMoreByFollowers,
|
followers: loadMoreByFollowers,
|
||||||
}[searchParams().by]()
|
}[searchParams().by]()
|
||||||
|
const translate = (author: Author) =>
|
||||||
|
lang() === 'en' && isCyrillic(author.name)
|
||||||
|
? capitalize(author.slug.replace(/-/, ' '), true)
|
||||||
|
: author.name
|
||||||
const byLetter = createMemo<{ [letter: string]: Author[] }>(() => {
|
const byLetter = createMemo<{ [letter: string]: Author[] }>(() => {
|
||||||
return sortedAuthors().reduce(
|
return sortedAuthors().reduce(
|
||||||
(acc, author) => {
|
(acc, author) => {
|
||||||
let letter = ''
|
let letter = ''
|
||||||
if (author && author.name) {
|
if (!letter && author && author.name) {
|
||||||
const nameParts = author.name.trim().split(' ')
|
const name = translate(author)
|
||||||
const lastName = nameParts.pop()
|
const nameParts = name.trim().split(' ')
|
||||||
if (lastName && lastName.length > 0) {
|
const found = nameParts.filter(Boolean).pop()
|
||||||
letter = lastName[0].toUpperCase()
|
if (found && found.length > 0) {
|
||||||
|
letter = found[0].toUpperCase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/[^ËА-яё]/.test(letter) && lang() === 'ru') letter = '@'
|
if (/[^ËА-яё]/.test(letter) && lang() === 'ru') letter = '@'
|
||||||
|
if (/[^A-z]/.test(letter) && lang() === 'en') letter = '@'
|
||||||
|
|
||||||
if (!acc[letter]) acc[letter] = []
|
if (!acc[letter]) acc[letter] = []
|
||||||
|
|
||||||
|
@ -193,7 +200,7 @@ export const AllAuthorsView = (props: Props) => {
|
||||||
{(author) => (
|
{(author) => (
|
||||||
<div class={clsx(styles.topic, 'topic col-sm-12 col-md-8')}>
|
<div class={clsx(styles.topic, 'topic col-sm-12 col-md-8')}>
|
||||||
<div class="topic-title">
|
<div class="topic-title">
|
||||||
<a href={`/author/${author.slug}`}>{author.name}</a>
|
<a href={`/author/${author.slug}`}>{translate(author)}</a>
|
||||||
<Show when={author.stat}>
|
<Show when={author.stat}>
|
||||||
<span class={styles.articlesCounter}>{author.stat.shouts}</span>
|
<span class={styles.articlesCounter}>{author.stat.shouts}</span>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
|
@ -189,7 +189,7 @@ export const AuthorView = (props: Props) => {
|
||||||
<div class={clsx('col-md-8', styles.additionalControls)}>
|
<div class={clsx('col-md-8', styles.additionalControls)}>
|
||||||
<Show when={props.author?.stat?.rating || props.author?.stat?.rating === 0}>
|
<Show when={props.author?.stat?.rating || props.author?.stat?.rating === 0}>
|
||||||
<div class={styles.ratingContainer}>
|
<div class={styles.ratingContainer}>
|
||||||
{t('Karma')}
|
{t('All posts rating')}
|
||||||
<AuthorShoutsRating author={props.author} class={styles.ratingControl} />
|
<AuthorShoutsRating author={props.author} class={styles.ratingControl} />
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { DropDown } from '../../_shared/DropDown'
|
||||||
import { Icon } from '../../_shared/Icon'
|
import { Icon } from '../../_shared/Icon'
|
||||||
import { Loading } from '../../_shared/Loading'
|
import { Loading } from '../../_shared/Loading'
|
||||||
import { CommentDate } from '../../Article/CommentDate'
|
import { CommentDate } from '../../Article/CommentDate'
|
||||||
import { AuthorLink } from '../../Author/AhtorLink'
|
import { AuthorLink } from '../../Author/AuthorLink'
|
||||||
import { AuthorBadge } from '../../Author/AuthorBadge'
|
import { AuthorBadge } from '../../Author/AuthorBadge'
|
||||||
import { ArticleCard } from '../../Feed/ArticleCard'
|
import { ArticleCard } from '../../Feed/ArticleCard'
|
||||||
import { Sidebar } from '../../Feed/Sidebar'
|
import { Sidebar } from '../../Feed/Sidebar'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user