From ed01006b21d50f91c2cfeb185b5b7ffc5c3848c9 Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Sat, 29 Sep 2018 13:38:18 +0200 Subject: [PATCH] logs, logs-content: Added basic view of logs and added characters to logs --- marko/components/annotation/style.less | 5 +- .../components/content-list-item/index.marko | 10 ++- marko/components/content-list-item/style.less | 15 ++++ marko/components/markdown/index.marko | 2 +- marko/components/markdown/style.less | 3 +- marko/components/menu-link/style.less | 9 +++ marko/global/colors.less | 6 +- .../components/logs-content-menu/index.marko | 8 ++ .../logs-content/components/page/component.js | 17 ++++ .../logs-content/components/page/index.marko | 7 ++ .../logs-content/components/page/style.less | 10 +++ .../components/post-meta/component.js | 50 ++++++++++++ .../components/post-meta/index.marko | 6 ++ .../components/post-meta/style.less | 20 +++++ .../logs-content/components/post/component.js | 50 ++++++++++++ .../logs-content/components/post/index.marko | 20 +++++ .../logs-content/components/post/style.less | 36 +++++++++ marko/page/logs-content/view.marko | 6 ++ .../logs/components/logs-list/index.marko | 1 + .../components/chapter/index.marko | 2 +- .../components/chapter/style.less | 4 + routes/logs-content/index.js | 12 +++ rpdata/api/Channel.js | 17 ++++ rpdata/api/Character.js | 29 ++++++- rpdata/api/Log.js | 81 +++++++++++++++++++ rpdata/api/Post.js | 26 ++++++ server.js | 3 +- 27 files changed, 442 insertions(+), 13 deletions(-) create mode 100644 marko/page/logs-content/components/logs-content-menu/index.marko create mode 100644 marko/page/logs-content/components/page/component.js create mode 100644 marko/page/logs-content/components/page/index.marko create mode 100644 marko/page/logs-content/components/page/style.less create mode 100644 marko/page/logs-content/components/post-meta/component.js create mode 100644 marko/page/logs-content/components/post-meta/index.marko create mode 100644 marko/page/logs-content/components/post-meta/style.less create mode 100644 marko/page/logs-content/components/post/component.js create mode 100644 marko/page/logs-content/components/post/index.marko create mode 100644 marko/page/logs-content/components/post/style.less create mode 100644 marko/page/logs-content/view.marko create mode 100644 routes/logs-content/index.js create mode 100644 rpdata/api/Channel.js create mode 100644 rpdata/api/Log.js create mode 100644 rpdata/api/Post.js diff --git a/marko/components/annotation/style.less b/marko/components/annotation/style.less index 00800c2..82fcdc1 100644 --- a/marko/components/annotation/style.less +++ b/marko/components/annotation/style.less @@ -12,11 +12,12 @@ div.annotation { padding-bottom: 0.25em; } - p { + p, div.markdown-content > p { margin-top: 0.5em; } - p:first-of-type { + p:first-of-type, div.markdown-content > p:first-of-type { margin: 0; + padding: 0; } } diff --git a/marko/components/content-list-item/index.marko b/marko/components/content-list-item/index.marko index 0cbd89a..46a02d2 100644 --- a/marko/components/content-list-item/index.marko +++ b/marko/components/content-list-item/index.marko @@ -4,7 +4,15 @@
${input.name}
-
${input.description || ""}
+
+
${input.description}
+
+
+
+ ${input.characters.length > 6 ? character.shortName : character.name} + , +
+
diff --git a/marko/components/content-list-item/style.less b/marko/components/content-list-item/style.less index 8c91227..1915b3a 100644 --- a/marko/components/content-list-item/style.less +++ b/marko/components/content-list-item/style.less @@ -34,6 +34,21 @@ tr.content-list-item { } } + > .characters { + margin: 0 1ch; + + > .character { + display: inline-block; + margin-right: 1ch; + } + + > .character:last-of-type { + .comma { + display: none; + } + } + } + > .meta { > div { display: inline-block; diff --git a/marko/components/markdown/index.marko b/marko/components/markdown/index.marko index cd0e754..ca647ef 100644 --- a/marko/components/markdown/index.marko +++ b/marko/components/markdown/index.marko @@ -1,3 +1,3 @@ -
+
\ No newline at end of file diff --git a/marko/components/markdown/style.less b/marko/components/markdown/style.less index f31be4e..5e9ee40 100644 --- a/marko/components/markdown/style.less +++ b/marko/components/markdown/style.less @@ -1,6 +1,5 @@ div.markdown-content { - line-height: 1.333em; - font-size: 1.25em; + line-height: 1.40em; h1 { font-size: 2em; diff --git a/marko/components/menu-link/style.less b/marko/components/menu-link/style.less index 89566de..875c6cc 100644 --- a/marko/components/menu-link/style.less +++ b/marko/components/menu-link/style.less @@ -3,6 +3,8 @@ div.menu-link { padding-left: 0.5ch; font-size: 1.1em; + white-space: nowrap; + cursor: pointer; div.icon { @@ -26,6 +28,13 @@ div.menu-link { } } } +div.menu-link:hover { + div.text { + span.weak { + opacity: 0.75; + } + } +} div.menu-link.dark { opacity: 0.5; } diff --git a/marko/global/colors.less b/marko/global/colors.less index df96e0d..c6ead63 100644 --- a/marko/global/colors.less +++ b/marko/global/colors.less @@ -28,7 +28,7 @@ body.theme-logs { color: #776; } .menu-link.selected { - background-color: rgba(255, 187, 17, 0.125); + background-color: rgba(255, 183, 0, 0.226); } .menu-link:hover, .Menu > .head-menu > a:hover { background-color: rgba(255, 187, 17, 0.25); @@ -37,13 +37,13 @@ body.theme-logs { color: #DA1; } .color-text, input, textarea, select { - color: #AAA; + color: #BBB; } .color-highlight-dark { background-color: rgba(18, 9, 0, 0.50); } .color-highlight-primary { - background-color: rgba(255, 187, 15, 0.25); + background-color: rgba(255, 187, 17, 0.25); color: #DA1; } } diff --git a/marko/page/logs-content/components/logs-content-menu/index.marko b/marko/page/logs-content/components/logs-content-menu/index.marko new file mode 100644 index 0000000..5fbd2d4 --- /dev/null +++ b/marko/page/logs-content/components/logs-content-menu/index.marko @@ -0,0 +1,8 @@ + + Log + ${input.log.channel.name} + ${input.log.channel.eventName} + + ${character.name} (${character.author}) + + \ No newline at end of file diff --git a/marko/page/logs-content/components/page/component.js b/marko/page/logs-content/components/page/component.js new file mode 100644 index 0000000..88ff022 --- /dev/null +++ b/marko/page/logs-content/components/page/component.js @@ -0,0 +1,17 @@ +const moment = require("moment") + +module.exports = class { + onCreate(input) { + this.state = { + log: input.log + } + } + + get title() { + if (this.state.log.title) { + return this.state.log.title + } + + return `${this.state.log.channel.name} – ${moment(this.state.log.date).format("MMMM D, YYYY")}` + } +} \ No newline at end of file diff --git a/marko/page/logs-content/components/page/index.marko b/marko/page/logs-content/components/page/index.marko new file mode 100644 index 0000000..21b990b --- /dev/null +++ b/marko/page/logs-content/components/page/index.marko @@ -0,0 +1,7 @@ + +
+
+

${component.title}

+ +
+
\ No newline at end of file diff --git a/marko/page/logs-content/components/page/style.less b/marko/page/logs-content/components/page/style.less new file mode 100644 index 0000000..45f47fb --- /dev/null +++ b/marko/page/logs-content/components/page/style.less @@ -0,0 +1,10 @@ +div.logs-content { + width: 90%; + max-width: 75ch; + margin: auto; + + h1 { + font-weight: 200; + text-align: center; + } +} \ No newline at end of file diff --git a/marko/page/logs-content/components/post-meta/component.js b/marko/page/logs-content/components/post-meta/component.js new file mode 100644 index 0000000..5a92295 --- /dev/null +++ b/marko/page/logs-content/components/post-meta/component.js @@ -0,0 +1,50 @@ +const moment = require("moment") + +module.exports = class { + onCreate() { + this.state = {text: null, color: "color-menu", href: null, tooltip: null} + } + + onInput(input) { + if (this.state != null) { + this.updateState(input) + } + } + + updateState({kind, weak, value, updated}) { + this.state = {text: null, color: "color-menu", href: null, tooltip: null} + + if (value == null || value == "") { + return + } + + switch (kind) { + case "timestamp": { + const m = moment(value) + if (m.year() < 2) { + break + } + + this.state.tooltip = m.format("YYYY-MM-DD HH:mm:ss") + this.state.text = `[${m.format("HH:mm")}]` + + break + } + + case "author": { + this.state.text = value + this.state.tooltip = "See all stories by " + value + this.state.href = `/story/by-author/${value}/` + + break + } + + default: { + this.state.color = "color-menu" + this.state.text = value + + break + } + } + } +} \ No newline at end of file diff --git a/marko/page/logs-content/components/post-meta/index.marko b/marko/page/logs-content/components/post-meta/index.marko new file mode 100644 index 0000000..919bc85 --- /dev/null +++ b/marko/page/logs-content/components/post-meta/index.marko @@ -0,0 +1,6 @@ + +
+ ${state.text} + ${state.text} +
+ \ No newline at end of file diff --git a/marko/page/logs-content/components/post-meta/style.less b/marko/page/logs-content/components/post-meta/style.less new file mode 100644 index 0000000..9990166 --- /dev/null +++ b/marko/page/logs-content/components/post-meta/style.less @@ -0,0 +1,20 @@ +div.post-meta { + display: inline-block; + padding: 0; + padding-right: 1em; + margin: 0; + + user-select: none; + + a { + color: inherit; + border-bottom: 0.25px dotted; + } + a:hover { + border-bottom: 0.5px solid; + } +} + +div.post-meta.weak { + opacity: 0.5; +} \ No newline at end of file diff --git a/marko/page/logs-content/components/post/component.js b/marko/page/logs-content/components/post/component.js new file mode 100644 index 0000000..d761573 --- /dev/null +++ b/marko/page/logs-content/components/post/component.js @@ -0,0 +1,50 @@ +module.exports = class { + onCreate(input) { + this.state = { + shortName: "", + name: "", + text: "", + } + + this.updatePost(input) + } + + onInput(input) { + if (this.state == null) { + return + } + + this.updatePost(input) + } + + updatePost(input) { + this.state.shortName = input.post.nick.split("_").shift() + this.state.name = input.post.nick + + this.state.text = input.post.text.replace(/\x02/g, "**") + + if (input.post.kind === "text" && !this.state.text.includes("\"")) { + this.state.text = '"' + this.state.text + '"' + } + + if (!input.post.nick.startsWith("=")) { + const postNick = input.post.nick.replace("'s", "").replace("s'", "s") + for (const character of input.characters) { + for (const nick of character.nicks) { + if (nick === postNick) { + this.state.shortName = character.shortName + return + } + } + } + } + } + + kindClass(prefix) { + if (this.input.post == null) { + return + } + + return `${prefix}${this.input.post.kind.replace(".", "-")}` + } +} \ No newline at end of file diff --git a/marko/page/logs-content/components/post/index.marko b/marko/page/logs-content/components/post/index.marko new file mode 100644 index 0000000..93b20fd --- /dev/null +++ b/marko/page/logs-content/components/post/index.marko @@ -0,0 +1,20 @@ +
+ +
+ + + +
+
+ +
+
+ +
+
+ +
+
\ No newline at end of file diff --git a/marko/page/logs-content/components/post/style.less b/marko/page/logs-content/components/post/style.less new file mode 100644 index 0000000..c65c594 --- /dev/null +++ b/marko/page/logs-content/components/post/style.less @@ -0,0 +1,36 @@ +div.post { + margin-bottom: 1ch; + + .post-meta-row { + padding: 0; + margin: 0; + } + + div.post-body { + font-size: 1.25em; + + div.nick-wrapper { + display: inline; + + .nick-decoration { + display: inline; + } + + .nick { + display: inline; + } + } + + div.post-content { + display: inline; + } + + div.annotation { + margin-top: 0.33em; + } + } + div.post-body p:first-of-type { + margin-top: 0; + padding-top: 0; + } +} \ No newline at end of file diff --git a/marko/page/logs-content/view.marko b/marko/page/logs-content/view.marko new file mode 100644 index 0000000..2a0715f --- /dev/null +++ b/marko/page/logs-content/view.marko @@ -0,0 +1,6 @@ + + <@body> + + + + \ No newline at end of file diff --git a/marko/page/logs/components/logs-list/index.marko b/marko/page/logs/components/logs-list/index.marko index b752755..aeaf35e 100644 --- a/marko/page/logs/components/logs-list/index.marko +++ b/marko/page/logs/components/logs-list/index.marko @@ -6,6 +6,7 @@ import moment from "moment" icon="L" link=("/logs/" + log.id) description=log.description + characters=log.characters name=(log.title || (log.channelName + " - " + moment(log.date).format("MMMM D, YYYY"))) tags=[{kind: "Location", name: log.channelName}, {kind: "Event", name: log.event}] enableAllTags=true diff --git a/marko/page/story-content/components/chapter/index.marko b/marko/page/story-content/components/chapter/index.marko index f167b14..5be1f64 100644 --- a/marko/page/story-content/components/chapter/index.marko +++ b/marko/page/story-content/components/chapter/index.marko @@ -12,7 +12,7 @@ import moment from "moment"
- + diff --git a/marko/page/story-content/components/chapter/style.less b/marko/page/story-content/components/chapter/style.less index 1c37f02..0b3311b 100644 --- a/marko/page/story-content/components/chapter/style.less +++ b/marko/page/story-content/components/chapter/style.less @@ -31,4 +31,8 @@ opacity: 1; } } + + div.chapter-content { + font-size: 1.25em; + } } \ No newline at end of file diff --git a/routes/logs-content/index.js b/routes/logs-content/index.js new file mode 100644 index 0000000..e32746a --- /dev/null +++ b/routes/logs-content/index.js @@ -0,0 +1,12 @@ +const express = require("express") + +const {logsApi} = require("../../rpdata/api/Log") + +const viewTemplate = require("../../marko/page/logs-content/view.marko") + +module.exports = async(req, res, next) => { + res.markoAsync(viewTemplate, { + log: logsApi.find(req.params.id), + selected: {index: true}, + }) +} \ No newline at end of file diff --git a/rpdata/api/Channel.js b/rpdata/api/Channel.js new file mode 100644 index 0000000..4482ee5 --- /dev/null +++ b/rpdata/api/Channel.js @@ -0,0 +1,17 @@ +const {query} = require("../client") + +class Channel { + constructor(name, logged, hub, eventName, locationName) { + this.name = name + this.logged = logged + this.hub = hub + this.eventName = eventName + this.locationName = locationName + } + + static fromData(data) { + return new Channel(data.name, data.logged, data.hub, data.eventName, data.locationName) + } +} + +module.exports = { Channel } \ No newline at end of file diff --git a/rpdata/api/Character.js b/rpdata/api/Character.js index f877647..50b9ecf 100644 --- a/rpdata/api/Character.js +++ b/rpdata/api/Character.js @@ -1,5 +1,30 @@ const {query} = require("../client") class Character { - -} \ No newline at end of file + /** + * @param {string} id + * @param {string[]} nicks + * @param {string} author + * @param {string} name + * @param {string} shortName + * @param {string} description + */ + constructor(id, nicks, author, name, shortName, description) { + this.id = id + this.nicks = nicks + this.nick = this.nicks[0] || null + this.author = author + this.name = name + this.shortName = shortName + this.description = description + } + + /** + * Create a character object from data. + */ + static fromData(data) { + return new Character(data.id, data.nicks, data.author, data.name, data.shortName, data.description) + } +} + +module.exports = { Character } \ No newline at end of file diff --git a/rpdata/api/Log.js b/rpdata/api/Log.js new file mode 100644 index 0000000..b17d107 --- /dev/null +++ b/rpdata/api/Log.js @@ -0,0 +1,81 @@ +const {query} = require("../client") + +const {Character} = require("./Character") +const {Channel} = require("./Channel") +const {Post} = require("./Post") + +class Log { + /** + * @param {string} id + * @param {string} shortId + * @param {Date | string | number} date + * @param {string} title + * @param {string} eventName + * @param {string} description + * @param {string} open + * @param {any} channel + * @param {any[]} characters + * @param {any[]} posts + */ + constructor(id, shortId, date, title, eventName, description, open, channel, characters, posts) { + this.id = id + this.shortId = shortId + this.date = date + this.title = title + this.eventName = eventName + this.description = description + this.open = open + this.channel = Channel.fromData(channel) + this.characters = characters.map(c => Character.fromData(c)) + this.posts = posts.map(p => Post.fromData(p)) + } + + static fromData(data) { + return new Log(data.id, data.shortId, data.date, data.title, data.eventName, data.description, data.open, data.channel, data.characters, data.posts) + } +} + +const logsApi = { + find(id) { + return query(` + query FindLog($id: String!) { + log(id: $id) { + id + shortId + date + title + eventName + description + open + channel { + name + logged + hub + eventName + locationName + } + characters { + id + nicks + author + name + shortName + description + } + posts { + id + position + time + kind + nick + text + } + } + } + `, {id}).then(({log}) => { + return Log.fromData(log) + }) + }, +} + +module.exports = { Log, logsApi } \ No newline at end of file diff --git a/rpdata/api/Post.js b/rpdata/api/Post.js new file mode 100644 index 0000000..d57cefb --- /dev/null +++ b/rpdata/api/Post.js @@ -0,0 +1,26 @@ +const {query} = require("../client") + +class Post { + /** + * @param {string} id + * @param {number} position + * @param {Date | string | number} time + * @param {string} kind + * @param {string} nick + * @param {string} text + */ + constructor(id, position, time, kind, nick, text) { + this.id = id + this.position = position + this.time = new Date(time) + this.kind = kind + this.nick = nick + this.text = text + } + + static fromData(data) { + return new Post(data.id, data.position, data.time, data.kind, data.nick, data.text) + } +} + +module.exports = {Post} \ No newline at end of file diff --git a/server.js b/server.js index e6c0bae..f574aea 100644 --- a/server.js +++ b/server.js @@ -76,7 +76,8 @@ app.use("/story/by-tag/", require("./routes/story/by-tag")) app.use("/story/tag-list/", require("./routes/story/tag-list")) app.use("/story/:id(S[0-9a-z]{15})/", require("./routes/story-content")) app.use("/logs/", require("./routes/logs")) - +app.use("/logs/:id([0-9]{4}-[0-1][0-9]-[0-3][0-9]_[0-9]{9}_[A-Za-z\,\']{2,})/", require("./routes/logs-content")) +// 2018-03-10_035344747_Miner'sRespite // Entry point app.get("/", function(req, res) { res.redirect("/story/")