Browse Source

refactor

master
Milan Pässler 8 months ago
parent
commit
acc2425d2e

+ 0
- 3
.eslintignore View File

@@ -1,3 +0,0 @@
dist/**
dev/**
tmp/**

+ 0
- 13
.eslintrc.js View File

@@ -1,13 +0,0 @@
module.exports = {
"parser": "babel-eslint",
"extends": "eslint-config-standard",
"rules": {
"indent": ["error", "tab"],
"no-tabs": "off",
"semi": [2, "always"],
"no-extra-semi": 2,
"semi-spacing": [2, { "before": false, "after": true }],
"no-template-curly-in-string": "off"
},
"env": {"node": true, "browser": true, "worker": true}
};

+ 0
- 5
.gitignore View File

@@ -1,5 +0,0 @@
dist
dev
tmp
node_modules
yarn-error.log

+ 0
- 11
Dockerfile View File

@@ -1,11 +0,0 @@
FROM node:latest
RUN mkdir /app
WORKDIR /app
ADD . /app
RUN npm i -g yarn
RUN yarn
RUN ./node_modules/.bin/gulp
RUN apt-get update -y -qq; apt-get install nginx -y -qq
RUN cp nginx.conf.dev.example /etc/nginx/nginx.conf
RUN cp -r dist/ /usr/share/nginx/;
CMD ["nginx", "-g", "daemon off;"]

+ 0
- 13
README.md View File

@@ -1,13 +0,0 @@
# deepart.ai Frontend

This repository contains the frontend for deepart.ai. It is used to present the project, display rendered images and collect input from the user.

## Development

You will need current versions of NodeJS, [the yarn package manager](https://yarnpkg.com/) and NGINX. Use the NGINX configuration provided and change the URL to the backend.
* Run `yarn` to install the dependencies required for the build process
* Run `node_modules/.bin/gulp` to build the project
* Run `node_modules/.bin/gulp watch` to let gulp watch for changes in the project and automatically rebuild
* The output will be located in the `dist` directory

* Make sure your NGINX version is greater than 1.13.9! *

+ 0
- 12
app/main.js View File

@@ -1,12 +0,0 @@
'use strict';

import { router } from './router';

router.go(window.location.pathname);

const sw = navigator.serviceWorker;
if (sw) {
sw.register('/sw.js', {
scope: '/'
});
}

BIN
app/placeholder.png View File


+ 0
- 5
app/router/index.js View File

@@ -1,5 +0,0 @@
'use strict';

export * from './router';
export * from './register';


+ 0
- 10
app/router/register.js View File

@@ -1,10 +0,0 @@
'use strict';

import { router } from '../router';
import * as routes from '../routes';

router.route(/^.*$/, routes.header);
router.route(/^\/?$/, routes.about);
router.route(/^\/feed$/, routes.feed);
router.route(/^\/gallery$/, routes.gallery);
router.route(/^.*$/, routes.notfound);

+ 0
- 47
app/router/router.js View File

@@ -1,47 +0,0 @@
'use strict';

class Router {
constructor() {
this.routes = [];

window.onpopstate = (evt) => {
this.go(window.location.pathname);
};

document.onclick = (evt) => {
for (let el of evt['composedPath']()) {
if (el.href && el.href.startsWith(window.location.origin) && this.go(el.pathname)) {
evt.preventDefault();
return false;
}
}
return true;
};
}

go(path) {
let routes = this.routes.map(r => { return { route: r, match: r.path.exec(path) } }).filter(r => r.match);

if (!routes.length) return false;

history.pushState({}, '', path);

let self = this;
// returns a promise, which is truthy
return (async () => {
for (let { route, match } of routes) {
let res = await route.func(match);
if (res) break;
}
}) ();
}

route(path, func) {
this.routes.push({
path: path,
func: func
});
}
}

export const router = new Router();

+ 0
- 12
app/routes/about.js View File

@@ -1,12 +0,0 @@
'use strict';

import { render } from 'lit-html';
import { tag } from '../util';
import { about as aboutTemplate } from '../templates';

export const about = async () => {
render(aboutTemplate(), tag('main'));
return true;
};



+ 0
- 12
app/routes/feed.js View File

@@ -1,12 +0,0 @@
'use strict';

import { render } from 'lit-html';
import { tag } from '../util';
import { feed as feedTemplate } from '../templates';

export const feed = async () => {
//render(feedTemplate(notes), tag('main'));
//return true;
};



+ 0
- 111
app/routes/gallery.js View File

@@ -1,111 +0,0 @@
'use strict';

import { render } from 'lit-html';
import { tag, cssClass, selAll, id, sleep } from '../util';
import { gallery as galleryTemplate } from '../templates';

export const gallery = async () => {
const apiUri = 'http://127.0.0.1:5000/api/';

const get = (path) => fetch(apiUri + path, {cache: "no-store"});

let nnId = '';
let images = [];
let data = {};
let j = 0;


const nextSet = async (selected) => {
render(galleryTemplate(images, true), tag('main'));
images = [];

let newId;
if (selected !== undefined) {
await get('answer/' + nnId + '/' + selected);
do {
newId = await get('get_latest_id').then(resp => resp.text());
await sleep(200);
} while (newId === nnId);
nnId = newId;
} else {
nnId = await get('get_latest_id').then(resp => resp.text());
}
data = await get('get_latest_data').then(resp => resp.json());

j = 0;
let size = 128;
let canvas = document.createElement('canvas');
canvas.height = size;
canvas.width = size;
let ctx = canvas.getContext('2d');
Object.keys(data).forEach((index) => {
let artwork = data[index];
ctx.clearRect(0, 0, size, size);
artwork['objects'].forEach((obj) => {
let first = obj['points'].shift();
let x = first['x'] * size;
let y = first['y'] * size;
let r = Math.round(first['r']*255);
let g = Math.round(first['g']*255);
let b = Math.round(first['b']*255);
ctx.fillStyle = `rgba(${r}, ${g}, ${b}, 1)`;
ctx.moveTo(x, y);
ctx.beginPath();
if (obj['radius']) {
let radius = obj['radius'] * size;
if (radius < 0) {
console.warn('oops, radius was < 0: ' + radius);
} else {
ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
}
} else {
let second = obj['points'][0];
let x2 = second['x'] * size;
let y2 = second['y'] * size;
let r2 = Math.round(second['r']*255);
let g2 = Math.round(second['g']*255);
let b2 = Math.round(second['b']*255);
let grd = ctx.createLinearGradient(x, y, x2, y2);
grd.addColorStop(0, `rgba(${r}, ${g}, ${b}, 1)`);
grd.addColorStop(1, `rgba(${r2}, ${g2}, ${b2}, 1)`);
ctx.fillStyle = grd;
console.log(obj['points'].length);
obj['points'].forEach((point) => {
ctx.lineTo(point['x'] * size, point['y'] * size);
});
}
ctx.closePath();
ctx.fill();
});
images.push({
id: index,
url: canvas.toDataURL("image/png")
});
});

render(galleryTemplate(images), tag('main'));
}

await nextSet();

let i = 0;

cssClass('grid').onclick = (evt) => {
if (evt.target.tagName !== 'IMG') return;
let id = evt.target.getAttribute('data-id');
/*images[id].selected = ++i;
render(galleryTemplate(images), tag('main'));
i = 0;
let selectedId = images.filter(i => i.selected === 1)[0].id;*/
nextSet(id);
};

