From eca5e3c841e1dc3d70acc0c560114b099952156d Mon Sep 17 00:00:00 2001 From: waveringana Date: Fri, 2 Dec 2022 13:59:50 +0000 Subject: [PATCH] housekeeping --- .github/workflows/docker-publish.yml | 1 + .github/workflows/main.yml | 2 +- README.md | 6 +- .eslintrc.json => app/.eslintrc.json | 62 +- app.js => app/app.js | 2 +- db.js => app/db.js | 37 +- .../public}/android-chrome-192x192.png | Bin .../public}/android-chrome-512x512.png | Bin {public => app/public}/apple-touch-icon.png | Bin {public => app/public}/css/app.css | 232 +++--- {public => app/public}/css/base.css | 282 +++---- {public => app/public}/css/home.css | 84 +- {public => app/public}/css/index.css | 786 +++++++++--------- {public => app/public}/css/login.css | 232 +++--- {public => app/public}/favicon-16x16.png | Bin {public => app/public}/favicon-32x32.png | Bin {public => app/public}/favicon.ico | Bin {public => app/public}/js/index.js | 286 +++---- {public => app/public}/site.webmanifest | 0 {routes => app/routes}/auth.js | 2 +- {routes => app/routes}/index.js | 2 +- {routes => app/routes}/middleware.js | 2 +- {views => app/views}/error.ejs | 2 +- {views => app/views}/gifv.ejs | 112 +-- {views => app/views}/home.ejs | 60 +- {views => app/views}/index.ejs | 208 ++--- {views => app/views}/login.ejs | 74 +- docker-entrypoint.sh | 4 - .dockerignore => docker/.dockerignore | 24 +- Dockerfile => docker/Dockerfile | 12 +- package.json | 4 +- 31 files changed, 1259 insertions(+), 1259 deletions(-) rename .eslintrc.json => app/.eslintrc.json (94%) rename app.js => app/app.js (99%) rename db.js => app/db.js (55%) rename {public => app/public}/android-chrome-192x192.png (100%) rename {public => app/public}/android-chrome-512x512.png (100%) rename {public => app/public}/apple-touch-icon.png (100%) rename {public => app/public}/css/app.css (95%) rename {public => app/public}/css/base.css (92%) rename {public => app/public}/css/home.css (94%) rename {public => app/public}/css/index.css (94%) rename {public => app/public}/css/login.css (94%) rename {public => app/public}/favicon-16x16.png (100%) rename {public => app/public}/favicon-32x32.png (100%) rename {public => app/public}/favicon.ico (100%) rename {public => app/public}/js/index.js (96%) rename {public => app/public}/site.webmanifest (100%) rename {routes => app/routes}/auth.js (97%) rename {routes => app/routes}/index.js (99%) rename {routes => app/routes}/middleware.js (99%) rename {views => app/views}/error.ejs (95%) rename {views => app/views}/gifv.ejs (71%) rename {views => app/views}/home.ejs (97%) rename {views => app/views}/index.ejs (97%) rename {views => app/views}/login.ejs (97%) delete mode 100755 docker-entrypoint.sh rename .dockerignore => docker/.dockerignore (88%) rename Dockerfile => docker/Dockerfile (72%) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 9ce43a5..df01b09 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -91,3 +91,4 @@ jobs: labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max + file: {context}/docker/Dockerfile diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 284e6f1..381bf36 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,5 +11,5 @@ jobs: - name: Cypress run uses: cypress-io/github-action@v4 with: - build: node db.js + build: node app/db.js start: npm start diff --git a/README.md b/README.md index 83bdace..8e4fd9e 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ Upcoming Features: Source: ```Bash EBPASS=changeme -EBPORT=4000 +EBPORT=3000 EBAPI_KEY=changeme #ShareX support $ npm install -$ node db.js +$ node app/db.js $ npm start ``` Default username is admin with the password being whatever EBPASS is @@ -49,7 +49,7 @@ JSON Docker config ``` -docker run -d -p "4000:4000" -e EBPORT=4000 -e EBPASS=changeme -e EBAPI_KEY=changeme ghcr.io/waveringana/embedder:1.7.1 +docker run -d -p "3000:3000" -e EBPORT=3000 -e EBPASS=changeme -e EBAPI_KEY=changeme ghcr.io/waveringana/embedder:1.7.1 ``` Docker Compose diff --git a/.eslintrc.json b/app/.eslintrc.json similarity index 94% rename from .eslintrc.json rename to app/.eslintrc.json index 489abb5..8152ccd 100644 --- a/.eslintrc.json +++ b/app/.eslintrc.json @@ -1,31 +1,31 @@ -{ - "env": { - "node": true, - "commonjs": true, - "es2021": true - }, - "extends": "eslint:recommended", - "overrides": [ - ], - "parserOptions": { - "ecmaVersion": "latest" - }, - "rules": { - "indent": [ - "error", - "tab" - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "double" - ], - "semi": [ - "error", - "always" - ] - } -} +{ + "env": { + "node": true, + "commonjs": true, + "es2021": true + }, + "extends": "eslint:recommended", + "overrides": [ + ], + "parserOptions": { + "ecmaVersion": "latest" + }, + "rules": { + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ] + } +} diff --git a/app.js b/app/app.js similarity index 99% rename from app.js rename to app/app.js index 22b8f13..f277146 100644 --- a/app.js +++ b/app/app.js @@ -13,7 +13,7 @@ const path = require("path"); const authRouter = require("./routes/auth"); const indexRouter = require("./routes/index"); -const db = require("./db"); +const db = require("./db").db; let app = express(); let server = http.createServer(app); diff --git a/db.js b/app/db.js similarity index 55% rename from db.js rename to app/db.js index cdc15c4..f50acc0 100644 --- a/db.js +++ b/app/db.js @@ -10,25 +10,28 @@ let db = new sqlite3.Database("./var/db/media.db"); db.serialize(function() { // create the database schema for the todos app db.run("CREATE TABLE IF NOT EXISTS users ( \ - id INTEGER PRIMARY KEY, \ - username TEXT UNIQUE, \ - hashed_password BLOB, \ - salt BLOB \ - )"); + id INTEGER PRIMARY KEY, \ + username TEXT UNIQUE, \ + hashed_password BLOB, \ + salt BLOB \ + )"); db.run("CREATE TABLE IF NOT EXISTS media ( \ - id INTEGER PRIMARY KEY, \ - path TEXT NOT NULL, \ - expire INTEGER \ - )"); + id INTEGER PRIMARY KEY, \ + path TEXT NOT NULL, \ + expire INTEGER \ + )"); - // create an initial user (username: alice, password: letmein) - var salt = crypto.randomBytes(16); - db.run("INSERT OR IGNORE INTO users (username, hashed_password, salt) VALUES (?, ?, ?)", [ - "admin", - crypto.pbkdf2Sync(process.env.EBPASS || "changeme", salt, 310000, 32, "sha256"), - salt - ]); + createUser("admin", process.env.EBPASS || "changeme"); }); -module.exports = db; +function createUser(username, password) { + var salt = crypto.randomBytes(16); + db.run("INSERT OR IGNORE INTO users (username, hashed_password, salt) VALUES (?, ?, ?)", [ + username, + crypto.pbkdf2Sync(password, salt, 310000, 32, "sha256"), + salt + ]); +} + +module.exports = {db: db, createUser: createUser}; diff --git a/public/android-chrome-192x192.png b/app/public/android-chrome-192x192.png similarity index 100% rename from public/android-chrome-192x192.png rename to app/public/android-chrome-192x192.png diff --git a/public/android-chrome-512x512.png b/app/public/android-chrome-512x512.png similarity index 100% rename from public/android-chrome-512x512.png rename to app/public/android-chrome-512x512.png diff --git a/public/apple-touch-icon.png b/app/public/apple-touch-icon.png similarity index 100% rename from public/apple-touch-icon.png rename to app/public/apple-touch-icon.png diff --git a/public/css/app.css b/app/public/css/app.css similarity index 95% rename from public/css/app.css rename to app/public/css/app.css index 5580864..d2f2227 100644 --- a/public/css/app.css +++ b/app/public/css/app.css @@ -1,116 +1,116 @@ -.nav { - position: absolute; - top: -130px; - right: 0; -} - -.nav ul { - margin: 0; - list-style: none; - text-align: center; -} - -.nav li { - display: inline-block; - height: 40px; - margin-left: 12px; - font-size: 14px; - font-weight: 400; - line-height: 40px; -} - -.nav a { - display: block; - color: inherit; - text-decoration: none; -} - -.nav a:hover { - border-bottom: 1px solid #DB7676; -} - -.nav button { - height: 40px; -} - -.nav button:hover { - border-bottom: 1px solid #DB7676; - cursor: pointer; -} - -/* background image by Cole Bemis */ -.nav .user { - padding-left: 20px; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-user'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); - background-repeat: no-repeat; - background-position: center left; -} - -/* background image by Cole Bemis */ -.nav .logout { - padding-left: 20px; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-log-out'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'%3E%3C/path%3E%3Cpolyline points='16 17 21 12 16 7'%3E%3C/polyline%3E%3Cline x1='21' y1='12' x2='9' y2='12'%3E%3C/line%3E%3C/svg%3E%0A"); - background-repeat: no-repeat; - background-position: center left; -} - -#dropArea { - border: 2px dashed #ccc; - border-radius: 20px; - width: 100%; - font-family: sans-serif; - padding: 50px 0px 50px 0px; -} - -#dropArea.highlight { - border-color: purple; -} - -.dragregion { - text-align: center; -} - -.image { - width: 100%; -} - -div.nonmedia { - height: 100px; - width: 100%; -} - -div.nonmedia p { - color: #444; - font-size: 20px; - font-weight: 400; - line-height: 100px; - text-align: center; -} - -label { - text-align: center; -} - -.video { - position: relative; -} - -.video .overlay { - position: absolute; - top: 0%; - left: 70%; - transform: translateY(0%) translateX(70%); - z-index: 1; - border-radius: 25px; - border: 2px solid #73AD21; - padding: 5px; - background-color: #eee; -} - -.video .overlay a { - color: #73AD21; - font-size: 12px; - font-weight: 400; - line-height: 20px; - text-align: center; -} +.nav { + position: absolute; + top: -130px; + right: 0; +} + +.nav ul { + margin: 0; + list-style: none; + text-align: center; +} + +.nav li { + display: inline-block; + height: 40px; + margin-left: 12px; + font-size: 14px; + font-weight: 400; + line-height: 40px; +} + +.nav a { + display: block; + color: inherit; + text-decoration: none; +} + +.nav a:hover { + border-bottom: 1px solid #DB7676; +} + +.nav button { + height: 40px; +} + +.nav button:hover { + border-bottom: 1px solid #DB7676; + cursor: pointer; +} + +/* background image by Cole Bemis */ +.nav .user { + padding-left: 20px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-user'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center left; +} + +/* background image by Cole Bemis */ +.nav .logout { + padding-left: 20px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-log-out'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'%3E%3C/path%3E%3Cpolyline points='16 17 21 12 16 7'%3E%3C/polyline%3E%3Cline x1='21' y1='12' x2='9' y2='12'%3E%3C/line%3E%3C/svg%3E%0A"); + background-repeat: no-repeat; + background-position: center left; +} + +#dropArea { + border: 2px dashed #ccc; + border-radius: 20px; + width: 100%; + font-family: sans-serif; + padding: 50px 0px 50px 0px; +} + +#dropArea.highlight { + border-color: purple; +} + +.dragregion { + text-align: center; +} + +.image { + width: 100%; +} + +div.nonmedia { + height: 100px; + width: 100%; +} + +div.nonmedia p { + color: #444; + font-size: 20px; + font-weight: 400; + line-height: 100px; + text-align: center; +} + +label { + text-align: center; +} + +.video { + position: relative; +} + +.video .overlay { + position: absolute; + top: 0%; + left: 70%; + transform: translateY(0%) translateX(70%); + z-index: 1; + border-radius: 25px; + border: 2px solid #73AD21; + padding: 5px; + background-color: #eee; +} + +.video .overlay a { + color: #73AD21; + font-size: 12px; + font-weight: 400; + line-height: 20px; + text-align: center; +} diff --git a/public/css/base.css b/app/public/css/base.css similarity index 92% rename from public/css/base.css rename to app/public/css/base.css index 8012123..da65968 100644 --- a/public/css/base.css +++ b/app/public/css/base.css @@ -1,141 +1,141 @@ -hr { - margin: 20px 0; - border: 0; - border-top: 1px dashed #c5c5c5; - border-bottom: 1px dashed #f7f7f7; -} - -.learn a { - font-weight: normal; - text-decoration: none; - color: #b83f45; -} - -.learn a:hover { - text-decoration: underline; - color: #787e7e; -} - -.learn h3, -.learn h4, -.learn h5 { - margin: 10px 0; - font-weight: 500; - line-height: 1.2; - color: #000; -} - -.learn h3 { - font-size: 24px; -} - -.learn h4 { - font-size: 18px; -} - -.learn h5 { - margin-bottom: 0; - font-size: 14px; -} - -.learn ul { - padding: 0; - margin: 0 0 30px 25px; -} - -.learn li { - line-height: 20px; -} - -.learn p { - font-size: 15px; - font-weight: 300; - line-height: 1.3; - margin-top: 0; - margin-bottom: 0; -} - -#issue-count { - display: none; -} - -.quote { - border: none; - margin: 20px 0 60px 0; -} - -.quote p { - font-style: italic; -} - -.quote p:before { - content: '“'; - font-size: 50px; - opacity: .15; - position: absolute; - top: -20px; - left: 3px; -} - -.quote p:after { - content: '”'; - font-size: 50px; - opacity: .15; - position: absolute; - bottom: -42px; - right: 3px; -} - -.quote footer { - position: absolute; - bottom: -40px; - right: 0; -} - -.quote footer img { - border-radius: 3px; -} - -.quote footer a { - margin-left: 5px; - vertical-align: middle; -} - -.speech-bubble { - position: relative; - padding: 10px; - background: rgba(0, 0, 0, .04); - border-radius: 5px; -} - -.speech-bubble:after { - content: ''; - position: absolute; - top: 100%; - right: 30px; - border: 13px solid transparent; - border-top-color: rgba(0, 0, 0, .04); -} - -.learn-bar > .learn { - position: absolute; - width: 272px; - top: 8px; - left: -300px; - padding: 10px; - border-radius: 5px; - background-color: rgba(255, 255, 255, .6); - transition-property: left; - transition-duration: 500ms; -} - -@media (min-width: 899px) { - .learn-bar { - width: auto; - padding-left: 300px; - } - - .learn-bar > .learn { - left: 8px; - } -} +hr { + margin: 20px 0; + border: 0; + border-top: 1px dashed #c5c5c5; + border-bottom: 1px dashed #f7f7f7; +} + +.learn a { + font-weight: normal; + text-decoration: none; + color: #b83f45; +} + +.learn a:hover { + text-decoration: underline; + color: #787e7e; +} + +.learn h3, +.learn h4, +.learn h5 { + margin: 10px 0; + font-weight: 500; + line-height: 1.2; + color: #000; +} + +.learn h3 { + font-size: 24px; +} + +.learn h4 { + font-size: 18px; +} + +.learn h5 { + margin-bottom: 0; + font-size: 14px; +} + +.learn ul { + padding: 0; + margin: 0 0 30px 25px; +} + +.learn li { + line-height: 20px; +} + +.learn p { + font-size: 15px; + font-weight: 300; + line-height: 1.3; + margin-top: 0; + margin-bottom: 0; +} + +#issue-count { + display: none; +} + +.quote { + border: none; + margin: 20px 0 60px 0; +} + +.quote p { + font-style: italic; +} + +.quote p:before { + content: '“'; + font-size: 50px; + opacity: .15; + position: absolute; + top: -20px; + left: 3px; +} + +.quote p:after { + content: '”'; + font-size: 50px; + opacity: .15; + position: absolute; + bottom: -42px; + right: 3px; +} + +.quote footer { + position: absolute; + bottom: -40px; + right: 0; +} + +.quote footer img { + border-radius: 3px; +} + +.quote footer a { + margin-left: 5px; + vertical-align: middle; +} + +.speech-bubble { + position: relative; + padding: 10px; + background: rgba(0, 0, 0, .04); + border-radius: 5px; +} + +.speech-bubble:after { + content: ''; + position: absolute; + top: 100%; + right: 30px; + border: 13px solid transparent; + border-top-color: rgba(0, 0, 0, .04); +} + +.learn-bar > .learn { + position: absolute; + width: 272px; + top: 8px; + left: -300px; + padding: 10px; + border-radius: 5px; + background-color: rgba(255, 255, 255, .6); + transition-property: left; + transition-duration: 500ms; +} + +@media (min-width: 899px) { + .learn-bar { + width: auto; + padding-left: 300px; + } + + .learn-bar > .learn { + left: 8px; + } +} diff --git a/public/css/home.css b/app/public/css/home.css similarity index 94% rename from public/css/home.css rename to app/public/css/home.css index 902f504..7f54514 100644 --- a/public/css/home.css +++ b/app/public/css/home.css @@ -1,42 +1,42 @@ -.todohome { - margin: 130px 0 40px 0; - position: relative; -} - -.todohome h1 { - position: absolute; - top: -140px; - width: 100%; - font-size: 80px; - font-weight: 200; - text-align: center; - color: #b83f45; - -webkit-text-rendering: optimizeLegibility; - -moz-text-rendering: optimizeLegibility; - text-rendering: optimizeLegibility; -} - -.todohome section { - padding-top: 1px; - text-align: center; -} - -.todohome h2 { - padding-bottom: 48px; - font-size: 28px; - font-weight: 300; - line-height: 1.5; -} - -.todohome .button { - padding: 13px 45px; - font-size: 16px; - font-weight: 500; - color: white; - border-radius: 5px; - background: #d83f45; -} - -.todohome a.button { - text-decoration: none; -} +.todohome { + margin: 130px 0 40px 0; + position: relative; +} + +.todohome h1 { + position: absolute; + top: -140px; + width: 100%; + font-size: 80px; + font-weight: 200; + text-align: center; + color: #b83f45; + -webkit-text-rendering: optimizeLegibility; + -moz-text-rendering: optimizeLegibility; + text-rendering: optimizeLegibility; +} + +.todohome section { + padding-top: 1px; + text-align: center; +} + +.todohome h2 { + padding-bottom: 48px; + font-size: 28px; + font-weight: 300; + line-height: 1.5; +} + +.todohome .button { + padding: 13px 45px; + font-size: 16px; + font-weight: 500; + color: white; + border-radius: 5px; + background: #d83f45; +} + +.todohome a.button { + text-decoration: none; +} diff --git a/public/css/index.css b/app/public/css/index.css similarity index 94% rename from public/css/index.css rename to app/public/css/index.css index e5d5863..8238dbf 100644 --- a/public/css/index.css +++ b/app/public/css/index.css @@ -1,393 +1,393 @@ -html, -body { - margin: 0; - padding: 0; -} - -button { - margin: 0; - padding: 0; - border: 0; - background: none; - font-size: 100%; - vertical-align: baseline; - font-family: inherit; - font-weight: inherit; - color: inherit; - -webkit-appearance: none; - appearance: none; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -body { - font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; - line-height: 1.4em; - background: #111111; - color: #f5f5f5; - min-width: 230px; - max-width: 550px; - margin: 0 auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-weight: 300; -} - -.view .header { - background: #121122; -} - -.hidden { - display: none; -} - -.todoapp { - background: #121212; - margin: 130px 0 40px 0; - position: relative; - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), - 0 25px 50px 0 rgba(0, 0, 0, 0.1); -} - -.todoapp input::-webkit-input-placeholder { - font-style: italic; - font-weight: 400; - color: #f5f5f5; - text-align: center; -} - -.todoapp input::-moz-placeholder { - font-style: italic; - font-weight: 400; - color: #f5f5f5; - text-align: center; -} - -.todoapp input::input-placeholder { - font-style: italic; - font-weight: 400; - color: #f5f5f5; - text-align: center; -} - -.todoapp h1 { - position: absolute; - top: -140px; - width: 100%; - font-size: 80px; - font-weight: 200; - text-align: center; - color: #b83f45; - -webkit-text-rendering: optimizeLegibility; - -moz-text-rendering: optimizeLegibility; - text-rendering: optimizeLegibility; -} - -.new-todo, -.edit { - position: relative; - margin: 0; - width: 100%; - font-size: 24px; - font-family: inherit; - font-weight: inherit; - line-height: 1.4em; - color: inherit; - padding: 6px; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.new-todo { - padding: 16px 16px 16px 60px; - height: 65px; - border: none; - background: rgba(0, 0, 0, 0.003); - box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); -} - -.main { - position: relative; - z-index: 2; -} - -.toggle-all { - width: 1px; - height: 1px; - border: none; /* Mobile Safari */ - opacity: 0; - position: absolute; - right: 100%; - bottom: 100%; -} - -.toggle-all + label { - display: flex; - align-items: center; - justify-content: center; - width: 45px; - height: 65px; - font-size: 0; - position: absolute; - top: -65px; - left: -0; -} - -.toggle-all + label:before { - content: '❯'; - display: inline-block; - font-size: 22px; - color: #949494; - padding: 10px 27px 10px 27px; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); -} - -.toggle-all:checked + label:before { - color: #484848; -} - -.todo-list { - margin: 0; - padding: 0; - list-style: none; -} - -.todo-list li { - position: relative; - font-size: 24px; -} - -.todo-list li:last-child { - border-bottom: none; -} - -.todo-list li.editing { - border-bottom: none; - padding: 0; -} - -.todo-list li.editing .edit { - display: block; - width: calc(100% - 43px); - padding: 12px 16px; - margin: 0 0 0 43px; -} - -.todo-list li.editing .view { - display: none; -} - -.todo-list li .toggle { - text-align: center; - width: 40px; - /* auto, since non-WebKit browsers doesn't support input styling */ - height: auto; - position: absolute; - top: 0; - bottom: 0; - margin: auto 0; - border: none; /* Mobile Safari */ - -webkit-appearance: none; - appearance: none; -} - -.todo-list li .toggle { - opacity: 0; -} - -.todo-list li .toggle + label { - /* - Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 - IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ - */ - background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23949494%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); - background-repeat: no-repeat; - background-position: center left; -} - -.todo-list li .toggle:checked + label { - background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%2359A193%22%20stroke-width%3D%223%22%2F%3E%3Cpath%20fill%3D%22%233EA390%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22%2F%3E%3C%2Fsvg%3E'); -} - -.todo-list li label { - word-break: break-all; - padding: 15px 15px 15px 60px; - display: block; - line-height: 1.2; - transition: color 0.4s; - font-weight: 400; - color: #BB86FC; -} - -.todo-list li.completed label { - color: #949494; - text-decoration: line-through; -} - -.todo-list li .destroy { - display: none; - position: absolute; - top: 0; - right: 10px; - bottom: 0; - width: 40px; - height: 40px; - margin: auto 0; - font-size: 30px; - color: #949494; - transition: color 0.2s ease-out; -} - -.todo-list li .destroy:hover, -.todo-list li .destroy:focus { - color: #C18585; -} - -.todo-list li .destroy:after { - content: '×'; - display: block; - height: 100%; - line-height: 1.1; -} - -.todo-list li:hover .destroy { - display: block; -} - -.todo-list li .edit { - display: none; -} - -.todo-list li.editing:last-child { - margin-bottom: -1px; -} - -.footer { - padding: 10px 15px; - height: 20px; - text-align: center; - font-size: 15px; - border-top: 1px solid #e6e6e6; -} - -.footer:before { - content: ''; - position: absolute; - right: 0; - bottom: 0; - left: 0; - height: 50px; - overflow: hidden; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), - 0 8px 0 -3px #f6f6f6, - 0 9px 1px -3px rgba(0, 0, 0, 0.2), - 0 16px 0 -6px #f6f6f6, - 0 17px 2px -6px rgba(0, 0, 0, 0.2); -} - -.todo-count { - float: left; - text-align: left; -} - -.todo-count strong { - font-weight: 300; -} - -.filters { - margin: 0; - padding: 0; - list-style: none; - position: absolute; - right: 0; - left: 0; -} - -.filters li { - display: inline; -} - -.filters li a { - color: inherit; - margin: 3px; - padding: 3px 7px; - text-decoration: none; - border: 1px solid transparent; - border-radius: 3px; -} - -.filters li a:hover { - border-color: #DB7676; -} - -.filters li a.selected { - border-color: #CE4646; -} - -.clear-completed, -html .clear-completed:active { - float: right; - position: relative; - line-height: 19px; - text-decoration: none; - cursor: pointer; -} - -.clear-completed:hover { - text-decoration: underline; -} - -.info { - margin: 65px auto 0; - color: #4d4d4d; - font-size: 11px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - text-align: center; -} - -.info p { - line-height: 1; -} - -.info a { - color: inherit; - text-decoration: none; - font-weight: 400; -} - -.info a:hover { - text-decoration: underline; -} - -/* - Hack to remove background from Mobile Safari. - Can't use it globally since it destroys checkboxes in Firefox -*/ -@media screen and (-webkit-min-device-pixel-ratio:0) { - .toggle-all, - .todo-list li .toggle { - background: none; - } - - .todo-list li .toggle { - height: 40px; - } -} - -@media (max-width: 430px) { - .footer { - height: 50px; - } - - .filters { - bottom: 10px; - } -} - -:focus, -.toggle:focus + label, -.toggle-all:focus + label { - box-shadow: 0 0 2px 2px #CF7D7D; - outline: 0; -} +html, +body { + margin: 0; + padding: 0; +} + +button { + margin: 0; + padding: 0; + border: 0; + background: none; + font-size: 100%; + vertical-align: baseline; + font-family: inherit; + font-weight: inherit; + color: inherit; + -webkit-appearance: none; + appearance: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.4em; + background: #111111; + color: #f5f5f5; + min-width: 230px; + max-width: 550px; + margin: 0 auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-weight: 300; +} + +.view .header { + background: #121122; +} + +.hidden { + display: none; +} + +.todoapp { + background: #121212; + margin: 130px 0 40px 0; + position: relative; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), + 0 25px 50px 0 rgba(0, 0, 0, 0.1); +} + +.todoapp input::-webkit-input-placeholder { + font-style: italic; + font-weight: 400; + color: #f5f5f5; + text-align: center; +} + +.todoapp input::-moz-placeholder { + font-style: italic; + font-weight: 400; + color: #f5f5f5; + text-align: center; +} + +.todoapp input::input-placeholder { + font-style: italic; + font-weight: 400; + color: #f5f5f5; + text-align: center; +} + +.todoapp h1 { + position: absolute; + top: -140px; + width: 100%; + font-size: 80px; + font-weight: 200; + text-align: center; + color: #b83f45; + -webkit-text-rendering: optimizeLegibility; + -moz-text-rendering: optimizeLegibility; + text-rendering: optimizeLegibility; +} + +.new-todo, +.edit { + position: relative; + margin: 0; + width: 100%; + font-size: 24px; + font-family: inherit; + font-weight: inherit; + line-height: 1.4em; + color: inherit; + padding: 6px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.new-todo { + padding: 16px 16px 16px 60px; + height: 65px; + border: none; + background: rgba(0, 0, 0, 0.003); + box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); +} + +.main { + position: relative; + z-index: 2; +} + +.toggle-all { + width: 1px; + height: 1px; + border: none; /* Mobile Safari */ + opacity: 0; + position: absolute; + right: 100%; + bottom: 100%; +} + +.toggle-all + label { + display: flex; + align-items: center; + justify-content: center; + width: 45px; + height: 65px; + font-size: 0; + position: absolute; + top: -65px; + left: -0; +} + +.toggle-all + label:before { + content: '❯'; + display: inline-block; + font-size: 22px; + color: #949494; + padding: 10px 27px 10px 27px; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} + +.toggle-all:checked + label:before { + color: #484848; +} + +.todo-list { + margin: 0; + padding: 0; + list-style: none; +} + +.todo-list li { + position: relative; + font-size: 24px; +} + +.todo-list li:last-child { + border-bottom: none; +} + +.todo-list li.editing { + border-bottom: none; + padding: 0; +} + +.todo-list li.editing .edit { + display: block; + width: calc(100% - 43px); + padding: 12px 16px; + margin: 0 0 0 43px; +} + +.todo-list li.editing .view { + display: none; +} + +.todo-list li .toggle { + text-align: center; + width: 40px; + /* auto, since non-WebKit browsers doesn't support input styling */ + height: auto; + position: absolute; + top: 0; + bottom: 0; + margin: auto 0; + border: none; /* Mobile Safari */ + -webkit-appearance: none; + appearance: none; +} + +.todo-list li .toggle { + opacity: 0; +} + +.todo-list li .toggle + label { + /* + Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 + IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ + */ + background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23949494%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); + background-repeat: no-repeat; + background-position: center left; +} + +.todo-list li .toggle:checked + label { + background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%2359A193%22%20stroke-width%3D%223%22%2F%3E%3Cpath%20fill%3D%22%233EA390%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22%2F%3E%3C%2Fsvg%3E'); +} + +.todo-list li label { + word-break: break-all; + padding: 15px 15px 15px 60px; + display: block; + line-height: 1.2; + transition: color 0.4s; + font-weight: 400; + color: #BB86FC; +} + +.todo-list li.completed label { + color: #949494; + text-decoration: line-through; +} + +.todo-list li .destroy { + display: none; + position: absolute; + top: 0; + right: 10px; + bottom: 0; + width: 40px; + height: 40px; + margin: auto 0; + font-size: 30px; + color: #949494; + transition: color 0.2s ease-out; +} + +.todo-list li .destroy:hover, +.todo-list li .destroy:focus { + color: #C18585; +} + +.todo-list li .destroy:after { + content: '×'; + display: block; + height: 100%; + line-height: 1.1; +} + +.todo-list li:hover .destroy { + display: block; +} + +.todo-list li .edit { + display: none; +} + +.todo-list li.editing:last-child { + margin-bottom: -1px; +} + +.footer { + padding: 10px 15px; + height: 20px; + text-align: center; + font-size: 15px; + border-top: 1px solid #e6e6e6; +} + +.footer:before { + content: ''; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 50px; + overflow: hidden; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), + 0 8px 0 -3px #f6f6f6, + 0 9px 1px -3px rgba(0, 0, 0, 0.2), + 0 16px 0 -6px #f6f6f6, + 0 17px 2px -6px rgba(0, 0, 0, 0.2); +} + +.todo-count { + float: left; + text-align: left; +} + +.todo-count strong { + font-weight: 300; +} + +.filters { + margin: 0; + padding: 0; + list-style: none; + position: absolute; + right: 0; + left: 0; +} + +.filters li { + display: inline; +} + +.filters li a { + color: inherit; + margin: 3px; + padding: 3px 7px; + text-decoration: none; + border: 1px solid transparent; + border-radius: 3px; +} + +.filters li a:hover { + border-color: #DB7676; +} + +.filters li a.selected { + border-color: #CE4646; +} + +.clear-completed, +html .clear-completed:active { + float: right; + position: relative; + line-height: 19px; + text-decoration: none; + cursor: pointer; +} + +.clear-completed:hover { + text-decoration: underline; +} + +.info { + margin: 65px auto 0; + color: #4d4d4d; + font-size: 11px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-align: center; +} + +.info p { + line-height: 1; +} + +.info a { + color: inherit; + text-decoration: none; + font-weight: 400; +} + +.info a:hover { + text-decoration: underline; +} + +/* + Hack to remove background from Mobile Safari. + Can't use it globally since it destroys checkboxes in Firefox +*/ +@media screen and (-webkit-min-device-pixel-ratio:0) { + .toggle-all, + .todo-list li .toggle { + background: none; + } + + .todo-list li .toggle { + height: 40px; + } +} + +@media (max-width: 430px) { + .footer { + height: 50px; + } + + .filters { + bottom: 10px; + } +} + +:focus, +.toggle:focus + label, +.toggle-all:focus + label { + box-shadow: 0 0 2px 2px #CF7D7D; + outline: 0; +} diff --git a/public/css/login.css b/app/public/css/login.css similarity index 94% rename from public/css/login.css rename to app/public/css/login.css index 89a51a1..d33b643 100644 --- a/public/css/login.css +++ b/app/public/css/login.css @@ -1,116 +1,116 @@ -.prompt { - max-width: 400px; - margin: 50px auto; - padding: 25px; - background: #11111; - border: 1px solid #e6e6e6; - border-radius: 8px; -} - -button { - display: block; - padding: 10px; - width: 100%; - border-radius: 3px; - background: #d83f45; - font-size: 14px; - font-weight: 700; - color: white; - cursor: pointer; -} - -a.button { - box-sizing: border-box; - display: block; - padding: 10px; - width: 100%; - border-radius: 3px; - background: #000; - font-size: 14px; - font-weight: 700; - text-align: center; - text-decoration: none; - color: white; -} - -a.google { - background: #4787ed; -} - -a.facebook { - background: #4267b2; -} - -button:hover { - background-color: #c83f45; -} - -h1 { - margin: 0 0 20px 0; - padding: 0 0 5px 0; - font-size: 24px; - font-weight: 500; -} - -h3 { - margin-top: 0; - font-size: 24px; - font-weight: 300; - text-align: center; - color: #b83f45; -} - -form section { - margin: 0 0 20px 0; - position: relative; /* for password toggle positioning */ -} - -label { - display: block; - margin: 0 0 3px 0; - font-size: 14px; - font-weight: 500; -} - -input { - box-sizing: border-box; - width: 100%; - padding: 10px; - font-size: 14px; - border: 1px solid #d9d9d9; - border-radius: 5px; - background-color:#200; - color:#fff; -} - -input[type=email]:not(:focus):invalid, -input[type=password]:not(:focus):invalid { - color: red; - outline-color: red; -} - -hr { - border-top: 1px solid #d9d9d9; - border-bottom: none; -} - -p.instructions { - font-weight: 400; -} - -p.help { - text-align: center; - font-weight: 400; -} - -/* background image by Cole Bemis */ -.messages p { - font-size: 14px; - font-weight: 400; - line-height: 1.3; - color: #d83f45; - padding-left: 20px; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23d83f45' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-alert-circle'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); - background-repeat: no-repeat; - background-position: center left; -} +.prompt { + max-width: 400px; + margin: 50px auto; + padding: 25px; + background: #11111; + border: 1px solid #e6e6e6; + border-radius: 8px; +} + +button { + display: block; + padding: 10px; + width: 100%; + border-radius: 3px; + background: #d83f45; + font-size: 14px; + font-weight: 700; + color: white; + cursor: pointer; +} + +a.button { + box-sizing: border-box; + display: block; + padding: 10px; + width: 100%; + border-radius: 3px; + background: #000; + font-size: 14px; + font-weight: 700; + text-align: center; + text-decoration: none; + color: white; +} + +a.google { + background: #4787ed; +} + +a.facebook { + background: #4267b2; +} + +button:hover { + background-color: #c83f45; +} + +h1 { + margin: 0 0 20px 0; + padding: 0 0 5px 0; + font-size: 24px; + font-weight: 500; +} + +h3 { + margin-top: 0; + font-size: 24px; + font-weight: 300; + text-align: center; + color: #b83f45; +} + +form section { + margin: 0 0 20px 0; + position: relative; /* for password toggle positioning */ +} + +label { + display: block; + margin: 0 0 3px 0; + font-size: 14px; + font-weight: 500; +} + +input { + box-sizing: border-box; + width: 100%; + padding: 10px; + font-size: 14px; + border: 1px solid #d9d9d9; + border-radius: 5px; + background-color:#200; + color:#fff; +} + +input[type=email]:not(:focus):invalid, +input[type=password]:not(:focus):invalid { + color: red; + outline-color: red; +} + +hr { + border-top: 1px solid #d9d9d9; + border-bottom: none; +} + +p.instructions { + font-weight: 400; +} + +p.help { + text-align: center; + font-weight: 400; +} + +/* background image by Cole Bemis */ +.messages p { + font-size: 14px; + font-weight: 400; + line-height: 1.3; + color: #d83f45; + padding-left: 20px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23d83f45' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-alert-circle'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center left; +} diff --git a/public/favicon-16x16.png b/app/public/favicon-16x16.png similarity index 100% rename from public/favicon-16x16.png rename to app/public/favicon-16x16.png diff --git a/public/favicon-32x32.png b/app/public/favicon-32x32.png similarity index 100% rename from public/favicon-32x32.png rename to app/public/favicon-32x32.png diff --git a/public/favicon.ico b/app/public/favicon.ico similarity index 100% rename from public/favicon.ico rename to app/public/favicon.ico diff --git a/public/js/index.js b/app/public/js/index.js similarity index 96% rename from public/js/index.js rename to app/public/js/index.js index 36d8b74..7a8abb2 100644 --- a/public/js/index.js +++ b/app/public/js/index.js @@ -1,143 +1,143 @@ -/* eslint-env browser: true */ - -function copyURI(evt) { - evt.preventDefault(); - navigator.clipboard.writeText(absolutePath(evt.target.getAttribute("src"))).then(() => { - /* clipboard successfully set */ - console.log("copied"); - }, () => { - /* clipboard write failed */ - console.log("failed"); - }); -} - -function copyA(evt) { - evt.preventDefault(); - navigator.clipboard.writeText(absolutePath(evt.target.getAttribute("href"))).then(() => { - console.log("copied"); - }, () => { - console.log("failed"); - }); -} - -function copyPath(evt) { - navigator.clipboard.writeText(absolutePath(evt)).then(() => { - console.log("copied"); - }, () => { - console.log("failed"); - }); -} - -function absolutePath (href) { - let link = document.createElement("a"); - link.href = href; - return link.href; -} - -function extension(string) { - return string.slice((string.lastIndexOf(".") - 2 >>> 0) + 2); -} - -let dropArea = document.getElementById("dropArea"); - -["dragenter", "dragover", "dragleave", "drop"].forEach(eventName => { - dropArea.addEventListener(eventName, preventDefaults, false); -}); - -function preventDefaults (e) { - e.preventDefault(); - e.stopPropagation(); -} - -["dragenter", "dragover"].forEach(eventName => { - dropArea.addEventListener(eventName, highlight, false); -}) - -;["dragleave", "drop"].forEach(eventName => { - dropArea.addEventListener(eventName, unhighlight, false); -}); - -function highlight(e) { - dropArea.classList.add("highlight"); -} - -function unhighlight(e) { - dropArea.classList.remove("highlight"); -} - -dropArea.addEventListener("drop", handleDrop, false); -window.addEventListener("paste", handlePaste); - -function handleDrop(e) { - let dt = e.dataTransfer; - let files = dt.files; - handleFiles(files); -} - -function handlePaste(e) { - // Get the data of clipboard - const clipboardItems = e.clipboardData.items; - const items = [].slice.call(clipboardItems).filter(function (item) { - // Filter the image items only - return item.type.indexOf("image") !== -1; - }); - if (items.length === 0) { - return; - } - - const item = items[0]; - // Get the blob of image - const blob = item.getAsFile(); - console.log(blob); - - uploadFile(blob); - previewFile(blob); -} - -function handleFiles(files) { - files = [...files]; - files.forEach(uploadFile); - files.forEach(previewFile); -} - - -function previewFile(file) { - let reader = new FileReader(); - reader.readAsDataURL(file); - reader.onloadend = function() { - let img = document.createElement("img"); - img.src = reader.result; - img.className = "image"; - document.getElementById("gallery").appendChild(img); - console.log(document.getElementById("fileupload")); - document.getElementById("fileupload").src = img.src; - }; -} - -function uploadFile(file) { - let xhr = new XMLHttpRequest(); - let formData = new FormData(); - let reader = new FileReader(); - - xhr.open("POST", "/", true); - - xhr.addEventListener("readystatechange", function(e) { - if (xhr.readyState == 4 && xhr.status == 200) { - location.reload(); - } - else if (xhr.readyState == 4 && xhr.status != 200) { - // Error. Inform the user - } - }); - - if (file == null || file == undefined) { - //file = reader.readAsDataURL(document.getElementById("fileupload").files[0]); - //file = reader.readAsDataURL(document.querySelector("#fileupload").files[0]); - file = document.querySelector("#fileupload").files[0]; - } - - formData.append("fileupload", file); - formData.append("expire", document.getElementById("expire").value); - console.log(formData); - xhr.send(formData); -} +/* eslint-env browser: true */ + +function copyURI(evt) { + evt.preventDefault(); + navigator.clipboard.writeText(absolutePath(evt.target.getAttribute("src"))).then(() => { + /* clipboard successfully set */ + console.log("copied"); + }, () => { + /* clipboard write failed */ + console.log("failed"); + }); +} + +function copyA(evt) { + evt.preventDefault(); + navigator.clipboard.writeText(absolutePath(evt.target.getAttribute("href"))).then(() => { + console.log("copied"); + }, () => { + console.log("failed"); + }); +} + +function copyPath(evt) { + navigator.clipboard.writeText(absolutePath(evt)).then(() => { + console.log("copied"); + }, () => { + console.log("failed"); + }); +} + +function absolutePath (href) { + let link = document.createElement("a"); + link.href = href; + return link.href; +} + +function extension(string) { + return string.slice((string.lastIndexOf(".") - 2 >>> 0) + 2); +} + +let dropArea = document.getElementById("dropArea"); + +["dragenter", "dragover", "dragleave", "drop"].forEach(eventName => { + dropArea.addEventListener(eventName, preventDefaults, false); +}); + +function preventDefaults (e) { + e.preventDefault(); + e.stopPropagation(); +} + +["dragenter", "dragover"].forEach(eventName => { + dropArea.addEventListener(eventName, highlight, false); +}) + +;["dragleave", "drop"].forEach(eventName => { + dropArea.addEventListener(eventName, unhighlight, false); +}); + +function highlight(e) { + dropArea.classList.add("highlight"); +} + +function unhighlight(e) { + dropArea.classList.remove("highlight"); +} + +dropArea.addEventListener("drop", handleDrop, false); +window.addEventListener("paste", handlePaste); + +function handleDrop(e) { + let dt = e.dataTransfer; + let files = dt.files; + handleFiles(files); +} + +function handlePaste(e) { + // Get the data of clipboard + const clipboardItems = e.clipboardData.items; + const items = [].slice.call(clipboardItems).filter(function (item) { + // Filter the image items only + return item.type.indexOf("image") !== -1; + }); + if (items.length === 0) { + return; + } + + const item = items[0]; + // Get the blob of image + const blob = item.getAsFile(); + console.log(blob); + + uploadFile(blob); + previewFile(blob); +} + +function handleFiles(files) { + files = [...files]; + files.forEach(uploadFile); + files.forEach(previewFile); +} + + +function previewFile(file) { + let reader = new FileReader(); + reader.readAsDataURL(file); + reader.onloadend = function() { + let img = document.createElement("img"); + img.src = reader.result; + img.className = "image"; + document.getElementById("gallery").appendChild(img); + console.log(document.getElementById("fileupload")); + document.getElementById("fileupload").src = img.src; + }; +} + +function uploadFile(file) { + let xhr = new XMLHttpRequest(); + let formData = new FormData(); + let reader = new FileReader(); + + xhr.open("POST", "/", true); + + xhr.addEventListener("readystatechange", function(e) { + if (xhr.readyState == 4 && xhr.status == 200) { + location.reload(); + } + else if (xhr.readyState == 4 && xhr.status != 200) { + // Error. Inform the user + } + }); + + if (file == null || file == undefined) { + //file = reader.readAsDataURL(document.getElementById("fileupload").files[0]); + //file = reader.readAsDataURL(document.querySelector("#fileupload").files[0]); + file = document.querySelector("#fileupload").files[0]; + } + + formData.append("fileupload", file); + formData.append("expire", document.getElementById("expire").value); + console.log(formData); + xhr.send(formData); +} diff --git a/public/site.webmanifest b/app/public/site.webmanifest similarity index 100% rename from public/site.webmanifest rename to app/public/site.webmanifest diff --git a/routes/auth.js b/app/routes/auth.js similarity index 97% rename from routes/auth.js rename to app/routes/auth.js index 865f4cf..d460213 100644 --- a/routes/auth.js +++ b/app/routes/auth.js @@ -3,7 +3,7 @@ const express = require("express"); const passport = require("passport"); const LocalStrategy = require("passport-local"); -let db = require("../db"); +let db = require("../db").db; let router = express.Router(); diff --git a/routes/index.js b/app/routes/index.js similarity index 99% rename from routes/index.js rename to app/routes/index.js index 9c1cace..6a02eab 100644 --- a/routes/index.js +++ b/app/routes/index.js @@ -10,7 +10,7 @@ ffmpeg.setFfprobePath(ffprobepath); const fs = require("fs"); -let db = require("../db"); +let db = require("../db").db; let {checkAuth, convert, handleUpload} = require("./middleware"); function extension(str){ diff --git a/routes/middleware.js b/app/routes/middleware.js similarity index 99% rename from routes/middleware.js rename to app/routes/middleware.js index 950398d..2433513 100644 --- a/routes/middleware.js +++ b/app/routes/middleware.js @@ -7,7 +7,7 @@ ffmpeg.setFfprobePath(ffprobepath); const fs = require("fs"); const process = require("process"); -let db = require("../db.js"); +let db = require("../db.js").db; function extension(str){ let file = str.split("/").pop(); diff --git a/views/error.ejs b/app/views/error.ejs similarity index 95% rename from views/error.ejs rename to app/views/error.ejs index 1a8d4f5..69bfa1d 100644 --- a/views/error.ejs +++ b/app/views/error.ejs @@ -1 +1 @@ -

<%= error %>

+

<%= error %>

diff --git a/views/gifv.ejs b/app/views/gifv.ejs similarity index 71% rename from views/gifv.ejs rename to app/views/gifv.ejs index 6b971de..043febc 100644 --- a/views/gifv.ejs +++ b/app/views/gifv.ejs @@ -1,56 +1,56 @@ -<% -function extension(str){ - let file = str.split('/').pop(); - return [file.substr(0,file.lastIndexOf('.')),file.substr(file.lastIndexOf('.'),file.length).toLowerCase()] -} -%> - - - - - <% if (extension(url)[1] == ".gif") { %> - - - - - - - - - - - - <% } else if (extension(url)[1] == ".mp4") { %> - - - - - - - - - - - - <% } else { %> - - - - - - - - - - "> - - <% } %> - - - <% if (extension(url)[1] == ".mp4") { %> - - <% } else { %> - - <% } %> - - +<% +function extension(str){ + let file = str.split('/').pop(); + return [file.substr(0,file.lastIndexOf('.')),file.substr(file.lastIndexOf('.'),file.length).toLowerCase()] +} +%> + + + + + <% if (extension(url)[1] == ".gif") { %> + + + + + + + + + + + + <% } else if (extension(url)[1] == ".mp4") { %> + + + + + + + + + + + + <% } else { %> + + + + + + + + + + "> + + <% } %> + + + <% if (extension(url)[1] == ".mp4") { %> + + <% } else { %> + + <% } %> + + diff --git a/views/home.ejs b/app/views/home.ejs similarity index 97% rename from views/home.ejs rename to app/views/home.ejs index ab5c8c5..9ad55f2 100644 --- a/views/home.ejs +++ b/app/views/home.ejs @@ -1,30 +1,30 @@ - - - - - - Embedder - - - - - - - - - -
-
-

Embedder

-
-
-

A media host specialized in good looking embeds for services like Discord

- Sign in -
-
- - - + + + + + + Embedder + + + + + + + + + +
+
+

Embedder

+
+
+

A media host specialized in good looking embeds for services like Discord

+ Sign in +
+
+ + + diff --git a/views/index.ejs b/app/views/index.ejs similarity index 97% rename from views/index.ejs rename to app/views/index.ejs index 419c3a9..fa99fcf 100644 --- a/views/index.ejs +++ b/app/views/index.ejs @@ -1,104 +1,104 @@ - - - - - - Embedder - - - - - - - -<% -function extension(string) { -return string.slice((string.lastIndexOf(".") - 2 >>> 0) + 2); -} -%> - - -
- -
-

Embedder

-
-
-

Upload a file, copy paste, or drag n' drop into the dashed region

- -

-
-
-

Select file expiration date:

-

Click the file to copy the url

-
-
-
- <% if (Count > 0) { %> -
-
    - <% files.forEach(function(file) { %> -
  • -
    -
    - <% if (extension(file.path) == ".mp4" || extension(file.path) == ".mov" || extension(file.path) == "webp") { %> -
    - - -
    - <% } else if (extension(file.path) == ".gif") { %> -
    - - -
    - <% } else if (extension(file.path) == ".jpg" || extension(file.path) == ".jpeg" || extension(file.path) == ".png" || extension(file.path) == ".gif" || extension(file.path) == ".webp" ) { %> - - <% } else {%> -
    -

    <%=extension(file.path)%> file

    -
    - <% } %> - - -
    -
    -
    -
    -
  • - <% }); %> -
-
- <% } %> -
- - - - + + + + + + Embedder + + + + + + + +<% +function extension(string) { +return string.slice((string.lastIndexOf(".") - 2 >>> 0) + 2); +} +%> + + +
+ +
+

Embedder

+
+
+

Upload a file, copy paste, or drag n' drop into the dashed region

+ +

+
+
+

Select file expiration date:

+

Click the file to copy the url

+
+
+
+ <% if (Count > 0) { %> +
+
    + <% files.forEach(function(file) { %> +
  • +
    +
    + <% if (extension(file.path) == ".mp4" || extension(file.path) == ".mov" || extension(file.path) == "webp") { %> +
    + + +
    + <% } else if (extension(file.path) == ".gif") { %> +
    + + +
    + <% } else if (extension(file.path) == ".jpg" || extension(file.path) == ".jpeg" || extension(file.path) == ".png" || extension(file.path) == ".gif" || extension(file.path) == ".webp" ) { %> + + <% } else {%> +
    +

    <%=extension(file.path)%> file

    +
    + <% } %> + + +
    +
    +
    +
    +
  • + <% }); %> +
+
+ <% } %> +
+ + + + diff --git a/views/login.ejs b/app/views/login.ejs similarity index 97% rename from views/login.ejs rename to app/views/login.ejs index 1ef8c9c..f727a96 100644 --- a/views/login.ejs +++ b/app/views/login.ejs @@ -1,37 +1,37 @@ - - - - - - Embedder - - - - - - - - - -
-

Embedder

-

Sign in

-
-
- - -
-
- - -
- -
-
-
- - - + + + + + + Embedder + + + + + + + + + +
+

Embedder

+

Sign in

+
+
+ + +
+
+ + +
+ +
+
+
+ + + diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100755 index 1d408a5..0000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -node db.js -npm start diff --git a/.dockerignore b/docker/.dockerignore similarity index 88% rename from .dockerignore rename to docker/.dockerignore index d250f35..bc1c56b 100644 --- a/.dockerignore +++ b/docker/.dockerignore @@ -1,12 +1,12 @@ -.env -var -uploads - -# Node.js -node_modules/ -npm-debug.log* - -# Mac OS X -.DS_Store - -Dockerfile +.env +var +uploads + +# Node.js +node_modules/ +npm-debug.log* + +# Mac OS X +.DS_Store + +Dockerfile diff --git a/Dockerfile b/docker/Dockerfile similarity index 72% rename from Dockerfile rename to docker/Dockerfile index 4c1dbde..4e20266 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -1,22 +1,22 @@ FROM node:16-alpine AS BUILD_IMAGE -RUN apk add curl bash +RUN apk add curl +RUN curl -sf https://gobinaries.com/tj/node-prune | sh -# Install dependencies COPY package*.json ./ RUN npm install RUN npm prune --production - -RUN curl -sf https://gobinaries.com/tj/node-prune | sh +RUN /usr/local/bin/node-prune FROM node:16-alpine COPY --from=BUILD_IMAGE /node_modules ./node_modules -COPY . . +COPY /app ./app +COPY package*.json ./ ENV NODE_ENV=production -RUN node db.js +RUN node /app/db.js CMD ["npm", "start"] \ No newline at end of file diff --git a/package.json b/package.json index 502701d..f54fb63 100644 --- a/package.json +++ b/package.json @@ -21,14 +21,13 @@ }, "license": "Unlicense", "scripts": { - "start": "node ./app.js" + "start": "node ./app/app.js" }, "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", "@ffprobe-installer/ffprobe": "^1.4.1", "connect-sqlite3": "^0.9.13", "cookie-parser": "~1.4.4", - "cypress-real-events": "^1.7.4", "dotenv": "^8.6.0", "ejs": "^3.1.8", "express": "~4.16.1", @@ -45,6 +44,7 @@ "devDependencies": { "cypress": "^11.1.0", "cypress-file-upload": "^5.0.8", + "cypress-real-events": "^1.7.4", "eslint": "^8.28.0" } }