Tweaked discord markdown
This commit is contained in:
parent
bc13cced34
commit
63eecd3f94
@ -1 +1 @@
|
|||||||
[{"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js":"1","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\History.js":"2","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\App.js":"3","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Dash.js":"4","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Constants\\constants.js":"5","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Loading.js":"6","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Navigation.js":"7","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\System.js":"8","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js":"9","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js":"10"},{"size":309,"mtime":1607504507185,"results":"11","hashOfConfig":"12"},{"size":87,"mtime":1607504507181,"results":"13","hashOfConfig":"12"},{"size":3564,"mtime":1607532218056,"results":"14","hashOfConfig":"12"},{"size":297,"mtime":1607504507172,"results":"15","hashOfConfig":"12"},{"size":73,"mtime":1607504507180,"results":"16","hashOfConfig":"12"},{"size":231,"mtime":1607504507174,"results":"17","hashOfConfig":"12"},{"size":1207,"mtime":1607530583774,"results":"18","hashOfConfig":"12"},{"size":1731,"mtime":1607532125462,"results":"19","hashOfConfig":"12"},{"size":2160,"mtime":1607504507176,"results":"20","hashOfConfig":"12"},{"size":2309,"mtime":1607532124555,"results":"21","hashOfConfig":"12"},{"filePath":"22","messages":"23","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},"1uc84gl",{"filePath":"25","messages":"26","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},{"filePath":"27","messages":"28","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},{"filePath":"31","messages":"32","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},{"filePath":"33","messages":"34","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},{"filePath":"35","messages":"36","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"37","messages":"38","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"39","messages":"40","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"24"},{"filePath":"41","messages":"42","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js",[],["43","44"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\History.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\App.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Dash.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Constants\\constants.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Loading.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Navigation.js",["45"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\System.js",["46"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js",["47"],{"ruleId":"48","replacedBy":"49"},{"ruleId":"50","replacedBy":"51"},{"ruleId":"52","severity":1,"message":"53","line":1,"column":8,"nodeType":"54","messageId":"55","endLine":1,"endColumn":13},{"ruleId":"56","severity":1,"message":"57","line":18,"column":4,"nodeType":"58","endLine":18,"endColumn":22,"suggestions":"59"},{"ruleId":"56","severity":1,"message":"57","line":26,"column":8,"nodeType":"58","endLine":26,"endColumn":42,"suggestions":"60"},"no-native-reassign",["61"],"no-negated-in-lhs",["62"],"no-unused-vars","'react' is defined but never used.","Identifier","unusedVar","react-hooks/exhaustive-deps","React Hook useEffect has a missing dependency: 'toHTML'. Either include it or remove the dependency array.","ArrayExpression",["63"],["64"],"no-global-assign","no-unsafe-negation",{"desc":"65","fix":"66"},{"desc":"67","fix":"68"},"Update the dependencies array to be: [toHTML, user.description]",{"range":"69","text":"70"},"Update the dependencies array to be: [member.description, member.color, toHTML]",{"range":"71","text":"72"},[550,568],"[toHTML, user.description]",[710,744],"[member.description, member.color, toHTML]"]
|
[{"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js":"1","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\History.js":"2","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\App.js":"3","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Dash.js":"4","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Constants\\constants.js":"5","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Loading.js":"6","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Navigation.js":"7","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\System.js":"8","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js":"9","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js":"10","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js":"11"},{"size":309,"mtime":1607504507185,"results":"12","hashOfConfig":"13"},{"size":87,"mtime":1607504507181,"results":"14","hashOfConfig":"13"},{"size":3564,"mtime":1607532218056,"results":"15","hashOfConfig":"13"},{"size":297,"mtime":1607504507172,"results":"16","hashOfConfig":"13"},{"size":73,"mtime":1607504507180,"results":"17","hashOfConfig":"13"},{"size":231,"mtime":1607504507174,"results":"18","hashOfConfig":"13"},{"size":1212,"mtime":1607537102637,"results":"19","hashOfConfig":"13"},{"size":1745,"mtime":1607549962223,"results":"20","hashOfConfig":"13"},{"size":2160,"mtime":1607534877891,"results":"21","hashOfConfig":"13"},{"size":2320,"mtime":1607549951923,"results":"22","hashOfConfig":"13"},{"size":10382,"mtime":1607549930730,"results":"23","hashOfConfig":"13"},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"1uc84gl",{"filePath":"26","messages":"27","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"28","messages":"29","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"30","messages":"31","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"34","messages":"35","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"38","messages":"39","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"40","messages":"41","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"42","messages":"43","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"44","messages":"45","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\History.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\App.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Dash.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Constants\\constants.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Loading.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Navigation.js",["46"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\System.js",["47"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js",["48"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js",[],{"ruleId":"49","severity":1,"message":"50","line":1,"column":8,"nodeType":"51","messageId":"52","endLine":1,"endColumn":13},{"ruleId":"53","severity":1,"message":"54","line":18,"column":4,"nodeType":"55","endLine":18,"endColumn":22,"suggestions":"56"},{"ruleId":"53","severity":1,"message":"54","line":26,"column":8,"nodeType":"55","endLine":26,"endColumn":42,"suggestions":"57"},"no-unused-vars","'react' is defined but never used.","Identifier","unusedVar","react-hooks/exhaustive-deps","React Hook useEffect has a missing dependency: 'toHTML'. Either include it or remove the dependency array.","ArrayExpression",["58"],["59"],{"desc":"60","fix":"61"},{"desc":"62","fix":"63"},"Update the dependencies array to be: [toHTML, user.description]",{"range":"64","text":"65"},"Update the dependencies array to be: [member.description, member.color, toHTML]",{"range":"66","text":"67"},[564,582],"[toHTML, user.description]",[724,758],"[member.description, member.color, toHTML]"]
|
@ -7,8 +7,35 @@
|
|||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Web site created using create-react-app"
|
content="A web interface for pluralkit"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- Start Single Page Apps for GitHub Pages -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Single Page Apps for GitHub Pages
|
||||||
|
// MIT License
|
||||||
|
// https://github.com/rafgraph/spa-github-pages
|
||||||
|
// This script checks to see if a redirect is present in the query string,
|
||||||
|
// converts it back into the correct url and adds it to the
|
||||||
|
// browser's history using window.history.replaceState(...),
|
||||||
|
// which won't cause the browser to attempt to load the new url.
|
||||||
|
// When the single page app is loaded further down in this file,
|
||||||
|
// the correct url will be waiting in the browser's history for
|
||||||
|
// the single page app to route accordingly.
|
||||||
|
(function(l) {
|
||||||
|
if (l.search[1] === '/' ) {
|
||||||
|
var decoded = l.search.slice(1).split('&').map(function(s) {
|
||||||
|
return s.replace(/~and~/g, '&')
|
||||||
|
}).join('?');
|
||||||
|
window.history.replaceState(null, null,
|
||||||
|
l.pathname.slice(0, -1) + decoded + l.hash
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}(window.location))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- End Single Page Apps for GitHub Pages -->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||||
|
40
src/404.html
Normal file
40
src/404.html
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Single Page Apps for GitHub Pages</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Single Page Apps for GitHub Pages
|
||||||
|
// MIT License
|
||||||
|
// https://github.com/rafgraph/spa-github-pages
|
||||||
|
// This script takes the current url and converts the path and query
|
||||||
|
// string into just a query string, and then redirects the browser
|
||||||
|
// to the new url with only a query string and hash fragment,
|
||||||
|
// e.g. https://www.foo.tld/one/two?a=b&c=d#qwe, becomes
|
||||||
|
// https://www.foo.tld/?/one/two&a=b~and~c=d#qwe
|
||||||
|
// Note: this 404.html file must be at least 512 bytes for it to work
|
||||||
|
// with Internet Explorer (it is currently > 512 bytes)
|
||||||
|
|
||||||
|
// If you're creating a Project Pages site and NOT using a custom domain,
|
||||||
|
// then set pathSegmentsToKeep to 1 (enterprise users may need to set it to > 1).
|
||||||
|
// This way the code will only replace the route part of the path, and not
|
||||||
|
// the real directory in which the app resides, for example:
|
||||||
|
// https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
|
||||||
|
// https://username.github.io/repo-name/?/one/two&a=b~and~c=d#qwe
|
||||||
|
// Otherwise, leave pathSegmentsToKeep as 0.
|
||||||
|
var pathSegmentsToKeep = 1;
|
||||||
|
|
||||||
|
var l = window.location;
|
||||||
|
l.replace(
|
||||||
|
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
|
||||||
|
l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' +
|
||||||
|
l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
|
||||||
|
(l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
|
||||||
|
l.hash
|
||||||
|
);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -6,7 +6,7 @@ import { FaUser } from "react-icons/fa";
|
|||||||
|
|
||||||
export default function MemberCard(props) {
|
export default function MemberCard(props) {
|
||||||
|
|
||||||
const { toHTML } = require('discord-markdown');
|
const { toHTML } = require('../Functions/discord-parser.js');
|
||||||
|
|
||||||
const [ desc, setDesc ] = useState("");
|
const [ desc, setDesc ] = useState("");
|
||||||
const [ color, setColor ] = useState("");
|
const [ color, setColor ] = useState("");
|
||||||
@ -33,7 +33,7 @@ export default function MemberCard(props) {
|
|||||||
<BS.Image src={defaultAvatar} style={{width: 50, height: 50}} className="float-right" roundedCircle />}
|
<BS.Image src={defaultAvatar} style={{width: 50, height: 50}} className="float-right" roundedCircle />}
|
||||||
</BS.Accordion.Toggle>
|
</BS.Accordion.Toggle>
|
||||||
<BS.Accordion.Collapse eventKey={member.id}>
|
<BS.Accordion.Collapse eventKey={member.id}>
|
||||||
<BS.Card.Body style={{'border-left': `5px solid #${color}` }}>
|
<BS.Card.Body style={{borderLeft: `5px solid #${color}` }}>
|
||||||
<BS.Row>
|
<BS.Row>
|
||||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>ID:</b> {member.id}</BS.Col>
|
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>ID:</b> {member.id}</BS.Col>
|
||||||
{ member.display_name ? <BS.Col className="mb-lg-3" xs={12} lg={3}><b>AKA: </b>{member.display_name}</BS.Col> : "" }
|
{ member.display_name ? <BS.Col className="mb-lg-3" xs={12} lg={3}><b>AKA: </b>{member.display_name}</BS.Col> : "" }
|
||||||
|
@ -56,7 +56,7 @@ export default function Memberlist() {
|
|||||||
<BS.Alert variant="danger">Error fetching members.</BS.Alert> :
|
<BS.Alert variant="danger">Error fetching members.</BS.Alert> :
|
||||||
<>
|
<>
|
||||||
<BS.Row className="justify-content-md-center">
|
<BS.Row className="justify-content-md-center">
|
||||||
<BS.Col xs={12} md={4}>
|
<BS.Col xs={12} lg={4}>
|
||||||
<BS.Form inline>
|
<BS.Form inline>
|
||||||
<BS.Form.Control className="w-100" value={value} onChange={e => setValue(e.target.value)} placeholder="Search"/>
|
<BS.Form.Control className="w-100" value={value} onChange={e => setValue(e.target.value)} placeholder="Search"/>
|
||||||
</BS.Form>
|
</BS.Form>
|
||||||
|
@ -17,11 +17,11 @@ export default function Navigation(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BS.Navbar className="mb-3 d-flex align-items-center justify-content-between light" expand="md">
|
<BS.Navbar className="mb-3 align-items-center justify-content-between">
|
||||||
<BS.Navbar.Brand>
|
<BS.Navbar.Brand>
|
||||||
pk-web
|
pk-web
|
||||||
</BS.Navbar.Brand>
|
</BS.Navbar.Brand>
|
||||||
<BS.Nav className="mr-md-2">
|
<BS.Nav className="mr-lg-2 d-flex align-items-center row">
|
||||||
<Toggle
|
<Toggle
|
||||||
defaultChecked={true}
|
defaultChecked={true}
|
||||||
icons={false}
|
icons={false}
|
||||||
@ -29,7 +29,7 @@ export default function Navigation(props) {
|
|||||||
{darkMode.value ? <FaMoon className="m-1"/> : <FaSun className="m-1"/>}
|
{darkMode.value ? <FaMoon className="m-1"/> : <FaSun className="m-1"/>}
|
||||||
</BS.Nav>
|
</BS.Nav>
|
||||||
<BS.Form inline>
|
<BS.Form inline>
|
||||||
{ localStorage.getItem('token') ? <BS.Button className=" mr-md-2" variant="primary" onClick={logOut}>Log Out</BS.Button> : "" }
|
{ localStorage.getItem('token') ? <BS.Button className=" mr-lg-2" variant="primary" onClick={logOut}>Log Out</BS.Button> : "" }
|
||||||
</BS.Form>
|
</BS.Form>
|
||||||
</BS.Navbar>
|
</BS.Navbar>
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,7 @@ import defaultAvatar from '../default_discord_avatar.png'
|
|||||||
|
|
||||||
export default function System(props) {
|
export default function System(props) {
|
||||||
|
|
||||||
const { toHTML } = require('discord-markdown');
|
const { toHTML } = require('../Functions/discord-parser.js');
|
||||||
|
|
||||||
const [ desc, setDesc ] = useState("");
|
const [ desc, setDesc ] = useState("");
|
||||||
const user = JSON.parse(localStorage.getItem("user"));
|
const user = JSON.parse(localStorage.getItem("user"));
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
.dark-mode {
|
.dark-mode {
|
||||||
background-color: $gray-800;
|
background-color: $gray-800;
|
||||||
transition: background-color 0.3s ease;
|
transition: background-color 0.3s ease;
|
||||||
@ -6,7 +7,7 @@
|
|||||||
.dark-mode .card {
|
.dark-mode .card {
|
||||||
color: $white;
|
color: $white;
|
||||||
background-color: $gray-800;
|
background-color: $gray-800;
|
||||||
border: 1px solid $gray-900 !important;
|
border: 1px solid #191c1f !important;
|
||||||
transition: background-color 0.3s ease;
|
transition: background-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,7 +17,7 @@
|
|||||||
transition: background-color 0.3s ease;
|
transition: background-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark-mode .card .card-header {
|
.dark-mode .card-header {
|
||||||
color: $gray-100;
|
color: $gray-100;
|
||||||
background-color: $gray-900;
|
background-color: $gray-900;
|
||||||
transition: background-color 0.3s ease;
|
transition: background-color 0.3s ease;
|
||||||
@ -36,25 +37,96 @@
|
|||||||
color: $gray-100 !important;
|
color: $gray-100 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark-mode .form-control {
|
.dark-mode .card .form-control {
|
||||||
color: $gray-100;
|
|
||||||
border-color: #000000;
|
|
||||||
background-color: $gray-900;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark-mode .form-control:focus {
|
|
||||||
color: $gray-200;
|
color: $gray-200;
|
||||||
border-color: #000000;
|
border-color: #191c1f;
|
||||||
background-color: $gray-900;
|
background-color: $gray-900;
|
||||||
transition: background-color 0.3s ease;
|
transition: background-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark-mode .alert-danger {
|
.dark-mode .alert-danger {
|
||||||
color: $white;
|
color: $white;
|
||||||
background-color: $red;
|
background-color: $danger;
|
||||||
border: $gray-900;
|
border: $gray-900;
|
||||||
transition: background-color 0.3s ease;
|
transition: background-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
color: black !important;
|
||||||
|
background-color: $gray-300;
|
||||||
|
padding: 5px 7px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 3px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode code{
|
||||||
|
color: white !important;
|
||||||
|
background-color: $gray-900;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
margin: 2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
code.hljs {
|
||||||
|
display: block;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||||
|
margin: 3px 3px 7px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-spoiler {
|
||||||
|
color: $gray-300 !important;
|
||||||
|
background-color: $gray-300;
|
||||||
|
padding: 3px 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 3px;
|
||||||
|
display: inline-block;
|
||||||
|
transition-delay: 6000s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-spoiler::selection {
|
||||||
|
color: $gray-300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode .d-spoiler {
|
||||||
|
color: $gray-900 !important;
|
||||||
|
background-color: $gray-900;
|
||||||
|
padding: 3px 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 3px;
|
||||||
|
display: inline-block;
|
||||||
|
transition-delay: 6000s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode .d-spoiler::selection {
|
||||||
|
color: $gray-900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-spoiler:active {
|
||||||
|
color: $gray-900 !important;
|
||||||
|
background-color: $gray-200;
|
||||||
|
transition-delay: 0s;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode .d-spoiler:active {
|
||||||
|
color: $gray-200 !important;
|
||||||
|
background-color: $gray-700;
|
||||||
|
transition-delay: 0s;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-left: 6px solid $gray-200;
|
||||||
|
padding: 2px 5px 2px 15px;
|
||||||
|
margin: 7px !important;
|
||||||
|
margin-left: 9px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode blockquote {
|
||||||
|
border-left: 6px solid $gray-700;
|
||||||
|
}
|
||||||
|
|
||||||
@import "~bootstrap/scss/bootstrap";
|
@import "~bootstrap/scss/bootstrap";
|
323
src/Functions/discord-parser.js
Normal file
323
src/Functions/discord-parser.js
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
const markdown = require('simple-markdown');
|
||||||
|
const highlight = require('highlight.js');
|
||||||
|
|
||||||
|
function htmlTag(tagName, content, attributes, isClosed = true, state = { }) {
|
||||||
|
if (typeof isClosed === 'object') {
|
||||||
|
state = isClosed;
|
||||||
|
isClosed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attributes)
|
||||||
|
attributes = { };
|
||||||
|
|
||||||
|
if (attributes.class && state.cssModuleNames)
|
||||||
|
attributes.class = attributes.class.split(' ').map(cl => state.cssModuleNames[cl] || cl).join(' ');
|
||||||
|
|
||||||
|
let attributeString = '';
|
||||||
|
for (let attr in attributes) {
|
||||||
|
// Removes falsy attributes
|
||||||
|
if (Object.prototype.hasOwnProperty.call(attributes, attr) && attributes[attr])
|
||||||
|
attributeString += ` ${markdown.sanitizeText(attr)}="${markdown.sanitizeText(attributes[attr])}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let unclosedTag = `<${tagName}${attributeString}>`;
|
||||||
|
|
||||||
|
if (isClosed)
|
||||||
|
return unclosedTag + content + `</${tagName}>`;
|
||||||
|
return unclosedTag;
|
||||||
|
}
|
||||||
|
markdown.htmlTag = htmlTag;
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
blockQuote: Object.assign({ }, markdown.defaultRules.blockQuote, {
|
||||||
|
match: function(source, state, prevSource) {
|
||||||
|
return !/^$|\n *$/.test(prevSource) || state.inQuote ? null : /^( *>>> ([\s\S]*))|^( *> [^\n]*(\n *> [^\n]*)*\n?)/.exec(source);
|
||||||
|
},
|
||||||
|
parse: function(capture, parse, state) {
|
||||||
|
const all = capture[0];
|
||||||
|
const isBlock = Boolean(/^ *>>> ?/.exec(all));
|
||||||
|
const removeSyntaxRegex = isBlock ? /^ *>>> ?/ : /^ *> ?/gm;
|
||||||
|
const content = all.replace(removeSyntaxRegex, '');
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: parse(content, Object.assign({ }, state, { inQuote: true })),
|
||||||
|
type: 'blockQuote'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
codeBlock: Object.assign({ }, markdown.defaultRules.codeBlock, {
|
||||||
|
match: markdown.inlineRegex(/^```(([a-z0-9-]+?)\n+)?\n*([^]+?)\n*```/i),
|
||||||
|
parse: function(capture, parse, state) {
|
||||||
|
return {
|
||||||
|
lang: (capture[2] || '').trim(),
|
||||||
|
content: capture[3] || '',
|
||||||
|
inQuote: state.inQuote || false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
html: (node, output, state) => {
|
||||||
|
let code;
|
||||||
|
if (node.lang && highlight.getLanguage(node.lang))
|
||||||
|
code = highlight.highlight(node.lang, node.content, true); // Discord seems to set ignoreIllegals: true
|
||||||
|
|
||||||
|
if (code && state.cssModuleNames) // Replace classes in hljs output
|
||||||
|
code.value = code.value.replace(/<span class="([a-z0-9-_ ]+)">/gi, (str, m) =>
|
||||||
|
str.replace(m, m.split(' ').map(cl => state.cssModuleNames[cl] || cl).join(' ')));
|
||||||
|
|
||||||
|
return htmlTag('pre', htmlTag(
|
||||||
|
'code', code ? code.value : markdown.sanitizeText(node.content), { class: `hljs${code ? ' ' + code.language : ''}` }, state
|
||||||
|
), null, state);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
newline: markdown.defaultRules.newline,
|
||||||
|
escape: markdown.defaultRules.escape,
|
||||||
|
autolink: Object.assign({ }, markdown.defaultRules.autolink, {
|
||||||
|
parse: capture => {
|
||||||
|
return {
|
||||||
|
content: [{
|
||||||
|
type: 'text',
|
||||||
|
content: capture[1]
|
||||||
|
}],
|
||||||
|
target: capture[1]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
html: (node, output, state) => {
|
||||||
|
return htmlTag('a', output(node.content, state), { href: markdown.sanitizeUrl(node.target) }, state);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
url: Object.assign({ }, markdown.defaultRules.url, {
|
||||||
|
parse: capture => {
|
||||||
|
return {
|
||||||
|
content: [{
|
||||||
|
type: 'text',
|
||||||
|
content: capture[1]
|
||||||
|
}],
|
||||||
|
target: capture[1]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
html: (node, output, state) => {
|
||||||
|
return htmlTag('a', output(node.content, state), { href: markdown.sanitizeUrl(node.target) }, state);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
em: Object.assign({ }, markdown.defaultRules.em, {
|
||||||
|
parse: function(capture, parse, state) {
|
||||||
|
const parsed = markdown.defaultRules.em.parse(capture, parse, Object.assign({ }, state, { inEmphasis: true }));
|
||||||
|
return state.inEmphasis ? parsed.content : parsed;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
strong: markdown.defaultRules.strong,
|
||||||
|
u: markdown.defaultRules.u,
|
||||||
|
strike: Object.assign({ }, markdown.defaultRules.del, {
|
||||||
|
match: markdown.inlineRegex(/^~~([\s\S]+?)~~(?!_)/),
|
||||||
|
}),
|
||||||
|
inlineCode: Object.assign({ }, markdown.defaultRules.inlineCode, {
|
||||||
|
match: source => markdown.defaultRules.inlineCode.match.regex.exec(source),
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return htmlTag('code', markdown.sanitizeText(node.content.trim()), null, state);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
text: Object.assign({ }, markdown.defaultRules.text, {
|
||||||
|
match: source => /^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff-]|\n\n|\n|\w+:\S|$)/.exec(source),
|
||||||
|
html: function(node, output, state) {
|
||||||
|
if (state.escapeHTML)
|
||||||
|
return markdown.sanitizeText(node.content);
|
||||||
|
|
||||||
|
return node.content;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
emoticon: {
|
||||||
|
order: markdown.defaultRules.text.order,
|
||||||
|
match: source => /^(¯\\_\(ツ\)_\/¯)/.exec(source),
|
||||||
|
parse: function(capture) {
|
||||||
|
return {
|
||||||
|
type: 'text',
|
||||||
|
content: capture[1]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return output(node.content, state);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
br: Object.assign({ }, markdown.defaultRules.br, {
|
||||||
|
match: markdown.anyScopeRegex(/^\n/),
|
||||||
|
}),
|
||||||
|
spoiler: {
|
||||||
|
order: 0,
|
||||||
|
match: source => /^\|\|([\s\S]+?)\|\|/.exec(source),
|
||||||
|
parse: function(capture, parse, state) {
|
||||||
|
return {
|
||||||
|
content: parse(capture[1], state)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return htmlTag('a', output(node.content, state), { class: 'd-spoiler' }, state);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
link: markdown.defaultRules.link
|
||||||
|
};
|
||||||
|
|
||||||
|
const discordCallbackDefaults = {
|
||||||
|
user: node => '@' + markdown.sanitizeText(node.id),
|
||||||
|
channel: node => '#' + markdown.sanitizeText(node.id),
|
||||||
|
role: node => '&' + markdown.sanitizeText(node.id),
|
||||||
|
everyone: () => '@everyone',
|
||||||
|
here: () => '@here'
|
||||||
|
};
|
||||||
|
|
||||||
|
const rulesDiscord = {
|
||||||
|
discordUser: {
|
||||||
|
order: markdown.defaultRules.strong.order,
|
||||||
|
match: source => /^<@!?([0-9]*)>/.exec(source),
|
||||||
|
parse: function(capture) {
|
||||||
|
return {
|
||||||
|
id: capture[1]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return htmlTag('span', state.discordCallback.user(node), { class: 'd-mention d-user' }, state);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
discordChannel: {
|
||||||
|
order: markdown.defaultRules.strong.order,
|
||||||
|
match: source => /^<#?([0-9]*)>/.exec(source),
|
||||||
|
parse: function(capture) {
|
||||||
|
return {
|
||||||
|
id: capture[1]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return htmlTag('span', state.discordCallback.channel(node), { class: 'd-mention d-channel' }, state);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
discordRole: {
|
||||||
|
order: markdown.defaultRules.strong.order,
|
||||||
|
match: source => /^<@&([0-9]*)>/.exec(source),
|
||||||
|
parse: function(capture) {
|
||||||
|
return {
|
||||||
|
id: capture[1]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return htmlTag('span', state.discordCallback.role(node), { class: 'd-mention d-role' }, state);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
discordEmoji: {
|
||||||
|
order: markdown.defaultRules.strong.order,
|
||||||
|
match: source => /^<(a?):(\w+):(\d+)>/.exec(source),
|
||||||
|
parse: function(capture) {
|
||||||
|
return {
|
||||||
|
animated: capture[1] === "a",
|
||||||
|
name: capture[2],
|
||||||
|
id: capture[3],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return htmlTag('img', '', {
|
||||||
|
class: `d-emoji${node.animated ? ' d-emoji-animated' : ''}`,
|
||||||
|
src: `https://cdn.discordapp.com/emojis/${node.id}.${node.animated ? 'gif' : 'png'}`,
|
||||||
|
alt: `:${node.name}:`
|
||||||
|
}, false, state);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
discordEveryone: {
|
||||||
|
order: markdown.defaultRules.strong.order,
|
||||||
|
match: source => /^@everyone/.exec(source),
|
||||||
|
parse: function() {
|
||||||
|
return { };
|
||||||
|
},
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return htmlTag('span', state.discordCallback.everyone(node), { class: 'd-mention d-user' }, state);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
discordHere: {
|
||||||
|
order: markdown.defaultRules.strong.order,
|
||||||
|
match: source => /^@here/.exec(source),
|
||||||
|
parse: function() {
|
||||||
|
return { };
|
||||||
|
},
|
||||||
|
html: function(node, output, state) {
|
||||||
|
return htmlTag('span', state.discordCallback.here(node), { class: 'd-mention d-user' }, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(rules, rulesDiscord);
|
||||||
|
|
||||||
|
const rulesDiscordOnly = Object.assign({ }, rulesDiscord, {
|
||||||
|
text: Object.assign({ }, markdown.defaultRules.text, {
|
||||||
|
match: source => /^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff-]|\n\n|\n|\w+:\S|$)/.exec(source),
|
||||||
|
html: function(node, output, state) {
|
||||||
|
if (state.escapeHTML)
|
||||||
|
return markdown.sanitizeText(node.content);
|
||||||
|
|
||||||
|
return node.content;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const rulesEmbed = Object.assign({ }, rules, {
|
||||||
|
link: markdown.defaultRules.link
|
||||||
|
});
|
||||||
|
|
||||||
|
const parser = markdown.parserFor(rules);
|
||||||
|
const htmlOutput = markdown.htmlFor(markdown.ruleOutput(rules, 'html'));
|
||||||
|
const parserDiscord = markdown.parserFor(rulesDiscordOnly);
|
||||||
|
const htmlOutputDiscord = markdown.htmlFor(markdown.ruleOutput(rulesDiscordOnly, 'html'));
|
||||||
|
const parserEmbed = markdown.parserFor(rulesEmbed);
|
||||||
|
const htmlOutputEmbed = markdown.htmlFor(markdown.ruleOutput(rulesEmbed, 'html'));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse markdown and return the HTML output
|
||||||
|
* @param {String} source Source markdown content
|
||||||
|
* @param {Object} [options] Options for the parser
|
||||||
|
* @param {Boolean} [options.embed=false] Parse as embed content
|
||||||
|
* @param {Boolean} [options.escapeHTML=true] Escape HTML in the output
|
||||||
|
* @param {Boolean} [options.discordOnly=false] Only parse Discord-specific stuff (such as mentions)
|
||||||
|
* @param {Object} [options.discordCallback] Provide custom handling for mentions and emojis
|
||||||
|
* @param {Object} [options.cssModuleNames] An object mapping css classes to css module classes
|
||||||
|
*/
|
||||||
|
function toHTML(source, options, customParser, customHtmlOutput) {
|
||||||
|
if ((customParser || customHtmlOutput) && (!customParser || !customHtmlOutput))
|
||||||
|
throw new Error('You must pass both a custom parser and custom htmlOutput function, not just one');
|
||||||
|
|
||||||
|
options = Object.assign({
|
||||||
|
embed: false,
|
||||||
|
escapeHTML: true,
|
||||||
|
discordOnly: false,
|
||||||
|
discordCallback: { }
|
||||||
|
}, options || { });
|
||||||
|
|
||||||
|
let _parser = parser;
|
||||||
|
let _htmlOutput = htmlOutput;
|
||||||
|
if (customParser) {
|
||||||
|
_parser = customParser;
|
||||||
|
_htmlOutput = customHtmlOutput;
|
||||||
|
} else if (options.discordOnly) {
|
||||||
|
_parser = parserDiscord;
|
||||||
|
_htmlOutput = htmlOutputDiscord;
|
||||||
|
} else if (options.embed) {
|
||||||
|
_parser = parserEmbed;
|
||||||
|
_htmlOutput = htmlOutputEmbed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
inline: true,
|
||||||
|
inQuote: false,
|
||||||
|
inEmphasis: false,
|
||||||
|
escapeHTML: options.escapeHTML,
|
||||||
|
cssModuleNames: options.cssModuleNames || null,
|
||||||
|
discordCallback: Object.assign({ }, discordCallbackDefaults, options.discordCallback)
|
||||||
|
};
|
||||||
|
|
||||||
|
return _htmlOutput(_parser(source, state), state);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
parser: source => parser(source, { inline: true }),
|
||||||
|
htmlOutput,
|
||||||
|
toHTML,
|
||||||
|
rules,
|
||||||
|
rulesDiscordOnly,
|
||||||
|
rulesEmbed,
|
||||||
|
markdownEngine: markdown,
|
||||||
|
htmlTag
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user