id('next').onclick = () => {
i = 0;
let selectedId = images.filter(i => i.selected === 1)[0].id;
nextSet(selectedId);
};

return true;
};


+ 0
- 12
app/routes/header.js View File

@@ -1,12 +0,0 @@
'use strict';

import { render } from 'lit-html';
import { tag } from '../util';
import { header as headerTemplate } from '../templates';

export const header = async () => {
render(headerTemplate(), tag('header'));
return false;
};



+ 0
- 7
app/routes/index.js View File

@@ -1,7 +0,0 @@
'use strict';

export * from './header';
export * from './about';
export * from './gallery';
export * from './feed';
export * from './notfound';

+ 0
- 12
app/routes/notfound.js View File

@@ -1,12 +0,0 @@
'use strict';

import { render } from 'lit-html';
import { tag } from '../util';
import { notfound as notfoundTemplate } from '../templates';

export const notfound = async () => {
render(notfoundTemplate(), tag('main'));
return true;
};



+ 0
- 9
app/templates/feed.js View File

@@ -1,9 +0,0 @@
'use strict';

import { html } from 'lit-html';

export const feed = (images) => html`
${images.map(image => html`
<img id="image-${image.id}" src="${image.url}">
`)}
`;

+ 0
- 31
app/templates/gallery.js View File

