diff --git a/marko/components/date/index.marko b/marko/components/date/index.marko
new file mode 100644
index 0000000..a98d6fa
--- /dev/null
+++ b/marko/components/date/index.marko
@@ -0,0 +1,5 @@
+import moment from "moment";
+
+
+ ${(input.utc ? moment.utc(input.value) : moment(input.value)).format(input.format || "MMM D, YYYY")}
+
\ No newline at end of file
diff --git a/marko/components/markdown/index.marko b/marko/components/markdown/index.marko
index ca647ef..756bb53 100644
--- a/marko/components/markdown/index.marko
+++ b/marko/components/markdown/index.marko
@@ -1,3 +1,4 @@
+
\ No newline at end of file
diff --git a/marko/global/base.less b/marko/global/base.less
index e4a07cf..e7f4b74 100644
--- a/marko/global/base.less
+++ b/marko/global/base.less
@@ -51,3 +51,71 @@ body {
background-color: #555;
color: #000;
}
+
+/*
+ * Tooltip magic.
+ */
+.tooltip {
+ position: relative;
+ border-bottom: 0.5px dotted; /* If you want dots under the hoverable text */
+
+ span {
+ cursor: default;
+ }
+
+ > .tooltip-content {
+ visibility: hidden;
+ width: 400px;
+ text-align: left;
+ padding: 0.25em 1ch;
+
+ position: absolute;
+ z-index: 11000;
+ pointer-events: none;
+
+ top: 0;
+ left: 105%;
+
+ border: 1px solid;
+
+ > h1 {
+ font-size: 1.5em;
+ margin: 0;
+ text-align: center;
+ border: none;
+ }
+
+ > h2 {
+ font-size: 1em;
+ margin: 0;
+ margin-bottom: 0.15em;
+ margin-top: -0.25em;
+ font-weight: 200;
+ opacity: 0.5;
+ text-align: center;
+ border: none;
+ }
+
+ p:last-of-type {
+ padding-bottom: 0;
+ }
+ }
+}
+
+.no-tooltip {
+ position: relative;
+}
+
+.tooltip:hover {
+ > .tooltip-content {
+ visibility: visible;
+ }
+}
+
+@media screen and (max-width: 1200px) {
+ .tooltip {
+ > .tooltip-content {
+ visibility: hidden !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/marko/global/colors.less b/marko/global/colors.less
index 050d1f4..ae3bf8a 100644
--- a/marko/global/colors.less
+++ b/marko/global/colors.less
@@ -92,7 +92,7 @@ body.theme-data {
}
-div.markdown-content .orange, body.theme-logs div.markdown-content blockquote, body.theme-logs div.markdown-content table, body.theme-logs div.markdown-content pre {
+div.markdown-content .orange, body.theme-logs .color-blockquote, body.theme-logs div.markdown-content blockquote, body.theme-logs div.markdown-content table, body.theme-logs div.markdown-content pre {
background-color: rgba(221, 170, 17, 0.125);
color: #DA1;
@@ -100,7 +100,7 @@ div.markdown-content .orange, body.theme-logs div.markdown-content blockquote, b
color: #DA1;
}
}
-div.markdown-content .blue, body.theme-story div.markdown-content blockquote, body.theme-story div.markdown-content table, body.theme-story div.markdown-content pre {
+div.markdown-content .blue, body.theme-story .color-blockquote, body.theme-story div.markdown-content blockquote, body.theme-story div.markdown-content table, body.theme-story div.markdown-content pre {
background-color: rgba(34, 187, 255, 0.125);
color: #4BF;
@@ -108,7 +108,7 @@ div.markdown-content .blue, body.theme-story div.markdown-content blockquote, bo
color: #4BF; //
}
}
-div.markdown-content .green, body.theme-mapp div.markdown-content blockquote, body.theme-mapp div.markdown-content table, body.theme-mapp div.markdown-content pre {
+div.markdown-content .green, body.theme-mapp .color-blockquote, body.theme-mapp div.markdown-content blockquote, body.theme-mapp div.markdown-content table, body.theme-mapp div.markdown-content pre {
background-color: rgba(17,255,136, 0.125);
color: #1F8;
diff --git a/marko/page/story-content/components/chapter-meta/index.marko b/marko/page/story-content/components/chapter-meta/index.marko
index 747cf07..9165ff5 100644
--- a/marko/page/story-content/components/chapter-meta/index.marko
+++ b/marko/page/story-content/components/chapter-meta/index.marko
@@ -1,6 +1,14 @@
\ No newline at end of file
diff --git a/marko/page/story-content/components/chapter-meta/style.less b/marko/page/story-content/components/chapter-meta/style.less
index 16d07ea..c5a6a1c 100644
--- a/marko/page/story-content/components/chapter-meta/style.less
+++ b/marko/page/story-content/components/chapter-meta/style.less
@@ -13,6 +13,10 @@ div.chapter-meta {
a:hover {
border-bottom: 0.5px solid;
}
+
+ .tooltip {
+ border-bottom: 0.25px dotted;
+ }
}
div.chapter-meta.weak {
diff --git a/marko/page/story-content/components/chapter/component.js b/marko/page/story-content/components/chapter/component.js
index 3138782..05929a8 100644
--- a/marko/page/story-content/components/chapter/component.js
+++ b/marko/page/story-content/components/chapter/component.js
@@ -3,6 +3,11 @@ module.exports = class {
this.state = {
modal: null,
removed: false,
+ commentLabels: {
+ Article: "Comment",
+ Message: "Message",
+ Chat: "Chat Message",
+ },
}
}
diff --git a/marko/page/story-content/components/chapter/index.marko b/marko/page/story-content/components/chapter/index.marko
index 24066db..3b7465d 100644
--- a/marko/page/story-content/components/chapter/index.marko
+++ b/marko/page/story-content/components/chapter/index.marko
@@ -16,10 +16,22 @@
+
-
+
+
\ No newline at end of file
diff --git a/marko/page/story-content/components/chapter/style.less b/marko/page/story-content/components/chapter/style.less
index dd658f6..67698fb 100644
--- a/marko/page/story-content/components/chapter/style.less
+++ b/marko/page/story-content/components/chapter/style.less
@@ -49,4 +49,30 @@
div.chapter-content {
font-size: 1.25em;
}
+
+ div.comment-section {
+ margin: 1em 4ch 2em 4ch;
+
+ div.add-comment {
+ text-align: center;
+ margin-top: 1em;
+ padding: 1em 0;
+ font-size: 1.5em;
+ border: 1px solid;
+ opacity: 0.5;
+ cursor: pointer;
+ }
+ div.add-comment:hover {
+ opacity: 1;
+ }
+ div.add-comment:first-child {
+ margin-top: 0;
+ }
+ }
+
+ @media screen and (max-width: 1200px) {
+ div.comment-section {
+ margin: 1em 2ch 2em 2ch;
+ }
+ }
}
\ No newline at end of file
diff --git a/marko/page/story-content/components/comment/component.js b/marko/page/story-content/components/comment/component.js
new file mode 100644
index 0000000..4c7e0bf
--- /dev/null
+++ b/marko/page/story-content/components/comment/component.js
@@ -0,0 +1,18 @@
+module.exports = class {
+ onCreate(input) {
+ this.state = {
+ showCharacter: false,
+ paragraphs: input.comment.source.split('\n').filter(l => l.length > 1),
+ }
+ }
+
+ onInput(input) {
+ if (this.state) {
+ this.state.paragraphs = input.comment.source.split('\n').filter(l => l.length > 1)
+ }
+ }
+
+ toggle(key) {
+ this.state[key] = !this.state[key]
+ }
+}
\ No newline at end of file
diff --git a/marko/page/story-content/components/comment/index.marko b/marko/page/story-content/components/comment/index.marko
new file mode 100644
index 0000000..2cbbe5b
--- /dev/null
+++ b/marko/page/story-content/components/comment/index.marko
@@ -0,0 +1,110 @@
+import moment from "moment"
+
+
\ No newline at end of file
diff --git a/marko/page/story-content/components/comment/style.less b/marko/page/story-content/components/comment/style.less
new file mode 100644
index 0000000..748d791
--- /dev/null
+++ b/marko/page/story-content/components/comment/style.less
@@ -0,0 +1,113 @@
+div.comment {
+ position: relative;
+
+ div.options {
+ width: 100%;
+ max-width: 95ch;
+ }
+}
+
+div.comment.mode-message {
+ margin-bottom: 1.5em;
+ font-size: 1em;
+
+ .metadata {
+ padding-bottom: 0.5em;
+ }
+
+ .content {
+ outline: 1px solid;
+ padding: 0.25em 1ch;
+
+ font-size: 1.25em;
+
+ table.header {
+ border-bottom: 0.5px solid;
+ margin: 0;
+ width: 100%;
+
+ tbody {
+ tr {
+ text-align: left;
+
+ th {
+ width: 12ch;
+ padding-right: 1ch;
+ }
+
+ td {
+ width: 100%;
+ }
+ }
+ }
+ }
+ }
+
+ div.body {
+ padding-top: 0.5em;
+
+ p:first-of-type {
+ margin-top: 0;
+ padding-top: 0;
+ }
+ }
+}
+
+div.comment.mode-chat {
+ div.options {
+ display: none;
+ bottom: -0.25em;
+
+ a {
+ background: black;
+ opacity: 0.666;
+ }
+ a:hover {
+ opacity: 1;
+ }
+ }
+
+ div.content {
+ line-height: 2em;
+ font-size: 1.125em;
+
+ div.tooltip-content {
+ text-indent: 0;
+ }
+
+ div.message-text {
+ vertical-align: top;
+ padding-left: 2ch;
+ text-indent: -2ch;
+
+ div.body {
+ p:first-of-type {
+ display: inline;
+ }
+
+ p:last-of-type {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ }
+
+ p {
+ line-height: 1.5em;
+ }
+ }
+ }
+ }
+}
+
+div.comment.mode-article {
+ margin-bottom: 1em;
+
+ .content {
+ font-size: 1.25em;
+ }
+}
+
+div.comment.mode-chat:hover {
+ div.options {
+ display: block;
+ }
+}
\ No newline at end of file
diff --git a/marko/page/story-content/components/create-chapter-modal/component.js b/marko/page/story-content/components/create-chapter-modal/component.js
index cf7c03f..184f0d3 100644
--- a/marko/page/story-content/components/create-chapter-modal/component.js
+++ b/marko/page/story-content/components/create-chapter-modal/component.js
@@ -11,6 +11,7 @@ module.exports = class {
title: "",
source: "",
fictionalDate: "",
+ commentMode: "Disabled",
},
}
@@ -19,18 +20,18 @@ module.exports = class {
onInput(input) {
if (input.chapter && !this.first) {
- let {fictionalDate, title, source} = input.chapter
+ let {fictionalDate, title, source, commentMode, commentsLocked} = input.chapter
if (fictionalDate != null) {
fictionalDate = moment.utc(fictionalDate).format("MMM D, YYYY")
}
- this.state.values = {fictionalDate, title, source}
+ this.state.values = {fictionalDate, title, source, commentMode, commentsLocked}
}
}
change(key, ev) {
- this.state.values[key] = ev.target.value
+ this.state.values = Object.assign({}, this.state.values, {[key]: ev.target.value})
}
open() {
@@ -60,7 +61,7 @@ module.exports = class {
fictionalDate = null
}
- const input = {storyId: this.input.storyId, title: values.title, source: values.source, fictionalDate}
+ const input = {storyId: this.input.storyId, title: values.title, source: values.source, fictionalDate, commentMode: values.commentMode}
chapterApi.addChapter(input).then(chapter => {
this.emit("add", chapter)
@@ -70,11 +71,12 @@ module.exports = class {
title: "",
source: "",
fictionalDate: "",
+ commentMode: "Disabled",
}
}).catch(errs => {
console.warn("Failed to edit:", errs)
- this.state.error = "Failed to edit: " + errs[0].message
+ this.state.error = "Failed to edit: " + (errs[0]||errs||{}).message || errs
}).then(() => {
this.state.loading = false
})
diff --git a/marko/page/story-content/components/create-chapter-modal/index.marko b/marko/page/story-content/components/create-chapter-modal/index.marko
index 212d402..df40492 100644
--- a/marko/page/story-content/components/create-chapter-modal/index.marko
+++ b/marko/page/story-content/components/create-chapter-modal/index.marko
@@ -12,5 +12,13 @@
+
+
+
\ No newline at end of file
diff --git a/marko/page/story-content/components/create-comment-modal/component.js b/marko/page/story-content/components/create-comment-modal/component.js
new file mode 100644
index 0000000..806f04f
--- /dev/null
+++ b/marko/page/story-content/components/create-comment-modal/component.js
@@ -0,0 +1,96 @@
+const moment = require("moment")
+
+const {commentApi} = require("../../../../../rpdata/api/Comment")
+const {charactersApi} = require("../../../../../rpdata/api/Character")
+
+module.exports = class {
+ onCreate(input) {
+ this.state = {
+ error: null,
+ loading: false,
+ values: {
+ subject: "",
+ source: "",
+ characterName: "",
+ characterId: "",
+ fictionalDate: "",
+ },
+ characters: [],
+ opened: false,
+ }
+
+ this.first = false
+ }
+
+ onMount() {
+ charactersApi.list({author: (this.input.user||{}).name}).then((characters) => {
+ this.state.characters = characters.sort((a,b) => a.name.localeCompare(b.name))
+ })
+ }
+
+ change(key, ev) {
+ this.state.values = Object.assign({}, this.state.values, {[key]: ev.target.value})
+ }
+
+ open() {
+ if (!this.state.opened) {
+ charactersApi.list({author: (this.input.user||{}).name}).then((characters) => {
+ this.state.characters = characters.sort((a,b) => a.name.localeCompare(b.name))
+ })
+ }
+ }
+
+ close() {
+ this.first = false
+ this.state.opened = false
+ this.emit("close")
+ }
+
+ save() {
+ const values = this.state.values
+
+ if (values.source.length < 1) {
+ this.state.error = "You cannot post an empty comment."
+ console.warn(values)
+ return
+ }
+
+ let fictionalDate = new Date(values.fictionalDate + " UTC")
+ if (values.fictionalDate != "") {
+ if (Number.isNaN(fictionalDate)) {
+ this.state.error = `Could not parse ${values.fictionalDate} as date!`
+ return
+ }
+ } else {
+ fictionalDate = null
+ }
+
+ const input = {
+ chapterId: this.input.chapter.id,
+ subject: values.subject,
+ source: values.source,
+ characterName: values.characterName,
+ characterId: values.characterId,
+ fictionalDate: fictionalDate,
+ }
+
+ commentApi.addComment(input).then(chapter => {
+ this.emit("add", chapter)
+ this.emit("close")
+
+ this.state.values = {
+ subject: "",
+ source: "",
+ characterName: "",
+ characterId: "",
+ fictionalDate: "",
+ }
+ }).catch(errs => {
+ console.warn("Failed to add comemnt:", errs)
+
+ this.state.error = "Failed to add comemnt: " + (errs[0]||errs||{}).message || errs
+ }).then(() => {
+ this.state.loading = false
+ })
+ }
+}
\ No newline at end of file
diff --git a/marko/page/story-content/components/create-comment-modal/index.marko b/marko/page/story-content/components/create-comment-modal/index.marko
new file mode 100644
index 0000000..cba8f24
--- /dev/null
+++ b/marko/page/story-content/components/create-comment-modal/index.marko
@@ -0,0 +1,27 @@
+
+ Create Chapter
+
+ ${state.error}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/marko/page/story-content/components/edit-chapter-modal/component.js b/marko/page/story-content/components/edit-chapter-modal/component.js
index c551084..dedbebb 100644
--- a/marko/page/story-content/components/edit-chapter-modal/component.js
+++ b/marko/page/story-content/components/edit-chapter-modal/component.js
@@ -11,6 +11,8 @@ module.exports = class {
title: "",
source: "",
fictionalDate: "",
+ commentMode: "Article",
+ commentsLocked: false,
},
}
@@ -19,18 +21,18 @@ module.exports = class {
onInput(input) {
if (input.chapter && !this.first) {
- let {fictionalDate, title, source} = input.chapter
+ let {fictionalDate, title, source, commentMode, commentsLocked} = input.chapter
if (fictionalDate != null) {
fictionalDate = moment.utc(fictionalDate).format("MMM D, YYYY")
}
- this.state.values = {fictionalDate, title, source}
+ this.state.values = {fictionalDate, title, source, commentMode, commentsLocked}
}
}
change(key, ev) {
- this.state.values[key] = ev.target.value
+ this.state.values = Object.assign({}, this.state.values, {[key]: ev.target.value})
}
open() {
@@ -55,7 +57,7 @@ module.exports = class {
fictionalDate = null
}
- const input = {id: this.input.chapter.id, title: values.title, source: values.source}
+ const input = {id: this.input.chapter.id, title: values.title, source: values.source, commentsLocked: values.commentsLocked, commentMode: values.commentMode}
if (fictionalDate != null) {
input.fictionalDate = fictionalDate
diff --git a/marko/page/story-content/components/edit-chapter-modal/index.marko b/marko/page/story-content/components/edit-chapter-modal/index.marko
index 24e7575..30ae30a 100644
--- a/marko/page/story-content/components/edit-chapter-modal/index.marko
+++ b/marko/page/story-content/components/edit-chapter-modal/index.marko
@@ -12,5 +12,17 @@
+
+
+
+
\ No newline at end of file
diff --git a/rpdata/api/Chapter.js b/rpdata/api/Chapter.js
index b46788e..915c74f 100644
--- a/rpdata/api/Chapter.js
+++ b/rpdata/api/Chapter.js
@@ -48,12 +48,31 @@ class ChapterAPI {
createdDate
fictionalDate
editedDate
+ canComment
+ commentMode
+ commentsLocked
+ comments {
+ id
+ subject
+ author
+ characterName
+ character {
+ id
+ name
+ author
+ description
+ }
+ fictionalDate
+ createdDate
+ editedDate
+ source
+ }
}
}
`, {input}, {permissions: ["member", "story.add"]}).then((data) => {
const ac = data.addChapter
- return new Chapter(ac.id, ac.title, ac.author, ac.source, ac.createdDate, ac.fictionalDate, ac.editedDate)
+ return new Chapter(ac.id, ac.title, ac.author, ac.source, ac.createdDate, ac.fictionalDate, ac.editedDate, ac.canComment, ac.commentMode, ac.commentsLocked, ac.comments)
})
}
@@ -70,6 +89,25 @@ class ChapterAPI {
title
fictionalDate
source
+ canComment
+ commentMode
+ commentsLocked
+ comments {
+ id
+ subject
+ author
+ characterName
+ character {
+ id
+ name
+ author
+ description
+ }
+ fictionalDate
+ createdDate
+ editedDate
+ source
+ }
}
}
`, {input}, {permissions: ["member", "story.edit"]}).then(({editChapter}) => {
@@ -77,7 +115,7 @@ class ChapterAPI {
editChapter.fictionalDate = new Date(editChapter.fictionalDate)
}
- return editChapter
+ return Object.assign({comments:[]}, editChapter)
})
}
diff --git a/rpdata/api/Comment.js b/rpdata/api/Comment.js
index bb02c2c..5c8ead7 100644
--- a/rpdata/api/Comment.js
+++ b/rpdata/api/Comment.js
@@ -48,4 +48,74 @@ class CommentCharacter {
}
}
-module.exports = {Comment, CommentCharacter}
\ No newline at end of file
+class CommentAPI {
+ /**
+ * @param {string} id
+ * @returns {Promise}
+ */
+ find(id) {
+ return query(`
+ query FindComment($id: String!) {
+ comment(id: $id) {
+ id
+ subject
+ author
+ characterName
+ character {
+ id
+ name
+ author
+ description
+ }
+ fictionalDate
+ createdDate
+ editedDate
+ source
+ }
+ }
+ `, {id}).then(({comment}) => {
+ return new Comment(
+ comment.id, comment.subject, comment.author,
+ comment.characterName, comment.character,
+ comment.fictionalDate, comment.createdDate,
+ comment.editedDate, comment.source,
+ )
+ })
+ }
+
+ /**
+ * @param {any} input
+ * @returns {Promise}
+ */
+ addComment(input) {
+ return query(`
+ mutation AddComment($input: CommentAddInput!) {
+ addComment(input: $input) {
+ id
+ subject
+ author
+ characterName
+ character {
+ id
+ name
+ author
+ description
+ }
+ fictionalDate
+ createdDate
+ editedDate
+ source
+ }
+ }
+ `, {input}).then(({comment}) => {
+ return new Comment(
+ comment.id, comment.subject, comment.author,
+ comment.characterName, comment.character,
+ comment.fictionalDate, comment.createdDate,
+ comment.editedDate, comment.source,
+ )
+ })
+ }
+}
+
+module.exports = {Comment, CommentCharacter, commentApi: new CommentAPI}
\ No newline at end of file