user blog markdown WYSIWYG

pull/9740/head
Thibault Duplessis 2021-09-06 11:07:40 +02:00
parent 7d6068ba28
commit 3c8d64d686
14 changed files with 156 additions and 7 deletions

View File

@ -17,7 +17,7 @@ object form {
def create(user: User, f: Form[UblogPostData], captcha: Captcha)(implicit ctx: Context) =
views.html.base.layout(
moreCss = cssTag("ublog"),
moreCss = cssTag("ublog.form"),
moreJs = captchaTag,
title = s"${trans.ublog.xBlog.txt(user.username)}${trans.ublog.newPost()}"
) {
@ -30,7 +30,7 @@ object form {
def edit(user: User, post: UblogPost, f: Form[UblogPostData])(implicit ctx: Context) =
views.html.base.layout(
moreCss = cssTag("ublog"),
moreCss = cssTag("ublog.form"),
moreJs = jsModule("ublog"),
title = s"${trans.ublog.xBlog.txt(user.username)} blog • ${post.title}"
) {
@ -89,8 +89,13 @@ object form {
form3.group(
form("markdown"),
trans.ublog.postBody(),
help = frag(markdownAvailable, br, trans.embedsAvailable()).some
)(form3.textarea(_)(rows := 30)),
help = frag(trans.embedsAvailable()).some
) { field =>
frag(
form3.textarea(field)(),
div(id := "markdown-editor")
)
},
captcha.fold(views.html.base.captcha.hiddenEmpty(form)) { c =>
views.html.base.captcha(form, c)
},

View File

@ -0,0 +1 @@
../../../node_modules/@toast-ui/editor/dist/theme/toastui-editor-dark.css

View File

@ -0,0 +1 @@
../../../node_modules/@toast-ui/editor/dist/toastui-editor-only.css

View File

@ -0,0 +1 @@
../../../node_modules/@toast-ui/editor/dist/toastui-editor.css

View File

@ -0,0 +1,6 @@
@import '../../../common/css/plugin';
@import '../../../common/css/form/form3';
@import '../../../common/css/form/captcha';
@import '../../../../public/vendor/toastui/toastui-editor';
@import '../../../../public/vendor/toastui/toastui-editor-dark';
@import '../ublog/form';

View File

@ -1,5 +1,3 @@
@import '../../../common/css/plugin';
@import '../../../common/css/component/slist';
@import '../../../common/css/form/form3';
@import '../../../common/css/form/captcha';
@import '../ublog/ublog';

View File

@ -0,0 +1,2 @@
@import '../../../common/css/theme/dark';
@import 'ublog.form';

View File

@ -0,0 +1,2 @@
@import '../../../common/css/theme/light';
@import 'ublog.form';

View File

@ -0,0 +1,2 @@
@import '../../../common/css/theme/transp';
@import 'ublog.form';

View File

@ -24,3 +24,16 @@
max-width: 80ch;
}
}
#form3-markdown {
display: none;
}
#markdown-editor {
height: 80vh;
.toastui-editor-popup-body li[data-type='Heading'] {
&[data-level='1'],
&[data-level='5'],
&[data-level='6'] {
display: none;
}
}
}

View File

