Implemented dark mode and frontpage sidebar
|
@ -40,7 +40,7 @@ const Media = bookshelf.createModel({
|
||||||
},
|
},
|
||||||
|
|
||||||
link() {
|
link() {
|
||||||
return `${Media.baseUrl}${this.get('large_image')}`
|
return `${Media.baseUrl}${this.get('org_image')}`
|
||||||
},
|
},
|
||||||
|
|
||||||
url() {
|
url() {
|
||||||
|
|
|
@ -17,6 +17,9 @@ export default class Resizer {
|
||||||
fit: sharp.fit.inside,
|
fit: sharp.fit.inside,
|
||||||
withoutEnlargement: true,
|
withoutEnlargement: true,
|
||||||
})
|
})
|
||||||
|
.jpeg({
|
||||||
|
quality: 80,
|
||||||
|
})
|
||||||
.toFile(output)
|
.toFile(output)
|
||||||
.then(() => output)
|
.then(() => output)
|
||||||
}
|
}
|
||||||
|
@ -29,6 +32,20 @@ export default class Resizer {
|
||||||
fit: sharp.fit.inside,
|
fit: sharp.fit.inside,
|
||||||
withoutEnlargement: true,
|
withoutEnlargement: true,
|
||||||
})
|
})
|
||||||
|
.jpeg({
|
||||||
|
quality: 80,
|
||||||
|
})
|
||||||
|
.toFile(output)
|
||||||
|
.then(() => output)
|
||||||
|
}
|
||||||
|
|
||||||
|
createLarge(input) {
|
||||||
|
let output = this.Media.getSubUrl(input, 'large')
|
||||||
|
|
||||||
|
return this.sharp(input)
|
||||||
|
.jpeg({
|
||||||
|
quality: 80,
|
||||||
|
})
|
||||||
.toFile(output)
|
.toFile(output)
|
||||||
.then(() => output)
|
.then(() => output)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,15 @@ export default class MediaRoutes {
|
||||||
|
|
||||||
let smallPath = await this.resize.createSmall(result.path)
|
let smallPath = await this.resize.createSmall(result.path)
|
||||||
let mediumPath = await this.resize.createMedium(result.path)
|
let mediumPath = await this.resize.createMedium(result.path)
|
||||||
|
let largePath = await this.resize.createLarge(result.path)
|
||||||
|
|
||||||
let token = this.jwt.signDirect({ site: config.get('upload:name') }, config.get('upload:secret'))
|
let token = this.jwt.signDirect({ site: config.get('upload:name') }, config.get('upload:secret'))
|
||||||
|
|
||||||
let [large, small, medium] = await Promise.all([
|
let [org, small, medium, large] = await Promise.all([
|
||||||
this.uploadFile(token, result.path),
|
this.uploadFile(token, result.path),
|
||||||
this.uploadFile(token, smallPath),
|
this.uploadFile(token, smallPath),
|
||||||
this.uploadFile(token, mediumPath),
|
this.uploadFile(token, mediumPath),
|
||||||
|
this.uploadFile(token, largePath),
|
||||||
])
|
])
|
||||||
|
|
||||||
ctx.body = await this.Media.create({
|
ctx.body = await this.Media.create({
|
||||||
|
@ -36,6 +38,7 @@ export default class MediaRoutes {
|
||||||
small_image: small.path,
|
small_image: small.path,
|
||||||
medium_image: medium.path,
|
medium_image: medium.path,
|
||||||
large_image: large.path,
|
large_image: large.path,
|
||||||
|
org_image: org.path,
|
||||||
size: result.size,
|
size: result.size,
|
||||||
staff_id: ctx.state.user.id,
|
staff_id: ctx.state.user.id,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import send from 'koa-send'
|
import send from 'koa-send'
|
||||||
|
import defaults from './defaults'
|
||||||
|
|
||||||
export function serve(docRoot, pathname, options = {}) {
|
export function serve(docRoot, pathname, options = {}) {
|
||||||
options.root = docRoot
|
options.root = docRoot
|
||||||
|
|
||||||
return (ctx, next) => {
|
return (ctx, next) => {
|
||||||
|
let opts = defaults({}, options)
|
||||||
if (ctx.request.method === 'OPTIONS') return
|
if (ctx.request.method === 'OPTIONS') return
|
||||||
|
|
||||||
let filepath = ctx.path.replace(pathname, '')
|
let filepath = ctx.path.replace(pathname, '')
|
||||||
|
@ -12,7 +14,15 @@ export function serve(docRoot, pathname, options = {}) {
|
||||||
filepath = '/index.html'
|
filepath = '/index.html'
|
||||||
}
|
}
|
||||||
|
|
||||||
return send(ctx, filepath, options).catch((er) => {
|
if (filepath.endsWith('.jpg')
|
||||||
|
|| filepath.endsWith('.png')
|
||||||
|
|| filepath.endsWith('.js')
|
||||||
|
|| filepath.endsWith('.css')
|
||||||
|
|| filepath.endsWith('.svg')) {
|
||||||
|
opts = defaults({ maxage: 2592000 * 1000 }, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
return send(ctx, filepath, opts).catch((er) => {
|
||||||
if (er.code === 'ENOENT' && er.status === 404) {
|
if (er.code === 'ENOENT' && er.status === 404) {
|
||||||
return send(ctx, '/index.html', options)
|
return send(ctx, '/index.html', options)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
$primary-bg: #01579b;
|
$primary-bg: #01579b;
|
||||||
$primary-fg: white;
|
$primary-fg: white;
|
||||||
$primary-light-bg: #3D77C7; /*#4f83cc;*/
|
$primary-fg-url: #FFC7C7;
|
||||||
|
$primary-light-bg: #3D77C7; // #4f83cc;
|
||||||
$primary-light-fg: white;
|
$primary-light-fg: white;
|
||||||
$primary-dark-bg: #002f6c;
|
$primary-dark-bg: #002f6c;
|
||||||
$primary-dark-fg: white;
|
$primary-dark-fg: white;
|
||||||
|
@ -12,7 +14,53 @@ $secondary-light-fg: black;
|
||||||
$secondary-dark-bg: #bb4d00;
|
$secondary-dark-bg: #bb4d00;
|
||||||
$secondary-dark-fg: white;
|
$secondary-dark-fg: white;
|
||||||
|
|
||||||
|
$table-fg: #333;
|
||||||
$border: #ccc;
|
$border: #ccc;
|
||||||
|
$border-fg: black;
|
||||||
|
$border-fg-url: #8f3c00;
|
||||||
$title-fg: #555;
|
$title-fg: #555;
|
||||||
$meta-fg: #757575; /* #999 */
|
$meta-fg: #757575; // #999
|
||||||
$meta-light-fg: #999999;
|
$meta-light-fg: #999999;
|
||||||
|
|
||||||
|
$main-bg: white;
|
||||||
|
$main-fg: black;
|
||||||
|
$input-bg: white;
|
||||||
|
$input-border: #333;
|
||||||
|
$input-fg: black;
|
||||||
|
|
||||||
|
$newsitem-bg: transparent;
|
||||||
|
$newsitem-border: none;
|
||||||
|
|
||||||
|
/* Dark theme */
|
||||||
|
|
||||||
|
$dark_primary-bg: #013b68;
|
||||||
|
$dark_primary-fg: white;
|
||||||
|
$dark_primary-fg-url: #FFC7C7;
|
||||||
|
$dark_primary-light-bg: #28518B;
|
||||||
|
$dark_primary-light-fg: white;
|
||||||
|
$dark_primary-dark-bg: #002f6c;
|
||||||
|
$dark_primary-dark-fg: white;
|
||||||
|
|
||||||
|
$dark_secondary-bg: #e05e00;
|
||||||
|
$dark_secondary-fg: black;
|
||||||
|
$dark_secondary-light-bg: #ffad42;
|
||||||
|
$dark_secondary-light-fg: black;
|
||||||
|
$dark_secondary-dark-bg: #e05e00;
|
||||||
|
$dark_secondary-dark-fg: white;
|
||||||
|
|
||||||
|
$dark_table-fg: #333;
|
||||||
|
$dark_border: #343536;
|
||||||
|
$dark_border-fg: #d7dadc;;
|
||||||
|
$dark_border-fg-url: #e05e00;
|
||||||
|
$dark_title-fg: #808080;
|
||||||
|
$dark_meta-fg: #d7dadc;
|
||||||
|
$dark_meta-light-fg: #999999;
|
||||||
|
|
||||||
|
$dark_main-bg: black;
|
||||||
|
$dark_main-fg: #d7dadc;
|
||||||
|
$dark_input-bg: #272729;
|
||||||
|
$dark_input-border: #343536;
|
||||||
|
$dark_input-fg: white;
|
||||||
|
|
||||||
|
$dark_newsitem-bg: #1a1a1b;
|
||||||
|
$dark_newsitem-border: 1px solid #343536;
|
||||||
|
|
|
@ -38,3 +38,21 @@
|
||||||
@import 'pages';
|
@import 'pages';
|
||||||
@import 'articles';
|
@import 'articles';
|
||||||
@import 'staff';
|
@import 'staff';
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
.admin-wrapper {
|
||||||
|
background: $dark_primary-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-actions {
|
||||||
|
background: $dark_primary-bg;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: $dark_primary-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $dark_secondary-light-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
102
app/app.scss
|
@ -21,6 +21,10 @@ body {
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
ol, ul {
|
ol, ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +55,8 @@ img {
|
||||||
}
|
}
|
||||||
|
|
||||||
.maincontainer {
|
.maincontainer {
|
||||||
|
background: $main-bg;
|
||||||
|
color: $main-fg;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -133,9 +139,9 @@ form {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
margin: 0 0 0.5em;
|
margin: 0 0 0.5em;
|
||||||
background: white;
|
background: $input-bg;
|
||||||
border: 1px solid #333;
|
border: 1px solid $input-border;
|
||||||
color: black;
|
color: $input-fg;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
|
@ -203,7 +209,7 @@ table {
|
||||||
tbody td {
|
tbody td {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: solid 1px $bordercolor;
|
border: solid 1px $bordercolor;
|
||||||
color: #333;
|
color: $table-fg;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
a,
|
a,
|
||||||
|
@ -247,3 +253,91 @@ table {
|
||||||
@import 'pages/page';
|
@import 'pages/page';
|
||||||
@import 'article/article';
|
@import 'article/article';
|
||||||
@import 'frontpage/frontpage';
|
@import 'frontpage/frontpage';
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
.maincontainer {
|
||||||
|
background: $dark_main-bg;
|
||||||
|
color: $dark_main-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
header {
|
||||||
|
h1 {
|
||||||
|
color: $dark_title-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: $dark_meta-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
h5 {
|
||||||
|
color: $dark_title-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
input[type=text],
|
||||||
|
input[type=password],
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
background: $dark_input-bg;
|
||||||
|
border: 1px solid $dark_input-border;
|
||||||
|
color: $dark_input-fg;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
border-color: $dark_secondary-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=submit] {
|
||||||
|
border: 1px solid $dark_secondary-bg;
|
||||||
|
background: $dark_secondary-light-bg;
|
||||||
|
color: $dark_secondary-light-fg;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $dark_secondary-dark-bg;
|
||||||
|
color: $dark_secondary-dark-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fr-view {
|
||||||
|
a { color: $dark_secondary-dark-bg; }
|
||||||
|
}
|
||||||
|
|
||||||
|
$dark_bordercolor: $dark_primary-bg;
|
||||||
|
$dark_headcolor: $dark_primary-light-bg;
|
||||||
|
$dark_headtext: $dark_primary-light-fg;
|
||||||
|
|
||||||
|
table {
|
||||||
|
border: solid 1px $dark_bordercolor;
|
||||||
|
|
||||||
|
thead th {
|
||||||
|
background-color: $dark_headcolor;
|
||||||
|
border: solid 1px $dark_bordercolor;
|
||||||
|
color: $dark_headtext;
|
||||||
|
}
|
||||||
|
tbody td {
|
||||||
|
border: solid 1px $dark_bordercolor;
|
||||||
|
color: $dark_table-fg;
|
||||||
|
}
|
||||||
|
a,
|
||||||
|
a:visited,
|
||||||
|
a:hover {
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
border: 1px solid $dark_secondary-dark-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
article.article {
|
article.article {
|
||||||
background: white;
|
padding: 0;
|
||||||
padding: 0 0 40px;
|
|
||||||
|
|
||||||
header {
|
header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 20px;
|
margin: 20px 20px 0;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background: $secondary-bg;
|
background: $secondary-bg;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -26,11 +26,14 @@ article.article {
|
||||||
|
|
||||||
.fr-view {
|
.fr-view {
|
||||||
margin: 0 20px;
|
margin: 0 20px;
|
||||||
padding: 0 20px;
|
padding: 20px 20px 60px;
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
flex: 2 0 0;
|
flex: 2 0 0;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
background: $newsitem-bg;
|
||||||
|
border-right: 1px solid #343536;
|
||||||
|
border-left: 1px solid #343536;
|
||||||
|
|
||||||
a.cover img {
|
a.cover img {
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
@ -41,3 +44,19 @@ article.article {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
article.article {
|
||||||
|
header {
|
||||||
|
background: $dark_secondary-bg;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: $dark_secondary-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fr-view {
|
||||||
|
background: $dark_newsitem-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
app/darkmode.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
const storageName = 'darkmode'
|
||||||
|
|
||||||
|
const Darkmode = {
|
||||||
|
darkIsOn: false,
|
||||||
|
|
||||||
|
setDarkMode: function(setOn) {
|
||||||
|
if (setOn) {
|
||||||
|
localStorage.setItem(storageName, true)
|
||||||
|
document.body.className = 'darkmodeon'
|
||||||
|
Darkmode.darkIsOn = true
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem(storageName)
|
||||||
|
document.body.className = ''
|
||||||
|
Darkmode.darkIsOn = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isOn: function() {
|
||||||
|
return Darkmode.darkIsOn
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Darkmode.darkIsOn = localStorage.getItem(storageName)
|
||||||
|
|
||||||
|
module.exports = Darkmode
|
|
@ -1,6 +1,7 @@
|
||||||
const m = require('mithril')
|
const m = require('mithril')
|
||||||
const { Tree } = require('../api/page')
|
const { Tree } = require('../api/page')
|
||||||
const Authentication = require('../authentication')
|
const Authentication = require('../authentication')
|
||||||
|
const Darkmode = require('../darkmode')
|
||||||
|
|
||||||
const Footer = {
|
const Footer = {
|
||||||
oninit: function(vnode) {
|
oninit: function(vnode) {
|
||||||
|
@ -8,7 +9,11 @@ const Footer = {
|
||||||
},
|
},
|
||||||
|
|
||||||
view: function() {
|
view: function() {
|
||||||
console.log(Tree)
|
var pixelRatio = window.devicePixelRatio || 1
|
||||||
|
var darkPrefix = ''
|
||||||
|
if (Darkmode.darkIsOn) {
|
||||||
|
darkPrefix = 'dark_'
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
m('div.sitemap', [
|
m('div.sitemap', [
|
||||||
m('div', 'Sitemap'),
|
m('div', 'Sitemap'),
|
||||||
|
@ -33,7 +38,9 @@ const Footer = {
|
||||||
' (Fuck EU)',
|
' (Fuck EU)',
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
m('div.footer-logo'),
|
m('div.footer-logo', { style: {
|
||||||
|
'background-image': pixelRatio > 1 ? 'url("/assets/img/' + darkPrefix + 'tsun.jpg")' : 'url("/assets/img/' + darkPrefix + 'tsun_small.jpg")'
|
||||||
|
} }),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background: $border;
|
background: $border;
|
||||||
|
color: $border-fg;
|
||||||
|
|
||||||
.sitemap {
|
.sitemap {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -17,7 +18,7 @@ footer {
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #8f3c00;
|
color: $border-fg-url;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.root {
|
a.root {
|
||||||
|
@ -40,7 +41,7 @@ footer {
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-logo {
|
.footer-logo {
|
||||||
background: url('./img/tsun.png') center no-repeat transparent;
|
background: center no-repeat transparent;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
width: 119px;
|
width: 119px;
|
||||||
height: 150px;
|
height: 150px;
|
||||||
|
@ -58,3 +59,17 @@ footer {
|
||||||
a { margin: 0 3px; }
|
a { margin: 0 3px; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
footer {
|
||||||
|
border-top: 1px solid $dark_border;
|
||||||
|
background: $dark_border;
|
||||||
|
color: $dark_border-fg;
|
||||||
|
|
||||||
|
.sitemap {
|
||||||
|
a {
|
||||||
|
color: $dark_border-fg-url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
const m = require('mithril')
|
const m = require('mithril')
|
||||||
|
|
||||||
|
const { Tree } = require('../api/page')
|
||||||
const { getAllArticlesPagination } = require('../api/article')
|
const { getAllArticlesPagination } = require('../api/article')
|
||||||
const { fetchPage } = require('../api/pagination')
|
const { fetchPage } = require('../api/pagination')
|
||||||
const Pages = require('../widgets/pages')
|
const Pages = require('../widgets/pages')
|
||||||
const Newsitem = require('../widgets/newsitem')
|
const Newsitem = require('../widgets/newsitem')
|
||||||
|
const Darkmode = require('../darkmode')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
oninit: function(vnode) {
|
oninit: function(vnode) {
|
||||||
|
@ -52,9 +54,20 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
view: function(vnode) {
|
view: function(vnode) {
|
||||||
|
var deviceWidth = window.innerWidth
|
||||||
|
|
||||||
var bannerPath = ''
|
var bannerPath = ''
|
||||||
|
var asuna_side = ''
|
||||||
|
|
||||||
|
if (deviceWidth > 800) {
|
||||||
|
if (Darkmode.darkIsOn) {
|
||||||
|
asuna_side = '/assets/img/dark_asuna_frontpage.jpg'
|
||||||
|
} else {
|
||||||
|
asuna_side = '/assets/img/asuna_frontpage.jpg'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.featured && this.featured.banner) {
|
if (this.featured && this.featured.banner) {
|
||||||
var deviceWidth = window.innerWidth
|
|
||||||
var pixelRatio = window.devicePixelRatio || 1
|
var pixelRatio = window.devicePixelRatio || 1
|
||||||
if (deviceWidth < 400 && pixelRatio <= 1) {
|
if (deviceWidth < 400 && pixelRatio <= 1) {
|
||||||
bannerPath = this.featured.banner.small_url
|
bannerPath = this.featured.banner.small_url
|
||||||
|
@ -76,16 +89,34 @@ module.exports = {
|
||||||
)
|
)
|
||||||
: null),
|
: null),
|
||||||
m('frontpage', [
|
m('frontpage', [
|
||||||
(this.loading
|
m('aside.sidebar', [
|
||||||
? m('div.loading-spinner')
|
m('div.categories', [
|
||||||
: null),
|
m('h4', 'Categories'),
|
||||||
this.articles.map(function(article) {
|
Tree.map(function(page) {
|
||||||
return m(Newsitem, article)
|
return [
|
||||||
}),
|
m(m.route.Link, { class: 'root', href: '/page/' + page.path }, page.name),
|
||||||
m(Pages, {
|
(page.children.length
|
||||||
base: '/',
|
? m('ul', page.children.map(function(subpage) {
|
||||||
links: this.links,
|
return m('li', m(m.route.Link, { class: 'child', href: '/page/' + subpage.path }, subpage.name))
|
||||||
}),
|
}))
|
||||||
|
: null),
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
asuna_side ? m('img', { src: asuna_side, alt: 'Asuna standing tall welcomes you' }) : null,
|
||||||
|
]),
|
||||||
|
m('.frontpage-news', [
|
||||||
|
(this.loading
|
||||||
|
? m('div.loading-spinner')
|
||||||
|
: null),
|
||||||
|
this.articles.map(function(article) {
|
||||||
|
return m(Newsitem, article)
|
||||||
|
}),
|
||||||
|
m(Pages, {
|
||||||
|
base: '/',
|
||||||
|
links: this.links,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.frontpage-banner {
|
.frontpage-banner {
|
||||||
background-color: #999999;
|
background-color: $meta-light-fg;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
@ -20,14 +20,68 @@
|
||||||
|
|
||||||
frontpage {
|
frontpage {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-self: center;
|
align-self: center;
|
||||||
margin: 0 20px;
|
|
||||||
padding: 0 20px 40px;
|
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
max-width: 1000px;
|
max-width: 1200px;
|
||||||
flex: 2 0 0;
|
flex: 2 0 0;
|
||||||
|
|
||||||
|
.frontpage-news {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.sidebar {
|
||||||
|
width: 250px;
|
||||||
|
flex: 0 0 250px;
|
||||||
|
align-self: flex-start;
|
||||||
|
margin-right: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
img {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.categories {
|
||||||
|
padding: 10px 10px 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background: $newsitem-bg;
|
||||||
|
border: $newsitem-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0 5px 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
border-bottom: 1px solid $border;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding-left: 10px;
|
||||||
|
list-style-type: disc;
|
||||||
|
list-style-position: inside;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
padding: 5px 5px 0px;
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
color: $secondary-dark-bg;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.loading-spinner {
|
.loading-spinner {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +91,28 @@ frontpage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1000px){
|
||||||
|
frontpage aside.sidebar {
|
||||||
|
width: 200px;
|
||||||
|
flex: 0 0 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px){
|
||||||
|
frontpage {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
frontpage aside.sidebar {
|
||||||
|
width: auto;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
align-self: stretch;
|
||||||
|
margin: 20px 0 30px;
|
||||||
|
border-bottom: 1px solid $border;
|
||||||
|
order: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 480px){
|
@media screen and (max-width: 480px){
|
||||||
.frontpage-banner {
|
.frontpage-banner {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -48,3 +124,26 @@ frontpage {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
.frontpage-banner {
|
||||||
|
background-color: $dark_meta-light-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
frontpage {
|
||||||
|
aside.sidebar {
|
||||||
|
.categories {
|
||||||
|
background: $dark_newsitem-bg;
|
||||||
|
border: $dark_newsitem-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
border-bottom: 1px solid $dark_border;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ article.login {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
border: 1px solid $title-fg;
|
border: 1px solid $title-fg;
|
||||||
background: white;
|
background: $main-bg;
|
||||||
|
color: $main-fg;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
@ -45,3 +46,15 @@ article.login {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
.login-wrapper {
|
||||||
|
background: $dark_border;
|
||||||
|
}
|
||||||
|
|
||||||
|
article.login {
|
||||||
|
border: 1px solid $dark_title-fg;
|
||||||
|
background: $dark_main-bg;
|
||||||
|
color: $dark_main-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const m = require('mithril')
|
const m = require('mithril')
|
||||||
const Authentication = require('../authentication')
|
const Authentication = require('../authentication')
|
||||||
|
const Darkmode = require('../darkmode')
|
||||||
const { Tree, getTree } = require('../api/page')
|
const { Tree, getTree } = require('../api/page')
|
||||||
|
|
||||||
const Menu = {
|
const Menu = {
|
||||||
|
@ -34,16 +35,23 @@ const Menu = {
|
||||||
},
|
},
|
||||||
|
|
||||||
view: function() {
|
view: function() {
|
||||||
|
var pixelRatio = window.devicePixelRatio || 1
|
||||||
return [
|
return [
|
||||||
m('div.top', [
|
m('div.top', [
|
||||||
m(m.route.Link,
|
m(m.route.Link,
|
||||||
{ href: '/', class: 'logo' },
|
{ href: '/', class: 'logo', style: {
|
||||||
|
'background-image': pixelRatio > 1 ? 'url("/assets/img/logo.jpg")' : 'url("/assets/img/logo_small.jpg")'
|
||||||
|
} },
|
||||||
m('h2', 'NFP Moe')
|
m('h2', 'NFP Moe')
|
||||||
),
|
),
|
||||||
m('aside', Authentication.currentUser ? [
|
m('aside', Authentication.currentUser ? [
|
||||||
m('p', [
|
m('p', [
|
||||||
'Welcome ' + Authentication.currentUser.email,
|
'Welcome ' + Authentication.currentUser.email,
|
||||||
m(m.route.Link, { href: '/logout' }, 'Logout'),
|
m(m.route.Link, { href: '/logout' }, 'Logout'),
|
||||||
|
(Darkmode.darkIsOn
|
||||||
|
? m('button.dark', { onclick: Darkmode.setDarkMode.bind(Darkmode, false) }, 'Day mode')
|
||||||
|
: m('button.dark', { onclick: Darkmode.setDarkMode.bind(Darkmode, true) }, 'Night mode')
|
||||||
|
)
|
||||||
]),
|
]),
|
||||||
(Authentication.currentUser.level >= 10
|
(Authentication.currentUser.level >= 10
|
||||||
? m('div.adminlinks', [
|
? m('div.adminlinks', [
|
||||||
|
@ -54,7 +62,11 @@ const Menu = {
|
||||||
])
|
])
|
||||||
: null
|
: null
|
||||||
),
|
),
|
||||||
] : null),
|
] : (Darkmode.darkIsOn
|
||||||
|
? m('button.dark', { onclick: Darkmode.setDarkMode.bind(Darkmode, false) }, 'Day mode')
|
||||||
|
: m('button.dark', { onclick: Darkmode.setDarkMode.bind(Darkmode, true) }, 'Night mode')
|
||||||
|
)
|
||||||
|
),
|
||||||
]),
|
]),
|
||||||
m('nav', [
|
m('nav', [
|
||||||
m(m.route.Link, {
|
m(m.route.Link, {
|
||||||
|
|
|
@ -11,8 +11,17 @@
|
||||||
height: 100px;
|
height: 100px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
button.dark {
|
||||||
|
background: transparent;
|
||||||
|
color: $secondary-light-bg;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
a.logo {
|
a.logo {
|
||||||
background: url('./img/logo.png') 25px center no-repeat transparent;
|
background: 25px center no-repeat transparent;
|
||||||
|
background-size: auto 91px;
|
||||||
padding-left: 120px;
|
padding-left: 120px;
|
||||||
display: flex;
|
display: flex;
|
||||||
color: $primary-dark-fg;
|
color: $primary-dark-fg;
|
||||||
|
@ -39,6 +48,10 @@
|
||||||
a {
|
a {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a, a:visited {
|
a, a:visited {
|
||||||
|
@ -103,7 +116,48 @@
|
||||||
background: $primary-bg;
|
background: $primary-bg;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
color: #FFC7C7;
|
color: $primary-fg-url;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
#nav {
|
||||||
|
.top {
|
||||||
|
background: $dark_primary-dark-bg;
|
||||||
|
color: $dark_primary-dark-fg;
|
||||||
|
|
||||||
|
a.logo {
|
||||||
|
color: $dark_primary-dark-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
p {
|
||||||
|
color: $dark_meta-light-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
a, a:visited {
|
||||||
|
color: $dark_secondary-light-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
background: $dark_primary-light-bg;
|
||||||
|
color: $dark_primary-light-fg;
|
||||||
|
|
||||||
|
a, a:visited {
|
||||||
|
color: $dark_primary-light-fg;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-bottom: 3px solid $dark_secondary-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuerror {
|
||||||
|
background: $dark_primary-bg;
|
||||||
|
color: $dark_primary-fg-url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
article.page {
|
article.page {
|
||||||
background: white;
|
padding-bottom: 0;
|
||||||
padding: 0 0 40px;
|
|
||||||
|
|
||||||
header {
|
header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 20px;
|
margin: 20px 20px 0;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background: $secondary-bg;
|
background: $secondary-bg;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -71,6 +70,11 @@ article.page {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
padding: 20px 0;
|
||||||
|
|
||||||
|
background: $newsitem-bg;
|
||||||
|
border-right: $newsitem-border;
|
||||||
|
border-left: $newsitem-border;
|
||||||
|
|
||||||
&.multi {
|
&.multi {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
@ -186,3 +190,44 @@ aside.news {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
article.page {
|
||||||
|
header {
|
||||||
|
background: $dark_secondary-bg;
|
||||||
|
h1 {
|
||||||
|
color: $dark_secondary-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background: $dark_newsitem-bg;
|
||||||
|
border-right: $dark_newsitem-border;
|
||||||
|
border-left: $dark_newsitem-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.sidebar {
|
||||||
|
h4 {
|
||||||
|
border-bottom: 1px solid $dark_border;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.news {
|
||||||
|
&.single {
|
||||||
|
& > h4 {
|
||||||
|
border-bottom: 1px solid $dark_border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 639px){
|
||||||
|
article.page aside.sidebar {
|
||||||
|
border-bottom: 1px solid $dark_border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -233,6 +233,8 @@ newsitem {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
background: $newsitem-bg;
|
||||||
|
border: $newsitem-border;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -342,3 +344,66 @@ pages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkmodeon {
|
||||||
|
fileupload {
|
||||||
|
.showbordericon {
|
||||||
|
border: 3px solid $dark_title-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogue {
|
||||||
|
h2 {
|
||||||
|
background: $dark_secondary-dark-bg;
|
||||||
|
color: $dark_secondary-dark-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: 1px solid $dark_secondary-dark-bg;
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newsentry {
|
||||||
|
color: $dark_meta-fg;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
a {
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.entrymeta {
|
||||||
|
color: $dark_meta-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileinfo {
|
||||||
|
.filetitle {
|
||||||
|
a {
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
border-right: 1px solid $dark_border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newsitem {
|
||||||
|
background: $dark_newsitem-bg;
|
||||||
|
border: $dark_newsitem-border;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
background: $dark_secondary-bg;
|
||||||
|
color: $dark_secondary-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entrymeta {
|
||||||
|
color: $dark_meta-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pages {
|
||||||
|
a {
|
||||||
|
color: $dark_secondary-dark-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ exports.up = function up(knex, Promise) {
|
||||||
table.text('small_image')
|
table.text('small_image')
|
||||||
table.text('medium_image')
|
table.text('medium_image')
|
||||||
table.text('large_image')
|
table.text('large_image')
|
||||||
|
table.text('org_image')
|
||||||
table.integer('size')
|
table.integer('size')
|
||||||
table.integer('staff_id')
|
table.integer('staff_id')
|
||||||
.references('staff.id')
|
.references('staff.id')
|
||||||
|
|
BIN
public/assets/img/asuna_frontpage.jpg
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
public/assets/img/asuna_frontpage.png
Normal file
After Width: | Height: | Size: 437 KiB |
BIN
public/assets/img/asuna_frontpage.xcf
Normal file
BIN
public/assets/img/dark_asuna_frontpage.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
public/assets/img/dark_asuna_frontpage.png
Normal file
After Width: | Height: | Size: 345 KiB |
BIN
public/assets/img/dark_asuna_frontpage.xcf
Normal file
BIN
public/assets/img/dark_tsun.jpg
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
public/assets/img/dark_tsun_small.jpg
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
public/assets/img/heart.psd
Normal file
BIN
public/assets/img/logo.jpg
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
public/assets/img/logo_small.jpg
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
public/assets/img/tsun.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
public/assets/img/tsun_small.jpg
Normal file
After Width: | Height: | Size: 7.7 KiB |
|
@ -10,6 +10,11 @@
|
||||||
<meta name="google-signin-client_id" content="1076074914074-3no1difo1jq3dfug3glfb25pn1t8idud.apps.googleusercontent.com">
|
<meta name="google-signin-client_id" content="1076074914074-3no1difo1jq3dfug3glfb25pn1t8idud.apps.googleusercontent.com">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<script type="text/javascript">
|
||||||
|
if (localStorage.getItem('darkmode')) {
|
||||||
|
document.body.className = 'darkmodeon'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<div class="maincontainer">
|
<div class="maincontainer">
|
||||||
<div id="nav"></div>
|
<div id="nav"></div>
|
||||||
<main id="main"></main>
|
<main id="main"></main>
|
||||||
|
|