From 75c3d5faea73af0469ae11dd0629aaad2295930c Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Fri, 16 Jun 2023 16:47:24 +0200 Subject: [PATCH] expo pages (#111) * layout pages * lint * code review, lint, build fix * lint --- public/locales/en/translation.json | 24 +- public/locales/ru/translation.json | 28 +-- src/components/Article/Article.module.scss | 2 + src/components/Article/Comment.module.scss | 3 +- src/components/Article/Comment.tsx | 4 - .../Article/CommentDate.module.scss | 3 +- src/components/Article/CommentDate.tsx | 13 +- src/components/Author/AuthorCard.tsx | 1 - src/components/Discours/Footer.module.scss | 1 + src/components/Discours/Subscribe.module.scss | 6 +- .../BubbleMenu/BlockquoteBubbleMenu.tsx | 1 - .../Editor/BubbleMenu/BubbleMenu.module.scss | 7 +- .../Editor/BubbleMenu/FigureBubbleMenu.tsx | 1 - src/components/Editor/Panel/Panel.module.scss | 2 +- src/components/Editor/Prosemirror.scss | 9 +- .../VideoUploader/VideoUploader.module.scss | 2 +- .../Editor/extensions/CustomBlockquote.ts | 1 - src/components/Feed/ArticleCard.module.scss | 22 +- src/components/Feed/Beside.module.scss | 4 +- .../Feed/Sidebar/Sidebar.module.scss | 2 + .../Nav/AuthModal/AuthModal.module.scss | 5 +- .../Nav/AuthModal/SocialProviders.module.scss | 1 + src/components/Nav/Topics.scss | 1 + src/components/Topic/Card.module.scss | 4 + src/components/Topic/Full.module.scss | 3 +- src/components/Views/Edit.tsx | 2 +- src/components/Views/Feed.module.scss | 12 +- .../DarkModeToggle/DarkModeToggle.module.scss | 6 +- .../_shared/DarkModeToggle/DarkModeToggle.tsx | 2 +- .../GrowingTextarea.module.scss | 2 +- src/components/_shared/Stat.module.scss | 1 + .../VideoPlayer/VideoPlayer.module.scss | 1 + src/context/session.tsx | 12 +- src/pages/edit.page.tsx | 2 +- src/pages/layoutShouts.page.server.ts | 3 +- src/pages/layoutShouts.page.tsx | 224 ++++++++++-------- src/pages/types.ts | 5 +- src/stores/zine/layouts.ts | 48 ---- src/styles/AllTopics.module.scss | 5 +- src/styles/app.scss | 3 + 40 files changed, 249 insertions(+), 229 deletions(-) delete mode 100644 src/stores/zine/layouts.ts diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index b4743edd..4aa8a024 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -56,11 +56,11 @@ "Create Chat": "Create Chat", "Create Group": "Create a group", "Create account": "Create an account", - "Create account from subscribe": "Create an account to subscribe to new publications", - "Create account from discussions": "Create an account to participate in discussions", - "Create account from vote": "Create an account to vote", "Create account from bookmark": "Create an account to add to your bookmarks", + "Create account from discussions": "Create an account to participate in discussions", "Create account from follow": "Create an account to subscribe", + "Create account from subscribe": "Create an account to subscribe to new publications", + "Create account from vote": "Create an account to vote", "Create post": "Create post", "Date of Birth": "Date of Birth", "Delete": "Delete", @@ -69,6 +69,7 @@ "Discours is created with our common effort": "Discours exists because of our common effort", "Discussing": "Discussing", "Discussion rules": "Discussion rules", + "Discussions": "Discussions", "Dogma": "Dogma", "Drafts": "Drafts", "Drag the image to this area": "Drag the image to this area", @@ -79,11 +80,11 @@ "Enter URL address": "Enter URL address", "Enter text": "Enter text", "Enter the Discours": "Enter the Discours", - "Enter the Discours from subscribe": "Sign in to subscribe to new publications", - "Enter the Discours from discussions": "Sign in to participate in the discussions", - "Enter the Discours from vote": "Sign in to vote", "Enter the Discours from bookmark": "Sign in to add to bookmarks", + "Enter the Discours from discussions": "Sign in to participate in the discussions", "Enter the Discours from follow": "Sign in to follow", + "Enter the Discours from subscribe": "Sign in to subscribe to new publications", + "Enter the Discours from vote": "Sign in to vote", "Enter the code or click the link from email to confirm": "Enter the code from the email or follow the link in the email to confirm registration", "Enter your new password": "Enter your new password", "Error": "Error", @@ -115,6 +116,7 @@ "Highlight": "Highlight", "Hooray! Welcome!": "Hooray! Welcome!", "Horizontal collaborative journalistic platform": "Horizontal collaborative journalism platform", + "Hot topics": "Hot topics", "Hotkeys": "Горячие клавиши", "How can I help/skills": "How can I help/skills", "How it works": "How it works", @@ -127,6 +129,7 @@ "Incut": "Incut", "Independant magazine with an open horizontal cooperation about culture, science and society": "Independant magazine with an open horizontal cooperation about culture, science and society", "Insert footnote": "Insert footnote", + "Insert video link": "Insert video link", "Introduce": "Introduction", "Invalid email": "Check if your email is correct", "Invalid image URL": "Invalid image URL", @@ -149,6 +152,7 @@ "Load more": "Show more", "Loading": "Loading", "Logout": "Logout", + "Looks like you forgot to upload the video": "Looks like you forgot to upload the video", "Manifest": "Manifest", "Many files, choose only one": "Many files, choose only one", "Material card": "Material card", @@ -165,6 +169,7 @@ "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", "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", @@ -256,7 +261,6 @@ "Top viewed": "Most viewed", "Topic is supported by": "Topic is supported by", "Topics": "Topics", - "Hot topics": "Hot topics", "Topics which supported by author": "Topics which supported by author", "Try to find another way": "Try to find another way", "Unfollow": "Unfollow", @@ -305,7 +309,6 @@ "community": "community", "delimiter": "delimiter", "discussion": "discourse", - "Discussions": "Discussions", "drafts": "drafts", "email not confirmed": "email not confirmed", "enter": "enter", @@ -322,7 +325,6 @@ "marker list": "marker list", "music": "music", "my feed": "my ribbon", - "Notifications": "Notifications", "number list": "number list", "personal data usage and email notifications": "to process personal data and receive email notifications", "post": "post", @@ -336,7 +338,5 @@ "user already exist": "user already exists", "video": "video", "view": "view", - "zine": "zine", - "Insert video link": "Insert video link", - "Looks like you forgot to upload the video": "Looks like you forgot to upload the video" + "zine": "zine" } diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index c17a94f1..b153ab42 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -3,6 +3,7 @@ "A short introduction to keep the reader interested": "Небольшое вступление, чтобы заинтересовать читателя", "About myself": "О себе", "About the project": "О проекте", + "Accomplices": "Соучастники", "Add another image": "Добавить другое изображение", "Add comment": "Комментировать", "Add image": "Добавить изображение", @@ -58,11 +59,11 @@ "Create Chat": "Создать чат", "Create Group": "Создать группу", "Create account": "Создать аккаунт", - "Create account from subscribe": "Создайте аккаунт для подписки на новые публикации", - "Create account from discussions": "Создайте аккаунт для участия в дискуссиях", - "Create account from vote": "Создайте аккаунт, чтобы голосовать", "Create account from bookmark": "Создайте аккаунт, чтобы добавить в закладки", + "Create account from discussions": "Создайте аккаунт для участия в дискуссиях", "Create account from follow": "Создайте аккаунт, чтобы подписаться", + "Create account from subscribe": "Создайте аккаунт для подписки на новые публикации", + "Create account from vote": "Создайте аккаунт, чтобы голосовать", "Create post": "Создать публикацию", "Date of Birth": "Дата рождения", "Delete": "Удалить", @@ -71,6 +72,7 @@ "Discours is created with our common effort": "Дискурс существует благодаря нашему общему вкладу", "Discussing": "Обсуждаемое", "Discussion rules": "Правила сообществ самиздата в соцсетях", + "Discussions": "Дискуссии", "Dogma": "Догма", "Drafts": "Черновики", "Drag the image to this area": "Перетащите изображение в эту область", @@ -82,11 +84,11 @@ "Enter URL address": "Введите адрес ссылки", "Enter text": "Введите текст", "Enter the Discours": "Войти в Дискурс", - "Enter the Discours from subscribe": "Войдите для подписки на новые публикации", - "Enter the Discours from discussions": "Войдите для участия в дискуссиях", - "Enter the Discours from vote": "Войдите, чтобы голосовать", "Enter the Discours from bookmark": "Войдите, чтобы добавить в закладки", + "Enter the Discours from discussions": "Войдите для участия в дискуссиях", "Enter the Discours from follow": "Войдите, чтобы подписаться", + "Enter the Discours from subscribe": "Войдите для подписки на новые публикации", + "Enter the Discours from vote": "Войдите, чтобы голосовать", "Enter the code or click the link from email to confirm": "Введите код из письма или пройдите по ссылке в письме для подтверждения регистрации", "Enter your new password": "Введите новый пароль", "Error": "Ошибка", @@ -120,6 +122,7 @@ "Highlight": "Подсветка", "Hooray! Welcome!": "Ура! Добро пожаловать!", "Horizontal collaborative journalistic platform": "Горизонтальная платформа для коллаборативной журналистики", + "Hot topics": "Горячие темы", "Hotkeys": "Горячие клавиши", "How can I help/skills": "Чем могу помочь/навыки", "How it works": "Как это работает", @@ -132,6 +135,7 @@ "Incut": "Подверстка", "Independant magazine with an open horizontal cooperation about culture, science and society": "Независимый журнал с открытой горизонтальной редакцией о культуре, науке и обществе", "Insert footnote": "Вставить сноску", + "Insert video link": "Вставить ссылку на видео", "Introduce": "Представление", "Invalid email": "Проверьте правильность ввода почты", "Invalid image URL": "Некорректная ссылка на изображение", @@ -156,6 +160,7 @@ "Load more": "Показать ещё", "Loading": "Загрузка", "Logout": "Выход", + "Looks like you forgot to upload the video": "Похоже, что вы забыли загрузить видео", "Manifest": "Манифест", "Many files, choose only one": "Много файлов, выберете один", "Material card": "Карточка материала", @@ -172,6 +177,7 @@ "No such account, please try to register": "Такой адрес не найден, попробуйте зарегистрироваться", "Nothing here yet": "Здесь пока ничего нет", "Nothing is here": "Здесь ничего нет", + "Notifications": "Уведомления", "Or continue with social network": "Или войдите через соцсеть", "Or paste a link to an image": "Или вставьте ссылку на изображение", "Ordered list": "Нумерованный список", @@ -255,7 +261,7 @@ "Thank you": "Благодарности", "This comment has not yet been rated": "Этот комментарий еще пока никто не оценил", "This email is already taken. If it's you": "Такой email уже зарегистрирован. Если это вы", - "This functionality is currently not available, we would like to work on this issue. Use the download link.": "В данный момент этот функционал не доступен, бы работаем над этой проблемой. Воспользуйтесь загрузкой по ссылке.", + "This functionality is currently not available, we would like to work on this issue. Use the download link.": "В данный момент этот функционал недоступен, мы работаем над этой проблемой. Воспользуйтесь загрузкой по ссылке.", "This post has not been rated yet": "Эту публикацию еще пока никто не оценил", "To leave a comment please": "Чтобы оставить комментарий, необходимо", "To write a comment, you must": "Чтобы написать комментарий, необходимо", @@ -269,7 +275,6 @@ "Top viewed": "Самое читаемое", "Topic is supported by": "Тему поддерживают", "Topics": "Темы", - "Hot topics": "Горячие темы", "Topics which supported by author": "Автор поддерживает темы", "Try to find another way": "Попробуйте найти по-другому", "Unfollow": "Отписаться", @@ -304,7 +309,6 @@ "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.": "Ваше имя появится на странице вашего профиля и как ваша подпись в публикациях, комментариях и откликах", - "Accomplices": "Соучастники", "actions": "действия", "add link": "добавить ссылку", "all topics": "все темы", @@ -323,7 +327,6 @@ "delimiter": "разделитель", "discourse_theme": "Тема дискурса", "discussion": "дискурс", - "Discussions": "Дискуссии", "drafts": "черновики", "email not confirmed": "email не подтвержден", "enter": "войдите", @@ -340,7 +343,6 @@ "marker list": "маркир. список", "music": "музыка", "my feed": "моя лента", - "Notifications": "Уведомления", "number list": "нумер. список", "or": "или", "personal data usage and email notifications": "на обработку персональных данных и на получение почтовых уведомлений", @@ -358,7 +360,5 @@ "user already exist": "пользователь уже существует", "video": "видео", "view": "просмотр", - "zine": "журнал", - "Insert video link": "Вставить ссылку на видео", - "Looks like you forgot to upload the video": "Похоже, что вы забыли загрузить видео" + "zine": "журнал" } diff --git a/src/components/Article/Article.module.scss b/src/components/Article/Article.module.scss index c0cbb7ed..b54d2b7f 100644 --- a/src/components/Article/Article.module.scss +++ b/src/components/Article/Article.module.scss @@ -1,5 +1,6 @@ h1 { @include font-size(4rem); + line-height: 1.1; margin-top: 0.5em; } @@ -154,6 +155,7 @@ img { .shoutStatsItem { @include font-size(1.5rem); + font-weight: 500; display: inline-block; margin: 0 6% 1em 0; diff --git a/src/components/Article/Comment.module.scss b/src/components/Article/Comment.module.scss index 5f5c2fe3..30706155 100644 --- a/src/components/Article/Comment.module.scss +++ b/src/components/Article/Comment.module.scss @@ -170,8 +170,9 @@ } .articleLink { - flex: 0 0 50%; @include font-size(1.2rem); + + flex: 0 0 50%; margin-right: 2em; @include media-breakpoint-down(md) { diff --git a/src/components/Article/Comment.tsx b/src/components/Article/Comment.tsx index 1f6e2197..51aa7203 100644 --- a/src/components/Article/Comment.tsx +++ b/src/components/Article/Comment.tsx @@ -5,7 +5,6 @@ import { Show, createMemo, createSignal, For, lazy, Suspense } from 'solid-js' import { clsx } from 'clsx' import type { Author, Reaction } from '../../graphql/types.gen' import MD from './MD' -import { formatDate } from '../../utils' import Userpic from '../Author/Userpic' import { useSession } from '../../context/session' import { ReactionKind } from '../../graphql/types.gen' @@ -78,9 +77,6 @@ export const Comment = (props: Props) => { } } - const formattedDate = (date) => - createMemo(() => formatDate(new Date(date), { hour: 'numeric', minute: 'numeric' })) - const toggleEditMode = () => { setEditMode((oldEditMode) => !oldEditMode) } diff --git a/src/components/Article/CommentDate.module.scss b/src/components/Article/CommentDate.module.scss index e827bdb9..65f3983e 100644 --- a/src/components/Article/CommentDate.module.scss +++ b/src/components/Article/CommentDate.module.scss @@ -1,4 +1,6 @@ .commentDates { + @include font-size(1.2rem); + flex: 1; display: flex; gap: 1rem; @@ -7,7 +9,6 @@ font-size: 1.2rem; margin: 0 1em 4px 0; color: rgb(0 0 0 / 30%); - @include font-size(1.2rem); .date { .icon { diff --git a/src/components/Article/CommentDate.tsx b/src/components/Article/CommentDate.tsx index 5054b703..c0dc67f4 100644 --- a/src/components/Article/CommentDate.tsx +++ b/src/components/Article/CommentDate.tsx @@ -1,6 +1,6 @@ import styles from './CommentDate.module.scss' import { Icon } from '../_shared/Icon' -import { Show, createMemo } from 'solid-js' +import { Show } from 'solid-js' import type { Reaction } from '../../graphql/types.gen' import { formatDate } from '../../utils' import { useLocalize } from '../../context/localize' @@ -15,10 +15,13 @@ type Props = { export const CommentDate = (props: Props) => { const { t } = useLocalize() - const formattedDate = (date) => - props.isShort - ? formatDate(new Date(date), { month: 'long', day: 'numeric', year: 'numeric' }) - : createMemo(() => formatDate(new Date(date), { hour: 'numeric', minute: 'numeric' })) + const formattedDate = (date) => { + const formatDateOptions: Intl.DateTimeFormatOptions = props.isShort + ? { month: 'long', day: 'numeric', year: 'numeric' } + : { hour: 'numeric', minute: 'numeric' } + + return formatDate(new Date(date), formatDateOptions) + } return (
diff --git a/src/components/Author/AuthorCard.tsx b/src/components/Author/AuthorCard.tsx index 6db661a5..98e8e807 100644 --- a/src/components/Author/AuthorCard.tsx +++ b/src/components/Author/AuthorCard.tsx @@ -13,7 +13,6 @@ import { FollowingEntity } from '../../graphql/types.gen' import { router, useRouter } from '../../stores/router' import { openPage } from '@nanostores/router' import { useLocalize } from '../../context/localize' -import { init } from 'i18next' interface AuthorCardProps { caption?: string diff --git a/src/components/Discours/Footer.module.scss b/src/components/Discours/Footer.module.scss index bb82ad84..6ed33046 100644 --- a/src/components/Discours/Footer.module.scss +++ b/src/components/Discours/Footer.module.scss @@ -1,5 +1,6 @@ .discoursFooter { @include font-size(1.7rem); + background: #000; color: rgb(255 255 255 / 64%); padding: 2.4rem 0 4.2rem; diff --git a/src/components/Discours/Subscribe.module.scss b/src/components/Discours/Subscribe.module.scss index dbdf22f5..a6424f38 100644 --- a/src/components/Discours/Subscribe.module.scss +++ b/src/components/Discours/Subscribe.module.scss @@ -1,10 +1,10 @@ @mixin input-placeholder-overflow($direction: 'down') { @if $direction == 'down' { - @media (max-width: 1410px) { + @media (width <= 1410px) { @content; } } @else if $direction == 'up' { - @media (min-width: 1411px) { + @media (width > 1410px) { @content; } } @else { @@ -38,7 +38,7 @@ margin: 0; overflow: hidden; text-overflow: ellipsis; - padding: 0.2em 0.5em 0.2em 0.5em; + padding: 0.2em 0.5em; width: 100%; outline: none; border: 1px solid #fff; diff --git a/src/components/Editor/BubbleMenu/BlockquoteBubbleMenu.tsx b/src/components/Editor/BubbleMenu/BlockquoteBubbleMenu.tsx index e92445fb..d1cbf278 100644 --- a/src/components/Editor/BubbleMenu/BlockquoteBubbleMenu.tsx +++ b/src/components/Editor/BubbleMenu/BlockquoteBubbleMenu.tsx @@ -1,6 +1,5 @@ import type { Editor } from '@tiptap/core' import styles from './BubbleMenu.module.scss' -import { clsx } from 'clsx' import { Icon } from '../../_shared/Icon' import { useLocalize } from '../../../context/localize' import { Popover } from '../../_shared/Popover' diff --git a/src/components/Editor/BubbleMenu/BubbleMenu.module.scss b/src/components/Editor/BubbleMenu/BubbleMenu.module.scss index 0d90afad..26bda730 100644 --- a/src/components/Editor/BubbleMenu/BubbleMenu.module.scss +++ b/src/components/Editor/BubbleMenu/BubbleMenu.module.scss @@ -73,22 +73,23 @@ &.yellow { background: #f6e3a1; } + &.white { background: #fff; box-shadow: inset 0 0 0 1px #000; border-color: #fff; } - &.yellow { - background: #f6e3a1; - } + &.pink { background: #f1b5bc; } + &.green { background: #bfe9cb; box-shadow: inset 0 0 0 1px #000; border-color: #fff; } + &.black { background: #000; } diff --git a/src/components/Editor/BubbleMenu/FigureBubbleMenu.tsx b/src/components/Editor/BubbleMenu/FigureBubbleMenu.tsx index 7f32c17d..9ba4f6ec 100644 --- a/src/components/Editor/BubbleMenu/FigureBubbleMenu.tsx +++ b/src/components/Editor/BubbleMenu/FigureBubbleMenu.tsx @@ -1,6 +1,5 @@ import type { Editor } from '@tiptap/core' import styles from './BubbleMenu.module.scss' -import { clsx } from 'clsx' import { Icon } from '../../_shared/Icon' import { useLocalize } from '../../../context/localize' import { Popover } from '../../_shared/Popover' diff --git a/src/components/Editor/Panel/Panel.module.scss b/src/components/Editor/Panel/Panel.module.scss index 2f8b590f..537ecee0 100644 --- a/src/components/Editor/Panel/Panel.module.scss +++ b/src/components/Editor/Panel/Panel.module.scss @@ -112,7 +112,7 @@ } .backToMenuControl { - color: rgb(255 255 255 / 0.7); + color: rgb(255 255 255 / 70%); } .shortcutList { diff --git a/src/components/Editor/Prosemirror.scss b/src/components/Editor/Prosemirror.scss index fc7e0dd6..b610390b 100644 --- a/src/components/Editor/Prosemirror.scss +++ b/src/components/Editor/Prosemirror.scss @@ -76,11 +76,13 @@ mark.highlight { [data-float] { max-width: 50%; } + [data-float='left'] { max-width: 30%; float: left; margin: 1rem 1rem 0 0; } + [data-float='right'] { max-width: 30%; float: right; @@ -93,11 +95,12 @@ mark.highlight { float: left; margin: 1rem 1rem 0; } + [data-float='half-right'] { max-width: 50%; min-width: 30%; float: right; - margin: 1rem 0 1rem; + margin: 1rem 0; } .ProseMirror blockquote { @@ -162,16 +165,20 @@ mark.highlight { background: #000; color: #fff; } + &[data-bg='yellow'] { background: #f6e3a1; } + &[data-bg='pink'] { background: #f1b5bc; } + &[data-bg='green'] { background: #bfe9cb; box-shadow: 0 0 0 1px #000; } + &[data-bg='white'] { background: #fff; box-shadow: 0 0 0 1px #000; diff --git a/src/components/Editor/VideoUploader/VideoUploader.module.scss b/src/components/Editor/VideoUploader/VideoUploader.module.scss index 57b3a47f..c6fde6c6 100644 --- a/src/components/Editor/VideoUploader/VideoUploader.module.scss +++ b/src/components/Editor/VideoUploader/VideoUploader.module.scss @@ -2,7 +2,7 @@ margin: 2rem 0; .dropArea { - border: 2px dashed rgba(38, 56, 217, 0.3); + border: 2px dashed rgb(38 56 217 / 30%); border-radius: 16px; color: #2638d9; display: flex; diff --git a/src/components/Editor/extensions/CustomBlockquote.ts b/src/components/Editor/extensions/CustomBlockquote.ts index 681b9a29..51b77796 100644 --- a/src/components/Editor/extensions/CustomBlockquote.ts +++ b/src/components/Editor/extensions/CustomBlockquote.ts @@ -1,5 +1,4 @@ import { Blockquote } from '@tiptap/extension-blockquote' -import { Command } from '@tiptap/core' export type QuoteTypes = 'quote' | 'punchline' diff --git a/src/components/Feed/ArticleCard.module.scss b/src/components/Feed/ArticleCard.module.scss index 1e5d6dca..ddbdd474 100644 --- a/src/components/Feed/ArticleCard.module.scss +++ b/src/components/Feed/ArticleCard.module.scss @@ -42,7 +42,7 @@ a:link { border: none; - &:before { + &::before { content: ''; height: 100%; left: 0; @@ -118,6 +118,7 @@ .shoutCardTitle { @include font-size(2.2rem); + font-weight: 700; line-height: 1.1; margin-bottom: 0.8rem; @@ -138,8 +139,9 @@ } .shoutCardSubtitle { - color: #141414; @include font-size(1.8rem); + + color: #141414; font-weight: 400; line-height: 1.3; margin-bottom: 1.4rem; @@ -269,6 +271,7 @@ .shoutCardTitle, .shoutCardSubtitle { @include font-size(2.6rem); + display: inline; line-height: 1.2; } @@ -324,11 +327,11 @@ } .shoutCardSubtitle { - color: rgb(255 255 255 / 0.5); + color: rgb(255 255 255 / 50%); } &:global(.swiper-slide-active) .shoutCardCover { - &:after { + &::after { background: linear-gradient(to bottom, rgb(0 0 0 / 0%) 40%, rgb(0 0 0 / 70%) 100%); } } @@ -336,7 +339,7 @@ .shoutCardWithCover { aspect-ratio: 16/9; - padding: 0 2.4rem 0; + padding: 0 2.4rem; width: 100%; @include media-breakpoint-down(sm) { @@ -561,7 +564,7 @@ } .shoutDate { - color: rgb(255 255 255 / 0.5); + color: rgb(255 255 255 / 50%); } } @@ -596,6 +599,7 @@ .shoutCardBigTitle { .shoutCardTitle { @include font-size(3.2rem); + display: block; padding-right: 0; } @@ -609,6 +613,7 @@ .shoutCardTitle, .shoutCardSubtitle { @include font-size(2.2rem); + display: inline; line-height: 1.2; } @@ -634,8 +639,9 @@ .shoutCardTitle, .shoutCardSubtitle { - display: inline; @include font-size(1.8rem); + + display: inline; } .shoutCardSubtitle { @@ -705,12 +711,14 @@ .shoutCardTitle { @include font-size(4rem); + font-weight: 900; line-height: 1.1; } .shoutCardSubtitle { @include font-size(2.4rem); + flex: 1; } } diff --git a/src/components/Feed/Beside.module.scss b/src/components/Feed/Beside.module.scss index a3f04775..25a4d653 100644 --- a/src/components/Feed/Beside.module.scss +++ b/src/components/Feed/Beside.module.scss @@ -68,8 +68,9 @@ } a:link { - border: none; @include font-size(1.4rem); + + border: none; font-weight: bold; padding-right: 0.3em; white-space: nowrap; @@ -87,6 +88,7 @@ h4 { @include font-size(2.6rem); + font-weight: bold; padding-right: 1em; } diff --git a/src/components/Feed/Sidebar/Sidebar.module.scss b/src/components/Feed/Sidebar/Sidebar.module.scss index 600dc052..a7deba7a 100644 --- a/src/components/Feed/Sidebar/Sidebar.module.scss +++ b/src/components/Feed/Sidebar/Sidebar.module.scss @@ -18,6 +18,7 @@ .counter { @include font-size(1.2rem); + align-items: center; align-self: flex-start; background: #f6f6f6; @@ -89,6 +90,7 @@ h4 { @include font-size(1.2rem); + font-weight: bold; color: #9fa1a7; cursor: pointer; diff --git a/src/components/Nav/AuthModal/AuthModal.module.scss b/src/components/Nav/AuthModal/AuthModal.module.scss index 20de8804..361cebbe 100644 --- a/src/components/Nav/AuthModal/AuthModal.module.scss +++ b/src/components/Nav/AuthModal/AuthModal.module.scss @@ -87,6 +87,7 @@ .disclaimer { @include font-size(1.2rem); + color: #9fa1a7; margin-bottom: 0; } @@ -127,13 +128,15 @@ } .authLink { - cursor: pointer; @include font-size(1.6rem); + + cursor: pointer; font-weight: 500; } .authSubtitle { @include font-size(1.5rem); + margin-bottom: 1em; } diff --git a/src/components/Nav/AuthModal/SocialProviders.module.scss b/src/components/Nav/AuthModal/SocialProviders.module.scss index a727752e..5eb5c648 100644 --- a/src/components/Nav/AuthModal/SocialProviders.module.scss +++ b/src/components/Nav/AuthModal/SocialProviders.module.scss @@ -7,6 +7,7 @@ .text { @include font-size(1.5rem); + font-weight: 500; margin-bottom: 1em; text-align: center; diff --git a/src/components/Nav/Topics.scss b/src/components/Nav/Topics.scss index aebcaa2d..c5d07b87 100644 --- a/src/components/Nav/Topics.scss +++ b/src/components/Nav/Topics.scss @@ -1,5 +1,6 @@ .subnavigation { @include font-size(1.4rem); + height: 6rem; line-height: 6rem; margin-bottom: 5rem !important; diff --git a/src/components/Topic/Card.module.scss b/src/components/Topic/Card.module.scss index 4e37e4a6..c043f0c5 100644 --- a/src/components/Topic/Card.module.scss +++ b/src/components/Topic/Card.module.scss @@ -35,6 +35,7 @@ .topicTitle { @include font-size(2.2rem); + font-weight: bold; margin-bottom: 1.2rem; margin-top: 0.5rem !important; @@ -59,6 +60,7 @@ .topicDescription { @include font-size(1.4rem); + font-weight: 500; color: #696969; line-height: 1.3; @@ -74,6 +76,7 @@ .topicDetails { @include font-size(1.6rem); + color: #9fa1a7; display: flex; margin-bottom: 1em; @@ -85,6 +88,7 @@ .topicDetailsItem { @include font-size(1.4rem); + margin-right: 1.6rem; white-space: nowrap; diff --git a/src/components/Topic/Full.module.scss b/src/components/Topic/Full.module.scss index 8c1112a3..3cf0420e 100644 --- a/src/components/Topic/Full.module.scss +++ b/src/components/Topic/Full.module.scss @@ -5,8 +5,9 @@ text-align: center; h1 { - color: #2638d9; @include font-size(2rem); + + color: #2638d9; text-transform: uppercase; } } diff --git a/src/components/Views/Edit.tsx b/src/components/Views/Edit.tsx index 456a1de1..7b0c7637 100644 --- a/src/components/Views/Edit.tsx +++ b/src/components/Views/Edit.tsx @@ -1,4 +1,4 @@ -import { createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js' +import { createSignal, For, onCleanup, onMount, Show } from 'solid-js' import { useLocalize } from '../../context/localize' import { clsx } from 'clsx' import { Title } from '@solidjs/meta' diff --git a/src/components/Views/Feed.module.scss b/src/components/Views/Feed.module.scss index fcec51d4..38be8403 100644 --- a/src/components/Views/Feed.module.scss +++ b/src/components/Views/Feed.module.scss @@ -4,6 +4,7 @@ .feedNavigation { @include font-size(1.6rem); + font-weight: 500; h4 { @@ -39,6 +40,7 @@ .feedAside { h4 { @include font-size(2.2rem); + font-weight: bold; margin-bottom: 2.4rem; } @@ -51,9 +53,10 @@ } .topic { + @include font-size(1.2rem); + background: transparentize(#2638d9, 0.95); display: inline-block; - @include font-size(1.2rem); font-weight: bold; line-height: 3.4rem; margin: 0 0.6rem 0.6rem 0; @@ -88,6 +91,7 @@ ul { @include font-size(1.4rem); + font-weight: bold; margin: 1rem 0 0; line-height: 1.3; @@ -97,7 +101,7 @@ padding-left: 2.6rem; position: relative; - &:before { + &::before { background: url(/public/icons/knowledge-base-bullet.svg) no-repeat; content: ''; height: 1.6rem; @@ -140,6 +144,7 @@ .commentBody { @include font-size(1.4rem); + margin-bottom: 1.2rem; line-clamp: 3; -webkit-line-clamp: 3; @@ -155,7 +160,7 @@ -webkit-line-clamp: 1; a { - color: rgb(0 0 0 / 0.65); + color: rgb(0 0 0 / 65%); &:hover { color: #fff; @@ -166,5 +171,6 @@ .commentArticleTitle, .commentAuthor { @include font-size(1.2rem); + font-weight: 500; } diff --git a/src/components/_shared/DarkModeToggle/DarkModeToggle.module.scss b/src/components/_shared/DarkModeToggle/DarkModeToggle.module.scss index e5a48870..2503b859 100644 --- a/src/components/_shared/DarkModeToggle/DarkModeToggle.module.scss +++ b/src/components/_shared/DarkModeToggle/DarkModeToggle.module.scss @@ -6,7 +6,7 @@ position: relative; width: 4.6rem; - &:before { + &::before { background: #fff; border-radius: 100%; content: ''; @@ -41,14 +41,14 @@ padding: 0; position: relative; - &:before { + &::before { display: none; } } &:checked + label { .switcher { - &:before { + &::before { left: 2.4rem; } } diff --git a/src/components/_shared/DarkModeToggle/DarkModeToggle.tsx b/src/components/_shared/DarkModeToggle/DarkModeToggle.tsx index 06ef580e..e68438ab 100644 --- a/src/components/_shared/DarkModeToggle/DarkModeToggle.tsx +++ b/src/components/_shared/DarkModeToggle/DarkModeToggle.tsx @@ -2,7 +2,7 @@ import { clsx } from 'clsx' import styles from './DarkModeToggle.module.scss' import { Icon } from '../Icon' import { useLocalize } from '../../../context/localize' -import { createEffect, createSignal, onCleanup, onMount } from 'solid-js' +import { createSignal, onCleanup, onMount } from 'solid-js' import { createPrefersDark } from '@solid-primitives/media' type Props = { diff --git a/src/components/_shared/GrowingTextarea/GrowingTextarea.module.scss b/src/components/_shared/GrowingTextarea/GrowingTextarea.module.scss index 272dc522..28aa37f3 100644 --- a/src/components/_shared/GrowingTextarea/GrowingTextarea.module.scss +++ b/src/components/_shared/GrowingTextarea/GrowingTextarea.module.scss @@ -59,7 +59,7 @@ line-height: 1; user-select: none; transition: opacity 0.3s ease-in-out; - background: rgba(255, 255, 255, 0.8); + background: rgb(255 255 255 / 80%); &.visible { opacity: 1; diff --git a/src/components/_shared/Stat.module.scss b/src/components/_shared/Stat.module.scss index 3cf0ecbb..0dd60f67 100644 --- a/src/components/_shared/Stat.module.scss +++ b/src/components/_shared/Stat.module.scss @@ -1,5 +1,6 @@ .statMetrics { @include font-size(1.7rem); + color: #9fa1a7; display: flex; margin: 0 0 1em; diff --git a/src/components/_shared/VideoPlayer/VideoPlayer.module.scss b/src/components/_shared/VideoPlayer/VideoPlayer.module.scss index c622392b..128e8abb 100644 --- a/src/components/_shared/VideoPlayer/VideoPlayer.module.scss +++ b/src/components/_shared/VideoPlayer/VideoPlayer.module.scss @@ -11,6 +11,7 @@ flex-direction: row; margin-top: auto; } + .deleteAction { position: absolute; top: -15px; diff --git a/src/context/session.tsx b/src/context/session.tsx index c0258387..da759e9a 100644 --- a/src/context/session.tsx +++ b/src/context/session.tsx @@ -1,5 +1,13 @@ -import { Accessor, JSX, Resource, createEffect } from 'solid-js' -import { createContext, createMemo, createResource, createSignal, onMount, useContext } from 'solid-js' +import type { Accessor, JSX, Resource } from 'solid-js' +import { + createEffect, + createContext, + createMemo, + createResource, + createSignal, + onMount, + useContext +} from 'solid-js' import type { AuthResult, User } from '../graphql/types.gen' import { apiClient } from '../utils/apiClient' import { resetToken, setToken } from '../graphql/privateGraphQLClient' diff --git a/src/pages/edit.page.tsx b/src/pages/edit.page.tsx index 7caa0ae7..751e2696 100644 --- a/src/pages/edit.page.tsx +++ b/src/pages/edit.page.tsx @@ -1,4 +1,4 @@ -import { createEffect, createMemo, createSignal, lazy, onMount, Show, Suspense } from 'solid-js' +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' diff --git a/src/pages/layoutShouts.page.server.ts b/src/pages/layoutShouts.page.server.ts index c97dd5f6..12f7ade3 100644 --- a/src/pages/layoutShouts.page.server.ts +++ b/src/pages/layoutShouts.page.server.ts @@ -1,11 +1,12 @@ import type { PageContext } from '../renderer/types' import { apiClient } from '../utils/apiClient' import type { PageProps } from './types' +import { PRERENDERED_ARTICLES_COUNT } from './layoutShouts.page' export const onBeforeRender = async (pageContext: PageContext) => { const { layout } = pageContext.routeParams - const layoutShouts = await apiClient.getShouts({ filters: { layout }, limit: 50 }) + const layoutShouts = await apiClient.getShouts({ filters: { layout }, limit: PRERENDERED_ARTICLES_COUNT }) const pageProps: PageProps = { layoutShouts } diff --git a/src/pages/layoutShouts.page.tsx b/src/pages/layoutShouts.page.tsx index 75e8a3f4..581d1921 100644 --- a/src/pages/layoutShouts.page.tsx +++ b/src/pages/layoutShouts.page.tsx @@ -1,9 +1,8 @@ import { PageLayout } from '../components/_shared/PageLayout' -import type { PageProps } from './types' -import { createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js' -import { loadShouts, resetSortedArticles } from '../stores/zine/articles' -import { useRouter } from '../stores/router' -import { LayoutType, useLayoutsStore } from '../stores/zine/layouts' +import type { LayoutType, PageProps } from './types' +import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js' +import { loadShouts, resetSortedArticles, useArticlesStore } from '../stores/zine/articles' +import { router, useRouter } from '../stores/router' import { Loading } from '../components/_shared/Loading' import { restoreScrollPosition, saveScrollPosition } from '../utils/scroll' import type { Shout } from '../graphql/types.gen' @@ -18,42 +17,38 @@ import { Row1 } from '../components/Feed/Row1' import styles from '../styles/Topic.module.scss' import { ArticleCard } from '../components/Feed/ArticleCard' import { useLocalize } from '../context/localize' +import { getPagePath } from '@nanostores/router' +import { Title } from '@solidjs/meta' -export const PRERENDERED_ARTICLES_COUNT = 21 +export const PRERENDERED_ARTICLES_COUNT = 27 const LOAD_MORE_PAGE_SIZE = 9 // Row3 + Row3 + Row3 export const LayoutShoutsPage = (props: PageProps) => { const { t } = useLocalize() + const { page: getPage } = useRouter() + const getLayout = createMemo(() => { - const { page: getPage } = useRouter() - const page = getPage() - if (page.route !== 'expo') { - throw new Error('ts guard') - } - const { layout } = page.params + const layout = getPage().params['layout'] return layout as LayoutType }) - const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) - const { sortedLayoutShouts, loadLayoutShoutsBy } = useLayoutsStore(getLayout(), props.layoutShouts) - const sortedArticles = createMemo(() => sortedLayoutShouts().get(getLayout()) || []) - const loadMoreLayout = async (_kind: LayoutType) => { - saveScrollPosition() - const { hasMore } = await loadLayoutShoutsBy({ - // filters: { layout: kind }, - limit: LOAD_MORE_PAGE_SIZE, + const { sortedArticles } = useArticlesStore({ + shouts: props.layoutShouts + }) + + const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) + + const loadMore = async (count) => { + saveScrollPosition() + const { hasMore } = await loadShouts({ + filters: { layout: getLayout() }, + limit: count, offset: sortedArticles().length }) setIsLoadMoreButtonVisible(hasMore) restoreScrollPosition() } - onMount(async () => { - if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) { - loadMoreLayout(getLayout()) - } - }) - const title = createMemo(() => { const l = getLayout() if (l === 'audio') return t('Audio') @@ -65,101 +60,120 @@ export const LayoutShoutsPage = (props: PageProps) => { const pages = createMemo(() => splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE) ) - const isLoaded = createMemo(() => Boolean(sortedArticles())) - onMount(async () => { - if (!isLoaded()) { - await loadShouts({ filters: { layout: getLayout() }, limit: PRERENDERED_ARTICLES_COUNT, offset: 0 }) + const isLoaded = createMemo(() => Boolean(props.layoutShouts)) + + onMount(() => { + if (isLoaded()) { + return + } + + loadMore(PRERENDERED_ARTICLES_COUNT + LOAD_MORE_PAGE_SIZE) + }) + + onMount(() => { + if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) { + loadMore(LOAD_MORE_PAGE_SIZE) } }) - onCleanup(() => resetSortedArticles()) + createEffect((prevLayout) => { + if (prevLayout !== getLayout()) { + resetSortedArticles() + loadMore(PRERENDERED_ARTICLES_COUNT + LOAD_MORE_PAGE_SIZE) + } + + return getLayout() + }, getLayout()) + + onCleanup(() => { + resetSortedArticles() + }) + + const handleLoadMoreClick = () => { + loadMore(LOAD_MORE_PAGE_SIZE) + } - const ModeSwitcher = () => ( -
-
- -
-
- {`${t('Show')} `} - {t('All posts')} -
-
-
-
- ) return ( + {title()} }>
- +

{title()}

- - - - - - {(a: Shout) => ( - +
+
+ +
+
+ + 0} fallback={}> + + + + + {(article) => ( + + )} + + + + 5}> + + + + + + + + + {(page) => ( + <> + + + + )} -
- - 5}> - - - - - - - - {(page) => ( - <> - - - - - )} - - - -

- -

+ +

+ +

+
diff --git a/src/pages/types.ts b/src/pages/types.ts index f320273e..3297c9c0 100644 --- a/src/pages/types.ts +++ b/src/pages/types.ts @@ -1,6 +1,5 @@ // in a separate file to avoid circular dependencies import type { Author, Chat, Shout, Topic } from '../graphql/types.gen' -import type { LayoutType } from '../stores/zine/layouts' // all the things (she said) that could be passed from the server export type PageProps = { @@ -15,7 +14,7 @@ export type PageProps = { topic?: Topic allTopics?: Topic[] searchQuery?: string - layout?: LayoutType + layout?: string // LayoutType // other types? searchResults?: Shout[] chats?: Chat[] @@ -32,3 +31,5 @@ export type UploadFile = { size: number file: File } + +export type LayoutType = 'article' | 'audio' | 'video' | 'image' | 'literature' diff --git a/src/stores/zine/layouts.ts b/src/stores/zine/layouts.ts deleted file mode 100644 index b96ea96c..00000000 --- a/src/stores/zine/layouts.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { Shout, LoadShoutsOptions } from '../../graphql/types.gen' -import { apiClient } from '../../utils/apiClient' -import { createSignal } from 'solid-js' - -export type LayoutType = 'article' | 'audio' | 'video' | 'image' | 'literature' - -const [sortedLayoutShouts, setSortedLayoutShouts] = createSignal>(new Map()) - -const addLayoutShouts = (layout: LayoutType, shouts: Shout[]) => { - setSortedLayoutShouts((prevSorted: Map) => { - const siblings = prevSorted.get(layout) - if (siblings) { - const uniqued = [...new Set([...siblings, ...shouts])] - prevSorted.set(layout, uniqued) - } - return prevSorted - }) -} - -export const resetSortedLayoutShouts = () => { - setSortedLayoutShouts(new Map()) -} - -export const loadLayoutShoutsBy = async (options: LoadShoutsOptions): Promise<{ hasMore: boolean }> => { - const newLayoutShouts = await apiClient.getShouts({ - ...options, - limit: options.limit + 1 - }) - - const hasMore = newLayoutShouts.length === options.limit + 1 - - if (hasMore) { - newLayoutShouts.splice(-1) - } - addLayoutShouts(options.filters.layout as LayoutType, newLayoutShouts) - - return { hasMore } -} - -export const useLayoutsStore = (layout: LayoutType, initialData: Shout[]) => { - addLayoutShouts(layout, initialData || []) - - return { - addLayoutShouts, - sortedLayoutShouts, - loadLayoutShoutsBy - } -} diff --git a/src/styles/AllTopics.module.scss b/src/styles/AllTopics.module.scss index bc194fb0..2ebbc5b9 100644 --- a/src/styles/AllTopics.module.scss +++ b/src/styles/AllTopics.module.scss @@ -1,6 +1,7 @@ .allTopicsPage { .group { @include font-size(1.6rem); + margin: 3em 0 9.6rem; @include media-breakpoint-down(sm) { @@ -50,11 +51,12 @@ } .alphabet { + @include font-size(1.5rem); + color: rgba(0 0 0 / 20%); display: flex; flex-wrap: wrap; font-weight: 700; - @include font-size(1.5rem); margin: 1.5em -3% 0 0; li { @@ -66,6 +68,7 @@ .articlesCounter { @include font-size(1.2rem); + margin-left: 0.5em; vertical-align: super; } diff --git a/src/styles/app.scss b/src/styles/app.scss index 52d78aaf..821766d7 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -545,12 +545,14 @@ figure { figcaption { @include font-size(1.2rem); + color: #9fa1a7; } } .view-switcher { @include font-size(1.4rem); + display: flex; flex-wrap: wrap; font-weight: 500; @@ -828,6 +830,7 @@ figure { .content-index { @include font-size(1.4rem); + line-height: 1.4; margin: 0 3.6rem 2em 0;