Merge branch 'styling'
This commit is contained in:
		
						commit
						24a2991292
					
				
					 8 changed files with 195 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -12,6 +12,7 @@
 | 
			
		|||
  "dependencies": {
 | 
			
		||||
    "body-parser": "^1.18.3",
 | 
			
		||||
    "bulma": "^0.7.2",
 | 
			
		||||
    "cookie-parser": "^1.4.3",
 | 
			
		||||
    "express": "^4.16.4",
 | 
			
		||||
    "express-fileupload": "^1.0.0",
 | 
			
		||||
    "fecha": "^3.0.2",
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +24,7 @@
 | 
			
		|||
    "socket.io": "^2.2.0",
 | 
			
		||||
    "socket.io-client": "^2.2.0",
 | 
			
		||||
    "striptags": "^3.1.1",
 | 
			
		||||
    "tinycolor2": "^1.4.1",
 | 
			
		||||
    "unused-filename": "^1.0.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,115 @@
 | 
			
		|||
.is-clickable,
 | 
			
		||||
.modal-button {
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Bookshelf Styling */
 | 
			
		||||
.bookshelf {
 | 
			
		||||
  border: 4px solid saddlebrown;
 | 
			
		||||
  background: sienna;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.book-slot {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  overflow: visible;
 | 
			
		||||
  width: 100px;
 | 
			
		||||
  height: 300px; /* The tallest a book could be */
 | 
			
		||||
  border-bottom: 4px solid saddlebrown;
 | 
			
		||||
  margin: 10px 1px -4px !important;
 | 
			
		||||
}
 | 
			
		||||
.book-slot.is-thin {
 | 
			
		||||
  width: 80px;
 | 
			
		||||
}
 | 
			
		||||
.book-slot.is-thick {
 | 
			
		||||
  width: 120px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.book {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  overflow: visible;
 | 
			
		||||
  top: 30px;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
}
 | 
			
		||||
.book.is-short {
 | 
			
		||||
  top: 60px;
 | 
			
		||||
}
 | 
			
		||||
.book.is-tall {
 | 
			
		||||
  top: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.book .spine {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  background: #c0ffee;
 | 
			
		||||
  border: 1px solid #aaa;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  margin-bottom: 4px;
 | 
			
		||||
  z-index: 1;
 | 
			
		||||
  transition: all 0.25s;
 | 
			
		||||
}
 | 
			
		||||
.book:hover .spine {
 | 
			
		||||
  width: 120%;
 | 
			
		||||
  margin-left: -10%;
 | 
			
		||||
  height: 120%;
 | 
			
		||||
  margin-top: -20%;
 | 
			
		||||
  z-index: 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.spine .text-container {
 | 
			
		||||
  width: 260px;
 | 
			
		||||
  height: 100px;
 | 
			
		||||
  transform: rotate(90deg) translateX(82px) translateY(80px);
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  word-break: break-all;
 | 
			
		||||
}
 | 
			
		||||
.spine .title {
 | 
			
		||||
  font-size: 1.3em;
 | 
			
		||||
}
 | 
			
		||||
.spine .subtitle {
 | 
			
		||||
  font-size: 1.1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.book-slot.is-thin .book .spine .text-container {
 | 
			
		||||
  height: 80px;
 | 
			
		||||
  transform: rotate(90deg) translateX(92px) translateY(92px);
 | 
			
		||||
}
 | 
			
		||||
.book-slot.is-thick .book .spine .text-container {
 | 
			
		||||
  height: 120px;
 | 
			
		||||
  transform: rotate(90deg) translateX(72px) translateY(72px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.book.is-short .spine .text-container {
 | 
			
		||||
  width: 230px;
 | 
			
		||||
  transform: rotate(90deg) translateX(68px) translateY(66px);
 | 
			
		||||
}
 | 
			
		||||
.book-slot.is-thin .book.is-short .spine .text-container {
 | 
			
		||||
  transform: rotate(90deg) translateX(78px) translateY(76px);
 | 
			
		||||
}
 | 
			
		||||
.book-slot.is-thick .book.is-short .spine .text-container {
 | 
			
		||||
  transform: rotate(90deg) translateX(58px) translateY(56px);
 | 
			
		||||
}
 | 
			
		||||
.book.is-short .spine .title {
 | 
			
		||||
  font-size: 1.1em;
 | 
			
		||||
}
 | 
			
		||||
.book.is-short .spine .subtitle {
 | 
			
		||||
  font-size: 0.9em;
 | 
			
		||||
}
 | 
			
		||||
.book.is-tall .spine .text-container {
 | 
			
		||||
  width: 290px;
 | 
			
		||||
  transform: rotate(90deg) translateX(98px) translateY(95px);
 | 
			
		||||
}
 | 
			
		||||
.book-slot.is-thin .book.is-tall .spine .text-container {
 | 
			
		||||
  transform: rotate(90deg) translateX(108px) translateY(106px);
 | 
			
		||||
}
 | 
			
		||||
.book-slot.is-thick .book.is-tall .spine .text-container {
 | 
			
		||||
  transform: rotate(90deg) translateX(88px) translateY(86px);
 | 
			
		||||
}
 | 
			
		||||
.book.is-tall .spine .title {
 | 
			
		||||
  font-size: 1.3em;
 | 
			
		||||
}
 | 
			
		||||
.book.is-tall .spine .subtitle {
 | 
			
		||||
  font-size: 1.1em;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,12 @@ $(document).ready(function() {
 | 
			
		|||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  $('#readableToggle').click(function() {
 | 
			
		||||
    var useReadable = getCookieValue('useReadable');
 | 
			
		||||
    document.cookie = 'useReadable=' + (useReadable !== 'yes' ? 'yes' : 'no');
 | 
			
		||||
    window.location.reload();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  $('.modal-background, .modal-close, .modal-card-head .delete, .modal .close').click(function() {
 | 
			
		||||
    $(this).closest('.modal').removeClass('is-active');
 | 
			
		||||
    downloadButton = undefined;
 | 
			
		||||
| 
						 | 
				
			
			@ -64,4 +70,9 @@ $(document).ready(function() {
 | 
			
		|||
    }
 | 
			
		||||
    $('#bookFileName').text(fileName ? fileName : 'None Selected');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function getCookieValue(key) {
 | 
			
		||||
  var matches = document.cookie.match('(^|;)\\s*' + key + '\\s*=\\s*([^;]+)');
 | 
			
		||||
  return matches ? matches.pop() : ''
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,21 +2,30 @@ const path = require('path');
 | 
			
		|||
const fs = require('fs');
 | 
			
		||||
const snarkdown = require('snarkdown');
 | 
			
		||||
const fecha = require('fecha');
 | 
			
		||||
const tinycolor = require('tinycolor2');
 | 
			
		||||
 | 
			
		||||
const settings = require('../settings.json');
 | 
			
		||||
 | 
			
		||||
module.exports = function (app) {
 | 
			
		||||
  app.server.get('/', (req, res) => {
 | 
			
		||||
    const useReadable = req.cookies['useReadable'] === 'yes';
 | 
			
		||||
    const files = fs.readdirSync(app.fileLocation).filter(fileName => fileName.includes('.json'))
 | 
			
		||||
      .map(fileName => {  // Cache the file data so sorting doesn't need to re-check each file
 | 
			
		||||
        return { name: fileName, time: fs.statSync(path.resolve(app.fileLocation, fileName)).mtime.getTime() };
 | 
			
		||||
      }).sort((a, b) => a.time - b.time).map(v => v.name);  // Sort from oldest to newest.
 | 
			
		||||
        const stats = fs.statSync(path.resolve(app.fileLocation, fileName));
 | 
			
		||||
        return {
 | 
			
		||||
          name: fileName,
 | 
			
		||||
          size: stats.size / (1000 * 1000),
 | 
			
		||||
          time: stats.mtime.getTime(),
 | 
			
		||||
        };
 | 
			
		||||
      }).sort((a, b) => a.time - b.time);  // Sort from oldest to newest.
 | 
			
		||||
 | 
			
		||||
    let books = files.map(fileName => {
 | 
			
		||||
      const bookData = JSON.parse(fs.readFileSync(path.resolve(app.fileLocation, fileName), 'utf8'));
 | 
			
		||||
    let books = files.map(fileDetails => {
 | 
			
		||||
      const bookData = JSON.parse(fs.readFileSync(path.resolve(app.fileLocation, fileDetails.name), 'utf8'));
 | 
			
		||||
      if (bookData.hasOwnProperty('fileName')) return '';
 | 
			
		||||
      bookData.author = bookData.author ? bookData.author : '<em>author not provided</em>';
 | 
			
		||||
      bookData.contributor = bookData.contributor ? bookData.contributor : 'Anonymous';
 | 
			
		||||
 | 
			
		||||
      const id = fileName.replace('.json', '');
 | 
			
		||||
      const id = fileDetails.name.replace('.json', '');
 | 
			
		||||
      const confirmId = 'confirm_' + id;
 | 
			
		||||
      const added = fecha.format(new Date(bookData.added), 'hh:mm:ssA on dddd MMMM Do, YYYY');
 | 
			
		||||
      const modal = app.templater.fill('./templates/elements/modalCard.html', {
 | 
			
		||||
| 
						 | 
				
			
			@ -37,10 +46,20 @@ module.exports = function (app) {
 | 
			
		|||
          }),
 | 
			
		||||
        footer: '<a class="button close">Close</a> <a class="button is-success modal-button" data-modal="' + confirmId + '">Take Book</a>',
 | 
			
		||||
      });
 | 
			
		||||
      return app.templater.fill('./templates/elements/book.html', {
 | 
			
		||||
      const maxSize = settings.maxFileSize > 0 ? settings.maxFileSize : 10;
 | 
			
		||||
      let spineColor = tinycolor('#' + id.substr(0, 6));
 | 
			
		||||
      if (!spineColor.isValid()) {
 | 
			
		||||
        spineColor = tinycolor.random();
 | 
			
		||||
      }
 | 
			
		||||
      return app.templater.fill(useReadable ? './templates/elements/book_readable.html' : './templates/elements/book.html', {
 | 
			
		||||
        id,
 | 
			
		||||
        title: bookData.title,
 | 
			
		||||
        author: bookData.author,
 | 
			
		||||
        thickness: (fileDetails.size > (maxSize * 0.3)) || (bookData.title.length > 28)
 | 
			
		||||
          ? 'is-thick' : (fileDetails.size < (maxSize * 0.6) ? 'is-thin' : ''),
 | 
			
		||||
        tallness: bookData.title.length > 16 ? 'is-tall' : (bookData.title.length < 8 ? 'is-short' : ''),
 | 
			
		||||
        spineColor: spineColor.toString(),
 | 
			
		||||
        textColor: spineColor.isLight() ? '#000000' : '#ffffff',
 | 
			
		||||
        fileType: bookData.fileType,
 | 
			
		||||
        modal,
 | 
			
		||||
      });
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +69,11 @@ module.exports = function (app) {
 | 
			
		|||
      books = '<div class="column"><div class="content">The shelf is empty. Would you like to <a href="/give">add a book</a>?</div></div>';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const body = '<h2 class="title">Available Books</h2><div class="columns is-multiline">' + books + '</div>';
 | 
			
		||||
    const body = '<h2 class="title is-inline">Available Books</h2>'
 | 
			
		||||
      + '<a id="readableToggle" class="button is-pulled-right">' + (!useReadable ? 'Make it readable' : 'Make it look cool') + '</a>'
 | 
			
		||||
      + '<div class="columns is-multiline' + (!useReadable ? ' is-gapless is-mobile bookshelf' : '') + '" style="margin-top:5px;">'
 | 
			
		||||
        + books
 | 
			
		||||
      + '</div>';
 | 
			
		||||
    const html = app.templater.fill('./templates/htmlContainer.html', {
 | 
			
		||||
      title: 'View',
 | 
			
		||||
      resourcePath: (req.url.substr(-1) === '/' ? '../' : './'),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ const path = require('path');
 | 
			
		|||
const fs = require('fs');
 | 
			
		||||
const express = require('express');
 | 
			
		||||
const helmet = require('helmet');
 | 
			
		||||
const cookieParser = require('cookie-parser');
 | 
			
		||||
const bodyParser = require('body-parser');
 | 
			
		||||
const fileUpload = require('express-fileupload');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +10,8 @@ const settings = require('../settings.json');
 | 
			
		|||
 | 
			
		||||
module.exports = function (app) {
 | 
			
		||||
  app.server.use(helmet());
 | 
			
		||||
  
 | 
			
		||||
  app.server.use(cookieParser());
 | 
			
		||||
 | 
			
		||||
  app.server.use(bodyParser.json()); // support json encoded bodies
 | 
			
		||||
  app.server.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,14 @@
 | 
			
		|||
<div class="column is-one-quarter" id="book_{{id}}">
 | 
			
		||||
  <div class="box modal-button has-text-centered" data-modal="{{id}}">
 | 
			
		||||
    <h2 class="title is-4">{{title}}</h2>
 | 
			
		||||
    <h4 class="subtitle">{{author}}</h4>
 | 
			
		||||
    <div class="tags has-addons">
 | 
			
		||||
      <span class="tag">File Format</span>
 | 
			
		||||
      <span class="tag is-info">{{fileType}}</span>
 | 
			
		||||
<div class="book-slot {{thickness}} column is-narrow is-paddingless" id="book_{{id}}">
 | 
			
		||||
  <div class="book {{tallness}} modal-button" data-modal="{{id}}">
 | 
			
		||||
    <div class="spine" style="background:{{spineColor}}">
 | 
			
		||||
      <div class="text-container">
 | 
			
		||||
        <h2 class="title" style="color:{{textColor}}">{{title}}</h2>
 | 
			
		||||
        <h4 class="subtitle" style="color:{{textColor}}">{{author}}</h4>
 | 
			
		||||
      </div>
 | 
			
		||||
      <!-- div class="tags has-addons">
 | 
			
		||||
        <span class="tag">File Format</span>
 | 
			
		||||
        <span class="tag is-info">{{fileType}}</span>
 | 
			
		||||
      </div -->
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								templates/elements/book_readable.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								templates/elements/book_readable.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
<div class="column is-one-quarter" id="book_{{id}}">
 | 
			
		||||
  <div class="box modal-button has-text-centered" data-modal="{{id}}">
 | 
			
		||||
    <h2 class="title is-4">{{title}}</h2>
 | 
			
		||||
    <h4 class="subtitle">{{author}}</h4>
 | 
			
		||||
    <div class="tags has-addons">
 | 
			
		||||
      <span class="tag">File Format</span>
 | 
			
		||||
      <span class="tag is-info">{{fileType}}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  
 | 
			
		||||
  {{modal}}
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										13
									
								
								yarn.lock
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								yarn.lock
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -164,6 +164,14 @@ content-type@~1.0.4:
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
 | 
			
		||||
  integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
 | 
			
		||||
 | 
			
		||||
cookie-parser@^1.4.3:
 | 
			
		||||
  version "1.4.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.3.tgz#0fe31fa19d000b95f4aadf1f53fdc2b8a203baa5"
 | 
			
		||||
  integrity sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=
 | 
			
		||||
  dependencies:
 | 
			
		||||
    cookie "0.3.1"
 | 
			
		||||
    cookie-signature "1.0.6"
 | 
			
		||||
 | 
			
		||||
cookie-signature@1.0.6:
 | 
			
		||||
  version "1.0.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
 | 
			
		||||
| 
						 | 
				
			
			@ -908,6 +916,11 @@ striptags@^3.1.1:
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.1.1.tgz#c8c3e7fdd6fb4bb3a32a3b752e5b5e3e38093ebd"
 | 
			
		||||
  integrity sha1-yMPn/db7S7OjKjt1LltePjgJPr0=
 | 
			
		||||
 | 
			
		||||
tinycolor2@^1.4.1:
 | 
			
		||||
  version "1.4.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"
 | 
			
		||||
  integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=
 | 
			
		||||
 | 
			
		||||
to-array@0.1.4:
 | 
			
		||||
  version "0.1.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue