diff --git a/package-lock.json b/package-lock.json index 90f794ce..726c46b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@aws-sdk/client-s3": "3.303.0", "@aws-sdk/lib-storage": "3.303.0", "@hocuspocus/provider": "2.0.6", + "@solid-primitives/media": "2.2.3", "form-data": "4.0.0", "formidable": "2.1.1", "i18next": "22.4.15", @@ -5634,6 +5635,47 @@ "@sinonjs/commons": "^2.0.0" } }, + "node_modules/@solid-primitives/event-listener": { + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/@solid-primitives/event-listener/-/event-listener-2.2.13.tgz", + "integrity": "sha512-8GtVEq0ECZoa5Klo1jjfGPfwg0zVJ8TNnNkWu8FqRkh0CkhbhCVJAKwjleem9K/qL6zUDfJihLjhqGBTBbb+8w==", + "dependencies": { + "@solid-primitives/utils": "^6.2.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/event-listener/node_modules/@solid-primitives/utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==", + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/media": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@solid-primitives/media/-/media-2.2.3.tgz", + "integrity": "sha512-xhKaTJjH6e65OL706/hA38WWitafbJCm/Zpv7qAn4cy/cgxZ39Cl0bPdYzZhUlkJvTt8YVT0IBcOBLKlJVaPRg==", + "dependencies": { + "@solid-primitives/event-listener": "^2.2.13", + "@solid-primitives/rootless": "^1.4.1", + "@solid-primitives/static-store": "^0.0.4", + "@solid-primitives/utils": "^6.2.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/media/node_modules/@solid-primitives/utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==", + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, "node_modules/@solid-primitives/memo": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@solid-primitives/memo/-/memo-1.2.4.tgz", @@ -5668,6 +5710,25 @@ "solid-js": "^1.6.12" } }, + "node_modules/@solid-primitives/rootless": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@solid-primitives/rootless/-/rootless-1.4.1.tgz", + "integrity": "sha512-h7VBUk8usD76Eh1a4wT17PcGtIRxGPlLuJ4Mf7roCNu46W5cc9DAoz8M6XebuZWVKeUkML/JuPMZQSV0mLo2Fw==", + "dependencies": { + "@solid-primitives/utils": "^6.2.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/rootless/node_modules/@solid-primitives/utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==", + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, "node_modules/@solid-primitives/scheduled": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@solid-primitives/scheduled/-/scheduled-1.3.2.tgz", @@ -5686,6 +5747,25 @@ "solid-js": "^1.6.12" } }, + "node_modules/@solid-primitives/static-store": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@solid-primitives/static-store/-/static-store-0.0.4.tgz", + "integrity": "sha512-NcLtDNA6H+Z9LmqaUe4SKfMx0YbszIMXEqfV15cB34t5XyEeOM5TihYwsVJ/dpkmpHYzflm0SwAL+P9uwyzvWQ==", + "dependencies": { + "@solid-primitives/utils": "^6.2.0" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/static-store/node_modules/@solid-primitives/utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==", + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, "node_modules/@solid-primitives/storage": { "version": "1.3.9", "resolved": "https://registry.npmjs.org/@solid-primitives/storage/-/storage-1.3.9.tgz", @@ -24755,6 +24835,41 @@ "@sinonjs/commons": "^2.0.0" } }, + "@solid-primitives/event-listener": { + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/@solid-primitives/event-listener/-/event-listener-2.2.13.tgz", + "integrity": "sha512-8GtVEq0ECZoa5Klo1jjfGPfwg0zVJ8TNnNkWu8FqRkh0CkhbhCVJAKwjleem9K/qL6zUDfJihLjhqGBTBbb+8w==", + "requires": { + "@solid-primitives/utils": "^6.2.0" + }, + "dependencies": { + "@solid-primitives/utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==", + "requires": {} + } + } + }, + "@solid-primitives/media": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@solid-primitives/media/-/media-2.2.3.tgz", + "integrity": "sha512-xhKaTJjH6e65OL706/hA38WWitafbJCm/Zpv7qAn4cy/cgxZ39Cl0bPdYzZhUlkJvTt8YVT0IBcOBLKlJVaPRg==", + "requires": { + "@solid-primitives/event-listener": "^2.2.13", + "@solid-primitives/rootless": "^1.4.1", + "@solid-primitives/static-store": "^0.0.4", + "@solid-primitives/utils": "^6.2.0" + }, + "dependencies": { + "@solid-primitives/utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==", + "requires": {} + } + } + }, "@solid-primitives/memo": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@solid-primitives/memo/-/memo-1.2.4.tgz", @@ -24783,6 +24898,22 @@ "@solid-primitives/utils": "^5.5.1" } }, + "@solid-primitives/rootless": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@solid-primitives/rootless/-/rootless-1.4.1.tgz", + "integrity": "sha512-h7VBUk8usD76Eh1a4wT17PcGtIRxGPlLuJ4Mf7roCNu46W5cc9DAoz8M6XebuZWVKeUkML/JuPMZQSV0mLo2Fw==", + "requires": { + "@solid-primitives/utils": "^6.2.0" + }, + "dependencies": { + "@solid-primitives/utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==", + "requires": {} + } + } + }, "@solid-primitives/scheduled": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@solid-primitives/scheduled/-/scheduled-1.3.2.tgz", @@ -24797,6 +24928,22 @@ "dev": true, "requires": {} }, + "@solid-primitives/static-store": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@solid-primitives/static-store/-/static-store-0.0.4.tgz", + "integrity": "sha512-NcLtDNA6H+Z9LmqaUe4SKfMx0YbszIMXEqfV15cB34t5XyEeOM5TihYwsVJ/dpkmpHYzflm0SwAL+P9uwyzvWQ==", + "requires": { + "@solid-primitives/utils": "^6.2.0" + }, + "dependencies": { + "@solid-primitives/utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==", + "requires": {} + } + } + }, "@solid-primitives/storage": { "version": "1.3.9", "resolved": "https://registry.npmjs.org/@solid-primitives/storage/-/storage-1.3.9.tgz", diff --git a/package.json b/package.json index 0bc6985f..b94cd67c 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "@aws-sdk/client-s3": "3.303.0", "@aws-sdk/lib-storage": "3.303.0", "@hocuspocus/provider": "2.0.6", + "@solid-primitives/media": "2.2.3", "form-data": "4.0.0", "formidable": "2.1.1", "i18next": "22.4.15", diff --git a/public/icons/night-theme.svg b/public/icons/night-theme.svg new file mode 100644 index 00000000..91aa910e --- /dev/null +++ b/public/icons/night-theme.svg @@ -0,0 +1,4 @@ + diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 453916b7..711e6c01 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -15,6 +15,7 @@ "Audio": "Audio", "Author": "Author", "Authors": "Authors", + "Autotypograph": "Autotypograph", "Back to main page": "Back to main page", "Become an author": "Become an author", "Bookmarked": "Saved", @@ -73,7 +74,7 @@ "Feed settings": "Feed settings", "Feedback": "Feedback", "Fill email": "Fill email", - "Fix typography": "Fix typography", + "Fixed": "Fixed", "Follow": "Follow", "Follow the topic": "Follow the topic", "Followers": "Followers", @@ -132,6 +133,7 @@ "New only": "New only", "New password": "New password", "New stories every day and even more!": "New stories and more are waiting for you every day!", + "Night mode": "Night mode", "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", @@ -204,6 +206,7 @@ "Suggest an idea": "Suggest an idea", "Support us": "Help the magazine", "Terms of use": "Site rules", + "Text checking": "Text checking", "Thank you": "Thank you", "This comment has not yet been rated": "This comment has not yet been rated", "This email is already taken. If it's you": "This email is already taken. If it's you", @@ -280,5 +283,17 @@ "topics": "topics", "user already exist": "user already exists", "view": "view", - "zine": "zine" + "zine": "zine", + "back to menu": "back to menu", + "bold": "bold", + "italic": "italic", + "add link": "add link", + "header 1": "header 1", + "header 2": "header 2", + "header 3": "header 3", + "marker list": "marker list", + "number list": "number list", + "delimiter": "delimiter", + "cancel_low_caps": "cancel", + "repeat": "repeat" } diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 644b415f..72a75569 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -17,6 +17,7 @@ "Audio": "Аудио", "Author": "Автор", "Authors": "Авторы", + "Autotypograph": "Автотипограф", "Back to main page": "Вернуться на главную", "Become an author": "Стать автором", "Bookmarked": "Сохранено", @@ -76,7 +77,7 @@ "Feed settings": "Настройки ленты", "Feedback": "Обратная связь", "Fill email": "Введите почту", - "Fix typography": "Исправить типографику", + "Fixed": "Все поправлено", "Follow": "Подписаться", "Follow the topic": "Подписаться на тему", "Followers": "Подписчики", @@ -139,6 +140,7 @@ "New only": "Только новые", "New password": "Новый пароль", "New stories every day and even more!": "Каждый день вас ждут новые истории и ещё много всего интересного!", + "Night mode": "Ночная тема", "No such account, please try to register": "Такой адрес не найден, попробуйте зарегистрироваться", "Nothing here yet": "Здесь пока ничего нет", "Nothing is here": "Здесь ничего нет", @@ -217,6 +219,7 @@ "Suggest an idea": "Предложить идею", "Support us": "Помочь журналу", "Terms of use": "Правила сайта", + "Text checking": "Проверка текста", "Thank you": "Благодарности", "This comment has not yet been rated": "Этот комментарий еще пока никто не оценил", "This email is already taken. If it's you": "Такой email уже зарегистрирован. Если это вы", @@ -301,5 +304,17 @@ "topics": "темы", "user already exist": "пользователь уже существует", "view": "просмотр", - "zine": "журнал" + "zine": "журнал", + "back to menu": "назад в меню", + "bold": "жирный", + "italic": "курсив", + "add link": "добавить ссылку", + "header 1": "заголовок 1", + "header 2": "заголовок 2", + "header 3": "заголовок 3", + "marker list": "маркир. список", + "number list": "нумер. список", + "delimiter": "разделитель", + "cancel_low_caps": "отменить", + "repeat": "повторить" } diff --git a/public/logo.svg b/public/logo.svg index bf7f6de3..6863a4bd 100644 --- a/public/logo.svg +++ b/public/logo.svg @@ -1,3 +1,4 @@ diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index 08105677..ad14135a 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -1,17 +1,7 @@ import { capitalize, formatDate } from '../../utils' import { Icon } from '../_shared/Icon' import { AuthorCard } from '../Author/AuthorCard' -import { - createEffect, - createMemo, - createSignal, - For, - Match, - onCleanup, - onMount, - Show, - Switch -} from 'solid-js' +import { createEffect, createMemo, createSignal, For, Match, onMount, Show, Switch } from 'solid-js' import type { Author, Shout } from '../../graphql/types.gen' import MD from './MD' import { SharePopup } from './SharePopup' diff --git a/src/components/Discours/Footer.module.scss b/src/components/Discours/Footer.module.scss index 129668e8..bb82ad84 100644 --- a/src/components/Discours/Footer.module.scss +++ b/src/components/Discours/Footer.module.scss @@ -1,6 +1,5 @@ .discoursFooter { @include font-size(1.7rem); - background: #000; color: rgb(255 255 255 / 64%); padding: 2.4rem 0 4.2rem; @@ -22,10 +21,11 @@ a { color: rgb(255 255 255 / 64%); - transition: color 0.3s; + transition: color 0.3s, background-color 0.3s; &:hover { - color: #fff; + background: #fff; + color: #000; } } } @@ -58,7 +58,8 @@ color: rgb(255 255 255 / 70%); &:hover { - color: #fff; + background: #fff; + color: #000; } } } diff --git a/src/components/Editor/Panel/Panel.module.scss b/src/components/Editor/Panel/Panel.module.scss index 539ff8ad..2f8b590f 100644 --- a/src/components/Editor/Panel/Panel.module.scss +++ b/src/components/Editor/Panel/Panel.module.scss @@ -1,10 +1,7 @@ .Panel { background: #1f1f1f; color: rgb(255 255 255 / 35%); - display: flex; - flex-direction: column; font-size: 1.7rem; - justify-content: flex-start; height: 100%; line-height: 1.4; padding: $grid-gutter-width calc($grid-gutter-width / 2); @@ -20,7 +17,9 @@ } .actionsHolder { - padding: 0 calc($grid-gutter-width / 2); + height: 100%; + display: flex; + flex-direction: column; &.scrolled { overflow-y: auto; @@ -61,6 +60,7 @@ text-decoration: none; border-bottom: none; color: rgb(255 255 255 / 35%); + font-size: inherit; font-weight: normal !important; &:hover { @@ -95,4 +95,41 @@ vertical-align: bottom; } } + + .typograph { + align-items: baseline; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + } + + .typographStatus { + @include font-size(1.2rem); + } + + .typographStatusSuccess { + color: #28d353; + } + + .backToMenuControl { + color: rgb(255 255 255 / 0.7); + } + + .shortcutList { + color: #fff; + } + + .shortcut { + margin-left: 1em; + } + + .shortcutButton { + border: 1px solid; + border-bottom-width: 2px; + border-radius: 2px; + display: inline-block; + font-style: italic; + margin-right: 0.5em; + padding: 0.1em 0.4em; + } } diff --git a/src/components/Editor/Panel/Panel.tsx b/src/components/Editor/Panel/Panel.tsx index 2313c50c..c9a7cca7 100644 --- a/src/components/Editor/Panel/Panel.tsx +++ b/src/components/Editor/Panel/Panel.tsx @@ -10,6 +10,8 @@ import { getPagePath } from '@nanostores/router' import { router } from '../../../stores/router' import { useEditorHTML } from 'solid-tiptap' import Typograf from 'typograf' +import { createSignal, Show } from 'solid-js' +import { DarkModeToggle } from '../../_shared/DarkModeToggle' const typograf = new Typograf({ locale: ['ru', 'en-US'] }) @@ -30,6 +32,9 @@ export const Panel = (props: Props) => { current: null } + const [isShortcutsVisible, setIsShortcutsVisible] = createSignal(false) + const [isTypographyFixed, setIsTypographyFixed] = createSignal(false) + useOutsideClickHandler({ containerRef, predicate: () => isEditorPanelVisible(), @@ -53,6 +58,7 @@ export const Panel = (props: Props) => { const handleFixTypographyClick = () => { const html = useEditorHTML(() => editorRef.current()) editorRef.current().commands.setContent(typograf.execute(html())) + setIsTypographyFixed(true) } return ( @@ -60,15 +66,13 @@ export const Panel = (props: Props) => { ref={(el) => (containerRef.current = el)} class={clsx('col-md-6', styles.Panel, { [styles.hidden]: !isEditorPanelVisible() })} > -
@@ -82,31 +86,6 @@ export const Panel = (props: Props) => {
-
-
{t('Invite co-authors')} @@ -121,15 +100,28 @@ export const Panel = (props: Props) => {
- - {t('Fix typography')} - -
-- {t('Corrections history')} + {t('Corrections history')}
{t('Text checking')}
+@@ -137,9 +129,9 @@ export const Panel = (props: Props) => {
- + +
@@ -160,6 +152,107 @@ export const Panel = (props: Props) => { {/*
+ +
+ ++ {t('bold')} + + Ctrl + B + +
++ {t('italic')} + + Ctrl + I + +
++ {t('add link')} + + Ctrl + K + +
++ {t('header 1')} + + Ctrl + Alt + 1 + +
++ {t('header 2')} + + Ctrl + Alt + 2 + +
++ {t('header 3')} + + Ctrl + Alt + 3 + +
++ {t('marker list')} + + * + Space + +
++ {t('number list')} + + 1 + Space + +
++ {t('delimiter')} + + *** + Enter + +
++ {t('cancel_low_caps')} + + Ctrl + Z + +
++ {t('repeat')} + + Ctrl + Shift + Z + +
+