@@ -1,31 +0,0 @@
'use strict';

import { html } from 'lit-html';

export const gallery = (images, loading) => html`
<div class="container gallery">
<div class="grid">
${images.map(image => html`
<div class="image">
<img data-id="${image.id}" src="${image.url}">
${image.selected ? html`
<div class="selected">
<span>${image.selected}</span>
</div>
` : ''}
</div>
`)}
</div>
</div>
${loading ? html`
<div class="loading">
<div class="spinner"></div>
</div>
` : ''}
<div class="nav">
<div class="container">
<span>Select the image you like most</span>
<a id="next">next &rarr;</a>
</div>
</div>
`;

+ 0
- 7
app/templates/index.js View File

@@ -1,7 +0,0 @@
'use strict';

export * from './header';
export * from './about';
export * from './gallery';
export * from './feed';
export * from './notfound';

+ 0
- 17
app/test.json View File

@@ -1,17 +0,0 @@
[{ "objects": [
{ "points": [
{ "x": 0.1727069605634174, "y":0.2938186297533175, "r":0.6072802997831339, "g":0.7070856195443572, "b":0.328747493128542},
{ "x": 0.834534709716035, "y":0.4790838730176238, "r":0.1839384892592466, "g":0.3150057714363551, "b":0.530200550767832}]},
{ "points": [
{ "x": 0.7028128824864439, "y":0.37338853853277376, "r":0.34705663392966657, "g":0.4626718483581611, "b":0.9316975958903573},
{ "x": 0.9968856890116655, "y":0.42191242676440743, "r":0.8474157112554067, "g":0.12301865052026395, "b":0.06680346251937574}]},
{ "points": [
{ "x": 0.7145907584984006, "y":0.2558619087286895, "r":0.19983946106328743, "g":0.004981112104021634, "b":0.5524829644289931},
{ "x": 0.7481266271627567, "y":0.09465811289937631, "r":0.2181874052314151, "g":0.010777328976116718, "b":0.08164538686580713},
{ "x": 0.9196925402391931, "y":0.17973941598139265, "r":0.40044277713053045, "g":0.8088438484739763, "b":0.06272046034487111},
{ "x": 0.2547628334548119, "y":0.3903890045677447, "r":0.10579509990576974, "g":0.07433816160278961, "b":0.11553917995773155}]},
{ "points": [
{ "x": 0.8896804894745697, "y":0.552054058685631, "r":0.2724616900004492, "g":0.23015247807544836, "b":0.5313836031496667},
{ "x": 0.9563299781198908, "y":0.5268888216603523, "r":0.5045544034252369, "g":0.9639100903638727, "b":0.7242239500573145}]},
{ "points": [
{ "x": 0.7277520565512419, "y":0.06258703792372788, "r":0.6674900130914164, "g":0.6857541456240441, "b":0.22736196574847078}], "radius": 0.5}]}]

