Merge remote-tracking branch 'gitlab/dev' into feed-article-popup
This commit is contained in:
commit
a84dac9577
|
@ -150,7 +150,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.commentAuthor,
|
.commentAuthor,
|
||||||
.commentDate,
|
|
||||||
.commentRating {
|
.commentRating {
|
||||||
@include font-size(1.2rem);
|
@include font-size(1.2rem);
|
||||||
}
|
}
|
||||||
|
@ -161,11 +160,30 @@
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commentDate {
|
.commentDates {
|
||||||
color: rgb(0 0 0 / 30%);
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@include media-breakpoint-down(md) {
|
display: flex;
|
||||||
margin-left: 1rem;
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
color: rgba(0, 0, 0, 0.3);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
color: rgb(0 0 0 / 30%);
|
||||||
|
@include font-size(1.2rem);
|
||||||
|
|
||||||
|
.date {
|
||||||
|
.icon {
|
||||||
|
line-height: 1;
|
||||||
|
width: 1rem;
|
||||||
|
display: inline-block;
|
||||||
|
opacity: 0.6;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
@include media-breakpoint-down(md) {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
import styles from './Comment.module.scss'
|
import styles from './Comment.module.scss'
|
||||||
import { Icon } from '../_shared/Icon'
|
import { Icon } from '../_shared/Icon'
|
||||||
import { AuthorCard } from '../Author/Card'
|
import { AuthorCard } from '../Author/Card'
|
||||||
import { Show, createMemo, createSignal, For } from 'solid-js'
|
import { Show, createMemo, createSignal, For, lazy, Suspense } from 'solid-js'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import type { Author, Reaction } from '../../graphql/types.gen'
|
import type { Author, Reaction } from '../../graphql/types.gen'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { createReaction, deleteReaction } from '../../stores/zine/reactions'
|
import { createReaction, deleteReaction, updateReaction } from '../../stores/zine/reactions'
|
||||||
import MD from './MD'
|
import MD from './MD'
|
||||||
import { formatDate } from '../../utils'
|
import { formatDate } from '../../utils'
|
||||||
import { SharePopup } from './SharePopup'
|
|
||||||
import stylesHeader from '../Nav/Header.module.scss'
|
|
||||||
import Userpic from '../Author/Userpic'
|
import Userpic from '../Author/Userpic'
|
||||||
import { useSession } from '../../context/session'
|
import { useSession } from '../../context/session'
|
||||||
import { ReactionKind } from '../../graphql/types.gen'
|
import { ReactionKind } from '../../graphql/types.gen'
|
||||||
import CommentEditor from '../_shared/CommentEditor'
|
const CommentEditor = lazy(() => import('../_shared/CommentEditor'))
|
||||||
import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient'
|
|
||||||
import { getDescription } from '../../utils/meta'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
comment: Reaction
|
comment: Reaction
|
||||||
|
@ -27,7 +23,7 @@ type Props = {
|
||||||
export const Comment = (props: Props) => {
|
export const Comment = (props: Props) => {
|
||||||
const [isReplyVisible, setIsReplyVisible] = createSignal(false)
|
const [isReplyVisible, setIsReplyVisible] = createSignal(false)
|
||||||
const [loading, setLoading] = createSignal<boolean>(false)
|
const [loading, setLoading] = createSignal<boolean>(false)
|
||||||
const [submitted, setSubmitted] = createSignal<boolean>(false)
|
const [editMode, setEditMode] = createSignal<boolean>(false)
|
||||||
const { session } = useSession()
|
const { session } = useSession()
|
||||||
|
|
||||||
const canEdit = createMemo(() => props.comment.createdBy?.slug === session()?.user?.slug)
|
const canEdit = createMemo(() => props.comment.createdBy?.slug === session()?.user?.slug)
|
||||||
|
@ -61,16 +57,33 @@ export const Comment = (props: Props) => {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
setIsReplyVisible(false)
|
setIsReplyVisible(false)
|
||||||
setSubmitted(true)
|
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[handleCreate reaction]:', error)
|
console.error('[handleCreate reaction]:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const formattedDate = createMemo(() =>
|
const formattedDate = (date) =>
|
||||||
formatDate(new Date(comment()?.createdAt), { hour: 'numeric', minute: 'numeric' })
|
createMemo(() => formatDate(new Date(date), { hour: 'numeric', minute: 'numeric' }))
|
||||||
)
|
|
||||||
|
const toggleEditMode = () => {
|
||||||
|
setEditMode((oldEditMode) => !oldEditMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUpdate = async (value) => {
|
||||||
|
setLoading(true)
|
||||||
|
try {
|
||||||
|
await updateReaction(props.comment.id, {
|
||||||
|
kind: ReactionKind.Comment,
|
||||||
|
body: value,
|
||||||
|
shout: props.comment.shout.id
|
||||||
|
})
|
||||||
|
setEditMode(false)
|
||||||
|
setLoading(false)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[handleCreate reaction]:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li class={styles.comment}>
|
<li class={styles.comment}>
|
||||||
|
@ -102,7 +115,15 @@ export const Comment = (props: Props) => {
|
||||||
<div class={styles.articleAuthor}>{t('Author')}</div>
|
<div class={styles.articleAuthor}>{t('Author')}</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<div class={styles.commentDate}>{formattedDate()}</div>
|
<div class={styles.commentDates}>
|
||||||
|
<div class={styles.date}>{formattedDate(comment()?.createdAt)}</div>
|
||||||
|
<Show when={comment()?.updatedAt}>
|
||||||
|
<div class={styles.date}>
|
||||||
|
<Icon name="edit" class={styles.icon} />
|
||||||
|
{t('Edited')} {formattedDate(comment()?.updatedAt)}
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class={styles.commentRating}
|
class={styles.commentRating}
|
||||||
classList={{
|
classList={{
|
||||||
|
@ -116,12 +137,12 @@ export const Comment = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
<div
|
<div class={styles.commentBody} id={'comment-' + (comment().id || '')}>
|
||||||
class={styles.commentBody}
|
<Show when={editMode()} fallback={<MD body={body()} />}>
|
||||||
contenteditable={canEdit()}
|
<Suspense fallback={<p>Loading...</p>}>
|
||||||
id={'comment-' + (comment().id || '')}
|
<CommentEditor initialContent={body()} onSubmit={(value) => handleUpdate(value)} />
|
||||||
>
|
</Suspense>
|
||||||
<MD body={body()} />
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when={!props.compact}>
|
<Show when={!props.compact}>
|
||||||
|
@ -136,14 +157,13 @@ export const Comment = (props: Props) => {
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<Show when={canEdit()}>
|
<Show when={canEdit()}>
|
||||||
{/*FIXME implement edit comment modal*/}
|
<button
|
||||||
{/*<button*/}
|
class={clsx(styles.commentControl, styles.commentControlEdit)}
|
||||||
{/* class={clsx(styles.commentControl, styles.commentControlEdit)}*/}
|
onClick={toggleEditMode}
|
||||||
{/* onClick={() => showModal('editComment')}*/}
|
>
|
||||||
{/*>*/}
|
<Icon name="edit" class={styles.icon} />
|
||||||
{/* <Icon name="edit" class={styles.icon} />*/}
|
{t('Edit')}
|
||||||
{/* {t('Edit')}*/}
|
</button>
|
||||||
{/*</button>*/}
|
|
||||||
<button
|
<button
|
||||||
class={clsx(styles.commentControl, styles.commentControlDelete)}
|
class={clsx(styles.commentControl, styles.commentControlDelete)}
|
||||||
onClick={() => remove()}
|
onClick={() => remove()}
|
||||||
|
@ -174,13 +194,9 @@ export const Comment = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when={isReplyVisible()}>
|
<Show when={isReplyVisible()}>
|
||||||
<ShowOnlyOnClient>
|
<Suspense fallback={<p>{t('Loading')}</p>}>
|
||||||
<CommentEditor
|
<CommentEditor placeholder={''} onSubmit={(value) => handleCreate(value)} />
|
||||||
initialValue={''}
|
</Suspense>
|
||||||
clear={submitted()}
|
|
||||||
onSubmit={(value) => handleCreate(value)}
|
|
||||||
/>
|
|
||||||
</ShowOnlyOnClient>
|
|
||||||
</Show>
|
</Show>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { For, Show, createMemo, createSignal, onMount } from 'solid-js'
|
import { Show, createMemo, createSignal, onMount, For } from 'solid-js'
|
||||||
import Comment from './Comment'
|
import Comment from './Comment'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import styles from '../../styles/Article.module.scss'
|
import styles from '../../styles/Article.module.scss'
|
||||||
|
@ -11,6 +11,7 @@ import { Author, ReactionKind } from '../../graphql/types.gen'
|
||||||
import { useSession } from '../../context/session'
|
import { useSession } from '../../context/session'
|
||||||
import CommentEditor from '../_shared/CommentEditor'
|
import CommentEditor from '../_shared/CommentEditor'
|
||||||
import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient'
|
import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient'
|
||||||
|
import Button from '../_shared/Button'
|
||||||
|
|
||||||
const ARTICLE_COMMENTS_PAGE_SIZE = 50
|
const ARTICLE_COMMENTS_PAGE_SIZE = 50
|
||||||
const MAX_COMMENT_LEVEL = 6
|
const MAX_COMMENT_LEVEL = 6
|
||||||
|
@ -27,9 +28,11 @@ export const CommentsTree = (props: Props) => {
|
||||||
const [isCommentsLoading, setIsCommentsLoading] = createSignal(false)
|
const [isCommentsLoading, setIsCommentsLoading] = createSignal(false)
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
const { sortedReactions, loadReactionsBy } = useReactionsStore()
|
const { sortedReactions, loadReactionsBy } = useReactionsStore()
|
||||||
|
|
||||||
const reactions = createMemo<Reaction[]>(() =>
|
const reactions = createMemo<Reaction[]>(() =>
|
||||||
sortedReactions().sort(commentsOrder() === 'rating' ? byStat('rating') : byCreated)
|
sortedReactions().sort(commentsOrder() === 'rating' ? byStat('rating') : byCreated)
|
||||||
)
|
)
|
||||||
|
|
||||||
const { session } = useSession()
|
const { session } = useSession()
|
||||||
const loadMore = async () => {
|
const loadMore = async () => {
|
||||||
try {
|
try {
|
||||||
|
@ -85,26 +88,22 @@ export const CommentsTree = (props: Props) => {
|
||||||
|
|
||||||
<ul class={clsx(styles.commentsViewSwitcher, 'view-switcher')}>
|
<ul class={clsx(styles.commentsViewSwitcher, 'view-switcher')}>
|
||||||
<li classList={{ selected: commentsOrder() === 'createdAt' || !commentsOrder() }}>
|
<li classList={{ selected: commentsOrder() === 'createdAt' || !commentsOrder() }}>
|
||||||
<a
|
<Button
|
||||||
href="#"
|
variant="inline"
|
||||||
onClick={(ev) => {
|
value={t('By time')}
|
||||||
ev.preventDefault()
|
onClick={() => {
|
||||||
setCommentsOrder('createdAt')
|
setCommentsOrder('createdAt')
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
{t('By time')}
|
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
<li classList={{ selected: commentsOrder() === 'rating' }}>
|
<li classList={{ selected: commentsOrder() === 'rating' }}>
|
||||||
<a
|
<Button
|
||||||
href="#"
|
variant="inline"
|
||||||
onClick={(ev) => {
|
value={t('By rating')}
|
||||||
ev.preventDefault()
|
onClick={() => {
|
||||||
setCommentsOrder('rating')
|
setCommentsOrder('rating')
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
{t('By rating')}
|
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -128,7 +127,7 @@ export const CommentsTree = (props: Props) => {
|
||||||
</Show>
|
</Show>
|
||||||
<ShowOnlyOnClient>
|
<ShowOnlyOnClient>
|
||||||
<CommentEditor
|
<CommentEditor
|
||||||
initialValue={t('Write a comment...')}
|
placeholder={t('Write a comment...')}
|
||||||
clear={submitted()}
|
clear={submitted()}
|
||||||
onSubmit={(value) => handleSubmitComment(value)}
|
onSubmit={(value) => handleSubmitComment(value)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -31,6 +31,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.inline {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 21px;
|
||||||
|
color: #696969;
|
||||||
|
|
||||||
|
&.hover,
|
||||||
|
&.active {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: #141414;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:disabled,
|
&:disabled,
|
||||||
&:disabled:hover {
|
&:disabled:hover {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import styles from './Button.module.scss'
|
||||||
type Props = {
|
type Props = {
|
||||||
value: string | JSX.Element
|
value: string | JSX.Element
|
||||||
size?: 'S' | 'M' | 'L'
|
size?: 'S' | 'M' | 'L'
|
||||||
variant?: 'primary' | 'secondary'
|
variant?: 'primary' | 'secondary' | 'inline'
|
||||||
type?: 'submit' | 'button'
|
type?: 'submit' | 'button'
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { t } from '../../../utils/intl'
|
||||||
import { schema } from './schema'
|
import { schema } from './schema'
|
||||||
import { EditorState } from 'prosemirror-state'
|
import { EditorState } from 'prosemirror-state'
|
||||||
import { EditorView } from 'prosemirror-view'
|
import { EditorView } from 'prosemirror-view'
|
||||||
import { DOMSerializer } from 'prosemirror-model'
|
import { DOMParser as ProseDOMParser, DOMSerializer } from 'prosemirror-model'
|
||||||
import { renderGrouped } from 'prosemirror-menu'
|
import { renderGrouped } from 'prosemirror-menu'
|
||||||
import { buildMenuItems } from './menu'
|
import { buildMenuItems } from './menu'
|
||||||
import { keymap } from 'prosemirror-keymap'
|
import { keymap } from 'prosemirror-keymap'
|
||||||
|
@ -20,9 +20,10 @@ import { useSession } from '../../../context/session'
|
||||||
import { showModal } from '../../../stores/ui'
|
import { showModal } from '../../../stores/ui'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
initialValue: string
|
placeholder?: string
|
||||||
onSubmit: (value: string) => void
|
onSubmit: (value: string) => void
|
||||||
clear?: boolean
|
clear?: boolean
|
||||||
|
initialContent?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const htmlContainer = typeof document === 'undefined' ? null : document.createElement('div')
|
const htmlContainer = typeof document === 'undefined' ? null : document.createElement('div')
|
||||||
|
@ -37,14 +38,19 @@ const CommentEditor = (props: Props) => {
|
||||||
const editorElRef: { current: HTMLDivElement } = { current: null }
|
const editorElRef: { current: HTMLDivElement } = { current: null }
|
||||||
const menuElRef: { current: HTMLDivElement } = { current: null }
|
const menuElRef: { current: HTMLDivElement } = { current: null }
|
||||||
const editorViewRef: { current: EditorView } = { current: null }
|
const editorViewRef: { current: EditorView } = { current: null }
|
||||||
|
|
||||||
|
const domNew = new DOMParser().parseFromString(`<div>${props.initialContent}</div>`, 'text/xml')
|
||||||
|
const doc = ProseDOMParser.fromSchema(schema).parse(domNew)
|
||||||
|
|
||||||
const initEditor = () => {
|
const initEditor = () => {
|
||||||
editorViewRef.current = new EditorView(editorElRef.current, {
|
editorViewRef.current = new EditorView(editorElRef.current, {
|
||||||
state: EditorState.create({
|
state: EditorState.create({
|
||||||
schema,
|
schema,
|
||||||
|
doc: props.initialContent ? doc : null,
|
||||||
plugins: [
|
plugins: [
|
||||||
history(),
|
history(),
|
||||||
customKeymap(),
|
customKeymap(),
|
||||||
placeholder(props.initialValue),
|
placeholder(props.placeholder),
|
||||||
keymap({ 'Mod-z': undo, 'Mod-y': redo }),
|
keymap({ 'Mod-z': undo, 'Mod-y': redo }),
|
||||||
keymap(baseKeymap)
|
keymap(baseKeymap)
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { gql } from '@urql/core'
|
import { gql } from '@urql/core'
|
||||||
|
|
||||||
export default gql`
|
export default gql`
|
||||||
mutation DeleteReactionMutation($reaction: Int!) {
|
mutation DeleteReactionMutation($id: Int!) {
|
||||||
deleteReaction(reaction: $reaction) {
|
deleteReaction(id: $id) {
|
||||||
error
|
error
|
||||||
reaction {
|
reaction {
|
||||||
id
|
id
|
||||||
|
|
|
@ -1,32 +1,13 @@
|
||||||
import { gql } from '@urql/core'
|
import { gql } from '@urql/core'
|
||||||
|
|
||||||
export default gql`
|
export default gql`
|
||||||
mutation UpdateReactionMutation($reaction: ReactionInput!) {
|
mutation UpdateReactionMutation($id: Int!, $reaction: ReactionInput!) {
|
||||||
updateReaction(reaction: $reaction) {
|
updateReaction(id: $id, reaction: $reaction) {
|
||||||
error
|
error
|
||||||
reaction {
|
reaction {
|
||||||
id
|
|
||||||
createdBy {
|
|
||||||
slug
|
|
||||||
name
|
|
||||||
userpic
|
|
||||||
}
|
|
||||||
body
|
body
|
||||||
kind
|
|
||||||
range
|
|
||||||
createdAt
|
|
||||||
updatedAt
|
updatedAt
|
||||||
shout
|
replyTo
|
||||||
replyTo {
|
|
||||||
id
|
|
||||||
createdBy {
|
|
||||||
slug
|
|
||||||
userpic
|
|
||||||
name
|
|
||||||
}
|
|
||||||
body
|
|
||||||
kind
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -537,11 +537,13 @@ export enum ReactionKind {
|
||||||
Disagree = 'DISAGREE',
|
Disagree = 'DISAGREE',
|
||||||
Dislike = 'DISLIKE',
|
Dislike = 'DISLIKE',
|
||||||
Disproof = 'DISPROOF',
|
Disproof = 'DISPROOF',
|
||||||
|
Footnote = 'FOOTNOTE',
|
||||||
Like = 'LIKE',
|
Like = 'LIKE',
|
||||||
Proof = 'PROOF',
|
Proof = 'PROOF',
|
||||||
Propose = 'PROPOSE',
|
Propose = 'PROPOSE',
|
||||||
Quote = 'QUOTE',
|
Quote = 'QUOTE',
|
||||||
Reject = 'REJECT'
|
Reject = 'REJECT',
|
||||||
|
Remark = 'REMARK'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ReactionStatus {
|
export enum ReactionStatus {
|
||||||
|
@ -656,12 +658,9 @@ export type Stat = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Subscription = {
|
export type Subscription = {
|
||||||
collabUpdate?: Maybe<Reaction>
|
|
||||||
newMessage?: Maybe<Message>
|
newMessage?: Maybe<Message>
|
||||||
}
|
newReaction?: Maybe<Reaction>
|
||||||
|
newShout?: Maybe<Shout>
|
||||||
export type SubscriptionCollabUpdateArgs = {
|
|
||||||
collab: Scalars['Int']
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Token = {
|
export type Token = {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"By name": "По имени",
|
"By name": "По имени",
|
||||||
"By popularity": "По популярности",
|
"By popularity": "По популярности",
|
||||||
"By rating": "По популярности",
|
"By rating": "По популярности",
|
||||||
|
"By time": "По времени",
|
||||||
"By relevance": "По релевантности",
|
"By relevance": "По релевантности",
|
||||||
"By shouts": "По публикациям",
|
"By shouts": "По публикациям",
|
||||||
"By signing up you agree with our": "Регистрируясь, вы соглашаетесь с",
|
"By signing up you agree with our": "Регистрируясь, вы соглашаетесь с",
|
||||||
|
@ -223,6 +224,8 @@
|
||||||
"Add comment": "Комментировать",
|
"Add comment": "Комментировать",
|
||||||
"My subscriptions": "Подписки",
|
"My subscriptions": "Подписки",
|
||||||
"Nothing here yet": "Здесь пока ничего нет",
|
"Nothing here yet": "Здесь пока ничего нет",
|
||||||
|
"Edited": "Отредактирован",
|
||||||
|
"Nothing here yet": "Здесь пока ничего нет",
|
||||||
"Invite experts": "Пригласить экспертов",
|
"Invite experts": "Пригласить экспертов",
|
||||||
"Subscribe to comments": "Подписаться на комментарии",
|
"Subscribe to comments": "Подписаться на комментарии",
|
||||||
"Add to bookmarks": "Добавить в закладки",
|
"Add to bookmarks": "Добавить в закладки",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { Reaction, ReactionInput } from '../../graphql/types.gen'
|
import type { Reaction, ReactionInput } from '../../graphql/types.gen'
|
||||||
import { apiClient } from '../../utils/apiClient'
|
import { apiClient } from '../../utils/apiClient'
|
||||||
import { createSignal } from 'solid-js'
|
import { createEffect, createSignal } from 'solid-js'
|
||||||
// TODO: import { roomConnect } from '../../utils/p2p'
|
// TODO: import { roomConnect } from '../../utils/p2p'
|
||||||
|
|
||||||
export const REACTIONS_AMOUNT_PER_PAGE = 100
|
export const REACTIONS_AMOUNT_PER_PAGE = 100
|
||||||
|
@ -34,15 +34,21 @@ export const createReaction = async (
|
||||||
setSortedReactions((prev) => [...prev, reaction])
|
setSortedReactions((prev) => [...prev, reaction])
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deleteReaction = async (reactionId: number) => {
|
export const deleteReaction = async (id: number) => {
|
||||||
const reaction = await apiClient.destroyReaction(reactionId)
|
const reaction = await apiClient.destroyReaction(id)
|
||||||
console.debug('[deleteReaction]:', reaction.reaction.id)
|
console.debug('[deleteReaction]:', reaction.reaction.id)
|
||||||
setSortedReactions(sortedReactions().filter((item) => item.id !== reaction.reaction.id))
|
setSortedReactions(sortedReactions().filter((item) => item.id !== reaction.reaction.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateReaction = async (reaction: Reaction) => {
|
export const updateReaction = async (id: number, input: ReactionInput) => {
|
||||||
const { reaction: r } = await apiClient.updateReaction({ reaction })
|
const reaction = await apiClient.updateReaction(id, input)
|
||||||
return r
|
const editedReactionIndex = sortedReactions().findIndex((r) => r.id === id)
|
||||||
|
const newSortedReactions = [...sortedReactions()]
|
||||||
|
newSortedReactions[editedReactionIndex] = {
|
||||||
|
...newSortedReactions[editedReactionIndex],
|
||||||
|
...reaction
|
||||||
|
}
|
||||||
|
setSortedReactions(newSortedReactions)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useReactionsStore = () => {
|
export const useReactionsStore = () => {
|
||||||
|
|
|
@ -237,14 +237,16 @@ export const apiClient = {
|
||||||
return response.data.createReaction.reaction
|
return response.data.createReaction.reaction
|
||||||
},
|
},
|
||||||
destroyReaction: async (id: number) => {
|
destroyReaction: async (id: number) => {
|
||||||
const response = await privateGraphQLClient.mutation(reactionDestroy, { reaction: id }).toPromise()
|
const response = await privateGraphQLClient.mutation(reactionDestroy, { id: id }).toPromise()
|
||||||
console.debug('[destroyReaction]:', response)
|
console.debug('[destroyReaction]:', response)
|
||||||
return response.data.deleteReaction
|
return response.data.deleteReaction
|
||||||
},
|
},
|
||||||
updateReaction: async (reaction) => {
|
updateReaction: async (id: number, input: ReactionInput) => {
|
||||||
const response = await privateGraphQLClient.mutation(reactionUpdate, reaction).toPromise()
|
const response = await privateGraphQLClient
|
||||||
|
.mutation(reactionUpdate, { id: id, reaction: input })
|
||||||
return response.data.createReaction
|
.toPromise()
|
||||||
|
console.debug('[updateReaction]:', response)
|
||||||
|
return response.data.updateReaction.reaction
|
||||||
},
|
},
|
||||||
getAuthorsBy: async (options: QueryLoadAuthorsByArgs) => {
|
getAuthorsBy: async (options: QueryLoadAuthorsByArgs) => {
|
||||||
const resp = await publicGraphQLClient.query(authorsLoadBy, options).toPromise()
|
const resp = await publicGraphQLClient.query(authorsLoadBy, options).toPromise()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user