From 06beecac54cdf02705d017a3e3ef93e2c4a9b371 Mon Sep 17 00:00:00 2001
From: Igor Lobanov
Date: Tue, 25 Oct 2022 17:36:32 +0200
Subject: [PATCH 1/3] common Popup component & SharePopup
---
src/components/Article/FullArticle.tsx | 11 ++--
src/components/Article/SharePopup.tsx | 45 ++++++++++++++++
src/components/Nav/Header.module.scss | 32 ++++-------
src/components/Nav/Header.tsx | 73 ++++++++------------------
src/components/Nav/Popup.module.scss | 24 +++++++--
src/components/Nav/Popup.tsx | 61 +++++++++++++--------
src/stores/ui.ts | 3 +-
7 files changed, 146 insertions(+), 103 deletions(-)
create mode 100644 src/components/Article/SharePopup.tsx
diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx
index 512cdac9..ab6d6b07 100644
--- a/src/components/Article/FullArticle.tsx
+++ b/src/components/Article/FullArticle.tsx
@@ -10,6 +10,7 @@ import { showModal } from '../../stores/ui'
import { useAuthStore } from '../../stores/auth'
import { incrementView } from '../../stores/zine/articles'
import MD from './MD'
+import { SharePopup } from './SharePopup'
const MAX_COMMENT_LEVEL = 6
@@ -126,9 +127,13 @@ export const FullArticle = (props: ArticleProps) => {
{/* */}
{/**/}
{/*FIXME*/}
{/**/}
diff --git a/src/components/Article/SharePopup.tsx b/src/components/Article/SharePopup.tsx
new file mode 100644
index 00000000..851cf599
--- /dev/null
+++ b/src/components/Article/SharePopup.tsx
@@ -0,0 +1,45 @@
+import { Icon } from '../Nav/Icon'
+import styles from '../Nav/Popup.module.scss'
+import { t } from '../../utils/intl'
+import { Popup, PopupProps } from '../Nav/Popup'
+
+type SharePopupProps = Omit
+
+export const SharePopup = (props: SharePopupProps) => {
+ return (
+
+
+
+ )
+}
diff --git a/src/components/Nav/Header.module.scss b/src/components/Nav/Header.module.scss
index 0a34a45e..9078872b 100644
--- a/src/components/Nav/Header.module.scss
+++ b/src/components/Nav/Header.module.scss
@@ -35,18 +35,6 @@
}
}
-.popupShare {
- opacity: 1;
- transition: opacity 0.3s;
- z-index: 1;
-
- .headerScrolledTop & {
- opacity: 0;
- transition: opacity 0.3s, z-index 0s 0.3s;
- z-index: -1;
- }
-}
-
.headerFixed {
position: fixed;
top: 0;
@@ -348,18 +336,16 @@
transform: translateY(-50%);
width: 100%;
- .icon {
+ .control {
+ cursor: pointer;
margin-left: 1.6rem;
- opacity: 0.6;
- transition: opacity 0.3s;
- }
+ border: 0;
- img {
- vertical-align: middle;
- }
+ .icon {
+ opacity: 0.6;
+ transition: opacity 0.3s;
+ }
- a {
- border: none;
&:hover {
background: none;
@@ -370,4 +356,8 @@
}
}
}
+
+ img {
+ vertical-align: middle;
+ }
}
diff --git a/src/components/Nav/Header.tsx b/src/components/Nav/Header.tsx
index ab2d6aeb..8a4e46f8 100644
--- a/src/components/Nav/Header.tsx
+++ b/src/components/Nav/Header.tsx
@@ -3,18 +3,17 @@ import Private from './Private'
import Notifications from './Notifications'
import { Icon } from './Icon'
import { Modal } from './Modal'
-import { Popup } from './Popup'
import AuthModal from './AuthModal'
import { t } from '../../utils/intl'
-import {useModalStore, showModal, useWarningsStore, toggleModal} from '../../stores/ui'
+import { useModalStore, showModal, useWarningsStore } from '../../stores/ui'
import { useAuthStore } from '../../stores/auth'
import { handleClientRouteLinkClick, router, Routes, useRouter } from '../../stores/router'
import styles from './Header.module.scss'
-import stylesPopup from './Popup.module.scss'
import privateStyles from './Private.module.scss'
import { getPagePath } from '@nanostores/router'
import { getLogger } from '../../utils/logger'
import { clsx } from 'clsx'
+import { SharePopup } from '../Article/SharePopup'
const log = getLogger('header')
@@ -39,6 +38,7 @@ export const Header = (props: Props) => {
const [getIsScrolled, setIsScrolled] = createSignal(false)
const [fixed, setFixed] = createSignal(false)
const [visibleWarnings, setVisibleWarnings] = createSignal(false)
+ const [isSharePopupVisible, setIsSharePopupVisible] = createSignal(false)
// stores
const { getWarnings } = useWarningsStore()
const { session } = useAuthStore()
@@ -48,14 +48,11 @@ export const Header = (props: Props) => {
// methods
const toggleWarnings = () => setVisibleWarnings(!visibleWarnings())
- const toggleFixed = () => setFixed(!fixed())
+ const toggleFixed = () => setFixed((oldFixed) => !oldFixed)
// effects
createEffect(() => {
- const isFixed = fixed() || (getModal() && getModal() !== 'share');
-
- document.body.classList.toggle('fixed', isFixed);
- document.body.classList.toggle(styles.fixed, isFixed && !getModal());
- }, [fixed(), getModal()])
+ document.body.classList.toggle('fixed', fixed() || getModal() !== null)
+ })
// derived
const authorized = createMemo(() => session()?.user?.slug)
@@ -90,7 +87,7 @@ export const Header = (props: Props) => {
classList={{
[styles.headerFixed]: props.isHeaderFixed,
[styles.headerScrolledTop]: !getIsScrollingBottom() && getIsScrolled(),
- [styles.headerScrolledBottom]: getIsScrollingBottom() && getIsScrolled(),
+ [styles.headerScrolledBottom]: (getIsScrollingBottom() && getIsScrolled()) || isSharePopupVisible(),
[styles.headerWithTitle]: Boolean(props.title)
}}
>
@@ -99,41 +96,6 @@ export const Header = (props: Props) => {
-
-
diff --git a/src/components/Nav/Popup.module.scss b/src/components/Nav/Popup.module.scss
index 63405563..d62d1c09 100644
--- a/src/components/Nav/Popup.module.scss
+++ b/src/components/Nav/Popup.module.scss
@@ -1,6 +1,13 @@
+.container {
+ position: relative;
+}
+
.popup {
background: #fff;
border: 2px solid #000;
+ top: calc(100% + 8px);
+ transform: translateX(-50%);
+ opacity: 1;
@include font-size(1.6rem);
@@ -24,6 +31,7 @@
a {
border: none;
+ white-space: nowrap;
}
img {
@@ -40,7 +48,15 @@
}
}
-.popupShare {
- right: 1em;
- top: 4.5rem;
-}
+// TODO: animation
+// .popup {
+// opacity: 1;
+// transition: opacity 0.3s;
+// z-index: 1;
+// &.visible {
+// opacity: 0;
+// transition: opacity 0.3s, z-index 0s 0.3s;
+// z-index: -1;
+// }
+// }
+
diff --git a/src/components/Nav/Popup.tsx b/src/components/Nav/Popup.tsx
index 451caf88..a53517cf 100644
--- a/src/components/Nav/Popup.tsx
+++ b/src/components/Nav/Popup.tsx
@@ -1,33 +1,50 @@
-import { createEffect, createSignal, onMount, Show } from 'solid-js'
-import style from './Popup.module.scss'
-import { hideModal, useModalStore } from '../../stores/ui'
-import {clsx} from 'clsx';
+import { createEffect, createSignal, JSX, onCleanup, onMount, Show } from 'solid-js'
+import styles from './Popup.module.scss'
+import { clsx } from 'clsx'
-interface PopupProps {
- name: string
- children: any
- class?: string
+export type PopupProps = {
+ containerCssClass?: string
+ trigger: JSX.Element
+ children: JSX.Element
+ onVisibilityChange?: (isVisible) => void
}
export const Popup = (props: PopupProps) => {
- const { getModal } = useModalStore()
+ const [isVisible, setIsVisible] = createSignal(false)
+
+ createEffect(() => {
+ if (props.onVisibilityChange) {
+ props.onVisibilityChange(isVisible())
+ }
+ })
+
+ let container: HTMLDivElement | undefined
+
+ const handleClickOutside = (event: MouseEvent & { target: Element }) => {
+ if (!isVisible()) {
+ return
+ }
+
+ if (event.target === container || container?.contains(event.target)) {
+ return
+ }
+
+ setIsVisible(false)
+ }
onMount(() => {
- window.addEventListener('keydown', (e: KeyboardEvent) => {
- if (e.key === 'Escape') hideModal()
- })
- })
-
- const [visible, setVisible] = createSignal(false)
- createEffect(() => {
- setVisible(getModal() === props.name)
+ document.addEventListener('click', handleClickOutside, { capture: true })
+ onCleanup(() => document.removeEventListener('click', handleClickOutside, { capture: true }))
})
+ const toggle = () => setIsVisible((oldVisible) => !oldVisible)
+ // class={clsx(styles.popupShare, stylesPopup.popupShare)}
return (
-
-
-
+
+ {props.trigger}
+
+
+
+
)
}
diff --git a/src/stores/ui.ts b/src/stores/ui.ts
index 39d4c717..e36e48c7 100644
--- a/src/stores/ui.ts
+++ b/src/stores/ui.ts
@@ -5,7 +5,7 @@ import { createSignal } from 'solid-js'
//export const locale = persistentAtom('locale', 'ru')
export const [locale, setLocale] = createSignal('ru')
-export type ModalType = 'auth' | 'subscribe' | 'feedback' | 'share' | 'thank' | 'donate' | null
+export type ModalType = 'auth' | 'subscribe' | 'feedback' | 'thank' | 'donate' | null
type WarnKind = 'error' | 'warn' | 'info'
export interface Warning {
@@ -20,7 +20,6 @@ const warnings = atom([])
export const showModal = (modalType: ModalType) => modal.set(modalType)
export const hideModal = () => modal.set(null)
-export const toggleModal = (modalType) => modal.get() ? hideModal() : showModal(modalType)
export const clearWarns = () => warnings.set([])
export const warn = (warning: Warning) => warnings.set([...warnings.get(), warning])
From f64bcc08f08020e4d29588ca5659cc6b260849d2 Mon Sep 17 00:00:00 2001
From: Igor Lobanov
Date: Tue, 25 Oct 2022 17:40:12 +0200
Subject: [PATCH 2/3] prettier
---
src/components/Discours/Banner.tsx | 2 +-
src/components/Discours/Footer.tsx | 2 +-
src/components/Feed/Row1.tsx | 2 +-
src/components/Nav/Header.module.scss | 1 -
src/components/Nav/Popup.module.scss | 1 -
src/components/Pages/about/ManifestPage.tsx | 83 +++++++++++----------
6 files changed, 47 insertions(+), 44 deletions(-)
diff --git a/src/components/Discours/Banner.tsx b/src/components/Discours/Banner.tsx
index 17c8875a..f14d2a8e 100644
--- a/src/components/Discours/Banner.tsx
+++ b/src/components/Discours/Banner.tsx
@@ -1,7 +1,7 @@
import styles from './Banner.module.scss'
import { t } from '../../utils/intl'
import { showModal } from '../../stores/ui'
-import {clsx} from "clsx";
+import { clsx } from 'clsx'
export default () => {
return (
diff --git a/src/components/Discours/Footer.tsx b/src/components/Discours/Footer.tsx
index ed0a50f7..941c5d3a 100644
--- a/src/components/Discours/Footer.tsx
+++ b/src/components/Discours/Footer.tsx
@@ -4,7 +4,7 @@ import { Icon } from '../Nav/Icon'
import Subscribe from './Subscribe'
import { t } from '../../utils/intl'
import { locale } from '../../stores/ui'
-import {clsx} from "clsx";
+import { clsx } from 'clsx'
export const Footer = () => {
const locale_title = createMemo(() => (locale() === 'ru' ? 'English' : 'Русский'))
diff --git a/src/components/Feed/Row1.tsx b/src/components/Feed/Row1.tsx
index abf6b9f8..b654fb82 100644
--- a/src/components/Feed/Row1.tsx
+++ b/src/components/Feed/Row1.tsx
@@ -7,7 +7,7 @@ export default (props: { article: Shout }) => (
diff --git a/src/components/Nav/Header.module.scss b/src/components/Nav/Header.module.scss
index 9078872b..83f0d992 100644
--- a/src/components/Nav/Header.module.scss
+++ b/src/components/Nav/Header.module.scss
@@ -346,7 +346,6 @@
transition: opacity 0.3s;
}
-
&:hover {
background: none;
diff --git a/src/components/Nav/Popup.module.scss b/src/components/Nav/Popup.module.scss
index d62d1c09..57c7263f 100644
--- a/src/components/Nav/Popup.module.scss
+++ b/src/components/Nav/Popup.module.scss
@@ -59,4 +59,3 @@
// z-index: -1;
// }
// }
-
diff --git a/src/components/Pages/about/ManifestPage.tsx b/src/components/Pages/about/ManifestPage.tsx
index 68e318c2..3a9cf69f 100644
--- a/src/components/Pages/about/ManifestPage.tsx
+++ b/src/components/Pages/about/ManifestPage.tsx
@@ -54,28 +54,29 @@ export const ManifestPage = () => {
- Дискурс — независимый художественно-аналитический журнал с горизонтальной редакцией,
- основанный на принципах свободы слова, прямой демократии и совместного редактирования.
- Дискурс создаётся открытым медиасообществом ученых, журналистов, музыкантов, писателей,
- предпринимателей, философов, инженеров, художников и специалистов со всего мира,
- объединившихся, чтобы вместе делать общий журнал и объяснять с разных точек
- зрения мозаичную картину современности.
+ Дискурс — независимый художественно-аналитический журнал с горизонтальной
+ редакцией, основанный на принципах свободы слова, прямой демократии и совместного
+ редактирования. Дискурс создаётся открытым медиасообществом ученых, журналистов, музыкантов,
+ писателей, предпринимателей, философов, инженеров, художников и специалистов
+ со всего мира, объединившихся, чтобы вместе делать общий журнал и объяснять
+ с разных точек зрения мозаичную картину современности.
- Мы пишем о культуре, науке и обществе, рассказываем о новых идеях и современном искусстве,
- публикуем статьи, исследования, репортажи, интервью людей, чью прямую речь стоит услышать,
- и работы художников из разных стран — от фильмов и музыки
- до живописи и фотографии. Помогая друг другу делать публикации качественнее
- и общим голосованием выбирая лучшие материалы для журнала, мы создаём новую
- горизонтальную журналистику, чтобы честно рассказывать о важном и интересном.
+ Мы пишем о культуре, науке и обществе, рассказываем о новых идеях
+ и современном искусстве, публикуем статьи, исследования, репортажи, интервью людей, чью
+ прямую речь стоит услышать, и работы художников из разных стран —
+ от фильмов и музыки до живописи и фотографии. Помогая друг другу делать
+ публикации качественнее и общим голосованием выбирая лучшие материалы для журнала,
+ мы создаём новую горизонтальную журналистику, чтобы честно рассказывать о важном
+ и интересном.
- Редакция Дискурса открыта для всех: у нас нет цензуры, запретных тем и идеологических рамок.
- Каждый может прислать материал в журнал
- и присоединиться к редакции. Предоставляя трибуну
- для независимой журналистики и художественных проектов, мы помогаем людям
- рассказывать свои истории так, чтобы они были услышаны. Мы убеждены: чем больше
- голосов будет звучать на Дискурсе, тем громче в полифонии мнений будет слышна истина.
+ Редакция Дискурса открыта для всех: у нас нет цензуры, запретных тем
+ и идеологических рамок. Каждый может прислать материал{' '}
+ в журнал и присоединиться к редакции. Предоставляя
+ трибуну для независимой журналистики и художественных проектов, мы помогаем людям
+ рассказывать свои истории так, чтобы они были услышаны. Мы убеждены: чем больше голосов
+ будет звучать на Дискурсе, тем громче в полифонии мнений будет слышна истина.
@@ -91,23 +92,26 @@ export const ManifestPage = () => {
Предлагать материалы
- Создавайте свои статьи и художественные работы — лучшие из них будут
- опубликованы в журнале. Дискурс — некоммерческое издание, авторы публикуются
- в журнале на общественных началах, получая при этом поддержку редакции,
- право голоса, множество других возможностей и читателей по всему миру.
+ Создавайте свои статьи и художественные работы —
+ лучшие из них будут опубликованы в журнале. Дискурс — некоммерческое
+ издание, авторы публикуются в журнале на общественных началах, получая при этом{' '}
+ поддержку редакции, право голоса, множество других
+ возможностей и читателей по всему миру.
Поддерживать проект
- Дискурс существует на пожертвования читателей. Если вам нравится журнал, пожалуйста,
- поддержите нашу работу. Ваши пожертвования пойдут на выпуск новых
- материалов, оплату серверов, труда программистов, дизайнеров и редакторов.
+ Дискурс существует на пожертвования читателей. Если вам нравится журнал, пожалуйста,
+
+
+ поддержите нашу работу. Ваши пожертвования пойдут на выпуск
+ новых материалов, оплату серверов, труда программистов, дизайнеров и редакторов.
Сотрудничать с журналом
Мы всегда открыты для сотрудничества и рады единомышленникам. Если вы хотите помогать
журналу с редактурой, корректурой, иллюстрациями, переводами, версткой, подкастами,
- мероприятиями, фандрайзингом или как-то ещё — скорее пишите нам
- на welcome@discours.io.
+ мероприятиями, фандрайзингом или как-то ещё — скорее пишите нам на
+ welcome@discours.io.
Если вы представляете некоммерческую организацию и хотите сделать с нами
@@ -116,25 +120,26 @@ export const ManifestPage = () => {
Если вы разработчик и хотите помогать с развитием сайта Дискурса,{' '}
- присоединяйтесь к IT-команде самиздата. Открытый
- код платформы для независимой журналистики, а также всех наших спецпроектов
- и медиаинструментов находится в свободном доступе на GitHub.
+ присоединяйтесь к IT-команде самиздата.
+ Открытый код платформы для независимой журналистики, а также всех наших спецпроектов
+ и медиаинструментов находится{' '}
+ в свободном доступе на GitHub.
Как еще можно помочь
Советуйте Дискурс друзьям и знакомым. Обсуждайте и распространяйте наши
публикации — все материалы открытой редакции можно читать и перепечатывать
- бесплатно. Подпишитесь на самиздат{' '}
- ВКонтакте,
+ бесплатно. Подпишитесь на самиздат ВКонтакте,
в Фейсбуке
- и в Телеграме, а также
- на рассылку лучших материалов,
- чтобы не пропустить ничего интересного.
+ и в Телеграме, а также на
+ рассылку лучших материалов, чтобы не пропустить
+ ничего интересного.
Рассказывайте о впечатлениях
от материалов открытой редакции, делитесь идеями,
- интересными темами, о которых хотели бы узнать больше, и историями, которые нужно рассказать.
+ интересными темами, о которых хотели бы узнать больше, и историями, которые нужно
+ рассказать.
@@ -145,9 +150,9 @@ export const ManifestPage = () => {
Если вы хотите предложить материал, сотрудничать, рассказать о проблеме, которую нужно
осветить, сообщить об ошибке или баге, что-то обсудить, уточнить или посоветовать,
- пожалуйста,
напишите нам здесь или
- на почту
welcome@discours.io. Мы обязательно
- ответим и постараемся реализовать все хорошие задумки.
+ пожалуйста,
напишите нам здесь или на почту{' '}
+
welcome@discours.io. Мы обязательно ответим
+ и постараемся реализовать все хорошие задумки.
From 0eb1430174be30fb30653cd1a4388c43190ddf87 Mon Sep 17 00:00:00 2001
From: Igor Lobanov
Date: Tue, 25 Oct 2022 17:44:31 +0200
Subject: [PATCH 3/3] prettier on on precommit enabled
---
.lintstagedrc | 5 +----
.lintstagedrc.bak | 6 ++++++
package.json | 2 +-
3 files changed, 8 insertions(+), 5 deletions(-)
create mode 100644 .lintstagedrc.bak
diff --git a/.lintstagedrc b/.lintstagedrc
index 6de8a64b..8c919270 100644
--- a/.lintstagedrc
+++ b/.lintstagedrc
@@ -1,6 +1,3 @@
{
- "*.{js,ts,tsx,json,scss,css,html}": "prettier --write",
- "package.json": "sort-package-json",
- "*.{scss,css}": "stylelint",
- "*.{ts,tsx,js}": "eslint --fix"
+ "*.{js,ts,tsx,json,scss,css,html}": "prettier --write"
}
diff --git a/.lintstagedrc.bak b/.lintstagedrc.bak
new file mode 100644
index 00000000..6de8a64b
--- /dev/null
+++ b/.lintstagedrc.bak
@@ -0,0 +1,6 @@
+{
+ "*.{js,ts,tsx,json,scss,css,html}": "prettier --write",
+ "package.json": "sort-package-json",
+ "*.{scss,css}": "stylelint",
+ "*.{ts,tsx,js}": "eslint --fix"
+}
diff --git a/package.json b/package.json
index fd8ff98e..cd3dcbce 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
"lint:code:fix": "eslint . --fix",
"lint:styles": "stylelint **/*.{scss,css}",
"lint:styles:fix": "stylelint **/*.{scss,css} --fix",
- "pre-commit": "",
+ "pre-commit": "lint-staged",
"pre-push": "",
"pre-commit-old": "lint-staged",
"pre-push-old": "npm run typecheck",