Browse code

add room support

devnewton authored on 07/01/2018 19:45:32
Showing 8 changed files
... ...
@@ -6,4 +6,5 @@ taab is a KISS tribune powered by vue.js, pegjs, blazecss, sqlite and php (sorry
6 6
 
7 7
 - TSV backend
8 8
 - lastId
9
-- X-Post-Id
10 9
\ No newline at end of file
10
+- X-Post-Id
11
+- rooms
11 12
\ No newline at end of file
... ...
@@ -2,19 +2,23 @@
2 2
 
3 3
 include_once "config.php";
4 4
 
5
-function taab_echo_backend($lastId, $newPostId = NULL) {
5
+function taab_echo_backend($lastId, $room = '', $newPostId = NULL) {
6 6
     global $pdo;
7 7
     $posts = $pdo->prepare(
8 8
                     "SELECT id, strftime('%Y%m%d%H%M%S', time) as time, login, info, message
9 9
          FROM posts
10 10
          WHERE id > :lastId
11
+         and room = :room
11 12
          ORDER BY id DESC
12 13
          LIMIT :maxPosts");
13
-    $posts->execute(array("lastId" => $lastId, "maxPosts" => TAAB_BACKEND_MAX_POSTS));
14
+    $posts->execute(array("lastId" => $lastId, "room" => $room, "maxPosts" => TAAB_BACKEND_MAX_POSTS));
14 15
     header("Content-Type: text/tab-separated-values");
15 16
     if ($newPostId !== NULL) {
16 17
         header('X-Post-Id: ' . $newPostId);
17 18
     }
19
+    if($room) {
20
+        header('X-Room: ' . $room);
21
+    }
18 22
     $outstream = fopen("php://output", 'w');
19 23
     while($post = $posts->fetch(PDO::FETCH_OBJ)) {
20 24
         fputs($outstream, $post->id);
... ...
@@ -5,6 +5,7 @@ $pdo = new PDO('sqlite:./data/backend.db');
5 5
 $pdo->query("CREATE TABLE IF NOT EXISTS posts ( 
6 6
 	id    INTEGER PRIMARY KEY AUTOINCREMENT,
7 7
 	time  TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
8
+        room  TEXT DEFAULT '' NOT NULL,
8 9
 	info  TEXT DEFAULT '' NOT NULL,
9 10
         login TEXT DEFAULT '' NOT NULL,
10 11
         message TEXT DEFAULT '' NOT NULL   
11 12
Binary files a/data/backend.db and b/data/backend.db differ
... ...
@@ -2,7 +2,8 @@
2 2
 
3 3
 include_once 'common.php';
4 4
 
5
+$room = filter_input(INPUT_GET, 'room', FILTER_VALIDATE_REGEXP, array('options' => array('default' => '', 'regexp' => "/\w+/")));
5 6
 $lastId = filter_input(INPUT_GET, 'lastId', FILTER_VALIDATE_INT, array('options' => array('default' => 0)));
6 7
 
7
-taab_echo_backend($lastId);
8
+taab_echo_backend($lastId, $room);
8 9
 ?>
9 10
\ No newline at end of file
... ...
@@ -9,8 +9,9 @@
9 9
     <body class="c-text">
10 10
         <main id="taab-coincoin" class="o-container o-container--super u-window-box--tiny" v-on:click="clicked" v-on:mouseover="mouseEntered" v-on:mouseout="mouseLeaved">
11 11
             <form class="c-input-group" v-on:submit.prevent="post" accept-charset="UTF-8" enctype="application/x-www-form-urlencoded" autofocus>
12
+                <div v-if="room" class="c-button">#{{ room }}</div>
12 13
                 <div class="o-field">
13
-                    <input v-model="message" ref="message" name="message" placeholder="message or command (/nick)" class="c-field" spellcheck="true">
14
+                    <input v-model="message" ref="message" name="message" placeholder="message or command (/nick, /join)" class="c-field" spellcheck="true">
14 15
                 </div>
15 16
                 <button type="submit" class="c-button c-button--info">Post</button>
16 17
             </form>
... ...
@@ -5,6 +5,7 @@ document.addEventListener('DOMContentLoaded', function () {
5 5
     new Vue({
6 6
         el: '#taab-coincoin',
7 7
         data: {
8
+            room: "",
8 9
             message: "",
9 10
             posts: []
10 11
         },
... ...
@@ -18,7 +19,7 @@ document.addEventListener('DOMContentLoaded', function () {
18 19
                     xhr.onreadystatechange = function () {
19 20
                         if (xhr.readyState === 4) {
20 21
                             if (xhr.status === 200) {
21
-                                self.parseBackendResponse(xhr.responseText);
22
+                                self.parseBackendResponse(xhr);
22 23
                                 self.message = "";
23 24
                             }
24 25
                         }
... ...
@@ -30,6 +31,10 @@ document.addEventListener('DOMContentLoaded', function () {
30 31
                     if (login) {
31 32
                         params += "&login=" + encodeURIComponent(login).replace(/%20/g, '+');
32 33
                     }
34
+                    var room = this.room;
35
+                    if (room) {
36
+                        params += "&room=" + encodeURIComponent(room).replace(/%20/g, '+');
37
+                    }
33 38
                     params += "&lastId=" + self.getLastId();
34 39
                     xhr.send(params);
35 40
                 }
... ...
@@ -40,15 +45,20 @@ document.addEventListener('DOMContentLoaded', function () {
40 45
                 xhr.onreadystatechange = function () {
41 46
                     if (xhr.readyState === 4) {
42 47
                         if (xhr.status === 200) {
43
-                            self.parseBackendResponse(xhr.responseText);
48
+                            self.parseBackendResponse(xhr);
44 49
                         }
45 50
                     }
46 51
                 };
47
-                xhr.open("GET", "get.php?lastId=" + encodeURIComponent(self.getLastId()));
52
+                var params = "?lastId=" + encodeURIComponent(self.getLastId());
53
+                var room = self.room;
54
+                if (room) {
55
+                    params += "&room=" + encodeURIComponent(room).replace(/%20/g, '+');
56
+                }
57
+                xhr.open("GET", "get.php" + params);
48 58
                 xhr.send();
49 59
             },
50 60
             handleCommand: function () {
51
-                return this.handleCommandNick();
61
+                return this.handleCommandNick() || this.handleCommandJoin();
52 62
             },
53 63
             handleCommandNick: function () {
54 64
                 var result = /\/nick (.*)/.exec(this.message);
... ...
@@ -59,6 +69,17 @@ document.addEventListener('DOMContentLoaded', function () {
59 69
                     return false;
60 70
                 }
61 71
             },
72
+            handleCommandJoin: function () {
73
+                var result = /\/join ?#?(\w+)?/.exec(this.message);
74
+                if (result && result.length === 2) {
75
+                    this.posts = [];
76
+                    this.room = result[1] || '';
77
+                    this.get();
78
+                    return true;
79
+                } else {
80
+                    return false;
81
+                }
82
+            },
62 83
             clicked: function (e) {
63 84
                 switch (e.target.tagName) {
64 85
                     case 'TIME':
... ...
@@ -106,25 +127,29 @@ document.addEventListener('DOMContentLoaded', function () {
106 127
                         break;
107 128
                 }
108 129
             },
109
-            parseBackendResponse: function (responseText) {
110
-                var newPosts = responseText.split(/\r\n|\n/).map(function (line) {
111
-                    var post = line.split(/\t/);
112
-                    if (post.length >= 5) {
113
-                        var time = post[1];
114
-                        var formattedTime = time.substr(0, 4) + "-" + time.substr(4, 2) + "-" + time.substr(6, 2) + "T" + time.substr(8, 2) + ":" + time.substr(10, 2) + ":" + time.substr(12, 2);
115
-                        var htmlMessage = taab_backend2html.parse(post[4]);
116
-                        return {id: post[0], time: formattedTime, info: post[2], login: post[3], message: htmlMessage};
117
-                    } else {
118
-                        return false;
119
-                    }
120
-                }).filter(function (post) {
121
-                    return post && post.id && post.time && post.message;
122
-                }).concat(this.posts);
123
-                this.posts = newPosts.sort(function (a, b) {
124
-                    return b.id - a.id;
125
-                }).filter(function (elem, pos) {
126
-                    return newPosts.indexOf(elem) === pos;
127
-                });
130
+            parseBackendResponse: function (xhr) {
131
+                var room = this.room || '';
132
+                var responseRoom = xhr.getResponseHeader("X-Room") || '';
133
+                if (room === responseRoom) {
134
+                    var newPosts = xhr.responseText.split(/\r\n|\n/).map(function (line) {
135
+                        var post = line.split(/\t/);
136
+                        if (post.length >= 5) {
137
+                            var time = post[1];
138
+                            var formattedTime = time.substr(0, 4) + "-" + time.substr(4, 2) + "-" + time.substr(6, 2) + "T" + time.substr(8, 2) + ":" + time.substr(10, 2) + ":" + time.substr(12, 2);
139
+                            var htmlMessage = taab_backend2html.parse(post[4]);
140
+                            return {id: post[0], time: formattedTime, info: post[2], login: post[3], message: htmlMessage};
141
+                        } else {
142
+                            return false;
143
+                        }
144
+                    }).filter(function (post) {
145
+                        return post && post.id && post.time && post.message;
146
+                    }).concat(this.posts);
147
+                    this.posts = newPosts.sort(function (a, b) {
148
+                        return b.id - a.id;
149
+                    }).filter(function (elem, pos) {
150
+                        return newPosts.indexOf(elem) === pos;
151
+                    });
152
+                }
128 153
             },
129 154
             getLastId: function () {
130 155
                 return this.posts.reduce(function (acc, val) {
... ...
@@ -2,6 +2,7 @@
2 2
 
3 3
 include_once 'common.php';
4 4
 
5
+$room = filter_input(INPUT_POST, 'room', FILTER_VALIDATE_REGEXP, array('options' => array('default' => '', 'regexp' => "/\w+/")));
5 6
 $lastId = filter_input(INPUT_POST, 'lastId', FILTER_VALIDATE_INT, array('options' => array('default' => 0)));
6 7
 $message = mb_substr(filter_input(INPUT_POST, 'message', FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW), 0, TAAB_MAX_POST_LENGTH);
7 8
 $login = trim(mb_substr(filter_input(INPUT_POST, 'login', FILTER_SANITIZE_EMAIL), 0, TAAB_MAX_LOGIN_LENGTH));
... ...
@@ -22,9 +23,9 @@ if (mb_strlen($login) === 0 && mb_strlen($info) === 0) {
22 23
 if (mb_strlen(trim($message)) > 0 && mb_detect_encoding($message, 'UTF-8', true)) {
23 24
     $pdo->prepare(
24 25
                     "INSERT INTO posts
25
-            (login, info, message)
26
-            VALUES (:login, :info, :message)
27
-         ")->execute(array("login" => $login, "info" => $info, "message" => $message));
26
+            (room, login, info, message)
27
+            VALUES (:room, :login, :info, :message)
28
+         ")->execute(array("room" => $room, "login" => $login, "info" => $info, "message" => $message));
28 29
 }
29
-taab_echo_backend($lastId, $pdo->lastInsertId());
30
+taab_echo_backend($lastId, $room, $pdo->lastInsertId());
30 31
 ?>
31 32
\ No newline at end of file