Skip to content

Commit

Permalink
Finish
Browse files Browse the repository at this point in the history
  • Loading branch information
dunglas committed May 2, 2020
1 parent bc2454d commit 2f7a784
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 26 deletions.
16 changes: 13 additions & 3 deletions examples/chat-python-flask/chat.py
Expand Up @@ -67,6 +67,7 @@ def chat():
local_last_event_id = last_event_id
cu = list(connected_users.keys())
lock.release()
cu.sort()

resp = make_response(render_template('chat.html', config={
'hubURL': HUB_URL, 'userIRI': user_iri, 'connectedUsers': cu, 'lastEventID': local_last_event_id}))
Expand Down Expand Up @@ -99,25 +100,34 @@ def sse_listener():
headers={'Authorization': b'Bearer '+token},
)
for update in updates:
app.logger.debug("Update received: %s", update)
data = json.loads(update.data)

if data['@type'] == 'https://chat.example.com/Message':
# Store the chat history somewhere if you want to
lock.acquire()
last_event_id = update.id
lock.release()
break

if data['@type'] == 'https://mercure.rocks/Subscription':
# Instead of maintaining a local user list, you may want to use Redis or similar service

user = next((x for x in data['subscribe'] if x.startswith(
'https://chat.example.com/users/')), None)

if user is None:
break

# Instead of maintaining a local user list, you may want to use Redis or similar service
lock.acquire()
last_event_id = update.id
if data['active']:
connected_users[user] = True
else:
elif user in connected_users:
del connected_users[user]
lock.release()
print(connected_users)

cu = list(connected_users.keys())
cu.sort()

app.logger.info("Connected users: %s", cu)
66 changes: 51 additions & 15 deletions examples/chat-python-flask/static/chat.js
Expand Up @@ -4,13 +4,48 @@ const { hubURL, userIRI, connectedUsers } = JSON.parse(
document.getElementById("config").textContent
);

const userList = new Map(
connectedUsers.reduce((acc, val) => {
acc.push([val, true]);
return acc;
}, [])
const iriToUserName = (iri) =>
iri.replace(/^https:\/\/chat.example.com\/users\//, "");
document.getElementById("username").textContent = iriToUserName(userIRI);

const $messages = document.getElementById("messages");
const $userList = document.getElementById("userList");
let $userListUL = null;
let $messagesUL = null;

let userList = new Map(
connectedUsers
.reduce((acc, val) => {
if (val !== userIRI) acc.push([val, true]);
return acc;
}, [])
.sort()
);

const updateUserListView = () => {
if (userList.size === 0) {
$userList.textContent = "No other users";
$messagesUL = null;
return;
}

$userList.textContent = "";
if ($userListUL === null) {
$userListUL = document.createElement("ul");
} else {
$userListUL.textContent = "";
}

userList.forEach((v, userIRI) => {
const li = document.createElement("li");
li.append(document.createTextNode(iriToUserName(userIRI)));
$userListUL.append(li);
});
$userList.append($userListUL);
};

updateUserListView();

const subscribeURL = new URL(hubURL);
subscribeURL.searchParams.append("Last-Event-ID", config.lastEventID);
subscribeURL.searchParams.append("topic", topic);
Expand All @@ -22,7 +57,6 @@ subscribeURL.searchParams.append(
);

const es = new EventSource(subscribeURL, { withCredentials: true });
let ul = null;
es.onmessage = ({ data }) => {
const update = JSON.parse(data);

Expand All @@ -39,27 +73,29 @@ es.onmessage = ({ data }) => {
};

const displayMessage = ({ user, message }) => {
if (!ul) {
ul = document.createElement("ul");
if (!$messagesUL) {
$messagesUL = document.createElement("ul");

const messages = document.getElementById("messages");
messages.innerHTML = "";
messages.append(ul);
$messages.innerText = "";
$messages.append($messagesUL);
}

const username = user.replace(/^https:\/\/chat.example.com\/users\//, "");
const li = document.createElement("li");
li.append(document.createTextNode(`<${username}> ${message}`));
ul.append(li);
li.append(document.createTextNode(`<${iriToUserName(user)}> ${message}`));
$messagesUL.append(li);
};

const updateUserList = ({ active, subscribe }) => {
const user = subscribe.find((u) =>
u.startsWith("https://chat.example.com/users/")
);
if (user === userIRI) return;

active ? userList.set(user, true) : userList.delete(user);

console.log(userList);
userList = new Map([...userList.entries()].sort());

updateUserListView();
};

document.querySelector("form").onsubmit = function (e) {
Expand Down
21 changes: 13 additions & 8 deletions examples/chat-python-flask/templates/chat.html
@@ -1,14 +1,19 @@
{% extends "layout.html" %}
{% block content %}
<form>
<input name="message" placeholder="Your message..." size="50" autocomplete="off" required>
<input type="submit" value="Post">
</form>
<hr>
<section>
<h2>User list</h2>
<div id="userList"></div>
<div id="username"></div>
</section>

<div id="messages">
No messages
</div>
<section id="messages">No messages</section>

<section>
<form>
<input name="message" placeholder="Your message..." size="50" autocomplete="off" required>
<input type="submit" value="Post">
</form>
</section>

<script type="application/json" id="config">
{{ config|tojson|safe }}
Expand Down

0 comments on commit 2f7a784

Please sign in to comment.