From 382da58af268013f3d3bb70d6274f1a27de95d5e Mon Sep 17 00:00:00 2001 From: bniwredyc Date: Thu, 4 May 2023 19:38:50 +0200 Subject: [PATCH 1/2] WIP --- public/icons/editor-horizontal-rule.svg | 5 ++++ src/components/Editor/Editor.tsx | 27 ++++++++----------- .../EditorFloatingMenu.module.scss | 2 +- .../EditorFloatingMenu/EditorFloatingMenu.tsx | 16 ++++++++--- .../Editor/EditorFloatingMenu/Menu/Menu.tsx | 12 +++++++-- src/components/Editor/Prosemirror.scss | 4 +++ .../Editor/UploadModal/UploadModalContent.tsx | 2 +- src/styles/app.scss | 2 +- 8 files changed, 45 insertions(+), 25 deletions(-) create mode 100644 public/icons/editor-horizontal-rule.svg diff --git a/public/icons/editor-horizontal-rule.svg b/public/icons/editor-horizontal-rule.svg new file mode 100644 index 00000000..3349d421 --- /dev/null +++ b/public/icons/editor-horizontal-rule.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index 23e012ae..6c05cf40 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -39,7 +39,6 @@ import { TextBubbleMenu } from './TextBubbleMenu' import { ImageBubbleMenu } from './ImageBubbleMenu' import { EditorFloatingMenu } from './EditorFloatingMenu' import { useEditorContext } from '../../context/editor' -import { isTextSelection } from '@tiptap/core' type EditorProps = { shoutId: number @@ -105,7 +104,11 @@ export const Editor = (props: EditorProps) => { Bold, Italic, Strike, - HorizontalRule, + HorizontalRule.configure({ + HTMLAttributes: { + class: 'horizontalRule' + } + }), Underline, Link.configure({ openOnClick: false @@ -144,25 +147,17 @@ export const Editor = (props: EditorProps) => { CharacterCount, BubbleMenu.configure({ pluginKey: 'textBubbleMenu', - element: textBubbleMenuRef.current, - shouldShow: ({ editor: e, view, state, oldState, from, to }) => { - const { doc, selection } = state - const { empty } = selection - - const isEmptyTextBlock = doc.textBetween(from, to).length === 0 && isTextSelection(selection) - - if (!view.hasFocus() || empty || isEmptyTextBlock || e.isActive('image')) { - return false - } - - return true - } + element: textBubbleMenuRef.current + // shouldShow: ({ editor: e, view, state, oldState, from, to }) => { + // console.log('!!! e:', view) + // return !e.isActive('image') + // } }), BubbleMenu.configure({ pluginKey: 'imageBubbleMenu', element: imageBubbleMenuRef.current, shouldShow: ({ editor: e, view, state, oldState, from, to }) => { - return view.hasFocus() && e.isActive('image') + return e.isFocused && e.isActive('image') } }), FloatingMenu.configure({ diff --git a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss index e6078156..83d6bdbd 100644 --- a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss +++ b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss @@ -12,10 +12,10 @@ opacity: 1; } } + .menuHolder { background: #fff; left: calc(100% + 1rem); - box-shadow: 0 4px 10px rgba(#000, 0.25); position: absolute; top: -0.8rem; min-width: 64vw; diff --git a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx index 23f916b9..30d91a07 100644 --- a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx +++ b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx @@ -7,6 +7,7 @@ import HTMLParser from 'html-to-json-parser' import { useLocalize } from '../../../context/localize' import { Modal } from '../../Nav/Modal' import { Menu } from './Menu' +import type { MenuItem } from './Menu/Menu' import { showModal } from '../../../stores/ui' import { UploadModalContent } from '../UploadModal' @@ -31,7 +32,7 @@ const validateEmbed = async (value) => { export const EditorFloatingMenu = (props: FloatingMenuProps) => { const { t } = useLocalize() - const [selectedMenuItem, setSelectedMenuItem] = createSignal(null) + const [selectedMenuItem, setSelectedMenuItem] = createSignal(null) const [menuOpen, setMenuOpen] = createSignal(false) const handleEmbedFormSubmit = async (value: string) => { // TODO: add support instagram embed (blockquote) @@ -40,8 +41,15 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => { } createEffect(() => { - if (selectedMenuItem() === 'image') { - showModal('uploadImage') + switch (selectedMenuItem()) { + case 'image': { + showModal('uploadImage') + return + } + case 'horizontal-rule': { + props.editor.chain().focus().setHorizontalRule().run() + return + } } }) const closeUploadModalHandler = () => { @@ -58,7 +66,7 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
- setSelectedMenuItem(value)} /> + setSelectedMenuItem(value)} /> void } export const Menu = (props: Props) => { + const setSelectedMenuItem = (value: MenuItem) => { + props.selectedItem(value) + } + return (
- - +
) } diff --git a/src/components/Editor/Prosemirror.scss b/src/components/Editor/Prosemirror.scss index 28885985..535d96f4 100644 --- a/src/components/Editor/Prosemirror.scss +++ b/src/components/Editor/Prosemirror.scss @@ -68,3 +68,7 @@ display: block; width: unset !important; } + +.horizontalRule { + border-top: 2px solid #000; +} diff --git a/src/components/Editor/UploadModal/UploadModalContent.tsx b/src/components/Editor/UploadModal/UploadModalContent.tsx index 7abd8424..8f2156fe 100644 --- a/src/components/Editor/UploadModal/UploadModalContent.tsx +++ b/src/components/Editor/UploadModal/UploadModalContent.tsx @@ -29,7 +29,7 @@ export const UploadModalContent = (props: Props) => { .chain() .focus() .extendMarkRange('link') - .setImage({ src: `/api/image?url=${src}` }) + .setImage({ src: `https://new.discours.io/api/image?url=${src}` }) .run() hideModal() } diff --git a/src/styles/app.scss b/src/styles/app.scss index 9a22667e..ee5b68f0 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -677,7 +677,7 @@ figcaption { .main-content { flex: 1 100%; - min-height: 300px; + min-height: 90vh; padding-top: 120px; position: relative; } From c4ec7d0a7ec8e16ccfdb4979a747941908a7ec4c Mon Sep 17 00:00:00 2001 From: bniwredyc Date: Thu, 4 May 2023 21:57:02 +0200 Subject: [PATCH 2/2] Merge remote-tracking branch 'gitlab/dev' into drafts # Conflicts: # src/components/Editor/Editor.tsx # src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss # src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx # src/components/Editor/EditorFloatingMenu/Menu/Menu.tsx # src/components/Editor/UploadModal/UploadModalContent.tsx --- src/components/Feed/ArticleCard.tsx | 6 ++-- src/components/Views/Author.tsx | 8 +---- src/components/Views/Edit.tsx | 36 ++++----------------- src/context/editor.tsx | 22 +++++++++++-- src/context/snackbar.tsx | 2 +- src/graphql/mutation/article-create.ts | 2 +- src/graphql/mutation/auth-confirm-email.ts | 2 +- src/graphql/mutation/community-update.ts | 2 +- src/graphql/mutation/my-session.ts | 1 - src/graphql/query/article-drafts-load-by.ts | 1 - src/graphql/query/articles-load-by.ts | 3 -- src/graphql/query/author-by-slug.ts | 2 -- src/graphql/query/author-followers.ts | 1 - src/graphql/query/author-reacted-shouts.ts | 3 -- src/graphql/query/authors-all.ts | 1 - src/graphql/query/authors-load-by.ts | 2 -- src/graphql/query/my-feed.ts | 3 -- src/graphql/query/topic-by-slug.ts | 1 - src/graphql/query/topics-all.ts | 2 -- src/graphql/query/topics-by-author.ts | 1 - src/graphql/query/topics-by-community.ts | 1 - src/graphql/query/topics-random.ts | 3 +- src/pages/author.page.tsx | 5 ++- 23 files changed, 40 insertions(+), 70 deletions(-) diff --git a/src/components/Feed/ArticleCard.tsx b/src/components/Feed/ArticleCard.tsx index b05535f3..ce902e03 100644 --- a/src/components/Feed/ArticleCard.tsx +++ b/src/components/Feed/ArticleCard.tsx @@ -1,5 +1,5 @@ import { createMemo, For, Show } from 'solid-js' -import type { Shout } from '../../graphql/types.gen' +import type { Shout, Topic } from '../../graphql/types.gen' import { capitalize } from '../../utils' import { translit } from '../../utils/ru2en' import { Icon } from '../_shared/Icon' @@ -80,7 +80,7 @@ export const ArticleCard = (props: ArticleCardProps) => { const { changeSearchParam } = useRouter() const scrollToComments = (event) => { event.preventDefault() - openPage(router, 'article', { slug: slug }) + openPage(router, 'article', { slug }) changeSearchParam('scrollTo', 'comments') } @@ -118,7 +118,7 @@ export const ArticleCard = (props: ArticleCardProps) => {
- + { - -

{t('Nothing here yet')}

- - } - > +

{author.bio}

diff --git a/src/components/Views/Edit.tsx b/src/components/Views/Edit.tsx index bc0fb617..d871fda0 100644 --- a/src/components/Views/Edit.tsx +++ b/src/components/Views/Edit.tsx @@ -12,16 +12,7 @@ import { openPage } from '@nanostores/router' import { translit } from '../../utils/ru2en' import { Editor } from '../Editor/Editor' import { Panel } from '../Editor/Panel' - -type ShoutForm = { - slug: string - title: string - subtitle: string - selectedTopics: Topic[] - mainTopic: string - body: string - coverImageUrl: string -} +import { useEditorContext } from '../../context/editor' type EditViewProps = { shout: Shout @@ -33,9 +24,14 @@ export const EditView = (props: EditViewProps) => { const [topics, setTopics] = createSignal(null) const { page } = useRouter() + const { + form, + actions: { setForm } + } = useEditorContext() + const [isSlugChanged, setIsSlugChanged] = createSignal(false) - const [form, setForm] = createStore({ + setForm({ slug: props.shout.slug, title: props.shout.title, subtitle: props.shout.subtitle, @@ -77,24 +73,6 @@ export const EditView = (props: EditViewProps) => { setForm('slug', slug) } - const handleSaveButtonClick = async (e) => { - e.preventDefault() - - await apiClient.updateArticle({ - slug: props.shout.slug, - article: { - slug: form.slug, - title: form.title, - subtitle: form.subtitle, - body: form.body, - topics: form.selectedTopics.map((topic) => topic.slug), - mainTopic: form.selectedTopics[0].slug - } - }) - - openPage(router, 'drafts') - } - return ( <>
diff --git a/src/context/editor.tsx b/src/context/editor.tsx index 5d8fe5dc..9b3072ff 100644 --- a/src/context/editor.tsx +++ b/src/context/editor.tsx @@ -1,17 +1,31 @@ import type { JSX } from 'solid-js' import { Accessor, createContext, createSignal, useContext } from 'solid-js' +import { createStore, SetStoreFunction } from 'solid-js/store' +import { Topic } from '../graphql/types.gen' type WordCounter = { characters: number words: number } +type ShoutForm = { + slug: string + title: string + subtitle: string + selectedTopics: Topic[] + mainTopic: string + body: string + coverImageUrl: string +} + type EditorContextType = { isEditorPanelVisible: Accessor wordCounter: Accessor + form: ShoutForm actions: { toggleEditorPanel: () => void countWords: (value: WordCounter) => void + setForm: SetStoreFunction } } @@ -23,6 +37,9 @@ export function useEditorContext() { export const EditorProvider = (props: { children: JSX.Element }) => { const [isEditorPanelVisible, setIsEditorPanelVisible] = createSignal(false) + + const [form, setForm] = createStore(null) + const [wordCounter, setWordCounter] = createSignal({ characters: 0, words: 0 @@ -31,10 +48,11 @@ export const EditorProvider = (props: { children: JSX.Element }) => { const countWords = (value) => setWordCounter(value) const actions = { toggleEditorPanel, - countWords + countWords, + setForm } - const value: EditorContextType = { actions, isEditorPanelVisible, wordCounter } + const value: EditorContextType = { actions, form, isEditorPanelVisible, wordCounter } return {props.children} } diff --git a/src/context/snackbar.tsx b/src/context/snackbar.tsx index bb7362a4..57d7de24 100644 --- a/src/context/snackbar.tsx +++ b/src/context/snackbar.tsx @@ -2,7 +2,7 @@ import type { Accessor, JSX } from 'solid-js' import { createContext, createSignal, useContext } from 'solid-js' import { delay } from '../utils/delay' -const DEFAULT_DURATION = 5000 // 5 sec +const DEFAULT_DURATION = 3000 // 3 sec type SnackbarMessage = { type: 'success' | 'error' diff --git a/src/graphql/mutation/article-create.ts b/src/graphql/mutation/article-create.ts index cbc7a890..f38b3240 100644 --- a/src/graphql/mutation/article-create.ts +++ b/src/graphql/mutation/article-create.ts @@ -5,7 +5,7 @@ export default gql` createShout(inp: $shout) { error shout { - _id: slug + id slug title subtitle diff --git a/src/graphql/mutation/auth-confirm-email.ts b/src/graphql/mutation/auth-confirm-email.ts index 0de4a5c7..f2286e3d 100644 --- a/src/graphql/mutation/auth-confirm-email.ts +++ b/src/graphql/mutation/auth-confirm-email.ts @@ -6,7 +6,7 @@ export default gql` error token user { - _id: slug + id email name slug diff --git a/src/graphql/mutation/community-update.ts b/src/graphql/mutation/community-update.ts index 8621613c..a7783faf 100644 --- a/src/graphql/mutation/community-update.ts +++ b/src/graphql/mutation/community-update.ts @@ -3,7 +3,7 @@ import { gql } from '@urql/core' export default gql` mutation CommunityUpdateMutation($community: Community!) { updateCommunity(community: $community) { - _id: slug + id slug desc name diff --git a/src/graphql/mutation/my-session.ts b/src/graphql/mutation/my-session.ts index 0102b07b..d2972be3 100644 --- a/src/graphql/mutation/my-session.ts +++ b/src/graphql/mutation/my-session.ts @@ -6,7 +6,6 @@ export default gql` error token user { - _id: slug id name slug diff --git a/src/graphql/query/article-drafts-load-by.ts b/src/graphql/query/article-drafts-load-by.ts index 6fd57bfc..59610321 100644 --- a/src/graphql/query/article-drafts-load-by.ts +++ b/src/graphql/query/article-drafts-load-by.ts @@ -17,7 +17,6 @@ export default gql` body slug stat { - _id: shouts shouts authors followers diff --git a/src/graphql/query/articles-load-by.ts b/src/graphql/query/articles-load-by.ts index b7929c2c..f7c7b541 100644 --- a/src/graphql/query/articles-load-by.ts +++ b/src/graphql/query/articles-load-by.ts @@ -3,7 +3,6 @@ import { gql } from '@urql/core' export default gql` query LoadShoutsQuery($options: LoadShoutsOptions) { loadShouts(options: $options) { - _id: slug id title subtitle @@ -18,7 +17,6 @@ export default gql` body slug stat { - _id: shouts shouts authors followers @@ -33,7 +31,6 @@ export default gql` createdAt publishedAt stat { - _id: viewed viewed reacted rating diff --git a/src/graphql/query/author-by-slug.ts b/src/graphql/query/author-by-slug.ts index f27a0068..b6537e9d 100644 --- a/src/graphql/query/author-by-slug.ts +++ b/src/graphql/query/author-by-slug.ts @@ -3,7 +3,6 @@ import { gql } from '@urql/core' export default gql` query GetAuthorBySlugQuery($slug: String!) { getAuthor(slug: $slug) { - _id: slug id slug name @@ -15,7 +14,6 @@ export default gql` createdAt lastSeen # ratings { - # _id: rater # rater # value # } diff --git a/src/graphql/query/author-followers.ts b/src/graphql/query/author-followers.ts index 882c5af0..13cf82b0 100644 --- a/src/graphql/query/author-followers.ts +++ b/src/graphql/query/author-followers.ts @@ -3,7 +3,6 @@ import { gql } from '@urql/core' export default gql` query UserSubscribersQuery($slug: String!) { userFollowers(slug: $slug) { - _id: slug id slug name diff --git a/src/graphql/query/author-reacted-shouts.ts b/src/graphql/query/author-reacted-shouts.ts index 825375d3..780e9c3a 100644 --- a/src/graphql/query/author-reacted-shouts.ts +++ b/src/graphql/query/author-reacted-shouts.ts @@ -5,7 +5,6 @@ import { gql } from '@urql/core' export default gql` query ShoutsReactedByUserQuery($slug: String!, $limit: Int!, $offset: Int!) { userReactedShouts(slug: String!, page: Int!, size: Int!) { - _id: slug title subtitle layout @@ -19,7 +18,6 @@ export default gql` body slug stat { - _id: shouts shouts authors followers @@ -34,7 +32,6 @@ export default gql` createdAt publishedAt stat { - _id: viewed viewed reacted rating diff --git a/src/graphql/query/authors-all.ts b/src/graphql/query/authors-all.ts index b5a6e65a..06e9ad75 100644 --- a/src/graphql/query/authors-all.ts +++ b/src/graphql/query/authors-all.ts @@ -3,7 +3,6 @@ import { gql } from '@urql/core' export default gql` query AuthorsAllQuery { authorsAll { - _id: slug id slug name diff --git a/src/graphql/query/authors-load-by.ts b/src/graphql/query/authors-load-by.ts index fdafd924..97cd436d 100644 --- a/src/graphql/query/authors-load-by.ts +++ b/src/graphql/query/authors-load-by.ts @@ -3,7 +3,6 @@ import { gql } from '@urql/core' export default gql` query AuthorLoadByQuery($by: AuthorsBy, $limit: Int, $offset: Int) { loadAuthorsBy(by: $by, limit: $limit, offset: $offset) { - _id: slug id slug name @@ -14,7 +13,6 @@ export default gql` # createdAt lastSeen # ratings { - # _id: rater # rater # value # } diff --git a/src/graphql/query/my-feed.ts b/src/graphql/query/my-feed.ts index dee34894..42463b92 100644 --- a/src/graphql/query/my-feed.ts +++ b/src/graphql/query/my-feed.ts @@ -3,7 +3,6 @@ import { gql } from '@urql/core' export default gql` query MyFeedQuery($options: LoadShoutsOptions) { myFeed(options: $options) { - _id: slug id title subtitle @@ -18,7 +17,6 @@ export default gql` body slug stat { - _id: shouts shouts authors followers @@ -33,7 +31,6 @@ export default gql` createdAt publishedAt stat { - _id: viewed viewed reacted rating diff --git a/src/graphql/query/topic-by-slug.ts b/src/graphql/query/topic-by-slug.ts index 7ed25aa2..7b01a05e 100644 --- a/src/graphql/query/topic-by-slug.ts +++ b/src/graphql/query/topic-by-slug.ts @@ -9,7 +9,6 @@ export default gql` pic # community stat { - _id: shouts shouts authors # viewed diff --git a/src/graphql/query/topics-all.ts b/src/graphql/query/topics-all.ts index e20575f2..d2ab1263 100644 --- a/src/graphql/query/topics-all.ts +++ b/src/graphql/query/topics-all.ts @@ -3,14 +3,12 @@ import { gql } from '@urql/core' export default gql` query TopicsAllQuery { topicsAll { - _id: slug title body slug pic # community stat { - _id: shouts shouts authors followers diff --git a/src/graphql/query/topics-by-author.ts b/src/graphql/query/topics-by-author.ts index eaae45bc..cb842d2a 100644 --- a/src/graphql/query/topics-by-author.ts +++ b/src/graphql/query/topics-by-author.ts @@ -9,7 +9,6 @@ export default gql` pic # community stat { - _id: shouts shouts authors followers diff --git a/src/graphql/query/topics-by-community.ts b/src/graphql/query/topics-by-community.ts index 32213a51..4060aacd 100644 --- a/src/graphql/query/topics-by-community.ts +++ b/src/graphql/query/topics-by-community.ts @@ -9,7 +9,6 @@ export default gql` pic # community stat { - _id: shouts shouts authors followers diff --git a/src/graphql/query/topics-random.ts b/src/graphql/query/topics-random.ts index c84b4360..43deecc4 100644 --- a/src/graphql/query/topics-random.ts +++ b/src/graphql/query/topics-random.ts @@ -3,14 +3,13 @@ import { gql } from '@urql/core' export default gql` query TopicsRandomQuery($amount: Int) { topicsRandom(amount: $amount) { - _id: slug + id title body slug pic # community stat { - _id: shouts shouts authors followers diff --git a/src/pages/author.page.tsx b/src/pages/author.page.tsx index 248cbb51..2a67d931 100644 --- a/src/pages/author.page.tsx +++ b/src/pages/author.page.tsx @@ -28,7 +28,10 @@ export const AuthorPage = (props: PageProps) => { return } - await loadShouts({ filters: { author: slug() }, limit: PRERENDERED_ARTICLES_COUNT }) + await loadShouts({ + filters: { author: slug(), visibility: 'community' }, + limit: PRERENDERED_ARTICLES_COUNT + }) await loadAuthor({ slug: slug() }) setIsLoaded(true)