From a8207c11c77cbc023d7061cb23504bc3dc284b67 Mon Sep 17 00:00:00 2001 From: Maartje Eyskens Date: Mon, 12 Nov 2018 12:32:46 +0100 Subject: [PATCH] Add colors and saved messages --- frontend/package-lock.json | 57 +++++++--------- frontend/package.json | 1 + frontend/src/api/messages.js | 10 ++- frontend/src/layouts/Main.vue | 4 -- frontend/src/pages/Controller.vue | 102 ++++++++++++++++++++++++++--- frontend/src/pages/Countdown.vue | 11 +++- server/db.go | 2 + server/main.go | 2 + server/messages.go | 104 ++++++++++++++++++++++++++++++ server/sessions.go | 30 --------- 10 files changed, 244 insertions(+), 79 deletions(-) create mode 100644 server/messages.go diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f35ef9cc..b49a098a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1229,7 +1229,7 @@ }, "util": { "version": "0.10.3", - "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { @@ -1740,7 +1740,7 @@ }, "cacache": { "version": "10.0.4", - "resolved": "http://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", "dev": true, "requires": { @@ -1797,7 +1797,7 @@ }, "camelcase-keys": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { @@ -3329,8 +3329,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -3351,14 +3350,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3373,20 +3370,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -3503,8 +3497,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -3516,7 +3509,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3531,7 +3523,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3546,7 +3537,6 @@ "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3565,7 +3555,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3646,8 +3635,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -3659,7 +3647,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3745,8 +3732,7 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -3782,7 +3768,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3802,7 +3787,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3846,14 +3830,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -4076,7 +4058,7 @@ }, "fast-deep-equal": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, @@ -4856,6 +4838,11 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "jquery": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", + "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" + }, "js-base64": { "version": "2.4.9", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz", @@ -4969,7 +4956,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -5167,7 +5154,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { @@ -6041,7 +6028,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } diff --git a/frontend/package.json b/frontend/package.json index 4cdf0b49..2b5ac330 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "axios": "^0.18.0", + "jquery": "^3.3.1", "materialize-css": "^1.0.0", "socket.io-client": "^1.7.4", "vue": "^2.5.17", diff --git a/frontend/src/api/messages.js b/frontend/src/api/messages.js index 9f961714..dc0ca1e5 100644 --- a/frontend/src/api/messages.js +++ b/frontend/src/api/messages.js @@ -1,6 +1,14 @@ import axios from "axios" import { URL } from "./const" +export const get = (key) => { + return axios.get(`${URL}/session/${key}/messages`) +} + +export const set = (key, messages) => { + return axios.post(`${URL}/session/${key}/messages`, { messages }) +} + export const send = (key, message) => { - return axios.post(`${URL}/session/${key}/message`, { message }) + return axios.post(`${URL}/session/${key}/message`, message) } diff --git a/frontend/src/layouts/Main.vue b/frontend/src/layouts/Main.vue index 6cb5fae4..1295c9af 100644 --- a/frontend/src/layouts/Main.vue +++ b/frontend/src/layouts/Main.vue @@ -8,10 +8,6 @@ diff --git a/frontend/src/pages/Controller.vue b/frontend/src/pages/Controller.vue index 1a2cffc3..d68b2866 100644 --- a/frontend/src/pages/Controller.vue +++ b/frontend/src/pages/Controller.vue @@ -45,15 +45,39 @@
Show Message -
- - +
+ + + +
+
+
+ edit +
+
+ + +
+
+
+
@@ -105,10 +129,28 @@ .vc-slider { width: 100%; } +.message-del { + margin-left: 10px; +} +.color-modal { + width: 280px !important; +} +.row .col.s05 { + width: 5%; + margin-left: auto; + left: auto; + right: auto; +} +.row .col.s115 { + width: 95%; + margin-left: auto; + left: auto; + right: auto; +} diff --git a/frontend/src/pages/Countdown.vue b/frontend/src/pages/Countdown.vue index 5cc271ef..66be7060 100644 --- a/frontend/src/pages/Countdown.vue +++ b/frontend/src/pages/Countdown.vue @@ -35,6 +35,7 @@ export default { error: null, socket: null, message: "", + messageColor: "", messageClearTimer: null, colors: [], }; @@ -42,6 +43,8 @@ export default { methods: { clearMessage: function() { this.message = "" + this.messageColor = "" + this.emitColor() }, getColors: function(){ Colors.get(this.sessionKey).then(response => { @@ -49,6 +52,9 @@ export default { }) }, emitColor: function() { + if (this.messageColor) { + return this.$emit('color', this.messageColor) + } let current = "" let time = Infinity for (let color of this.colors) { @@ -92,7 +98,10 @@ export default { }); if (this.showMessages) { this.socket.on("message", message => { - this.message = message; + console.log(message) + this.message = message.message + this.messageColor = message.color + this.emitColor() clearTimeout(this.messageClearTimer) this.messageClearTimer = setTimeout(this.clearMessage, 10000) }); diff --git a/server/db.go b/server/db.go index 0b0d2ab2..d0ddb855 100644 --- a/server/db.go +++ b/server/db.go @@ -14,12 +14,14 @@ func setupIndexes() { EnsureIndex(context.Background(), db.Collection("sessions"), []string{"key"}, options) EnsureIndex(context.Background(), db.Collection("sessions"), []string{"key", "instance"}, options) EnsureIndex(context.Background(), db.Collection("colors"), []string{"key"}, options) + EnsureIndex(context.Background(), db.Collection("messages"), []string{"key"}, options) expireOpts := mongo.NewIndexOptionsBuilder() expireOpts.Background(true) expireOpts.ExpireAfterSeconds(2592000) //30 days EnsureIndex(context.Background(), db.Collection("sessions"), []string{"created"}, expireOpts) EnsureIndex(context.Background(), db.Collection("colors"), []string{"created"}, expireOpts) + EnsureIndex(context.Background(), db.Collection("messages"), []string{"created"}, expireOpts) } // Thanks to https://gist.github.com/bweston92/5a796e15a6d7f436755795018dea9c1a diff --git a/server/main.go b/server/main.go index 6dd1c1da..077b180e 100644 --- a/server/main.go +++ b/server/main.go @@ -73,6 +73,8 @@ func configureWeb() { e.POST("/session/:uid/message", sendMessage) e.GET("/session/:uid/colors", getColors) e.POST("/session/:uid/colors", setColors) + e.GET("/session/:uid/messages", getMessages) + e.POST("/session/:uid/messages", setMessages) } func configureSocket() { diff --git a/server/messages.go b/server/messages.go new file mode 100644 index 00000000..cda0dd62 --- /dev/null +++ b/server/messages.go @@ -0,0 +1,104 @@ +package main + +import ( + "context" + "log" + "net/http" + "time" + + "github.com/labstack/echo" + "github.com/mongodb/mongo-go-driver/bson" + "github.com/mongodb/mongo-go-driver/bson/objectid" +) + +// Messages keeps the message options for for a session +type Messages struct { + ID objectid.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"` + SessionKey string `bson:"sessionKey" json:"sessionKey"` + Created time.Time `bson:"created" json:"created"` + Messages []Message `bson:"messages" json:"messages"` +} + +// Message keeps a string of a message with a given color +type Message struct { + Message string `bson:"message" json:"message"` + Color string `bson:"color" json:"color"` +} + +var defaultMessages = []Message{ + Message{ + Message: "Please repeat the question", + Color: "#ffffff", + }, + Message{ + Message: "Hold the mic closer", + Color: "#ffffff", + }, +} + +func setMessages(c echo.Context) error { + uid := c.Param("uid") + if uid == "" { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "no uid given"}) + } + + messages := Messages{} + c.Bind(&messages) + + messages.ID = objectid.NilObjectID + messages.SessionKey = uid + messages.Created = time.Now() + + db.Collection("messages").DeleteMany(context.Background(), bson.NewDocument(bson.EC.String("sessionKey", uid))) // delete old ones + _, err := db.Collection("messages").InsertOne(context.Background(), messages) + if err != nil { + log.Println(err) + return c.JSON(http.StatusInternalServerError, map[string]string{"error": "could not create database record"}) + } + + return c.JSON(http.StatusOK, messages) +} + +func getMessages(c echo.Context) error { + uid := c.Param("uid") + if uid == "" { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "no uid given"}) + } + + messages := Messages{} + db.Collection("messages").FindOne(context.Background(), bson.NewDocument(bson.EC.String("sessionKey", uid))).Decode(&messages) + + if len(messages.Messages) == 0 { + messages.Messages = defaultMessages + } + + return c.JSON(http.StatusOK, messages) +} + +type sendMessageBody struct { + Message string `json:"message" form:"message" query:"message"` + Color string `json:"color" form:"color" query:"color"` +} + +func sendMessage(c echo.Context) error { + uid := c.Param("uid") + if uid == "" { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "no uid given"}) + } + + count, err := db.Collection("sessions").Count(context.Background(), bson.NewDocument(bson.EC.String("key", uid))) + if err != nil { + log.Println(err) + return c.JSON(http.StatusInternalServerError, map[string]string{"error": "error looking up session"}) + } + if count < 1 { + return c.JSON(http.StatusNotFound, map[string]string{"error": "session not found"}) + } + + body := sendMessageBody{} + c.Bind(&body) + + io.BroadcastTo(uid, "message", body) + + return c.JSON(http.StatusOK, map[string]string{"status": "ok"}) +} diff --git a/server/sessions.go b/server/sessions.go index b4c1ae87..fcdf02f9 100644 --- a/server/sessions.go +++ b/server/sessions.go @@ -2,7 +2,6 @@ package main import ( "context" - "fmt" "log" "net/http" "reflect" @@ -106,32 +105,3 @@ func setTime(c echo.Context) error { return c.JSON(http.StatusOK, map[string]string{"status": "ok"}) } - -type sendMessageBody struct { - Message string `json:"message" form:"message" query:"message"` -} - -func sendMessage(c echo.Context) error { - uid := c.Param("uid") - if uid == "" { - return c.JSON(http.StatusBadRequest, map[string]string{"error": "no uid given"}) - } - - count, err := db.Collection("sessions").Count(context.Background(), bson.NewDocument(bson.EC.String("key", uid))) - if err != nil { - log.Println(err) - return c.JSON(http.StatusInternalServerError, map[string]string{"error": "error looking up session"}) - } - if count < 1 { - return c.JSON(http.StatusNotFound, map[string]string{"error": "session not found"}) - } - - body := sendMessageBody{} - c.Bind(&body) - - io.BroadcastTo(uid, "message", body.Message) - - fmt.Println(uid, body.Message) - - return c.JSON(http.StatusOK, map[string]string{"status": "ok"}) -}