Browse Source

Added log suggestions to the bottom of logs.

master 1.5.0
Gisle Aune 5 years ago
parent
commit
99aec4d2cb
  1. 93
      marko/page/logs-content/components/log-suggestions/component.js
  2. 41
      marko/page/logs-content/components/log-suggestions/index.marko
  3. 46
      marko/page/logs-content/components/log-suggestions/style.less
  4. 2
      marko/page/logs-content/components/page/index.marko
  5. 4
      marko/page/logs-content/components/page/style.less
  6. 9
      rpdata/api/LogHeader.js

93
marko/page/logs-content/components/log-suggestions/component.js

@ -0,0 +1,93 @@
const {logHeaderApi} = require("../../../../../rpdata/api/LogHeader")
module.exports = class {
onCreate(input) {
this.state = {
id: input.log.id,
channelName: input.log.channelName,
eventName: input.log.eventName,
nexts: [],
prevs: [],
loaded: false,
error: null,
}
}
onMount() {
this.timeout = setTimeout(() => {
logHeaderApi.list().then(logs => {
const index = logs.findIndex(l => l.id === this.state.id);
if (index === -1) {
return Promise.reject("This log not found in list.")
}
const log = logs[index]
const characterIds = log.characters.map(c => c.id);
const nexts = []
const prevs = []
const foundGroups = {}
let foundChannel = false
for (let i = index - 1; i >= 0; --i) {
const log2 = logs[i]
const hasEvent = (log.eventName ? log.eventName === log2.eventName : false)
const hasChannel = (log.channelName === log2.channelName)
const characters = log2.findCharacters(...characterIds)
const characterIdsKey = characters.map(c => c.id).sort().join(",")
const suggestion = {log: log2, characters, hasEvent, hasChannel}
if (hasChannel && !foundChannel) {
foundChannel = true
foundGroups[characterIdsKey] = true
nexts.push(suggestion)
} else if (hasEvent) {
foundGroups[characterIdsKey] = true
nexts.push(suggestion)
} else if (nexts.length < 8 && !hasEvent && characters.length > 1 && !foundGroups[characterIdsKey]) {
foundGroups[characterIdsKey] = true
nexts.push(suggestion)
}
}
for (let i = index + 1; i < logs.length; ++i) {
const log2 = logs[i]
const hasEvent = (log.eventName ? log.eventName === log2.eventName : false)
const hasChannel = (log.channelName === log2.channelName)
const characters = log2.findCharacters(...characterIds)
const characterIdsKey = characters.map(c => c.id).sort().join(",")
const suggestion = {log: log2, characters, hasEvent, hasChannel}
if (hasChannel && !foundChannel) {
foundChannel = true
foundGroups[characterIdsKey] = true
prevs.push(suggestion)
} else if (hasEvent) {
foundGroups[characterIdsKey] = true
prevs.push(suggestion)
} else if (prevs.length < 8 && !hasEvent && characters.length > 1 && !foundGroups[characterIdsKey]) {
foundGroups[characterIdsKey] = true
prevs.push(suggestion)
}
}
this.state.nexts = nexts;
this.state.prevs = prevs;
this.state.loaded = true;
}).catch(err => {
console.warn("Suggestions load error:", err)
this.suggestionsError = "Failed to load suggestions: " + err.toString()
})
}, 1000)
}
onUnmount() {
clearTimeout(this.timeout)
}
}

41
marko/page/logs-content/components/log-suggestions/index.marko