@ -1,5 +1,4 @@
@import 'card';
@import 'form';
@import 'markup';
.ublog {

View File

@ -20,6 +20,7 @@
},
"dependencies": {
"@fnando/sparkline": "^0.3.10",
"@toast-ui/editor": "^3.0.3",
"@yaireo/tagify": "^4.0.5",
"apexcharts": "^3.27.1",
"chat": "2.0.0",

View File

@ -1,5 +1,6 @@
import * as xhr from 'common/xhr';
import spinner from './component/spinner';
import Editor from '@toast-ui/editor';
lichess.load.then(() => {
$('.ublog-post-form__image').each(function (this: HTMLFormElement) {
@ -17,4 +18,28 @@ lichess.load.then(() => {
});
});
$('.flash').addClass('fade');
$('#markdown-editor').each(function (this: HTMLTextAreaElement) {
const editor = new Editor({
el: this,
usageStatistics: false,
height: '70vh',
theme: $('body').data('theme') == 'light' ? 'light' : 'dark',
initialValue: $('#form3-markdown').val() as string,
initialEditType: 'wysiwyg',
language: $('html').attr('lang') as string,
toolbarItems: [
['heading', 'bold', 'italic', 'strike'],
['hr', 'quote'],
['ul', 'ol'],
['table', 'image', 'link'],
['code', 'codeblock'],
['scrollSync'],
],
events: {
change() {
$('#form3-markdown').val(editor.getMarkdown());
},
},
});
});
});

View File

@ -159,6 +159,19 @@
estree-walker "^1.0.1"
picomatch "^2.2.2"
"@toast-ui/editor@^3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@toast-ui/editor/-/editor-3.0.3.tgz#8423e27ce92b6806c7dbdab1ea67f065afa91a81"
integrity sha512-uU8FhUKsbW6nYSS+NrwqE7d/63JvezfmQ9xsRwIV9crLLyZ3K6a9/kT8XPIDcep2yKviybIDLeTEbXxuwBWvFQ==
dependencies:
prosemirror-commands "^1.1.9"
prosemirror-history "^1.1.3"
prosemirror-inputrules "^1.1.3"
prosemirror-keymap "^1.1.4"
prosemirror-model "^1.14.1"
prosemirror-state "^1.3.4"
prosemirror-view "^1.18.7"
"@types/chart.js@^2.9.29":
version "2.9.33"
resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.33.tgz#59c6de80b8134379156f4ba7b96c0928a721c1ab"
@ -3888,6 +3901,11 @@ ordered-read-streams@^1.0.0:
dependencies:
readable-stream "^2.0.1"
orderedmap@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-1.1.1.tgz#c618e77611b3b21d0fe3edc92586265e0059c789"
integrity sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ==
os-locale@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
@ -4158,6 +4176,71 @@ prop-types@^15.7.2:
object-assign "^4.1.1"
react-is "^16.8.1"
prosemirror-commands@^1.1.9:
version "1.1.10"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.1.10.tgz#406a6589966e6cd80809cea2d801fb998639b37d"
integrity sha512-IWyBBXNAd44RM6NnBPljwq+/CM2oYCQJkF+YhKEAZNwzW0uFdGf4qComhjbKZzqFdu6Iub2ZhNsXgwPibA0lCQ==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-history@^1.1.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.2.0.tgz#04cc4df8d2f7b2a46651a2780de191ada6d465ea"
integrity sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ==
dependencies:
prosemirror-state "^1.2.2"
prosemirror-transform "^1.0.0"
rope-sequence "^1.3.0"
prosemirror-inputrules@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz#93f9199ca02473259c30d7e352e4c14022d54638"
integrity sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==
dependencies:
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-keymap@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.4.tgz#8b481bf8389a5ac40d38dbd67ec3da2c7eac6a6d"
integrity sha512-Al8cVUOnDFL4gcI5IDlG6xbZ0aOD/i3B17VT+1JbHWDguCgt/lBHVTHUBcKvvbSg6+q/W4Nj1Fu6bwZSca3xjg==
dependencies:
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
prosemirror-model@^1.0.0, prosemirror-model@^1.14.1, prosemirror-model@^1.14.3:
version "1.14.3"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.14.3.tgz#a9c250d3c4023ddf10ecb41a0a7a130e9741d37e"
integrity sha512-yzZlBaSxfUPIIP6U5Edh5zKxJPZ5f7bwZRhiCuH3UYkWhj+P3d8swHsbuAMOu/iDatDc5J/Qs5Mb3++mZf+CvQ==
dependencies:
orderedmap "^1.1.0"
prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.4.tgz#4c6b52628216e753fc901c6d2bfd84ce109e8952"
integrity sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.3.2.tgz#5620ebe7379e6fae4f34ecc881886cb22ce96579"
integrity sha512-/G6d/u9Mf6Bv3H1XR8VxhpjmUO75LYmnvj+s3ZfZpakU1hnQbsvCEybml1B3f2IWUAAQRFkbO1PnsbFhLZsYsw==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-view@^1.18.7:
version "1.20.0"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.20.0.tgz#64198845f0d112c14a5594732c46a96ac3d9d828"
integrity sha512-OqU/bHUIiJhpyb2ytX4fLalYAJJOyZ0k5H0AibP/WPsdHq9CqmJFU676gO+N8WWhR5tVz1NxsqMZgEBy5Lc6GQ==
dependencies:
prosemirror-model "^1.14.3"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
psl@^1.1.28:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
@ -4523,6 +4606,11 @@ rollup@^2.56.2:
optionalDependencies:
fsevents "~2.3.2"
rope-sequence@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.2.tgz#a19e02d72991ca71feb6b5f8a91154e48e3c098b"
integrity sha512-ku6MFrwEVSVmXLvy3dYph3LAMNS0890K7fabn+0YIRQ2T96T9F4gkFf0vf0WW0JUraNWwGRtInEpH7yO4tbQZg==
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
@ -5595,6 +5683,11 @@ vinyl@^2.0.0:
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
w3c-keyname@^2.2.0:
version "2.2.4"
resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b"
integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==
which-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"