diff --git a/public/auth-page.jpg b/public/auth-page.jpg deleted file mode 100644 index ab788a9f..00000000 Binary files a/public/auth-page.jpg and /dev/null differ diff --git a/public/bonfire.png b/public/bonfire.png deleted file mode 100644 index 11ee31fa..00000000 Binary files a/public/bonfire.png and /dev/null differ diff --git a/public/discours-banner.jpg b/public/discours-banner.jpg deleted file mode 100644 index 77299720..00000000 Binary files a/public/discours-banner.jpg and /dev/null differ diff --git a/public/fonts/JetBrainsMono-Regular.woff2 b/public/fonts/JetBrainsMono-Regular.woff2 deleted file mode 100644 index fdf95dde..00000000 Binary files a/public/fonts/JetBrainsMono-Regular.woff2 and /dev/null differ diff --git a/public/fonts/Muller-ExtraBold.eot b/public/fonts/Muller-ExtraBold.eot deleted file mode 100644 index fe188a9c..00000000 Binary files a/public/fonts/Muller-ExtraBold.eot and /dev/null differ diff --git a/public/fonts/Muller-MediumItalic.eot b/public/fonts/Muller-MediumItalic.eot deleted file mode 100644 index 986fecb2..00000000 Binary files a/public/fonts/Muller-MediumItalic.eot and /dev/null differ diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index 3e28032d..00000000 --- a/public/manifest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "theme_color": "#111111", - "background_color": "#ffffff", - "display": "standalone", - "scope": "/", - "start_url": "/", - "name": "discours.io", - "short_name": "discours.io", - "description": "Дискурс - коллаборативная журналистика", - "icons": [ - { - "src": "/favicon.png", - "sizes": "200x200", - "type": "image/png", - "purpose": "any maskable" - } - ] -} diff --git a/src/components/Article/AudioHeader/AudioHeader.tsx b/src/components/Article/AudioHeader/AudioHeader.tsx index af1541a0..5b2ffb77 100644 --- a/src/components/Article/AudioHeader/AudioHeader.tsx +++ b/src/components/Article/AudioHeader/AudioHeader.tsx @@ -21,7 +21,7 @@ export const AudioHeader = (props: Props) => { return (
- {props.title} + {props.title}
diff --git a/src/components/Editor/SimplifiedEditor.tsx b/src/components/Editor/SimplifiedEditor.tsx index 786e7eb4..a0448215 100644 --- a/src/components/Editor/SimplifiedEditor.tsx +++ b/src/components/Editor/SimplifiedEditor.tsx @@ -27,6 +27,7 @@ import { hideModal, showModal } from '../../stores/ui' import { Button } from '../_shared/Button' import { Icon } from '../_shared/Icon' import { Popover } from '../_shared/Popover' +import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient' import { Modal } from '../Nav/Modal' import { Figcaption } from './extensions/Figcaption' @@ -59,13 +60,16 @@ type Props = { isCancelButtonVisible?: boolean } -export const MAX_DESCRIPTION_LIMIT = 400 +const DEFAULT_MAX_LENGTH = 400 const SimplifiedEditor = (props: Props) => { const { t } = useLocalize() const [counter, setCounter] = createSignal() const [shouldShowLinkBubbleMenu, setShouldShowLinkBubbleMenu] = createSignal(false) const isCancelButtonVisible = createMemo(() => props.isCancelButtonVisible !== false) + + const maxLength = props.maxLength ?? DEFAULT_MAX_LENGTH + const wrapperEditorElRef: { current: HTMLElement } = { @@ -116,9 +120,8 @@ const SimplifiedEditor = (props: Props) => { Link.configure({ openOnClick: false, }), - CharacterCount.configure({ - limit: MAX_DESCRIPTION_LIMIT, + limit: maxLength, }), Blockquote.configure({ HTMLAttributes: { @@ -262,132 +265,134 @@ const SimplifiedEditor = (props: Props) => { setShouldShowLinkBubbleMenu(true) } return ( -
(wrapperEditorElRef.current = el)} - class={clsx(styles.SimplifiedEditor, { - [styles.smallHeight]: props.smallHeight, - [styles.minimal]: props.variant === 'minimal', - [styles.bordered]: props.variant === 'bordered', - [styles.isFocused]: isFocused() || !isEmpty(), - [styles.labelVisible]: props.label && counter() > 0, - })} - > - -
{MAX_DESCRIPTION_LIMIT - counter()}
-
- 0}> -
{props.label}
-
-
(editorElRef.current = el)} /> - -
-
- - {(triggerRef: (el) => void) => ( - - )} - - - {(triggerRef: (el) => void) => ( - - )} - - - {(triggerRef: (el) => void) => ( - - )} - - - + +
(wrapperEditorElRef.current = el)} + class={clsx(styles.SimplifiedEditor, { + [styles.smallHeight]: props.smallHeight, + [styles.minimal]: props.variant === 'minimal', + [styles.bordered]: props.variant === 'bordered', + [styles.isFocused]: isFocused() || !isEmpty(), + [styles.labelVisible]: props.label && counter() > 0, + })} + > + +
{maxLength - counter()}
+
+ 0}> +
{props.label}
+
+
(editorElRef.current = el)} /> + +
+
+ {(triggerRef: (el) => void) => ( )} - - - - {(triggerRef: (el) => void) => ( + + {(triggerRef) => ( )} + + {(triggerRef) => ( + + )} + + + + {(triggerRef) => ( + + )} + + + + + {(triggerRef) => ( + + )} + + +
+ +
+ +
- -
- -
-
-
- - - - - { - renderImage(value) - }} - /> - - - - - + + + + (textBubbleMenuRef.current = el)} + /> + + (textBubbleMenuRef.current = el)} + ref={(el) => (linkBubbleMenuRef.current = el)} + onClose={() => setShouldShowLinkBubbleMenu(false)} /> - - (linkBubbleMenuRef.current = el)} - onClose={() => setShouldShowLinkBubbleMenu(false)} - /> -
+
+ ) } diff --git a/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx b/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx index 246bc944..d30c5cb6 100644 --- a/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx +++ b/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx @@ -1,17 +1,18 @@ import type { Editor } from '@tiptap/core' import { clsx } from 'clsx' -import { Switch, Match, createSignal, Show, onMount, onCleanup, createEffect } from 'solid-js' +import { Switch, Match, createSignal, Show, onMount, onCleanup, createEffect, lazy } from 'solid-js' import { createEditorTransaction } from 'solid-tiptap' import { useLocalize } from '../../../context/localize' import { Icon } from '../../_shared/Icon' import { Popover } from '../../_shared/Popover' import { InsertLinkForm } from '../InsertLinkForm' -import SimplifiedEditor from '../SimplifiedEditor' import styles from './TextBubbleMenu.module.scss' +const SimplifiedEditor = lazy(() => import('../../Editor/SimplifiedEditor')) + type BubbleMenuProps = { editor: Editor isCommonMarkup: boolean diff --git a/src/components/Feed/ArticleCard/ArticleCard.module.scss b/src/components/Feed/ArticleCard/ArticleCard.module.scss index 932881ee..fba766f7 100644 --- a/src/components/Feed/ArticleCard/ArticleCard.module.scss +++ b/src/components/Feed/ArticleCard/ArticleCard.module.scss @@ -94,7 +94,6 @@ } .shoutCardCover { - background: rgb(0 0 0 / 30%); height: 0; margin-bottom: 1.6rem; overflow: hidden; @@ -103,6 +102,10 @@ transform-origin: 50% 50%; transition: transform 1s ease-in-out; + &.loading { + background: rgb(0 0 0 / 20%); + } + img { height: 100%; object-fit: cover; @@ -825,3 +828,7 @@ .shoutTopicTop { margin-bottom: 0.4rem !important; } + +.placeholderCoverImage { + position: absolute; +} diff --git a/src/components/Feed/ArticleCard/ArticleCard.tsx b/src/components/Feed/ArticleCard/ArticleCard.tsx index 1c3be9ff..116e73d4 100644 --- a/src/components/Feed/ArticleCard/ArticleCard.tsx +++ b/src/components/Feed/ArticleCard/ArticleCard.tsx @@ -12,6 +12,7 @@ import { getDescription } from '../../../utils/meta' import { Icon } from '../../_shared/Icon' import { Image } from '../../_shared/Image' import { Popover } from '../../_shared/Popover' +import { CoverImage } from '../../Article/CoverImage' import { getShareUrl, SharePopup } from '../../Article/SharePopup' import { ShoutRatingControl } from '../../Article/ShoutRatingControl' import { AuthorLink } from '../../Author/AhtorLink' @@ -21,7 +22,8 @@ import { FeedArticlePopup } from '../FeedArticlePopup' import styles from './ArticleCard.module.scss' import stylesHeader from '../../Nav/Header/Header.module.scss' -interface ArticleCardProps { +export type ArticleCardProps = { + // TODO: refactor this, please settings?: { noicon?: boolean noimage?: boolean @@ -44,9 +46,17 @@ interface ArticleCardProps { withViewed?: boolean noAuthorLink?: boolean } + desktopCoverSize: 'XS' | 'S' | 'M' | 'L' article: Shout } +const desktopCoverImageWidths: Record = { + XS: 300, + S: 400, + M: 600, + L: 800, +} + const getTitleAndSubtitle = ( article: Shout, ): { @@ -98,11 +108,12 @@ export const ArticleCard = (props: ArticleCardProps) => { } const [isActionPopupActive, setIsActionPopupActive] = createSignal(false) + const [isCoverImageLoadError, setIsCoverImageLoadError] = createSignal(false) + const [isCoverImageLoading, setIsCoverImageLoading] = createSignal(true) return (
{ [styles.shoutCardSingle]: props.settings?.isSingle, [styles.shoutCardBeside]: props.settings?.isBeside, [styles.shoutCardNoImage]: !props.article.cover, - }} + })} >
-
- - {title} +
+ } + > + {title} { + setIsCoverImageLoadError(true) + setIsCoverImageLoading(false) + }} + onLoad={() => setIsCoverImageLoading(false)} + />
@@ -214,7 +241,7 @@ export const ArticleCard = (props: ArticleCardProps) => {
- {title} + {title}
diff --git a/src/components/Feed/Beside.tsx b/src/components/Feed/Beside.tsx index 0c2fea53..373254fa 100644 --- a/src/components/Feed/Beside.tsx +++ b/src/components/Feed/Beside.tsx @@ -85,12 +85,14 @@ export const Beside = (props: Props) => { @@ -103,6 +105,7 @@ export const Beside = (props: Props) => {
diff --git a/src/components/Feed/Group.tsx b/src/components/Feed/Group.tsx index 6f67cfa4..0dd448ef 100644 --- a/src/components/Feed/Group.tsx +++ b/src/components/Feed/Group.tsx @@ -30,6 +30,7 @@ export default (props: GroupProps) => { isBigTitle: true, nodate: true, }} + desktopCoverSize="M" /> @@ -43,6 +44,7 @@ export default (props: GroupProps) => { @@ -63,6 +65,7 @@ export default (props: GroupProps) => { isFloorImportant: true, nodate: true, }} + desktopCoverSize="XS" /> )} @@ -80,6 +83,7 @@ export default (props: GroupProps) => { isFloorImportant: true, nodate: true, }} + desktopCoverSize="XS" /> )} diff --git a/src/components/Feed/Row1.tsx b/src/components/Feed/Row1.tsx index e57031bf..312bc9b6 100644 --- a/src/components/Feed/Row1.tsx +++ b/src/components/Feed/Row1.tsx @@ -23,6 +23,7 @@ export const Row1 = (props: { noAuthorLink: props.noAuthorLink, noauthor: props.noauthor, }} + desktopCoverSize="L" /> diff --git a/src/components/Feed/Row2.tsx b/src/components/Feed/Row2.tsx index 68120cba..ea68d93b 100644 --- a/src/components/Feed/Row2.tsx +++ b/src/components/Feed/Row2.tsx @@ -3,6 +3,7 @@ import type { Shout } from '../../graphql/types.gen' import { createComputed, createSignal, Show, For } from 'solid-js' import { ArticleCard } from './ArticleCard' +import { ArticleCardProps } from './ArticleCard/ArticleCard' const x = [ ['12', '12'], @@ -19,6 +20,7 @@ export const Row2 = (props: { }) => { const [y, setY] = createSignal(0) + // FIXME: random can break hydration createComputed(() => setY(Math.floor(Math.random() * x.length))) return ( @@ -28,20 +30,37 @@ export const Row2 = (props: {
{(a, i) => { + // FIXME: refactor this, too ugly now + const className = `col-md-${props.isEqual ? '12' : x[y()][i()]}` + let desktopCoverSize: ArticleCardProps['desktopCoverSize'] + + switch (className) { + case 'col-md-8': { + desktopCoverSize = 'S' + break + } + case 'col-md-12': { + desktopCoverSize = 'M' + break + } + default: { + desktopCoverSize = 'L' + } + } + return ( - -
- -
-
+
+ +
) }}
diff --git a/src/components/Feed/Row3.tsx b/src/components/Feed/Row3.tsx index 6accc8b5..e4896b92 100644 --- a/src/components/Feed/Row3.tsx +++ b/src/components/Feed/Row3.tsx @@ -28,6 +28,7 @@ export const Row3 = (props: { noAuthorLink: props.noAuthorLink, noauthor: props.noauthor, }} + desktopCoverSize="S" />
)} diff --git a/src/components/Feed/Row5.tsx b/src/components/Feed/Row5.tsx index eb564fc5..045790a1 100644 --- a/src/components/Feed/Row5.tsx +++ b/src/components/Feed/Row5.tsx @@ -8,23 +8,34 @@ export const Row5 = (props: { articles: Shout[]; nodate?: boolean }) => {
- +
- +
diff --git a/src/components/Feed/RowShort.tsx b/src/components/Feed/RowShort.tsx index 2fb773e2..c8eeec51 100644 --- a/src/components/Feed/RowShort.tsx +++ b/src/components/Feed/RowShort.tsx @@ -20,6 +20,7 @@ export default (props: { articles: Shout[] }) => ( isVertical: true, nodate: true, }} + desktopCoverSize="S" />
)} diff --git a/src/components/Nav/AuthModal/AuthModal.module.scss b/src/components/Nav/AuthModal/AuthModal.module.scss index 2ecb2c76..e596c41f 100644 --- a/src/components/Nav/AuthModal/AuthModal.module.scss +++ b/src/components/Nav/AuthModal/AuthModal.module.scss @@ -40,7 +40,8 @@ .authImage { @include font-size(1.5rem); - background: var(--background-color-invert) url('/auth-page.jpg') center no-repeat; + background: var(--background-color-invert) + url('https://images.discours.io/unsafe/1600x/production/image/auth-page.jpg') center no-repeat; background-size: cover; color: var(--default-color-invert); display: flex; diff --git a/src/components/Views/Edit.tsx b/src/components/Views/Edit.tsx index 501c5c06..5c497d13 100644 --- a/src/components/Views/Edit.tsx +++ b/src/components/Views/Edit.tsx @@ -2,7 +2,7 @@ import type { Shout, Topic } from '../../graphql/types.gen' import { clsx } from 'clsx' import deepEqual from 'fast-deep-equal' -import { Accessor, createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' +import { Accessor, createMemo, createSignal, lazy, onCleanup, onMount, Show } from 'solid-js' import { createStore } from 'solid-js/store' import { ShoutForm, useEditorContext } from '../../context/editor' @@ -14,14 +14,12 @@ import { getImageUrl } from '../../utils/getImageUrl' import { isDesktop } from '../../utils/media-query' import { slugify } from '../../utils/slugify' import { DropArea } from '../_shared/DropArea' -import { GrowingTextarea } from '../_shared/GrowingTextarea' import { Icon } from '../_shared/Icon' import { Popover } from '../_shared/Popover' import { ImageSwiper } from '../_shared/SolidSwiper' import { Editor, Panel } from '../Editor' import { AudioUploader } from '../Editor/AudioUploader' import { AutoSaveNotice } from '../Editor/AutoSaveNotice' -import SimplifiedEditor from '../Editor/SimplifiedEditor' import { VideoUploader } from '../Editor/VideoUploader' import { TableOfContents } from '../TableOfContents' @@ -29,6 +27,9 @@ import { PublishSettings } from './PublishSettings' import styles from './Edit.module.scss' +const SimplifiedEditor = lazy(() => import('../Editor/SimplifiedEditor')) +const GrowingTextarea = lazy(() => import('../_shared/GrowingTextarea/GrowingTextarea')) + type Props = { shout: Shout } diff --git a/src/components/Views/Expo/Expo.tsx b/src/components/Views/Expo/Expo.tsx index e230f611..51c9a6bb 100644 --- a/src/components/Views/Expo/Expo.tsx +++ b/src/components/Views/Expo/Expo.tsx @@ -145,6 +145,7 @@ export const Expo = (props: Props) => { )} @@ -157,6 +158,7 @@ export const Expo = (props: Props) => { )} diff --git a/src/components/Views/Feed.module.scss b/src/components/Views/Feed.module.scss index 7fa3da81..87fc5f6e 100644 --- a/src/components/Views/Feed.module.scss +++ b/src/components/Views/Feed.module.scss @@ -9,6 +9,7 @@ .feedNavigation { @include font-size(1.4rem); + font-weight: 500; h4 { diff --git a/src/components/Views/Feed.tsx b/src/components/Views/Feed.tsx index e554c743..f4672681 100644 --- a/src/components/Views/Feed.tsx +++ b/src/components/Views/Feed.tsx @@ -41,7 +41,10 @@ const getOrderBy = (by: FeedSearchParams['by']) => { } type Props = { - loadShouts: (options: LoadShoutsOptions) => Promise<{ hasMore: boolean; newShouts: Shout[] }> + loadShouts: (options: LoadShoutsOptions) => Promise<{ + hasMore: boolean + newShouts: Shout[] + }> } export const FeedView = (props: Props) => { @@ -148,7 +151,9 @@ export const FeedView = (props: Props) => { }> 0}> - {(article) => } + {(article) => ( + + )}
@@ -172,7 +177,9 @@ export const FeedView = (props: Props) => {
- {(article) => } + {(article) => ( + + )}
diff --git a/src/components/Views/Home.tsx b/src/components/Views/Home.tsx index 93765fdc..952bf1da 100644 --- a/src/components/Views/Home.tsx +++ b/src/components/Views/Home.tsx @@ -105,11 +105,8 @@ export const HomeView = (props: Props) => { return ( 0}> - - - PRERENDERED_ARTICLES_COUNT}> { - {(page) => ( <> @@ -183,7 +179,6 @@ export const HomeView = (props: Props) => { )} -