瀏覽代碼

add: Basic structure

gugdun 10 月之前
父節點
當前提交
410386b97d
共有 10 個文件被更改,包括 407 次插入13 次删除
  1. 144 8
      package-lock.json
  2. 1 0
      package.json
  3. 182 0
      public/css/main.css
  4. 二進制
      public/favicon.ico
  5. 二進制
      public/img/logo.png
  6. 19 5
      src/index.js
  7. 13 0
      views/home.ejs
  8. 13 0
      views/layout.ejs
  9. 16 0
      views/login.ejs
  10. 19 0
      views/register.ejs

+ 144 - 8
package-lock.json

@@ -1,15 +1,16 @@
 {
-  "name": "svin-chat-server",
+  "name": "svin-chat",
   "version": "1.0.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
-      "name": "svin-chat-server",
+      "name": "svin-chat",
       "version": "1.0.0",
       "license": "SEE LICENSE IN LICENSE",
       "dependencies": {
         "dotenv": "^16.5.0",
+        "ejs": "^3.1.10",
         "express": "^5.1.0",
         "express-longpoll": "^0.0.6",
         "passport": "^0.7.0",
@@ -32,6 +33,21 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
     "node_modules/anymatch": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@@ -53,11 +69,16 @@
         "node": ">=10.0.0"
       }
     },
+    "node_modules/async": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+      "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+      "license": "MIT"
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
-      "dev": true
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
     },
     "node_modules/binary-extensions": {
       "version": "2.3.0",
@@ -99,7 +120,6 @@
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dev": true,
       "dependencies": {
         "balanced-match": "^1.0.0",
         "concat-map": "0.0.1"
@@ -152,6 +172,43 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/chalk/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/chalk/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/chokidar": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@@ -176,11 +233,28 @@
         "fsevents": "~2.3.2"
       }
     },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "license": "MIT"
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
-      "dev": true
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
     },
     "node_modules/content-disposition": {
       "version": "1.0.0",
@@ -270,6 +344,21 @@
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
       "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
     },
+    "node_modules/ejs": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+      "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "jake": "^10.8.5"
+      },
+      "bin": {
+        "ejs": "bin/cli.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/encodeurl": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -374,6 +463,36 @@
         "lodash": ">=4.17.5"
       }
     },
+    "node_modules/filelist": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+      "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "minimatch": "^5.0.1"
+      }
+    },
+    "node_modules/filelist/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/filelist/node_modules/minimatch": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/fill-range": {
       "version": "7.1.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -621,6 +740,24 @@
       "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
       "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
     },
