create shout -> edit

This commit is contained in:
bniwredyc 2023-04-11 15:57:48 +02:00
parent 21282aad92
commit ac3f29defc
23 changed files with 126 additions and 279 deletions

View File

@ -1,6 +1,6 @@
overwrite: true overwrite: true
#schema: 'http://localhost:8080' schema: 'http://127.0.0.1:8080'
schema: 'https://v2.discours.io' #schema: 'https://v2.discours.io'
generates: generates:
src/graphql/introspec.gen.ts: src/graphql/introspec.gen.ts:
plugins: plugins:

View File

@ -27,6 +27,7 @@ import { ProjectsPage } from '../pages/about/projects.page'
import { TermsOfUsePage } from '../pages/about/termsOfUse.page' import { TermsOfUsePage } from '../pages/about/termsOfUse.page'
import { ThanksPage } from '../pages/about/thanks.page' import { ThanksPage } from '../pages/about/thanks.page'
import { CreatePage } from '../pages/create.page' import { CreatePage } from '../pages/create.page'
import { EditPage } from '../pages/edit.page'
import { ConnectPage } from '../pages/connect.page' import { ConnectPage } from '../pages/connect.page'
import { InboxPage } from '../pages/inbox.page' import { InboxPage } from '../pages/inbox.page'
import { LayoutShoutsPage } from '../pages/layoutShouts.page' import { LayoutShoutsPage } from '../pages/layoutShouts.page'
@ -45,7 +46,8 @@ const pagesMap: Record<keyof typeof ROUTES, Component<PageProps>> = {
expo: LayoutShoutsPage, expo: LayoutShoutsPage,
connect: ConnectPage, connect: ConnectPage,
create: CreatePage, create: CreatePage,
createSettings: CreatePage, edit: EditPage,
editSettings: EditPage,
home: HomePage, home: HomePage,
topics: AllTopicsPage, topics: AllTopicsPage,
topic: TopicPage, topic: TopicPage,

View File

@ -52,8 +52,6 @@ export const CommentsTree = (props: Props) => {
Object.values(reactionEntities).filter((reaction) => reaction.kind === 'COMMENT') Object.values(reactionEntities).filter((reaction) => reaction.kind === 'COMMENT')
) )
console.log(JSON.parse(JSON.stringify(reactionEntities)))
const sortedComments = createMemo(() => { const sortedComments = createMemo(() => {
let newSortedComments = [...comments()] let newSortedComments = [...comments()]
newSortedComments = newSortedComments.sort(byCreated) newSortedComments = newSortedComments.sort(byCreated)

View File

@ -208,10 +208,12 @@ export const FullArticle = (props: ArticleProps) => {
<Icon name="bookmark" class={styles.icon} /> <Icon name="bookmark" class={styles.icon} />
</div> </div>
</div> </div>
<Show when={canEdit()}> <Show when={canEdit()}>
<div class={styles.shoutStatsItem}> <div class={styles.shoutStatsItem}>
<a href="/edit" class={styles.shoutStatsItemInner}> <a
href={getPagePath(router, 'edit', { shoutSlug: props.article.slug })}
class={styles.shoutStatsItemInner}
>
<Icon name="edit" class={clsx(styles.icon, styles.iconEdit)} /> <Icon name="edit" class={clsx(styles.icon, styles.iconEdit)} />
{t('Edit')} {t('Edit')}
</a> </a>

View File

@ -30,7 +30,7 @@ import { TrailingNode } from './extensions/TrailingNode'
import { EditorBubbleMenu } from './EditorBubbleMenu/EditorBubbleMenu' import { EditorBubbleMenu } from './EditorBubbleMenu/EditorBubbleMenu'
import { EditorFloatingMenu } from './EditorFloatingMenu' import { EditorFloatingMenu } from './EditorFloatingMenu'
import * as Y from 'yjs' import * as Y from 'yjs'
import { WebrtcProvider } from 'y-webrtc' // import { WebrtcProvider } from 'y-webrtc'
import { CollaborationCursor } from '@tiptap/extension-collaboration-cursor' import { CollaborationCursor } from '@tiptap/extension-collaboration-cursor'
import { Collaboration } from '@tiptap/extension-collaboration' import { Collaboration } from '@tiptap/extension-collaboration'
import './Prosemirror.scss' import './Prosemirror.scss'
@ -40,7 +40,7 @@ import uniqolor from 'uniqolor'
import { HocuspocusProvider } from '@hocuspocus/provider' import { HocuspocusProvider } from '@hocuspocus/provider'
type EditorProps = { type EditorProps = {
shoutId: number shoutSlug: string
initialContent?: string initialContent?: string
onChange: (text: string) => void onChange: (text: string) => void
} }
@ -53,12 +53,12 @@ export const Editor = (props: EditorProps) => {
const { t } = useLocalize() const { t } = useLocalize()
const { user } = useSession() const { user } = useSession()
const docName = `shout-${props.shoutId}` const docName = `shout-${props.shoutSlug}`
if (!providers[docName]) { if (!providers[docName]) {
providers[docName] = new HocuspocusProvider({ providers[docName] = new HocuspocusProvider({
// url: 'wss://hocuspocus.discours.io', url: 'wss://hocuspocus.discours.io',
url: 'ws://localhost:4242', // url: 'ws://localhost:4242',
name: docName, name: docName,
document: yDoc document: yDoc
}) })
@ -88,6 +88,7 @@ export const Editor = (props: EditorProps) => {
const editor = createTiptapEditor(() => ({ const editor = createTiptapEditor(() => ({
element: editorElRef.current, element: editorElRef.current,
content: props.initialContent,
extensions: [ extensions: [
Document, Document,
Text, Text,

View File

@ -1,4 +1,4 @@
import { Switch, Match, createSignal, Show, createEffect } from 'solid-js' import { Switch, Match, createSignal, Show } from 'solid-js'
import type { Editor } from '@tiptap/core' import type { Editor } from '@tiptap/core'
import styles from './EditorBubbleMenu.module.scss' import styles from './EditorBubbleMenu.module.scss'
import { Icon } from '../../_shared/Icon' import { Icon } from '../../_shared/Icon'
@ -26,10 +26,6 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => {
} }
) )
createEffect(() => {
console.log('!!! editor:', props.editor)
})
const isBold = isActive('bold') const isBold = isActive('bold')
const isItalic = isActive('italic') const isItalic = isActive('italic')
const isH1 = isActive('heading', { level: 1 }) const isH1 = isActive('heading', { level: 1 })

View File

@ -44,7 +44,7 @@ export const HeaderAuth = (props: HeaderAuthProps) => {
<Show when={isSessionLoaded()} keyed={true}> <Show when={isSessionLoaded()} keyed={true}>
<div class={clsx(styles.usernav, 'col')}> <div class={clsx(styles.usernav, 'col')}>
<div class={clsx(styles.userControl, styles.userControl, 'col')}> <div class={clsx(styles.userControl, styles.userControl, 'col')}>
<Show when={page().route !== 'create'}> <Show when={page().route !== 'edit'}>
<div class={clsx(styles.userControlItem, styles.userControlItemVerbose)}> <div class={clsx(styles.userControlItem, styles.userControlItemVerbose)}>
<a href={getPagePath(router, 'create')}> <a href={getPagePath(router, 'create')}>
<span class={styles.textLabel}>{t('Create post')}</span> <span class={styles.textLabel}>{t('Create post')}</span>

View File

@ -37,7 +37,7 @@ export const FullTopic = (props: Props) => {
{t('Unfollow the topic')} {t('Unfollow the topic')}
</button> </button>
</Show> </Show>
<a href={`/create/${props.topic.slug}`}>{t('Write about the topic')}</a> <a href={`/create/?topicId=${props.topic.id}`}>{t('Write about the topic')}</a>
</div> </div>
<Show when={props.topic.pic}> <Show when={props.topic.pic}>
<img src={props.topic.pic} alt={props.topic.title} /> <img src={props.topic.pic} alt={props.topic.title} />

View File

@ -43,8 +43,8 @@
} }
} }
.createSettings, .editSettings,
.create { .edit {
display: none; display: none;
&.visible { &.visible {

View File

@ -1,15 +1,14 @@
import { createSignal, lazy, onMount, Show, Suspense } from 'solid-js' import { createSignal, onMount, Show } from 'solid-js'
import { Loading } from '../_shared/Loading'
import { useLocalize } from '../../context/localize' import { useLocalize } from '../../context/localize'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import styles from './Create.module.scss' import styles from './Edit.module.scss'
import { Title } from '@solidjs/meta' import { Title } from '@solidjs/meta'
import { createStore } from 'solid-js/store' import { createStore } from 'solid-js/store'
import type { Topic } from '../../graphql/types.gen' import type { Shout, Topic } from '../../graphql/types.gen'
import { apiClient } from '../../utils/apiClient' import { apiClient } from '../../utils/apiClient'
import { TopicSelect } from '../Editor/TopicSelect/TopicSelect' import { TopicSelect } from '../Editor/TopicSelect/TopicSelect'
import { router, useRouter } from '../../stores/router' import { router, useRouter } from '../../stores/router'
import { getPagePath } from '@nanostores/router' import { getPagePath, openPage } from '@nanostores/router'
import { translit } from '../../utils/ru2en' import { translit } from '../../utils/ru2en'
import { Editor } from '../Editor/Editor' import { Editor } from '../Editor/Editor'
@ -18,12 +17,16 @@ type ShoutForm = {
title: string title: string
subtitle: string subtitle: string
selectedTopics: Topic[] selectedTopics: Topic[]
mainTopic: Topic mainTopic: string
body: string body: string
coverImageUrl: string coverImageUrl: string
} }
export const CreateView = () => { type EditViewProps = {
shout: Shout
}
export const EditView = (props: EditViewProps) => {
const { t } = useLocalize() const { t } = useLocalize()
const [topics, setTopics] = createSignal<Topic[]>(null) const [topics, setTopics] = createSignal<Topic[]>(null)
@ -32,13 +35,13 @@ export const CreateView = () => {
const [isSlugChanged, setIsSlugChanged] = createSignal(false) const [isSlugChanged, setIsSlugChanged] = createSignal(false)
const [form, setForm] = createStore<ShoutForm>({ const [form, setForm] = createStore<ShoutForm>({
slug: '', slug: props.shout.slug,
title: '', title: props.shout.title,
subtitle: '', subtitle: props.shout.subtitle,
selectedTopics: [], selectedTopics: props.shout.topics,
mainTopic: null, mainTopic: props.shout.mainTopic,
body: '', body: props.shout.body,
coverImageUrl: '' coverImageUrl: props.shout.cover
}) })
onMount(async () => { onMount(async () => {
@ -49,18 +52,18 @@ export const CreateView = () => {
const handleFormSubmit = async (e) => { const handleFormSubmit = async (e) => {
e.preventDefault() e.preventDefault()
const newShout = await apiClient.createArticle({ // const newShout = await apiClient.updateArticle({
article: { // article: {
slug: form.slug, // slug: form.slug,
title: form.title, // title: form.title,
subtitle: form.subtitle, // subtitle: form.subtitle,
body: form.body, // body: form.body,
topics: form.selectedTopics.map((topic) => topic.slug), // topics: form.selectedTopics.map((topic) => topic.slug),
mainTopic: form.selectedTopics[0].slug // mainTopic: form.selectedTopics[0].slug
} // }
}) // })
router.open(getPagePath(router, 'article', { slug: newShout.slug })) // openPage(getPagePath(router, 'article', { slug: newShout.slug }))
} }
const handleTitleInputChange = (e) => { const handleTitleInputChange = (e) => {
@ -92,8 +95,8 @@ export const CreateView = () => {
<div class="row"> <div class="row">
<div class="col-md-20 col-lg-18 col-xl-16"> <div class="col-md-20 col-lg-18 col-xl-16">
<div <div
class={clsx(styles.create, { class={clsx(styles.edit, {
[styles.visible]: page().route === 'create' [styles.visible]: page().route === 'edit'
})} })}
> >
<input <input
@ -116,16 +119,22 @@ export const CreateView = () => {
onChange={(e) => setForm('subtitle', e.currentTarget.value)} onChange={(e) => setForm('subtitle', e.currentTarget.value)}
/> />
<Editor shoutId={42} onChange={(body) => setForm('body', body)} /> <Editor
shoutSlug={props.shout.slug}
initialContent={form.body}
onChange={(body) => setForm('body', body)}
/>
<div class={styles.saveBlock}> <div class={styles.saveBlock}>
{/*<button class={clsx('button button--outline', styles.button)}>Сохранить</button>*/} {/*<button class={clsx('button button--outline', styles.button)}>Сохранить</button>*/}
<a href={getPagePath(router, 'createSettings')}>Настройки</a> <a href={getPagePath(router, 'editSettings', { shoutSlug: props.shout.slug })}>
Настройки
</a>
</div> </div>
</div> </div>
<div <div
class={clsx(styles.createSettings, { class={clsx(styles.editSettings, {
[styles.visible]: page().route === 'createSettings' [styles.visible]: page().route === 'editSettings'
})} })}
> >
<h1>Настройки публикации</h1> <h1>Настройки публикации</h1>
@ -206,8 +215,8 @@ export const CreateView = () => {
Проверьте ещё раз введённые данные, если всё верно, вы&nbsp;можете сохранить или Проверьте ещё раз введённые данные, если всё верно, вы&nbsp;можете сохранить или
опубликовать ваш текст опубликовать ваш текст
</p> </p>
{/*<button class={clsx('button button--outline', styles.button)}>Сохранить</button>*/} <button class={clsx('button button--outline', styles.button)}>Сохранить</button>
<a href={getPagePath(router, 'create')}>Назад</a> <a href={getPagePath(router, 'edit', { shoutSlug: props.shout.slug })}>Назад</a>
<button type="submit" class={clsx('button button--submit', styles.button)}> <button type="submit" class={clsx('button button--submit', styles.button)}>
Опубликовать Опубликовать
</button> </button>
@ -222,4 +231,4 @@ export const CreateView = () => {
) )
} }
export default CreateView export default EditView

View File

@ -10,18 +10,6 @@ export default gql`
title title
subtitle subtitle
body body
topics {
id
title
slug
}
authors {
id
name
slug
userpic
caption
}
} }
} }
} }

View File

@ -1,28 +0,0 @@
import { gql } from '@urql/core'
export default gql`
mutation DraftCreateMutation($draft: DraftInput!) {
createDraft(draft: $draft) {
error
draft {
id
slug
title
subtitle
body
topics {
# id
title
slug
}
authors {
id
name
slug
userpic
caption
}
}
}
}
`

View File

@ -1,9 +0,0 @@
import { gql } from '@urql/core'
export default gql`
mutation DraftDestroyMutation($draft: Int!) {
deleteDraft(draft: $draft) {
error
}
}
`

View File

@ -1,28 +0,0 @@
import { gql } from '@urql/core'
export default gql`
mutation ShoutFromDraftMutation($draft: Int!) {
draftToShout(draft: $draft) {
error
shout {
_id: slug
slug
title
subtitle
body
topics {
# id
title
slug
}
authors {
id
name
slug
userpic
caption
}
}
}
}
`

View File

@ -1,28 +0,0 @@
import { gql } from '@urql/core'
export default gql`
mutation DraftUpdateMutation($draft: DraftInput!) {
updateDraft(draft: $draft) {
error
draft {
id
slug
title
subtitle
body
topics {
# id
title
slug
}
authors {
id
name
slug
userpic
caption
}
}
}
}
`

View File

@ -1,17 +0,0 @@
import { gql } from '@urql/core'
export default gql`
query MyDraftsQuery {
loadDrafts {
authors {
id
slug
name
pic
}
createdAt
body
title
}
}
`

View File

@ -105,30 +105,6 @@ export type Community = {
slug: Scalars['String'] slug: Scalars['String']
} }
export type DraftCollab = {
authors: Array<Maybe<Scalars['Int']>>
body?: Maybe<Scalars['String']>
chat?: Maybe<Chat>
cover?: Maybe<Scalars['String']>
createdAt: Scalars['Int']
layout?: Maybe<Scalars['String']>
slug?: Maybe<Scalars['String']>
subtitle?: Maybe<Scalars['String']>
title?: Maybe<Scalars['String']>
topics?: Maybe<Array<Maybe<Scalars['String']>>>
updatedAt?: Maybe<Scalars['Int']>
}
export type DraftInput = {
authors?: InputMaybe<Array<InputMaybe<Scalars['Int']>>>
body?: InputMaybe<Scalars['String']>
cover?: InputMaybe<Scalars['String']>
slug?: InputMaybe<Scalars['String']>
subtitle?: InputMaybe<Scalars['String']>
title?: InputMaybe<Scalars['String']>
topics?: InputMaybe<Array<InputMaybe<Scalars['Int']>>>
}
export enum FollowingEntity { export enum FollowingEntity {
Author = 'AUTHOR', Author = 'AUTHOR',
Community = 'COMMUNITY', Community = 'COMMUNITY',
@ -185,28 +161,23 @@ export type MessagesBy = {
export type Mutation = { export type Mutation = {
confirmEmail: AuthResult confirmEmail: AuthResult
createChat: Result createChat: Result
createDraft: Result
createMessage: Result createMessage: Result
createReaction: Result createReaction: Result
createShout: Result createShout: Result
createTopic: Result createTopic: Result
deleteChat: Result deleteChat: Result
deleteDraft: Result
deleteMessage: Result deleteMessage: Result
deleteReaction: Result deleteReaction: Result
deleteShout: Result deleteShout: Result
destroyTopic: Result destroyTopic: Result
follow: Result follow: Result
getSession: AuthResult getSession: AuthResult
inviteAccept: Result
inviteAuthor: Result
markAsRead: Result markAsRead: Result
rateUser: Result rateUser: Result
registerUser: AuthResult registerUser: AuthResult
sendLink: Result sendLink: Result
unfollow: Result unfollow: Result
updateChat: Result updateChat: Result
updateDraft: Result
updateMessage: Result updateMessage: Result
updateOnlineStatus: Result updateOnlineStatus: Result
updateProfile: Result updateProfile: Result
@ -224,10 +195,6 @@ export type MutationCreateChatArgs = {
title?: InputMaybe<Scalars['String']> title?: InputMaybe<Scalars['String']>
} }
export type MutationCreateDraftArgs = {
draft: DraftInput
}
export type MutationCreateMessageArgs = { export type MutationCreateMessageArgs = {
body: Scalars['String'] body: Scalars['String']
chat: Scalars['String'] chat: Scalars['String']
@ -250,10 +217,6 @@ export type MutationDeleteChatArgs = {
chatId: Scalars['String'] chatId: Scalars['String']
} }
export type MutationDeleteDraftArgs = {
draft: Scalars['Int']
}
export type MutationDeleteMessageArgs = { export type MutationDeleteMessageArgs = {
chatId: Scalars['String'] chatId: Scalars['String']
id: Scalars['Int'] id: Scalars['Int']
@ -276,15 +239,6 @@ export type MutationFollowArgs = {
what: FollowingEntity what: FollowingEntity
} }
export type MutationInviteAcceptArgs = {
draft: Scalars['Int']
}
export type MutationInviteAuthorArgs = {
author: Scalars['Int']
draft: Scalars['Int']
}
export type MutationMarkAsReadArgs = { export type MutationMarkAsReadArgs = {
chatId: Scalars['String'] chatId: Scalars['String']
ids: Array<InputMaybe<Scalars['Int']>> ids: Array<InputMaybe<Scalars['Int']>>
@ -316,10 +270,6 @@ export type MutationUpdateChatArgs = {
chat: ChatInput chat: ChatInput
} }
export type MutationUpdateDraftArgs = {
draft: DraftInput
}
export type MutationUpdateMessageArgs = { export type MutationUpdateMessageArgs = {
body: Scalars['String'] body: Scalars['String']
chatId: Scalars['String'] chatId: Scalars['String']
@ -375,13 +325,13 @@ export type Query = {
isEmailUsed: Scalars['Boolean'] isEmailUsed: Scalars['Boolean']
loadAuthorsBy: Array<Maybe<Author>> loadAuthorsBy: Array<Maybe<Author>>
loadChats: Result loadChats: Result
loadDrafts: Array<Maybe<DraftCollab>>
loadMessagesBy: Result loadMessagesBy: Result
loadReactionsBy: Array<Maybe<Reaction>> loadReactionsBy: Array<Maybe<Reaction>>
loadRecipients: Result loadRecipients: Result
loadShout?: Maybe<Shout> loadShout?: Maybe<Shout>
loadShouts: Array<Maybe<Shout>> loadShouts: Array<Maybe<Shout>>
markdownBody: Scalars['String'] markdownBody: Scalars['String']
myFeed?: Maybe<Array<Maybe<Shout>>>
searchMessages: Result searchMessages: Result
searchRecipients: Result searchRecipients: Result
signIn: AuthResult signIn: AuthResult
@ -447,6 +397,10 @@ export type QueryMarkdownBodyArgs = {
body: Scalars['String'] body: Scalars['String']
} }
export type QueryMyFeedArgs = {
options?: InputMaybe<LoadShoutsOptions>
}
export type QuerySearchMessagesArgs = { export type QuerySearchMessagesArgs = {
by: MessagesBy by: MessagesBy
limit?: InputMaybe<Scalars['Int']> limit?: InputMaybe<Scalars['Int']>
@ -573,7 +527,6 @@ export type Result = {
chats?: Maybe<Array<Maybe<Chat>>> chats?: Maybe<Array<Maybe<Chat>>>
communities?: Maybe<Array<Maybe<Community>>> communities?: Maybe<Array<Maybe<Community>>>
community?: Maybe<Community> community?: Maybe<Community>
drafts?: Maybe<Array<Maybe<DraftCollab>>>
error?: Maybe<Scalars['String']> error?: Maybe<Scalars['String']>
members?: Maybe<Array<Maybe<ChatMember>>> members?: Maybe<Array<Maybe<ChatMember>>>
message?: Maybe<Message> message?: Maybe<Message>
@ -585,7 +538,6 @@ export type Result = {
slugs?: Maybe<Array<Maybe<Scalars['String']>>> slugs?: Maybe<Array<Maybe<Scalars['String']>>>
topic?: Maybe<Topic> topic?: Maybe<Topic>
topics?: Maybe<Array<Maybe<Topic>>> topics?: Maybe<Array<Maybe<Topic>>>
uids?: Maybe<Array<Maybe<Scalars['String']>>>
} }
export type Role = { export type Role = {
@ -610,7 +562,6 @@ export type Shout = {
mainTopic?: Maybe<Scalars['String']> mainTopic?: Maybe<Scalars['String']>
media?: Maybe<Scalars['String']> media?: Maybe<Scalars['String']>
publishedAt?: Maybe<Scalars['DateTime']> publishedAt?: Maybe<Scalars['DateTime']>
publishedBy?: Maybe<User>
slug: Scalars['String'] slug: Scalars['String']
stat?: Maybe<Stat> stat?: Maybe<Stat>
subtitle?: Maybe<Scalars['String']> subtitle?: Maybe<Scalars['String']>
@ -624,7 +575,7 @@ export type Shout = {
export type ShoutInput = { export type ShoutInput = {
authors?: InputMaybe<Array<InputMaybe<Scalars['String']>>> authors?: InputMaybe<Array<InputMaybe<Scalars['String']>>>
body: Scalars['String'] body?: InputMaybe<Scalars['String']>
community?: InputMaybe<Scalars['Int']> community?: InputMaybe<Scalars['Int']>
mainTopic?: InputMaybe<Scalars['String']> mainTopic?: InputMaybe<Scalars['String']>
slug?: InputMaybe<Scalars['String']> slug?: InputMaybe<Scalars['String']>
@ -676,6 +627,7 @@ export type Token = {
export type Topic = { export type Topic = {
body?: Maybe<Scalars['String']> body?: Maybe<Scalars['String']>
community: Community community: Community
id: Scalars['Int']
oid?: Maybe<Scalars['String']> oid?: Maybe<Scalars['String']>
pic?: Maybe<Scalars['String']> pic?: Maybe<Scalars['String']>
slug: Scalars['String'] slug: Scalars['String']

View File

@ -1,22 +1,19 @@
import { lazy, Show, Suspense } from 'solid-js'
import { PageLayout } from '../components/_shared/PageLayout' import { PageLayout } from '../components/_shared/PageLayout'
import { Loading } from '../components/_shared/Loading' import { Loading } from '../components/_shared/Loading'
import { useSession } from '../context/session' import { onMount } from 'solid-js'
import { apiClient } from '../utils/apiClient'
const CreateView = lazy(() => import('../components/Views/Create')) import { router } from '../stores/router'
import { redirectPage } from '@nanostores/router'
export const CreatePage = () => { export const CreatePage = () => {
const { isAuthenticated, isSessionLoaded } = useSession() onMount(async () => {
const shout = await apiClient.createArticle({ article: {} })
redirectPage(router, 'edit', { shoutSlug: shout.slug })
})
return ( return (
<PageLayout> <PageLayout>
<Show when={isSessionLoaded()}> <Loading />
<Show when={isAuthenticated()} fallback="Давайте авторизуемся">
<Suspense fallback={<Loading />}>
<CreateView />
</Suspense>
</Show>
</Show>
</PageLayout> </PageLayout>
) )
} }

View File

@ -1,4 +1,4 @@
import { ROUTES } from '../stores/router' import { ROUTES } from '../stores/router'
import { getServerRoute } from '../utils/getServerRoute' import { getServerRoute } from '../utils/getServerRoute'
export default getServerRoute(ROUTES.createSettings) export default getServerRoute(ROUTES.edit)

40
src/pages/edit.page.tsx Normal file
View File

@ -0,0 +1,40 @@
import { createMemo, createSignal, lazy, onMount, Show, Suspense } from 'solid-js'
import { PageLayout } from '../components/_shared/PageLayout'
import { Loading } from '../components/_shared/Loading'
import { useSession } from '../context/session'
import { Shout } from '../graphql/types.gen'
import { useRouter } from '../stores/router'
import { apiClient } from '../utils/apiClient'
const EditView = lazy(() => import('../components/Views/Edit'))
export const EditPage = () => {
const { isAuthenticated, isSessionLoaded } = useSession()
const { page } = useRouter()
const shoutSlug = createMemo(() => (page().params as Record<'shoutSlug', string>).shoutSlug)
const [shout, setShout] = createSignal<Shout>(null)
onMount(async () => {
const loadedShout = await apiClient.getShout(shoutSlug())
setShout(loadedShout)
})
return (
<PageLayout>
<Show when={isSessionLoaded()}>
<Show when={isAuthenticated()} fallback="Давайте авторизуемся">
<Show when={shout()}>
<Suspense fallback={<Loading />}>
<EditView shout={shout()} />
</Suspense>
</Show>
</Show>
</Show>
</PageLayout>
)
}
export const Page = EditPage

View File

@ -0,0 +1,4 @@
import { ROUTES } from '../stores/router'
import { getServerRoute } from '../utils/getServerRoute'
export default getServerRoute(ROUTES.editSettings)

View File

@ -1,33 +0,0 @@
import { createStorageSignal } from '@solid-primitives/storage'
import type { Reaction } from '../graphql/types.gen'
import { createSignal } from 'solid-js'
// TODO: store drafts
// import type { Draft } from '../components/EditorExample/store/context'
interface Collab {
authors: string[] // slugs
invites?: string[]
createdAt: Date
body?: string
title?: string
}
export const drafts = createStorageSignal<{ [key: string]: string }>('drafts', {}) // save drafts on device
export const [collabs, setCollabs] = createSignal<Collab[]>([]) // save collabs in backend or in p2p network
export const [editorReactions, setReactions] = createSignal<Reaction[]>([])
/*
TODO: approvals and proposals derived stores
const approvals = computed(
reactions,
(rdict) => Object.values(rdict)
.filter((r: Reaction) => r.kind === ReactionKind.Accept)
)
const proposals = computed<Reaction[], typeof reactions>(
reactions,
(rdict) => Object.values(rdict)
.filter((r: Reaction) => r.kind === ReactionKind.Propose)
)
*/

View File

@ -9,7 +9,8 @@ export const ROUTES = {
inbox: '/inbox', inbox: '/inbox',
connect: '/connect', connect: '/connect',
create: '/create', create: '/create',
createSettings: '/create/settings', edit: '/edit/:shoutSlug',
editSettings: '/edit/:shoutSlug/settings',
topics: '/topics', topics: '/topics',
topic: '/topic/:slug', topic: '/topic/:slug',
authors: '/authors', authors: '/authors',