@ -0,0 +1,41 @@
import moment from "moment"
<div class="log-suggestions">
<if (state.loaded && state.error == null)>
<if (state.nexts.length > 0 || state.prevs.length > 0)>
<if (state.nexts.length > 0)>
<h2 class="color-primary">Next Logs</h2>
<div for(s in state.nexts) class="suggestion color-primary">
<div class="suggestion-header color-primary"><a href=`/logs/${s.log.id}`>${s.log.name || `${s.log.channelName} - ${moment(s.log.date).format("MMMM D, YYYY")}`}</a></div>
<div for(paragraph in (s.log.description||"").split("\n").filter(p => p)) class="suggestion-description color-text">${paragraph}</div>
<div class="suggestion-tags">
<div if(s.hasEvent) class="suggestion-tag color-tag-event">${s.log.eventName}</div>
<div if(s.hasChannel) class="suggestion-tag color-tag-location">${s.log.channelName}</div>
<div for(c in s.characters) class="suggestion-tag color-tag-character">${c.name}</div>
</div>
</div>
</if>
<if (state.prevs.length > 0)>
<h2 class="color-primary">Previous Logs</h2>
<div for(s in state.prevs) class="suggestion color-primary">
<div class="suggestion-header color-primary"><a href=`/logs/${s.log.id}`>${s.log.name || `${s.log.channelName} - ${moment(s.log.date).format("MMMM D, YYYY")}`}</a></div>
<div for(paragraph in (s.log.description||"").split("\n").filter(p => p)) class="suggestion-description color-text">${paragraph}</div>
<div class="suggestion-tags">
<div if(s.hasEvent) class="suggestion-tag color-tag-event">${s.log.eventName}</div>
<div if(s.hasChannel) class="suggestion-tag color-tag-location">${s.log.channelName}</div>
<div for(c in s.characters) class="suggestion-tag color-tag-character">${c.name}</div>
</div>
</div>
</if>
</if>
<else>
<div class="empty color-menu">(No suggestions)</div>
</else>
</if>
<else-if(state.error != null)>
<div class="error color-danger">{state.error}</div>
</else-if>
<else>
<div class="loading color-menu">Loading suggestions...</div>
</else>
</div>

46
marko/page/logs-content/components/log-suggestions/style.less

@ -0,0 +1,46 @@
div.log-suggestions {
padding: 0 0.5ch;
margin-top: 1em;
margin-bottom: 2em;
h2 {
text-align: center;
margin: 0;
margin-bottom: 0.25em;
}
div.empty, div.loading {
text-align: center;
}
div.suggestion {
margin-bottom: 0.5em;
padding: 0.5em;
div.suggestion-header {
margin: 0.125em 0.5ch;
a {
color: inherit;
}
a:hover {
color: white;
}
}
div.suggestion-description {
margin: 0.125em 0.5ch;
}
div.suggestion-tags {
margin-top: 0.25em;
div.suggestion-tag {
display: inline-block;
padding: 0 0.5ch;
margin: 0.125em 0.5ch;
border: 0.25px solid;
}
}
}
}

2
marko/page/logs-content/components/page/index.marko

@ -3,6 +3,7 @@
<div class="logs-content"> <div class="logs-content">
<div class="header"> <div class="header">
<h1 class="color-primary">${component.title}</h1> <h1 class="color-primary">${component.title}</h1>
<p for(paragraph in state.log.description.split("\n").filter(p => p)) class="color-text">${paragraph}</p>
<if-permitted user=input.user permission="log.edit"> <if-permitted user=input.user permission="log.edit">
<a on-click("open", "log.edit") class="color-menu">Edit</a> <a on-click("open", "log.edit") class="color-menu">Edit</a>
</if-permitted> </if-permitted>
@ -28,6 +29,7 @@
highlights=state.highlights highlights=state.highlights
last=(post.position === state.log.posts.length) last=(post.position === state.log.posts.length)
/> />
<log-suggestions log=state.log />
</div> </div>
<add-post-modal enabled=(state.modal === "post.add") logId=state.log.id on-close("close") on-added("postAdded") /> <add-post-modal enabled=(state.modal === "post.add") logId=state.log.id on-close("close") on-added("postAdded") />

4
marko/page/logs-content/components/page/style.less

@ -15,6 +15,10 @@ div.logs-content {
margin-bottom: 0; margin-bottom: 0;
} }
p {
margin: 0.25em 0 0 0;
}
a { a {
vertical-align: middle; vertical-align: middle;
display: inline-block; display: inline-block;

9
rpdata/api/LogHeader.js

@ -27,6 +27,15 @@ class LogHeader {
this.open = open this.open = open
this.characters = characters.map(ch => new LogHeaderCharacter(ch.id, ch.name, ch.shortName, ch.author)) this.characters = characters.map(ch => new LogHeaderCharacter(ch.id, ch.name, ch.shortName, ch.author))
} }
/**
* Return all characters in that log.
*
* @param {...string} ids Character IDs
*/
findCharacters(...ids) {
return this.characters.filter(c => ids.includes(c.id))
}
} }
class LogHeaderCharacter { class LogHeaderCharacter {

Loading…
Cancel
Save