+    "node_modules/jake": {
+      "version": "10.9.2",
+      "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+      "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "async": "^3.2.3",
+        "chalk": "^4.0.2",
+        "filelist": "^1.0.4",
+        "minimatch": "^3.1.2"
+      },
+      "bin": {
+        "jake": "bin/cli.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/lodash": {
       "version": "4.17.21",
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@@ -676,7 +813,6 @@
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
       "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
       "dependencies": {
         "brace-expansion": "^1.1.7"
       },

+ 1 - 0
package.json

@@ -27,6 +27,7 @@
   "homepage": "https://github.com/gugdun/svin-chat#readme",
   "dependencies": {
     "dotenv": "^16.5.0",
+    "ejs": "^3.1.10",
     "express": "^5.1.0",
     "express-longpoll": "^0.0.6",
     "passport": "^0.7.0",

+ 182 - 0
public/css/main.css

@@ -0,0 +1,182 @@
+* {
+    margin: 0;
+    padding: 0;
+}
+
+html {
+    color: #FFF;
+    background-color: #111;
+}
+
+body {
+    display: block;
+    box-sizing: border-box;
+    width: 100%;
+}
+
+.hss {
+    display: block;
+    box-sizing: border-box;
+    width: 100%;
+    height: 4px;
+}
+
+.vss {
+    display: block;
+    width: 4px;
+    height: 100%;
+}
+
+.hsm {
+    display: block;
+    box-sizing: border-box;
+    width: 100%;
+    height: 8px;
+}
+
+.vsm {
+    display: block;
+    width: 8px;
+    height: 100%;
+}
+
+.hsl {
+    display: block;
+    box-sizing: border-box;
+    width: 100%;
+    height: 12px;
+}
+
+.vsl {
+    display: block;
+    width: 12px;
+    height: 100%;
+}
+
+.hero-container {
+    display: block;
+    box-sizing: border-box;
+    justify-items: stretch;
+    width: 96px;
+    margin: auto auto;
+}
+
+.hero-logo {
+    display: block;
+    box-sizing: border-box;
+    margin: 0 auto;
+    width: 64px;
+    height: 64px;
+}
+
+.hero-label {
+    display: block;
+    width: 100%;
+    text-align: center;
+    font-size: 14pt;
+    font-weight: 700;
+}
+
+.login-container {
+    display: block;
+    box-sizing: border-box;
+    width: 96px;
+    margin: auto auto;
+}
+
+.login-logo {
+    display: block;
+    box-sizing: border-box;
+    margin: 0 auto;
+    width: 48px;
+    height: 48px;
+}
+
+.login-label {
+    display: block;
+    width: 100%;
+    text-align: center;
+    font-size: 12pt;
+    font-weight: 700;
+}
+
+.register-container {
+    display: block;
+    box-sizing: border-box;
+    width: 96px;
+    margin: auto auto;
+}
+
+.register-logo {
+    display: block;
+    box-sizing: border-box;
+    margin: 0 auto;
+    width: 48px;
+    height: 48px;
+}
+
+.register-label {
+    display: block;
+    width: 100%;
+    text-align: center;
+    font-size: 12pt;
+    font-weight: 700;
+}
+
+.button {
+    display: block;
+    width: 100%;
+    height: 24px;
+    border: none;
+    border-radius: 4px;
+    color: #FFF;
+    background-color: #50A0F0;
+    font-size: 8pt;
+    font-weight: 700;
+}
+
+.button:focus {
+    color: #EEE;
+    background-color: #4595E5;
+    outline-color: #70C0F0;
+    outline-width: 2px;
+}
+
+.button:hover {
+    color: #EEE;
+    background-color: #4595E5;
+}
+
+.button:active {
+    color: #CCC;
+    background-color: #3585D5;
+}
+
+.text-input {
+    display: block;
+    margin: auto;
+    padding-left: 4px;
+    max-width: 92px;
+    width: 100%;
+    height: 20px;
+    border: none;
+    border-radius: 4px;
+    background-color: #FFF;
+    font-weight: 700;
+}
+
+.text-input::placeholder {
+    color: #777;
+}
+
+.text-input:focus {
+    background-color: #FFF;
+    outline-color: #70C0F0;
+    outline-width: 2px;
+}
+
+.input-hint {
+    color: #fff;
+    font-size: 6pt;
+    font-weight: 500;
+}

二進制
public/favicon.ico


二進制
public/img/logo.png


+ 19 - 5
src/index.js

@@ -2,22 +2,36 @@
 // All rights reserved. Unauthorized use, copying, or distribution is strictly prohibited.
 
 var express = require("express");
-var app = express();
-var longpoll = require("express-longpoll")(app);
-
+var ejs = require("ejs");
 require("dotenv").config();
+
 const PORT = process.env.PORT || 5000;
 
+var app = express();
+app.set("view engine", "ejs");
+app.use(express.static("public"));
+
+var longpoll = require("express-longpoll")(app);
 longpoll.create("/poll");
 
+app.get("/", async (req, res) => {
+    res.render("layout", { child: await ejs.renderFile("views/home.ejs") });
+});
+
+app.get("/login", async (req, res) => {
+    res.render("layout", { child: await ejs.renderFile("views/login.ejs") });
+});
+
+app.get("/register", async (req, res) => {
+    res.render("layout", { child: await ejs.renderFile("views/register.ejs") });
+});
+
 app.listen(PORT, function() {
     console.log(`Listening on port ${PORT}`);
 });
 
 var data = { message: "Test" };
-
 longpoll.publish("/poll", data);
-
 setInterval(function () { 
     longpoll.publish("/poll", data);
 }, 5000);

+ 13 - 0
views/home.ejs

@@ -0,0 +1,13 @@
+<div class="hero-container">
+    <div class="hss"></div>
+    <img src="/img/logo.png" class="hero-logo" />
+    <p class="hero-label">SvinChat</p>
+    <div class="hss"></div>
+    <form action="/login">
+        <input type="submit" value="LOGIN" class="button" />
+    </form>
+    <div class="hss"></div>
+    <form action="/register">
+        <input type="submit" value="REGISTER" class="button" />
+    </form>
+</div>

+ 13 - 0
views/layout.ejs

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <link rel="icon" href="/favicon.ico" type="image/x-icon">
+    <link rel="stylesheet" href="/css/main.css">
+    <title>SvinChat</title>
+</head>
+<body>
+    <%- child %>
+</body>
+</html>

+ 16 - 0
views/login.ejs

@@ -0,0 +1,16 @@
+<div class="login-container">
+    <div class="hss"></div>
+    <img src="/img/logo.png" class="login-logo" />
+    <p class="login-label">SvinChat</p>
+    <div class="hss"></div>
+    <form method="POST" action="/login">
+        <p class="input-hint">Nickname</p>
+        <input type="text" class="text-input" />
+        <div class="hss"></div>
+        <p class="input-hint">Password</p>
+        <input type="password" class="text-input" />
+        <div class="hsm"></div>
+        <input type="submit" value="LOGIN" class="button" />
+        <div class="hsl"></div>
+    </form>
+</div>

+ 19 - 0
views/register.ejs

@@ -0,0 +1,19 @@
+<div class="register-container">
+    <div class="hss"></div>
+    <img src="/img/logo.png" class="register-logo" />
+    <p class="register-label">SvinChat</p>
+    <div class="hss"></div>
+    <form method="POST" action="/register">
+        <p class="input-hint">Nickname</p>
+        <input type="text" class="text-input" />
+        <div class="hss"></div>
+        <p class="input-hint">Password</p>
+        <input type="password" class="text-input" />
+        <div class="hss"></div>
+        <p class="input-hint">Repeat Password</p>
+        <input type="password" class="text-input" />
+        <div class="hsm"></div>
+        <input type="submit" value="REGISTER" class="button" />
+        <div class="hsl"></div>
+    </form>
+</div>