app/deepart.ai.png → deepart.ai.png View File


app/deepart.ai.svg → deepart.ai.svg View File


app/deepart.ai128.png → deepart.ai128.png View File


app/deepart.ai256.png → deepart.ai256.png View File


app/deepart.ai512.png → deepart.ai512.png View File


app/deepart.ai64.png → deepart.ai64.png View File


app/fonts/source-code-pro-v7-latin-500.woff → fonts/source-code-pro-v7-latin-500.woff View File


app/fonts/source-code-pro-v7-latin-500.woff2 → fonts/source-code-pro-v7-latin-500.woff2 View File


app/fonts/source-code-pro-v7-latin-700.woff → fonts/source-code-pro-v7-latin-700.woff View File


app/fonts/source-code-pro-v7-latin-700.woff2 → fonts/source-code-pro-v7-latin-700.woff2 View File


app/fonts/source-code-pro-v7-latin-regular.woff → fonts/source-code-pro-v7-latin-regular.woff View File


app/fonts/source-code-pro-v7-latin-regular.woff2 → fonts/source-code-pro-v7-latin-regular.woff2 View File


+ 0
- 128
gulpfile.js View File

@@ -1,128 +0,0 @@
const gulp = require('gulp');
const pump = require('pump');
const rollupPluginUglify = require('rollup-plugin-uglify');
const rollupPluginResolve = require('rollup-plugin-node-resolve');
const rollup = require('rollup-stream');
const loadGulpPlugins = require('gulp-load-plugins');
const cleanCss = require('postcss-clean');
const normalize = require('postcss-normalize');
const importCss = require('postcss-import');
const nested = require('postcss-nested');
const autoprefixer = require('autoprefixer');
const source = require('vinyl-source-stream');
const { minify } = require('uglify-es');
const { execSync } = require('child_process');
const { readFileSync } = require('fs');

const gulpPlugins = loadGulpPlugins();
const browsers = ['>2% in DE'];

function gitRevision () {
return execSync('git describe --tags --always --abbrev=7 --dirty', { cwd: __dirname }).toString().trim();
}

gulp.task('clean', (cb) => {
execSync('rm -rf dist/* dev/* tmp/*', { cwd: __dirname });
cb();
});

gulp.task('js', (cb) => {
pump([
rollup({
input: 'app/main.js',
format: 'iife',
plugins: [
rollupPluginResolve(),
rollupPluginUglify({
toplevel: true,
mangle: {
properties: {
builtins: false,
reserved: require('./node_modules/uglify-es/tools/domprops.json').concat([
'objects', 'points', 'radius'
]),
keep_quoted: true
}
},
}, minify)
]
}),
source('main.js'),
gulpPlugins.replace('\n', ''),
gulpPlugins.replace('\\n', ''),
gulpPlugins.replace('\t', ''),
gulpPlugins.replace('\\t', ''),
gulpPlugins.replace('__GIT_REVISION', gitRevision()),
gulpPlugins.replace('__BUILD_DATE', new Date().valueOf()),
gulp.dest('dist')
], cb);
});

gulp.task('sw', (cb) => {
pump([
rollup({
input: 'app/sw.js',
format: 'es',
plugins: [
rollupPluginUglify({
toplevel: true
}, minify)
]
}),
source('sw.js'),
gulpPlugins.replace('__BUILD_DATE', new Date().valueOf()),
gulp.dest('dist')
], cb);
});

gulp.task('css', (cb) => {
pump([
gulp.src('app/main.css'),
gulpPlugins.postcss([
normalize({
browsers: browsers
}),
autoprefixer({
browsers: browsers
}),
cleanCss()
]),
gulp.dest('tmp')
], cb);
});

gulp.task('copy', (cb) => {
pump([
gulp.src(['app/**', '!app/**/*.{html,css,js}', '!app/manifest.json'], { dot: true }),
gulp.dest('dist')
], cb);
});

