parent
0f54752111
commit
fac6422f2a
|
@ -9,11 +9,9 @@
|
|||
"Add audio": "Add audio",
|
||||
"Add blockquote": "Add blockquote",
|
||||
"Add comment": "Comment",
|
||||
"Here you can manage all your Discourse subscriptions": "Here you can manage all your Discourse subscriptions",
|
||||
"Add cover": "Add cover",
|
||||
"Add image": "Add image",
|
||||
"Add images": "Add images",
|
||||
"Collections": "Collections",
|
||||
"Add intro": "Add intro",
|
||||
"Add link": "Add link",
|
||||
"Add rule": "Add rule",
|
||||
|
@ -65,6 +63,7 @@
|
|||
"Choose a title image for the article. You can immediately see how the publication card will look like.": "Choose a title image for the article. You can immediately see how the publication card will look like.",
|
||||
"Choose who you want to write to": "Choose who you want to write to",
|
||||
"Collaborate": "Help Edit",
|
||||
"Collections": "Collections",
|
||||
"Come up with a subtitle for your story": "Come up with a subtitle for your story",
|
||||
"Come up with a title for your story": "Come up with a title for your story",
|
||||
"Comment successfully deleted": "Comment successfully deleted",
|
||||
|
@ -147,6 +146,7 @@
|
|||
"Help": "Помощь",
|
||||
"Help to edit": "Help to edit",
|
||||
"Here you can customize your profile the way you want.": "Here you can customize your profile the way you want.",
|
||||
"Here you can manage all your Discourse subscriptions": "Here you can manage all your Discourse subscriptions",
|
||||
"Hide table of contents": "Hide table of contents",
|
||||
"Highlight": "Highlight",
|
||||
"Hooray! Welcome!": "Hooray! Welcome!",
|
||||
|
@ -154,8 +154,8 @@
|
|||
"Hot topics": "Hot topics",
|
||||
"Hotkeys": "Горячие клавиши",
|
||||
"How can I help/skills": "How can I help/skills",
|
||||
"How to help": "How to help?",
|
||||
"How it works": "How it works",
|
||||
"How to help": "How to help?",
|
||||
"How to write a good article": "Как написать хорошую статью",
|
||||
"How to write an article": "How to write an article",
|
||||
"I have an account": "I have an account!",
|
||||
|
@ -202,16 +202,17 @@
|
|||
"My feed": "My feed",
|
||||
"My subscriptions": "Subscriptions",
|
||||
"Name": "Name",
|
||||
"Newsletter": "Newsletter",
|
||||
"New literary work": "New literary work",
|
||||
"New only": "New only",
|
||||
"New password": "New password",
|
||||
"New stories every day and even more!": "New stories and more are waiting for you every day!",
|
||||
"Newsletter": "Newsletter",
|
||||
"Night mode": "Night mode",
|
||||
"No such account, please try to register": "No such account found, please try to register",
|
||||
"Nothing here yet": "There's nothing here yet",
|
||||
"Nothing is here": "There is nothing here",
|
||||
"Notifications": "Notifications",
|
||||
"Registered since {{date}}": "Registered since {{date}}",
|
||||
"Or continue with social network": "Or continue with social network",
|
||||
"Or paste a link to an image": "Or paste a link to an image",
|
||||
"Ordered list": "Ordered list",
|
||||
|
@ -285,9 +286,9 @@
|
|||
"Start conversation": "Start a conversation",
|
||||
"Subsccriptions": "Subscriptions",
|
||||
"Subscribe": "Subscribe",
|
||||
"Subscribe us": "Subscribe us",
|
||||
"Subscribe what you like to tune your personal feed": "Subscribe to topics that interest you to customize your personal feed and get instant updates on new posts and discussions",
|
||||
"Subscribe who you like to tune your personal feed": "Subscribe to authors you're interested in to customize your personal feed and get instant updates on new posts and discussions",
|
||||
"Subscribe us": "Subscribe us",
|
||||
"Subscription": "Subscription",
|
||||
"Subscriptions": "Subscriptions",
|
||||
"Substrate": "Substrate",
|
||||
|
@ -328,6 +329,7 @@
|
|||
"Upload video": "Upload video",
|
||||
"Username": "Username",
|
||||
"Userpic": "Userpic",
|
||||
"Users": "Users",
|
||||
"Video": "Video",
|
||||
"Video format not supported": "Video format not supported",
|
||||
"Views": "Views",
|
||||
|
@ -351,8 +353,8 @@
|
|||
"You ll be able to participate in discussions, rate others' comments and learn about new responses": "You ll be able to participate in discussions, rate others' comments and learn about new responses",
|
||||
"You've confirmed email": "You've confirmed email",
|
||||
"You've reached a non-existed page": "You've reached a non-existed page",
|
||||
"Your name will appear on your profile page and as your signature in publications, comments and responses.": "Your name will appear on your profile page and as your signature in publications, comments and responses",
|
||||
"Your email": "Your email",
|
||||
"Your name will appear on your profile page and as your signature in publications, comments and responses.": "Your name will appear on your profile page and as your signature in publications, comments and responses",
|
||||
"accomplices": "accomplices",
|
||||
"actions": "actions",
|
||||
"add link": "add link",
|
||||
|
@ -395,17 +397,16 @@
|
|||
"shout": "post",
|
||||
"sign up or sign in": "sign up or sign in",
|
||||
"slug is used by another user": "Slug is already taken by another user",
|
||||
"terms of use": "terms of use",
|
||||
"topics": "topics",
|
||||
"user already exist": "user already exists",
|
||||
"video": "video",
|
||||
"view": "view",
|
||||
"zine": "zine",
|
||||
"subscriber": "subscriber",
|
||||
"subscriber_rp": "subscriber",
|
||||
"subscribers": "subscribers",
|
||||
"subscription": "subscription",
|
||||
"subscription_rp": "subscription",
|
||||
"subscriptions": "subscriptions",
|
||||
"Users": "Users"
|
||||
"terms of use": "terms of use",
|
||||
"topics": "topics",
|
||||
"user already exist": "user already exists",
|
||||
"video": "video",
|
||||
"view": "view",
|
||||
"zine": "zine"
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
"Choose a title image for the article. You can immediately see how the publication card will look like.": "Выберите заглавное изображение для статьи. Тут же сразу можно увидеть как будет выглядеть карточка публикации.",
|
||||
"Choose who you want to write to": "Выберите кому хотите написать",
|
||||
"Collaborate": "Помочь редактировать",
|
||||
"Collections": "Коллекции",
|
||||
"Come up with a subtitle for your story": "Придумайте подзаголовок вашей истории",
|
||||
"Come up with a title for your story": "Придумайте заголовок вашей истории",
|
||||
"Comment successfully deleted": "Комментарий успешно удален",
|
||||
|
@ -75,7 +76,6 @@
|
|||
"Confirm": "Подтвердить",
|
||||
"Cooperate": "Соучаствовать",
|
||||
"Copy": "Скопировать",
|
||||
"Collections": "Коллекции",
|
||||
"Copy link": "Скопировать ссылку",
|
||||
"Corrections history": "История правок",
|
||||
"Create Chat": "Создать чат",
|
||||
|
@ -111,6 +111,7 @@
|
|||
"Email": "Почта",
|
||||
"Enter": "Войти",
|
||||
"Enter URL address": "Введите адрес ссылки",
|
||||
"Enter footnote text": "Введите текст сноски",
|
||||
"Enter image description": "Введите описание изображения",
|
||||
"Enter image title": "Введите название изображения",
|
||||
"Enter text": "Введите текст",
|
||||
|
@ -153,6 +154,7 @@
|
|||
"Help": "Помощь",
|
||||
"Help to edit": "Помочь редактировать",
|
||||
"Here you can customize your profile the way you want.": "Здесь можно настроить свой профиль так, как вы хотите.",
|
||||
"Here you can manage all your Discourse subscriptions": "Здесь можно управлять всеми своими подписками на Дискурсе",
|
||||
"Hide table of contents": "Скрыть главление",
|
||||
"Highlight": "Подсветка",
|
||||
"Hooray! Welcome!": "Ура! Добро пожаловать!",
|
||||
|
@ -209,18 +211,18 @@
|
|||
"Move up": "Переместить вверх",
|
||||
"My feed": "Моя лента",
|
||||
"My subscriptions": "Подписки",
|
||||
"Here you can manage all your Discourse subscriptions": "Здесь можно управлять всеми своими подписками на Дискурсе",
|
||||
"Name": "Имя",
|
||||
"Newsletter": "Рассылка",
|
||||
"New literary work": "Новое произведение",
|
||||
"New only": "Только новые",
|
||||
"New password": "Новый пароль",
|
||||
"New stories every day and even more!": "Каждый день вас ждут новые истории и ещё много всего интересного!",
|
||||
"Newsletter": "Рассылка",
|
||||
"Night mode": "Ночная тема",
|
||||
"No such account, please try to register": "Такой адрес не найден, попробуйте зарегистрироваться",
|
||||
"Nothing here yet": "Здесь пока ничего нет",
|
||||
"Nothing is here": "Здесь ничего нет",
|
||||
"Notifications": "Уведомления",
|
||||
"Registered since {{date}}": "На сайте c {{date}}",
|
||||
"Or continue with social network": "Или войдите через соцсеть",
|
||||
"Or paste a link to an image": "Или вставьте ссылку на изображение",
|
||||
"Ordered list": "Нумерованный список",
|
||||
|
@ -286,8 +288,8 @@
|
|||
"Share": "Поделиться",
|
||||
"Short opening": "Расскажите вашу историю...",
|
||||
"Show": "Показать",
|
||||
"Show more": "Читать дальше",
|
||||
"Show lyrics": "Текст песни",
|
||||
"Show more": "Читать дальше",
|
||||
"Show table of contents": "Показать главление",
|
||||
"Slug": "Постоянная ссылка",
|
||||
"Social networks": "Социальные сети",
|
||||
|
@ -302,11 +304,10 @@
|
|||
"Subheader": "Подзаголовок",
|
||||
"Subscribe": "Подписаться",
|
||||
"Subscribe to comments": "Подписаться на комментарии",
|
||||
"Subscribe us": "Подпишитесь на нас",
|
||||
"Subscribe what you like to tune your personal feed": "Подпишитесь на интересующие вас темы, чтобы настроить вашу персональную ленту и моментально узнавать о новых публикациях и обсуждениях",
|
||||
"Subscribe who you like to tune your personal feed": "Подпишитесь на интересующих вас авторов, чтобы настроить вашу персональную ленту и моментально узнавать о новых публикациях и обсуждениях",
|
||||
"Subscribe us": "Подпишитесь на нас",
|
||||
"Subscription": "Подписка",
|
||||
"subscription": "подписка",
|
||||
"Subscriptions": "Подписки",
|
||||
"Substrate": "Подложка",
|
||||
"Success": "Успешно",
|
||||
|
@ -340,12 +341,13 @@
|
|||
"Try to find another way": "Попробуйте найти по-другому",
|
||||
"Unfollow": "Отписаться",
|
||||
"Unfollow the topic": "Отписаться от темы",
|
||||
"Unnamed draft": "Unnamed draft",
|
||||
"Unnamed draft": "Черновик без названия",
|
||||
"Upload": "Загрузить",
|
||||
"Upload error": "Ошибка загрузки",
|
||||
"Upload video": "Загрузить видео",
|
||||
"Username": "Имя пользователя",
|
||||
"Userpic": "Аватар",
|
||||
"Users": "Пользователи",
|
||||
"Video": "Видео",
|
||||
"Video format not supported": "Тип видео не поддерживается",
|
||||
"Views": "Просмотры",
|
||||
|
@ -371,8 +373,8 @@
|
|||
"You've confirmed email": "Вы подтвердили почту",
|
||||
"You've reached a non-existed page": "Вы попали на несуществующую страницу",
|
||||
"You've successfully logged out": "Вы успешно вышли из аккаунта",
|
||||
"Your name will appear on your profile page and as your signature in publications, comments and responses.": "Ваше имя появится на странице вашего профиля и как ваша подпись в публикациях, комментариях и откликах",
|
||||
"Your email": "Ваш email",
|
||||
"Your name will appear on your profile page and as your signature in publications, comments and responses.": "Ваше имя появится на странице вашего профиля и как ваша подпись в публикациях, комментариях и откликах",
|
||||
"actions": "действия",
|
||||
"add link": "добавить ссылку",
|
||||
"all topics": "все темы",
|
||||
|
@ -395,6 +397,7 @@
|
|||
"email not confirmed": "email не подтвержден",
|
||||
"enter": "войдите",
|
||||
"feed": "лента",
|
||||
"follower": "подписчик",
|
||||
"general feed": "Общая лента",
|
||||
"header 1": "заголовок 1",
|
||||
"header 2": "заголовок 2",
|
||||
|
@ -420,18 +423,16 @@
|
|||
"sign up or sign in": "зарегистрироваться или войти",
|
||||
"slug is used by another user": "Имя уже занято другим пользователем",
|
||||
"squib": "Подверстка",
|
||||
"subscriber": "подписчик",
|
||||
"subscriber_rp": "подписчика",
|
||||
"subscribers": "подписчиков",
|
||||
"subscription": "подписка",
|
||||
"subscription_rp": "подписки",
|
||||
"subscriptions": "подписок",
|
||||
"terms of use": "правилами пользования сайтом",
|
||||
"topics": "темы",
|
||||
"user already exist": "пользователь уже существует",
|
||||
"video": "видео",
|
||||
"view": "просмотр",
|
||||
"zine": "журнал",
|
||||
"Enter footnote text": "Введите текст сноски",
|
||||
"follower": "подписчик",
|
||||
"subscriber": "подписчик",
|
||||
"subscriber_rp": "подписчика",
|
||||
"subscribers": "подписчиков",
|
||||
"subscription_rp": "подписки",
|
||||
"subscriptions": "подписок",
|
||||
"Users": "Пользователи"
|
||||
"zine": "журнал"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { createEffect, JSX, Show } from 'solid-js'
|
||||
import { useSession } from '../../context/session'
|
||||
import { hideModal, showModal } from '../../stores/ui'
|
||||
import { hideModal } from '../../stores/ui'
|
||||
import { useRouter } from '../../stores/router'
|
||||
import { RootSearchParams } from '../../pages/types'
|
||||
import { AuthModalSearchParams } from '../Nav/AuthModal/types'
|
||||
|
|
32
src/components/Author/AuthorBadge/AuthorBadge.module.scss
Normal file
32
src/components/Author/AuthorBadge/AuthorBadge.module.scss
Normal file
|
@ -0,0 +1,32 @@
|
|||
.AuthorBadge {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.info {
|
||||
@include font-size(1.4rem);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
background: unset;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: var(--default-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.bio {
|
||||
color: var(--black-400);
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-left: auto;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
}
|
92
src/components/Author/AuthorBadge/AuthorBadge.tsx
Normal file
92
src/components/Author/AuthorBadge/AuthorBadge.tsx
Normal file
|
@ -0,0 +1,92 @@
|
|||
import { clsx } from 'clsx'
|
||||
import styles from './AuthorBadge.module.scss'
|
||||
import { Userpic } from '../Userpic'
|
||||
import { Author, FollowingEntity } from '../../../graphql/types.gen'
|
||||
import { createMemo, createSignal, Show } from 'solid-js'
|
||||
import { formatDate } from '../../../utils'
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
import { Button } from '../../_shared/Button'
|
||||
import { useSession } from '../../../context/session'
|
||||
import { follow, unfollow } from '../../../stores/zine/common'
|
||||
import { CheckButton } from '../../_shared/CheckButton'
|
||||
|
||||
type Props = {
|
||||
author: Author
|
||||
minimizeSubscribeButton?: boolean
|
||||
}
|
||||
export const AuthorBadge = (props: Props) => {
|
||||
const [isSubscribing, setIsSubscribing] = createSignal(false)
|
||||
const {
|
||||
isAuthenticated,
|
||||
session,
|
||||
actions: { loadSession }
|
||||
} = useSession()
|
||||
|
||||
const { t } = useLocalize()
|
||||
const subscribed = createMemo<boolean>(() => {
|
||||
return session()?.news?.authors?.some((u) => u === props.author.slug) || false
|
||||
})
|
||||
|
||||
const subscribe = async (really = true) => {
|
||||
setIsSubscribing(true)
|
||||
|
||||
await (really
|
||||
? follow({ what: FollowingEntity.Author, slug: props.author.slug })
|
||||
: unfollow({ what: FollowingEntity.Author, slug: props.author.slug }))
|
||||
|
||||
await loadSession()
|
||||
setIsSubscribing(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div class={clsx(styles.AuthorBadge)}>
|
||||
<Userpic hasLink={true} isMedium={true} name={props.author.name} userpic={props.author.userpic} />
|
||||
<a href={`/author/${props.author.slug}`} class={styles.info}>
|
||||
<div class={styles.name}>{props.author.name}</div>
|
||||
<Show
|
||||
when={props.author.bio}
|
||||
fallback={
|
||||
<div class={styles.bio}>
|
||||
{t('Registered since {{date}}', { date: formatDate(new Date(props.author.createdAt)) })}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div class={clsx('text-truncate', styles.bio)}>{props.author.bio}</div>
|
||||
</Show>
|
||||
</a>
|
||||
<Show when={isAuthenticated() && props.author.slug !== session().user.slug}>
|
||||
<div class={styles.actions}>
|
||||
<Show
|
||||
when={!props.minimizeSubscribeButton}
|
||||
fallback={
|
||||
<CheckButton
|
||||
text={t('Follow')}
|
||||
checked={subscribed()}
|
||||
onClick={() => subscribe(!subscribed)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Show
|
||||
when={subscribed()}
|
||||
fallback={
|
||||
<Button
|
||||
variant="primary"
|
||||
size="S"
|
||||
value={isSubscribing() ? t('...subscribing') : t('Subscribe')}
|
||||
onClick={() => subscribe(true)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={() => subscribe(false)}
|
||||
variant="secondary"
|
||||
size="S"
|
||||
value={t('You are subscribed')}
|
||||
/>
|
||||
</Show>
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
1
src/components/Author/AuthorBadge/index.ts
Normal file
1
src/components/Author/AuthorBadge/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { AuthorBadge } from './AuthorBadge'
|
|
@ -1,6 +1,6 @@
|
|||
.author {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-flow: row nowrap;
|
||||
margin-bottom: 1.6rem;
|
||||
|
||||
|
@ -600,8 +600,10 @@
|
|||
align-items: center;
|
||||
margin-bottom: 0.4rem;
|
||||
|
||||
.authorName {
|
||||
.authorName,
|
||||
.authorAbout {
|
||||
@include font-size(1.2rem);
|
||||
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@ import { useLocalize } from '../../../context/localize'
|
|||
import { ConditionalWrapper } from '../../_shared/ConditionalWrapper'
|
||||
import { Modal } from '../../Nav/Modal'
|
||||
import { showModal } from '../../../stores/ui'
|
||||
import { TopicCard } from '../../Topic/Card'
|
||||
import { getNumeralsDeclension } from '../../../utils/getNumeralsDeclension'
|
||||
import { SubscriptionFilter } from '../../../pages/types'
|
||||
import { isAuthor } from '../../../utils/isAuthor'
|
||||
import { CheckButton } from '../../_shared/CheckButton'
|
||||
import { AuthorBadge } from '../AuthorBadge'
|
||||
import { TopicBadge } from '../../Topic/TopicBadge'
|
||||
|
||||
type Props = {
|
||||
caption?: string
|
||||
|
@ -42,7 +42,6 @@ type Props = {
|
|||
followers?: Author[]
|
||||
following?: Array<Author | Topic>
|
||||
showPublicationsCounter?: boolean
|
||||
minimizeSubscribeButton?: boolean
|
||||
}
|
||||
|
||||
export const AuthorCard = (props: Props) => {
|
||||
|
@ -285,7 +284,7 @@ export const AuthorCard = (props: Props) => {
|
|||
</For>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={!props.minimizeSubscribeButton}>
|
||||
|
||||
<Show
|
||||
when={subscribed()}
|
||||
fallback={
|
||||
|
@ -349,14 +348,6 @@ export const AuthorCard = (props: Props) => {
|
|||
</Show>
|
||||
</button>
|
||||
</Show>
|
||||
</Show>
|
||||
<Show when={props.minimizeSubscribeButton}>
|
||||
<CheckButton
|
||||
text={t('Follow')}
|
||||
checked={subscribed()}
|
||||
onClick={() => subscribe(false)}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show when={!props.hideWriteButton}>
|
||||
<button
|
||||
|
@ -390,17 +381,7 @@ export const AuthorCard = (props: Props) => {
|
|||
<div class="row">
|
||||
<div class="col-24">
|
||||
<For each={props.followers}>
|
||||
{(follower: Author) => (
|
||||
<AuthorCard
|
||||
author={follower}
|
||||
hideWriteButton={true}
|
||||
hasLink={true}
|
||||
isTextButton={true}
|
||||
liteButtons={true}
|
||||
truncateBio={true}
|
||||
showPublicationsCounter={true}
|
||||
/>
|
||||
)}
|
||||
{(follower: Author) => <AuthorBadge author={follower} />}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -444,23 +425,9 @@ export const AuthorCard = (props: Props) => {
|
|||
<For each={following()}>
|
||||
{(subscription) =>
|
||||
isAuthor(subscription) ? (
|
||||
<AuthorCard
|
||||
author={subscription}
|
||||
hideWriteButton={true}
|
||||
hasLink={true}
|
||||
isTextButton={true}
|
||||
truncateBio={true}
|
||||
showPublicationsCounter={true}
|
||||
/>
|
||||
<AuthorBadge author={subscription} />
|
||||
) : (
|
||||
<TopicCard
|
||||
compact
|
||||
isTopicInRow
|
||||
showDescription
|
||||
isCardMode
|
||||
withIcon
|
||||
topic={subscription}
|
||||
/>
|
||||
<TopicBadge topic={subscription} />
|
||||
)
|
||||
}
|
||||
</For>
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
background: #f7f7f8;
|
||||
border-radius: 100%;
|
||||
display: flex;
|
||||
height: 32px;
|
||||
justify-content: center;
|
||||
margin-right: 1.2rem;
|
||||
min-width: 32px;
|
||||
max-width: 32px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 32px;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
|
@ -55,6 +55,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.medium {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
min-width: 40px;
|
||||
max-width: 40px;
|
||||
|
||||
.letters {
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
&.big {
|
||||
aspect-ratio: 1/1;
|
||||
margin: 0 auto;
|
||||
|
|
|
@ -13,8 +13,8 @@ type Props = {
|
|||
onClick?: () => void
|
||||
loading?: boolean
|
||||
isBig?: boolean
|
||||
isMedium?: boolean
|
||||
hasLink?: boolean
|
||||
|
||||
isAuthorsList?: boolean
|
||||
isFeedMode?: boolean
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ export const Userpic = (props: Props) => {
|
|||
<div
|
||||
class={clsx(styles.Userpic, props.class, {
|
||||
[styles.big]: props.isBig,
|
||||
[styles.medium]: props.isMedium,
|
||||
[styles.authorsList]: props.isAuthorsList,
|
||||
[styles.feedMode]: props.isFeedMode,
|
||||
['cursorPointer']: props.onClick
|
||||
|
|
|
@ -167,7 +167,6 @@ export const ArticleCard = (props: ArticleCardProps) => {
|
|||
</Show>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<Show when={!props.settings?.noauthor || !props.settings?.nodate}>
|
||||
<div
|
||||
class={clsx(styles.shoutDetails, { [styles.shoutDetailsFeedMode]: props.settings?.isFeedMode })}
|
||||
|
@ -181,6 +180,7 @@ export const ArticleCard = (props: ArticleCardProps) => {
|
|||
author={author}
|
||||
hideWriteButton={true}
|
||||
hideFollow={true}
|
||||
truncateBio={true}
|
||||
isFeedMode={true}
|
||||
hasLink={!props.settings?.noAuthorLink}
|
||||
/>
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
|
||||
import { For, Show } from 'solid-js'
|
||||
import { ArticleCard } from './ArticleCard'
|
||||
import { AuthorCard } from '../Author/AuthorCard'
|
||||
import { TopicCard } from '../Topic/Card'
|
||||
import styles from './Beside.module.scss'
|
||||
import type { Author, Shout, Topic, User } from '../../graphql/types.gen'
|
||||
import { Icon } from '../_shared/Icon'
|
||||
|
||||
import { clsx } from 'clsx'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { AuthorBadge } from '../Author/AuthorBadge'
|
||||
|
||||
interface BesideProps {
|
||||
type Props = {
|
||||
title?: string
|
||||
values: (Shout | User | Topic | Author)[]
|
||||
beside: Shout
|
||||
|
@ -24,7 +23,7 @@ interface BesideProps {
|
|||
nodate?: boolean
|
||||
}
|
||||
|
||||
export const Beside = (props: BesideProps) => {
|
||||
export const Beside = (props: Props) => {
|
||||
const { t } = useLocalize()
|
||||
return (
|
||||
<Show when={!!props.beside?.slug && props.values?.length > 0}>
|
||||
|
@ -76,14 +75,7 @@ export const Beside = (props: BesideProps) => {
|
|||
/>
|
||||
</Show>
|
||||
<Show when={props.wrapper === 'author'}>
|
||||
<AuthorCard
|
||||
author={value as Author}
|
||||
hideWriteButton={true}
|
||||
hasLink={true}
|
||||
truncateBio={true}
|
||||
isTextButton={true}
|
||||
class={styles.author}
|
||||
/>
|
||||
<AuthorBadge author={value as Author} />
|
||||
</Show>
|
||||
<Show when={props.wrapper === 'article' && value?.slug}>
|
||||
<ArticleCard
|
||||
|
|
|
@ -46,7 +46,7 @@ export const Header = (props: Props) => {
|
|||
actions: { requireAuthentication }
|
||||
} = useSession()
|
||||
|
||||
const { page, searchParams } = useRouter<HeaderSearchParams>()
|
||||
const { searchParams } = useRouter<HeaderSearchParams>()
|
||||
|
||||
const [randomTopics, setRandomTopics] = createSignal([])
|
||||
const [getIsScrollingBottom, setIsScrollingBottom] = createSignal(false)
|
||||
|
|
60
src/components/Topic/TopicBadge/TopicBadge.module.scss
Normal file
60
src/components/Topic/TopicBadge/TopicBadge.module.scss
Normal file
|
@ -0,0 +1,60 @@
|
|||
.TopicBadge {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.picture {
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
min-width: 40px;
|
||||
border-radius: 8px;
|
||||
background-color: var(--black-50);
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE5LjUgMTQuMjVDMTkuOTE0MSAxNC4yNSAyMC4yNSAxNC41ODU5IDIwLjI1IDE1QzIwLjI1IDE1LjQxNDEgMTkuOTE0MSAxNS43NSAxOS41IDE1Ljc1SDE1Ljc1VjE5LjVDMTUuNzUgMTkuOTE0MSAxNS40MTQxIDIwLjI1IDE1IDIwLjI1QzE0LjU4NTkgMjAuMjUgMTQuMjUgMTkuOTE0MSAxNC4yNSAxOS41VjE1Ljc1SDkuNzVWMTkuNUM5Ljc1IDE5LjkxNDEgOS40MTQwNiAyMC4yNSA5IDIwLjI1QzguNTg1OTQgMjAuMjUgOC4yNSAxOS45MTQxIDguMjUgMTkuNVYxNS43NUg0LjVDNC4wODU5NCAxNS43NSAzLjc1IDE1LjQxNDEgMy43NSAxNUMzLjc1IDE0LjU4NTkgNC4wODU5NCAxNC4yNSA0LjUgMTQuMjVIOC4yNVY5Ljc1SDQuNUM0LjA4NTk0IDkuNzUgMy43NSA5LjQxNDA2IDMuNzUgOUMzLjc1IDguNTg1OTQgNC4wODU5NCA4LjI1IDQuNSA4LjI1SDguMjVWNC41QzguMjUgNC4wODU5NCA4LjU4NTk0IDMuNzUgOSAzLjc1QzkuNDE0MDYgMy43NSA5Ljc1IDQuMDg1OTQgOS43NSA0LjVWOC4yNUgxNC4yNVY0LjVDMTQuMjUgNC4wODU5NCAxNC41ODU5IDMuNzUgMTUgMy43NUMxNS40MTQxIDMuNzUgMTUuNzUgNC4wODU5NCAxNS43NSA0LjVWOC4yNUgxOS41QzE5LjkxNDEgOC4yNSAyMC4yNSA4LjU4NTk0IDIwLjI1IDlDMjAuMjUgOS40MTQwNiAxOS45MTQxIDkuNzUgMTkuNSA5Ljc1SDE1Ljc1VjE0LjI1SDE5LjVaTTkuNzUgMTQuMjVIMTQuMjVWOS43NUg5Ljc1VjE0LjI1WiIgZmlsbD0iIzlGQTFBNyIvPgo8L3N2Zz4K');
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--black-50);
|
||||
}
|
||||
|
||||
&.withImage {
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: none;
|
||||
@include font-size(1.4rem);
|
||||
|
||||
&:hover {
|
||||
background: unset;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--blue-500);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: var(--black-400);
|
||||
}
|
||||
|
||||
.stat {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
flex-direction: row;
|
||||
color: var(--default-color);
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-left: auto;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
}
|
111
src/components/Topic/TopicBadge/TopicBadge.tsx
Normal file
111
src/components/Topic/TopicBadge/TopicBadge.tsx
Normal file
|
@ -0,0 +1,111 @@
|
|||
import { clsx } from 'clsx'
|
||||
import styles from './TopicBadge.module.scss'
|
||||
import { FollowingEntity, Topic } from '../../../graphql/types.gen'
|
||||
import { createMemo, createSignal, Show } from 'solid-js'
|
||||
import { imageProxy } from '../../../utils/imageProxy'
|
||||
import { capitalize } from '../../../utils'
|
||||
import { Button } from '../../_shared/Button'
|
||||
import { useSession } from '../../../context/session'
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
import { follow, unfollow } from '../../../stores/zine/common'
|
||||
import { CheckButton } from '../../_shared/CheckButton'
|
||||
|
||||
type Props = {
|
||||
topic: Topic
|
||||
minimizeSubscribeButton?: boolean
|
||||
}
|
||||
|
||||
export const TopicBadge = (props: Props) => {
|
||||
const [isSubscribing, setIsSubscribing] = createSignal(false)
|
||||
const { t } = useLocalize()
|
||||
const {
|
||||
isAuthenticated,
|
||||
session,
|
||||
actions: { loadSession }
|
||||
} = useSession()
|
||||
|
||||
const subscribed = createMemo(() => {
|
||||
if (!session()?.user?.slug || !session()?.news?.topics) {
|
||||
return false
|
||||
}
|
||||
|
||||
return session()?.news.topics.includes(props.topic.slug)
|
||||
})
|
||||
|
||||
const subscribe = async (really = true) => {
|
||||
setIsSubscribing(true)
|
||||
|
||||
await (really
|
||||
? follow({ what: FollowingEntity.Topic, slug: props.topic.slug })
|
||||
: unfollow({ what: FollowingEntity.Topic, slug: props.topic.slug }))
|
||||
|
||||
await loadSession()
|
||||
setIsSubscribing(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div class={styles.TopicBadge}>
|
||||
<a
|
||||
href={`/topic/${props.topic.slug}`}
|
||||
class={clsx(styles.picture, { [styles.withImage]: props.topic.pic })}
|
||||
style={props.topic.pic && { 'background-image': `url('${imageProxy(props.topic.pic)}')` }}
|
||||
/>
|
||||
<a href={`/topic/${props.topic.slug}`} class={styles.info}>
|
||||
<span class={styles.title}>{capitalize(props.topic.title)}</span>
|
||||
<Show when={props.topic.body}>
|
||||
<div class={clsx('text-truncate', styles.description)}>{props.topic.body}</div>
|
||||
</Show>
|
||||
<span class={styles.stat}>
|
||||
<Show when={props.topic.stat.authors}>
|
||||
<div>
|
||||
{t('Authors')}: {props.topic.stat.authors}
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={props.topic.stat.followers}>
|
||||
<div>
|
||||
{t('Followers')}: {props.topic.stat.followers}
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={props.topic.stat.shouts}>
|
||||
<div>
|
||||
{t('Publications')}: {props.topic.stat.shouts}
|
||||
</div>
|
||||
</Show>
|
||||
</span>
|
||||
</a>
|
||||
<Show when={isAuthenticated()}>
|
||||
<div class={styles.actions}>
|
||||
<Show
|
||||
when={!props.minimizeSubscribeButton}
|
||||
fallback={
|
||||
<CheckButton
|
||||
text={t('Follow')}
|
||||
checked={subscribed()}
|
||||
onClick={() => subscribe(!subscribed)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Show
|
||||
when={subscribed()}
|
||||
fallback={
|
||||
<Button
|
||||
variant="primary"
|
||||
size="S"
|
||||
value={isSubscribing() ? t('...subscribing') : t('Subscribe')}
|
||||
onClick={() => subscribe(true)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={() => subscribe(false)}
|
||||
variant="secondary"
|
||||
size="S"
|
||||
value={t('You are subscribed')}
|
||||
/>
|
||||
</Show>
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
1
src/components/Topic/TopicBadge/index.ts
Normal file
1
src/components/Topic/TopicBadge/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { TopicBadge } from './TopicBadge'
|
|
@ -1,4 +1,4 @@
|
|||
import { Accessor, createEffect, createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
import { Accessor, createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { clsx } from 'clsx'
|
||||
import { Title } from '@solidjs/meta'
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import { clsx } from 'clsx'
|
||||
// import styles from './ProfileSubscriptions.module.scss'
|
||||
import { ProfileSettingsNavigation } from '../../Nav/ProfileSettingsNavigation'
|
||||
import { createEffect, createSignal, For, onMount, Show } from 'solid-js'
|
||||
import { Loading } from '../../_shared/Loading'
|
||||
import { SearchField } from '../../_shared/SearchField'
|
||||
import { isAuthor } from '../../../utils/isAuthor'
|
||||
import { AuthorCard } from '../../Author/AuthorCard'
|
||||
import { TopicCard } from '../../Topic/Card'
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
import { useSession } from '../../../context/session'
|
||||
import { Author, Topic } from '../../../graphql/types.gen'
|
||||
|
@ -16,6 +13,8 @@ import { dummyFilter } from '../../../utils/dummyFilter'
|
|||
// TODO: refactor styles
|
||||
import styles from '../../../pages/profile/Settings.module.scss'
|
||||
import stylesSettings from '../../../styles/FeedSettings.module.scss'
|
||||
import { AuthorBadge } from '../../Author/AuthorBadge'
|
||||
import { TopicBadge } from '../../Topic/TopicBadge'
|
||||
|
||||
export const ProfileSubscriptions = () => {
|
||||
const { t, lang } = useLocalize()
|
||||
|
@ -104,23 +103,9 @@ export const ProfileSubscriptions = () => {
|
|||
{(followingItem) => (
|
||||
<div>
|
||||
{isAuthor(followingItem) ? (
|
||||
<AuthorCard
|
||||
author={followingItem}
|
||||
hideWriteButton={true}
|
||||
hasLink={true}
|
||||
isTextButton={true}
|
||||
truncateBio={true}
|
||||
minimizeSubscribeButton={true}
|
||||
/>
|
||||
<AuthorBadge minimizeSubscribeButton={true} author={followingItem} />
|
||||
) : (
|
||||
<TopicCard
|
||||
compact
|
||||
isTopicInRow
|
||||
showDescription
|
||||
isCardMode
|
||||
topic={followingItem}
|
||||
minimizeSubscribeButton={true}
|
||||
/>
|
||||
<TopicBadge minimizeSubscribeButton={true} topic={followingItem} />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
justify-content: center;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
|
||||
&.primary {
|
||||
background: #000;
|
||||
|
@ -57,7 +58,10 @@
|
|||
margin-right: 0.8em;
|
||||
min-width: auto !important;
|
||||
padding: 0;
|
||||
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
|
||||
transition:
|
||||
border-color 0.3s,
|
||||
background-color 0.3s,
|
||||
color 0.3s;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
justify-content: center;
|
||||
height: 32px;
|
||||
min-width: 33px;
|
||||
line-height: 32px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 8px;
|
||||
background: var(--background-color);
|
||||
|
|
|
@ -30,6 +30,8 @@ export default gql`
|
|||
name
|
||||
slug
|
||||
userpic
|
||||
createdAt
|
||||
bio
|
||||
}
|
||||
createdAt
|
||||
publishedAt
|
||||
|
|
|
@ -25,6 +25,7 @@ export type Author = {
|
|||
about?: Maybe<Scalars['String']>
|
||||
bio?: Maybe<Scalars['String']>
|
||||
caption?: Maybe<Scalars['String']>
|
||||
createdAt?: Maybe<Scalars['DateTime']>
|
||||
id: Scalars['Int']
|
||||
lastSeen?: Maybe<Scalars['DateTime']>
|
||||
links?: Maybe<Array<Maybe<Scalars['String']>>>
|
||||
|
@ -116,6 +117,7 @@ export type LoadShoutsFilters = {
|
|||
author?: InputMaybe<Scalars['String']>
|
||||
body?: InputMaybe<Scalars['String']>
|
||||
days?: InputMaybe<Scalars['Int']>
|
||||
excludeLayout?: InputMaybe<Scalars['String']>
|
||||
layout?: InputMaybe<Scalars['String']>
|
||||
reacted?: InputMaybe<Scalars['Boolean']>
|
||||
title?: InputMaybe<Scalars['String']>
|
||||
|
@ -589,20 +591,6 @@ export type ShoutInput = {
|
|||
topics?: InputMaybe<Array<InputMaybe<TopicInput>>>
|
||||
}
|
||||
|
||||
export type ShoutsFilterBy = {
|
||||
author?: InputMaybe<Scalars['String']>
|
||||
authors?: InputMaybe<Array<InputMaybe<Scalars['String']>>>
|
||||
body?: InputMaybe<Scalars['String']>
|
||||
days?: InputMaybe<Scalars['Int']>
|
||||
layout?: InputMaybe<Scalars['String']>
|
||||
slug?: InputMaybe<Scalars['String']>
|
||||
stat?: InputMaybe<Scalars['String']>
|
||||
title?: InputMaybe<Scalars['String']>
|
||||
topic?: InputMaybe<Scalars['String']>
|
||||
topics?: InputMaybe<Array<InputMaybe<Scalars['String']>>>
|
||||
visibility?: InputMaybe<Scalars['String']>
|
||||
}
|
||||
|
||||
export type Stat = {
|
||||
commented?: Maybe<Scalars['Int']>
|
||||
ranking?: Maybe<Scalars['Int']>
|
||||
|
|
|
@ -177,7 +177,7 @@ export const ProfileSettingsPage = () => {
|
|||
value={(value) => updateFormField('bio', value)}
|
||||
initialValue={form.bio}
|
||||
allowEnterKey={false}
|
||||
maxLength={80}
|
||||
maxLength={120}
|
||||
/>
|
||||
|
||||
<h4>{t('About myself')}</h4>
|
||||
|
|
|
@ -31,9 +31,11 @@
|
|||
// names from figma
|
||||
--black-50: #f7f7f8;
|
||||
--black-100: #e9e9ee;
|
||||
--black-300: #9fa1a7;
|
||||
--black-500: #141414;
|
||||
--black-400: #696969;
|
||||
--white-500: #fff;
|
||||
--blue-500: #2638d9;
|
||||
}
|
||||
|
||||
[data-editor-dark-mode='true'] {
|
||||
|
|
Loading…
Reference in New Issue
Block a user