Initial Commit
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
module.exports = class {
|
||||
onCreate(input) {
|
||||
this.state = {
|
||||
src: input.src,
|
||||
orientation: "portrait",
|
||||
style: {
|
||||
filter: `opacity(${input.opacity || 0.20})`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onInput(input) {
|
||||
if (input.src != this.state.src) {
|
||||
this.updateOrientation()
|
||||
}
|
||||
|
||||
if (input.opacity != this.state.opacity) {
|
||||
this.state.style.filter = `opacity(${input.opacity || 0.20})`
|
||||
}
|
||||
}
|
||||
|
||||
onMount() {
|
||||
this.updateOrientation()
|
||||
}
|
||||
|
||||
updateOrientation() {
|
||||
const image = this.getEl("image", 0)
|
||||
|
||||
if (image.complete && typeof(image.naturalHeight) !== 'undefined' && image.naturalHeight !== 0) {
|
||||
const width = image.naturalWidth
|
||||
const height = image.naturalHeight
|
||||
|
||||
this.setLandscape(width > (height * 1.50))
|
||||
} else {
|
||||
image.onload = () => {
|
||||
const width = image.naturalWidth
|
||||
const height = image.naturalHeight
|
||||
|
||||
this.setLandscape(width > (height * 1.50))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setLandscape(value) {
|
||||
const orientation = value ? "landscape" : "portrait"
|
||||
|
||||
if (orientation !== this.state.orientation) {
|
||||
this.state.orientation = orientation
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<img key="image" src=input.src style=state.style class=["background", state.orientation] />
|
||||
@@ -0,0 +1,23 @@
|
||||
.background {
|
||||
/* Set rules to fill background */
|
||||
width: 100%;
|
||||
/* Set up proportionate scaling */
|
||||
min-height: 100%;
|
||||
height: auto;
|
||||
/* Set up positioning */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.background.landscape {
|
||||
/* Set rules to fill background */
|
||||
height: 100%;
|
||||
/* Set up proportionate scaling */
|
||||
min-width: 100%;
|
||||
width: auto;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
const moment = require("moment")
|
||||
|
||||
module.exports = class {
|
||||
onCreate({kind, value, updated}) {
|
||||
this.state = {text: null, color: "color-menu", tooltip: null}
|
||||
|
||||
if (value == null || value == "") {
|
||||
return
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case "date": {
|
||||
const m = moment(value)
|
||||
if (m.year() < 2) {
|
||||
break
|
||||
}
|
||||
|
||||
const dateStr = m.format("MMM D, YYYY")
|
||||
|
||||
this.state.text = dateStr
|
||||
|
||||
if (updated != null && Date.parse(updated) > Date.parse(value)) {
|
||||
const m2 = moment(updated)
|
||||
this.state.tooltip = "Originally posted: " + dateStr
|
||||
this.state.text = m2.format("MMM D, YYYY") + " *"
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case "tag": {
|
||||
this.state.color = `color-tag-${value.kind.toLowerCase()}`
|
||||
this.state.text = value.name
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case "author": {
|
||||
this.state.text = value
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
default: {
|
||||
this.state.color = "color-menu"
|
||||
this.state.text = value
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<div if(state.text != null && state.text != "") class=["item-meta", input.kind, state.color] title=state.tooltip>${state.text}</div>
|
||||
<div class="spc"> </div>
|
||||
@@ -0,0 +1,6 @@
|
||||
<if(input.enableAllTags)>
|
||||
<item-meta for(tag in input.tags) kind="tag" value=tag />
|
||||
</if>
|
||||
<else>
|
||||
<item-meta kind="tag" value=(input.tags[0] || null) />
|
||||
</else>
|
||||
@@ -0,0 +1,15 @@
|
||||
<tr class="content-list-item color-primary">
|
||||
<td class="icon color-highlight-primary">${input.icon}</td>
|
||||
<td class="content color-primary color-highlight-dark">
|
||||
<div class="title">
|
||||
<a class="color-primary" href=input.link>${input.name}</a>
|
||||
</div>
|
||||
<div class="description color-text">${input.description || ""}</div>
|
||||
<div class="meta">
|
||||
<item-meta kind="date" value=input.createdDate updated=input.updatedDate />
|
||||
<item-meta kind="date" value=input.fictionalDate />
|
||||
<item-tag-list tags=input.tags enableAllTags=input.enableAllTags />
|
||||
<item-meta kind="author" value=input.author />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,51 @@
|
||||
tr.content-list-item {
|
||||
user-select: none;
|
||||
outline: 0.05px solid;
|
||||
|
||||
> td.icon {
|
||||
font-size: 2.75em;
|
||||
text-align: center;
|
||||
width: 2.5ch;
|
||||
outline: 0.05px solid;
|
||||
}
|
||||
|
||||
> td.content {
|
||||
padding: 0.25em;
|
||||
padding-bottom: 0.33em;
|
||||
margin: 0;
|
||||
|
||||
> .title {
|
||||
padding: 0.25em 1ch;
|
||||
user-select: text;
|
||||
|
||||
a {
|
||||
font-size: 1.333em;
|
||||
}
|
||||
a:hover {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
> .description {
|
||||
margin: 0 1ch;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .meta {
|
||||
> div {
|
||||
display: inline-block;
|
||||
padding: 0.25em 1ch;
|
||||
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
> div.spc {
|
||||
padding: 0;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<table class="content-list" cellSpacing="0px">
|
||||
<tbody>
|
||||
<include(input.renderBody)/>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,12 @@
|
||||
table.content-list {
|
||||
padding-bottom: 3em;
|
||||
|
||||
width: 99%;
|
||||
max-width: 100ch;
|
||||
padding-right: 1em;
|
||||
|
||||
margin: auto;
|
||||
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 1em;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<!-- style in marko/global/navbar.less -->
|
||||
|
||||
<nav class="layout-navbar color-primary">
|
||||
<h1 class="color-primary">Aite RP</h1>
|
||||
<div class="vr color-menu" />
|
||||
<div class="options">
|
||||
<a class=(input.site === "story" ? "color-primary" : "color-menu") href="/story/">Story</a>
|
||||
<a class=(input.site === "logs" ? "color-primary" : "color-menu") href="/logs/">Logs</a>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,39 @@
|
||||
const MarkdownIt = require("markdown-it")
|
||||
const md = new MarkdownIt({
|
||||
html: true,
|
||||
linkify: true,
|
||||
typographer: false,
|
||||
langPrefix: "language-",
|
||||
})
|
||||
md.use(require("markdown-it-container"), "green")
|
||||
md.use(require("markdown-it-container"), "orange")
|
||||
md.use(require("markdown-it-container"), "blue")
|
||||
md.use(require("./plugins/wikilink"))
|
||||
|
||||
const renderer = md.renderer
|
||||
|
||||
module.exports = class {
|
||||
onCreate(input) {
|
||||
this.state = {
|
||||
render: () => {},
|
||||
}
|
||||
|
||||
this.render(input.source || "")
|
||||
}
|
||||
|
||||
onInput(input) {
|
||||
if (input.source) {
|
||||
this.render(input.source)
|
||||
}
|
||||
}
|
||||
|
||||
render(source) {
|
||||
this.state.render = (out) => {
|
||||
if (out.w) {
|
||||
out.w(md.render(source))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderer.rules
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class=["markdown-content", "color-text", input.class]>
|
||||
<include(state.render) />
|
||||
</div>
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
|
||||
Based on the markdown-it-wikilinks, which is distributed under the MIT license.
|
||||
|
||||
https://github.com/jsepia/markdown-it-wikilinks @ 79fe609a03917f7df11128231118a66a559076d0
|
||||
|
||||
Copyright (c) 2016 Julio Sepia
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
const Plugin = require('markdown-it-regexp')
|
||||
|
||||
module.exports = new Plugin(/\[\[([\w'\s/]+)(\|([\w'\s/]+))?\]\]/, match => {
|
||||
let label = ""
|
||||
let page = ""
|
||||
|
||||
if (match[3] != null) {
|
||||
label = match[3]
|
||||
page = encodeURIComponent(match[1])
|
||||
} else {
|
||||
label = match[1]
|
||||
page = encodeURIComponent(label)
|
||||
}
|
||||
|
||||
if (label == "" || page == "") {
|
||||
return match.input
|
||||
}
|
||||
|
||||
return `<a class="wiki-link" href="https://wiki.aiterp.net?title=${page}">${label}</a>`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
div.markdown-content {
|
||||
line-height: 1.333em;
|
||||
font-size: 1.25em;
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0;
|
||||
margin-top: 0.75em;
|
||||
line-height: 1.2em;
|
||||
text-align: left;
|
||||
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
h1:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
margin: 0;
|
||||
margin-top: 0.75em;
|
||||
padding-bottom: 0.25em;
|
||||
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.25em;
|
||||
margin: 0;
|
||||
margin-top: 1em;
|
||||
padding: 0;
|
||||
margin-bottom: -0.25em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: -0.5em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1em;
|
||||
margin: 0;
|
||||
margin-bottom: -0.5em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1em;
|
||||
opacity: 0.5;
|
||||
margin: 0;
|
||||
margin-bottom: -0.5em;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
margin: 2em 2ch;
|
||||
border-bottom: 4px dotted;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding: 0.5em 3ch;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0.5em 0;
|
||||
margin: 0;
|
||||
}
|
||||
p:first-child {
|
||||
padding-top: 0.25em;
|
||||
}
|
||||
|
||||
.orange, .blue, .green, blockquote {
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
margin: 0.5em 0;
|
||||
padding: 0.125em 0.5em 0 0.5em;
|
||||
outline: 1px solid;
|
||||
|
||||
p {
|
||||
padding: 0.5em 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
border: 1px solid;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border: 1px solid;
|
||||
padding: 0em 0.5em;
|
||||
|
||||
th {
|
||||
font-size: 0.75em;
|
||||
padding: 0 1ch;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
opacity: 0.75;
|
||||
}
|
||||
a:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div class=["menu-blurb", input.class]><include(input.renderBody)/></div>
|
||||
@@ -0,0 +1,7 @@
|
||||
.menu-blurb {
|
||||
opacity: 0.5;
|
||||
padding: 0.25em 1.5ch;
|
||||
}
|
||||
.menu-blurb.error {
|
||||
color: red;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div class="menu-gap"></div>
|
||||
@@ -0,0 +1,3 @@
|
||||
.menu-gap {
|
||||
padding: 0.25em;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div class="menu-header color-menu"><include(input.renderBody)/></div>
|
||||
@@ -0,0 +1,5 @@
|
||||
.menu-header {
|
||||
padding: 0.125em 1.5ch;
|
||||
opacity: 0.5;
|
||||
user-select: none;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = class {
|
||||
onCreate(input) {
|
||||
this.state = {
|
||||
classes: ["menu-link", "color-menu", input.class],
|
||||
}
|
||||
|
||||
this.state.classes.push(input.selected ? "selected" : "not-selected")
|
||||
}
|
||||
|
||||
onClick() {
|
||||
this.emit("click")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<a on-click("onClick") href=input.href>
|
||||
<div class=state.classes>
|
||||
<div class="icon color-primary">${input.icon}</div>
|
||||
<div class=["text", input.selected ? "color-primary" : input.textClass]>
|
||||
<include(input.renderBody) />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
@@ -0,0 +1,28 @@
|
||||
div.menu-link {
|
||||
width: 100%;
|
||||
padding-left: 0.5ch;
|
||||
font-size: 1.1em;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
div.icon {
|
||||
display: inline-block;
|
||||
width: 3ch;
|
||||
padding: 0.15em 0.125em;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.text {
|
||||
display: inline-block;
|
||||
max-width: 22ch;
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
|
||||
span.weak {
|
||||
opacity: 0.3333;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="menu">
|
||||
<include(input.renderBody) />
|
||||
<if(input.user != null)>
|
||||
<menu-gap />
|
||||
<menu-header>User</menu-header>
|
||||
<menu-link if(!input.user.loggedIn) icon="L" href="/auth/login">Login</menu-link>
|
||||
<menu-link if(input.user.loggedIn) icon="L" href="/auth/logout">Logout <span class="weak">(${input.user.name})</span></menu-link>
|
||||
</if>
|
||||
<else-if(!input.allowNoUser)>
|
||||
<menu-blurb class="error">input.user is missing!</menu-blurb>
|
||||
</else-if>
|
||||
</div>
|
||||
@@ -0,0 +1,14 @@
|
||||
.menu {
|
||||
position: fixed;
|
||||
top: 5.5em;
|
||||
bottom: 0;
|
||||
width: 28ch;
|
||||
|
||||
padding: 0.333em;
|
||||
|
||||
text-align: left;
|
||||
|
||||
user-select: none;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
Reference in New Issue
Block a user