gulp.task('html', (cb) => {
pump([
gulp.src('app/index.html'),
gulpPlugins.htmlmin({ collapseWhitespace: true }),
gulpPlugins.replace('${INLINE_CSS}', readFileSync('tmp/main.css')),
gulp.dest('dist')
], cb);
});

gulp.task('manifest', (cb) => {
pump([
gulp.src('app/manifest.json'),
gulpPlugins.jsonminify(),
gulp.dest('dist')
], cb);
});

gulp.task('dist', gulp.parallel('clean', 'copy', 'js', gulp.series('css', 'html'), 'manifest', 'sw'));

gulp.task('watch', gulp.series('dist', () => {
gulp.watch('app/**/*.js', gulp.series('js', 'html', 'sw'));
gulp.watch('app/**/*.css', gulp.series('css', 'html', 'sw'));
gulp.watch('app/*.html', gulp.series('html', 'sw'));
gulp.watch('app/manifest.json', gulp.series('manifest', 'html', 'sw'));
gulp.watch('app/sw.js', gulp.series('html', 'sw'));
}));

gulp.task('default', gulp.series('dist'));

app/index.html → index.html View File

@@ -5,15 +5,15 @@
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="encoding" content="utf-8">
<meta name="Description" content="A social platform for minimalists.">
<link rel="manifest" href="/manifest.json"></link>
<link rel="icon" type="image/png" href="/deepart.ai128.png" sizes="128x128"></link>
<title>deepvoid</title>
<style>${INLINE_CSS}</style>
<link rel="manifest" href="manifest.json"></link>
<link rel="icon" type="image/png" href="deepart.ai128.png" sizes="128x128"></link>
<title>deepart.ai</title>
<link rel="stylesheet" href="main.css"></link>
</head>
<body>
<noscript>JavaScript is required to use the PWA!</noscript>
<header></header>
<main></main>
<script async src="/main.js"></script>
<script type="module" src="js/main.js"></script>
</body>
</html>

+ 1
- 0
js/lit-html.js
File diff suppressed because it is too large
View File


app/templates/header.js → js/main.js View File

@@ -1,9 +1,16 @@
'use strict';

import { html } from 'lit-html';
import { route, go } from './router.js';
import { tag } from '../util.js';
import { html, render } from './lit-html.js';

export const header = () => html`
<a href="/" class="container">
import { aboutRoute } from './routes/about.js';
import { feedRoute } from './routes/feed.js';
import { galleryRoute } from './routes/gallery.js';
import { notfoundRoute } from './routes/notfound.js';

export const headerTemplate = () => html`
<a href="#/" class="container">
<svg
viewBox="0 0 12.7 12.7"
height="48"
@@ -31,3 +38,19 @@ export const header = () => html`
<h1>deepart.ai</h1>
</a>
`;
render(headerTemplate(), tag('header'));

route(/^\/$/, aboutRoute);
route(/^\/feed$/, feedRoute);
route(/^\/gallery$/, galleryRoute);
route(/^.*$/, notfoundRoute);

if (!window.location.hash.length) go('/');

const sw = navigator.serviceWorker;
if (sw) {
sw.register('/sw.js', {
scope: '/'
});
}


+ 26
- 0
js/router.js View File

@@ -0,0 +1,26 @@
'use strict';

const routes = [];

export const route = (pattern, handler) => {
routes.push({
pattern: pattern,
handler: handler
});
};

export const go = (dest) => {
window.location.hash = '#' + dest;
};

const handler = (dest) => {
for (let route of routes) {
const match = route.pattern.exec(dest);
if (!match) continue;
return route.handler(match.slice(1));
}
};

window.addEventListener('hashchange', evt => handler(window.location.hash.slice(1)));

document.addEventListener("DOMContentLoaded", () => handler(window.location.hash.slice(1)));

app/templates/about.js → js/routes/about.js View File

@@ -1,22 +1,30 @@
'use strict';

import { html } from 'lit-html';
import { html, render } from '../lit-html.js';
import { tag } from '../util.js';

export const about = (error) => html`
const aboutTemplate = (error) => html`
<div class="container about">
<section>
<a href="/account">
<a href="#/account">
<h3>Sign up</h3>
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum. </p>
</a>
<a href="/gallery">
<a href="#/gallery">
<h3>Gallery</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p>
</a>
<a href="/feed">
<a href="#/feed">
<h3>Feed</h3>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium. </p>
</a>
</section>
</div>
`;

export const aboutRoute = () => {
render(aboutTemplate(), tag('main'));
return true;
};



+ 17
- 0
js/routes/feed.js View File

@@ -0,0 +1,17 @@
'use strict';

import { html, render } from '../lit-html.js';
import { tag } from '../util.js';

const feedTemplate = (images) => html`
${images.map(image => html`
<img id="image-${image.id}" src="${image.url}">
`)}
`;

export const feedRoute = () => {
const notes = JSON.parse(localStorage.getItem('notes') || "[]")
render(feedTemplate(notes), tag('main'));
};



+ 131
- 0
js/routes/gallery.js View File

@@ -0,0 +1,131 @@
'use strict';

import { html, render } from '../lit-html.js';
import { tag, cssClass, selAll, id, sleep } from '../util.js';

const size = 128;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.height = size;
canvas.width = size;

const galleryTemplate = (images, loading) => html`
<div class="container gallery">
<div class="grid">
${images.map(image => html`
<div class="image">
<img data-id="${image.id}" src="${image.url}">
${image.selected ? html`
<div class="selected">
<span>${image.selected}</span>
</div>
` : ''}
</div>
`)}
</div>
</div>
${loading ? html`
<div class="loading">
<div class="spinner"></div>
</div>
` : ''}
<div class="nav">
<div class="container">
<span>Select the image you like most</span>
<a id="next">next &rarr;</a>
</div>
</div>
`;

const renderImage = (artwork) => {
ctx.clearRect(0, 0, size, size);
artwork['objects'].forEach((obj) => {
let first = obj['points'].shift();
let x = first['x'] * size;
let y = first['y'] * size;
let r = Math.round(first['r']*255);
let g = Math.round(first['g']*255);
let b = Math.round(first['b']*255);
ctx.fillStyle = `rgba(${r}, ${g}, ${b}, 1)`;
ctx.moveTo(x, y);
ctx.beginPath();
if (obj['radius']) {
let radius = obj['radius'] * size;
if (radius < 0) {
console.warn('oops, radius was < 0: ' + radius);
} else {
ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
}
} else {
let second = obj['points'][0];
let x2 = second['x'] * size;
let y2 = second['y'] * size;
let r2 = Math.round(second['r']*255);
let g2 = Math.round(second['g']*255);
let b2 = Math.round(second['b']*255);
let grd = ctx.createLinearGradient(x, y, x2, y2);
grd.addColorStop(0, `rgba(${r}, ${g}, ${b}, 1)`);
grd.addColorStop(1, `rgba(${r2}, ${g2}, ${b2}, 1)`);
ctx.fillStyle = grd;
console.log(obj['points'].length);
obj['points'].forEach((point) => {
ctx.lineTo(point['x'] * size, point['y'] * size);
});
}
ctx.closePath();
ctx.fill();
});
return canvas.toDataURL("image/png");
};

export const galleryRoute = async () => {
const apiUri = '/api/';

const get = (path) => fetch(apiUri + path, {cache: "no-store"});

let nnId = '';
let data = {};

const nextSet = async (selected) => {
render(galleryTemplate([], true), tag('main'));

let newId;
if (selected !== undefined) {
await get('answer/' + nnId + '/' + selected);
do {
newId = await get('get_latest_id').then(resp => resp.text());
await sleep(200);
} while (newId === nnId);
nnId = newId;
} else {
nnId = await get('get_latest_id').then(resp => resp.text());
}
data = await get('get_latest_data').then(resp => resp.json());
let images = Object.keys(data).map(index => {
return {
id: index,
url: renderImage(data[index])
};
});
render(galleryTemplate(images), tag('main'));
};

await nextSet();

let i = 0;

cssClass('grid').onclick = (evt) => {
if (evt.target.tagName !== 'IMG') return;
let id = evt.target.getAttribute('data-id');
/*images[id].selected = ++i;
render(galleryTemplate(images), tag('main'));
i = 0;
let selectedId = images.filter(i => i.selected === 1)[0].id;*/
nextSet(id);
};

id('next').onclick = () => {
nextSet(0);
};
};


app/templates/notfound.js → js/routes/notfound.js View File

@@ -1,11 +1,17 @@
'use strict';

import { html } from 'lit-html';
import { html, render } from '../lit-html.js';
import { tag } from '../util.js';

export const notfound = () => html`
const notfoundTemplate = () => html`
<div class="container">
<h1>What are you looking for?</h1>
<h3>The page you tried to access was not found. Did you make a spelling mistake?</h3>
<a href="/">Back to the home page</a>
</div>
`;

export const notfoundRoute = () => {
render(notfoundTemplate(), tag('main'));
};


app/sw.js → js/sw.js View File

@@ -1,12 +1,35 @@
'use strict';

let preCache = [
'/',
'/main.js',
'/manifest.json',
'/fonts/source-code-pro-v7-latin-regular.woff2',
'/fonts/source-code-pro-v7-latin-500.woff2',
'/fonts/source-code-pro-v7-latin-700.woff2'
'./',
'./main.js',
'./manifest.json',
'./fonts/source-code-pro-v7-latin-regular.woff2',
'./fonts/source-code-pro-v7-latin-500.woff2',
'./fonts/source-code-pro-v7-latin-700.woff2',
'./deepart.ai.png',
'./deepart.ai.svg',
'./deepart.ai128.png',
'./deepart.ai256.png',
'./deepart.ai512.png',
'./deepart.ai64.png',
'./main.css',
'./main.js',
'./router.js',
'./routes/about.js',
'./routes/feed.js',
'./routes/gallery.js',
'./routes/header.js',
'./routes/index.js',
'./routes/notfound.js',
'./templates/about.js',
'./templates/feed.js',
'./templates/gallery.js',
'./templates/header.js',
'./templates/index.js',
'./templates/notfound.js',
'./util.js',
'./manifest.json'
];

const CACHE = 'cache-${BUILD_DATE}';

app/util.js → js/util.js View File


app/main.css → main.css View File


app/manifest.json → manifest.json View File

@@ -1,7 +1,7 @@
{
"name": "deepart.ai",
"short_name": "deepart.ai",
"start_url": "/",
"start_url": ".",
"icons": [
{
"src": "deepart.ai64.png",

+ 0
- 40
nginx.conf.dev.example View File

@@ -1,40 +0,0 @@
worker_processes 1;

events {
worker_connections 1024;
}

http {
charset UTF-8;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_types text/plain text/xml text/css application/x-javascript application/json application/javascript;

access_log off;
log_not_found off;

server {
listen [::]:80 ipv6only=off;
return 301 https://$host$request_uri;
}

server {
listen 0.0.0.0:8080;

autoindex off;
index index.html;

location / {
root /usr/share/nginx/dist/;
try_files $uri $uri/ /index.html;
}

location /api {
proxy_pass http://backend:5000/api;
}
}
}


+ 0
- 61
nginx.conf.prod.example View File

@@ -1,61 +0,0 @@
worker_processes 1;

events {
worker_connections 1024;
}

http {
charset UTF-8;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_types text/plain text/xml text/css application/x-javascript application/json application/javascript;

ssl_dhparam /etc/ssl/dhparams.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

access_log off;
log_not_found off;

server {
listen [::]:80 ipv6only=off;
return 301 https://$host$request_uri;
}

server {
listen [::]:443 ssl http2 ipv6only=off;
server_name foo.bar;

ssl on;
ssl_certificate /etc/letsencrypt/live/foo.bar/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/foo.bar/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/foo.bar/fullchain.pem;

add_header Strict-Transport-Security "max-age=63072000; preload; includeSubDomains";
add_header Cache-Control "max-age=604800";

root /srv/http/404;
autoindex off;
index index.html;

location / {
root /usr/share/nginx/dist/;
try_files $uri $uri/ /index.html;
http2_push "/main.js";
}

location /api/ {
proxy_pass https://foo.bar/api/;
}
}
}


+ 0
- 37
package.json View File

@@ -1,37 +0,0 @@
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"test": "gulp"
},
"author": "Milan Pässler",
"license": "AGPL-3.0",
"dependencies": {
"eslint": "^4.16.0",
"eslint-config-standard": "^11.0.0-beta.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-standard": "^3.0.1",
"gulp": "gulpjs/gulp.git#4.0",
"gulp-autoprefixer": "^4.0.0",
"gulp-clean-css": "^3.9.0",
"gulp-htmlmin": "^4.0.0",
"gulp-jsonminify": "^1.0.0",
"gulp-load-plugins": "^1.5.0",
"gulp-postcss": "^7.0.0",
"gulp-replace": "^0.6.1",
"gulp-sourcemaps": "^2.6.1",
"lit-html": "^0.8.0",
"postcss-clean": "^1.1.0",
"postcss-import": "^11.1.0",
"postcss-nested": "^3.0.0",
"postcss-normalize": "^4.0.0",
"pump": "^1.0.2",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-uglify": "^2.0.1",
"rollup-stream": "^1.24.1",
"uglify-es": "^3.3.8",
"vinyl-source-stream": "^2.0.0"
}
}

+ 63
- 0
sw.js View File

@@ -0,0 +1,63 @@
'use strict';

const CACHE = 'cache-v34';

let preCache = [
'./',
'./js/',
'./js/lit-html.js',
'./js/main.js',
'./js/router.js',
'./js/sw.js',
'./js/util.js',
'./js/routes',
'./js/routes/about.js',
'./js/routes/notfound.js',
'./js/routes/gallery.js',
'./js/routes/feed.js',
'./deepart.ai128.png',
'./deepart.ai256.png',
'./deepart.ai512.png',
'./deepart.ai64.png',
'./deepart.ai.png',
'./deepart.ai.svg',
'./fonts/source-code-pro-v7-latin-500.woff',
'./fonts/source-code-pro-v7-latin-500.woff2',
'./fonts/source-code-pro-v7-latin-700.woff',
'./fonts/source-code-pro-v7-latin-700.woff2',
'./fonts/source-code-pro-v7-latin-regular.woff',
'./fonts/source-code-pro-v7-latin-regular.woff2',
'./manifest.json'
];

self.addEventListener('install', function (evt) {
self.skipWaiting();
evt.waitUntil(caches.open(CACHE).then(function (cache) {
cache.addAll(preCache);
}));
});

self.addEventListener('fetch', function (evt) {
evt.respondWith(fromCache(evt.request).then(function (match) {
if (match) {
return match;
} else {
return fetch(evt.request);
}
}));
});

self.addEventListener('activate', function (event) {
event.waitUntil(clients.claim());
event.waitUntil(clients.claim().then(function () {
return caches.keys().then(function (cacheNames) {
return Promise.all(cacheNames.filter(c => c !== CACHE).map(c => caches.delete(c)));
});
}));
});

function fromCache (request) {
return caches.open(CACHE).then(function (cache) {
return cache.match(request);
});
}

+ 0
- 3843
yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save