Skip to content

Commit 5b204af

Browse files
author
Tomáš Král
committed
resolve channel problems
1 parent 944a66b commit 5b204af

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

assets/js/video.js

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ let Video = {
1717
let msgContainer = document.getElementById("msg-container");
1818
let msgInput = document.getElementById("msg-input");
1919
let postButton = document.getElementById("msg-submit");
20-
let vidChannel = socket.channel("videos:" + videoId);
20+
let lastSeenId = 0;
21+
let vidChannel = socket.channel("videos:" + videoId, () => {
22+
return { last_seen_id: lastSeenId };
23+
});
2124

2225
postButton.addEventListener("click", (e) => {
2326
let payload = { body: msgInput.value, at: Player.getCurrentTime() };
@@ -28,13 +31,29 @@ let Video = {
2831
});
2932

3033
vidChannel.on("new_annotation", (resp) => {
34+
lastSeenId = resp.id;
3135
this.renderAnnotation(msgContainer, resp);
3236
});
3337

38+
msgContainer.addEventListener("click", (e) => {
39+
e.preventDefault();
40+
let seconds =
41+
e.target.getAttribute("data-seek") ||
42+
e.target.parentNode.getAttribute("data-seek");
43+
if (!seconds) {
44+
return;
45+
}
46+
Player.seekTo(seconds);
47+
});
48+
3449
vidChannel
3550
.join()
36-
.receive("ok", ({ annotations }) => {
37-
annotations.forEach((ann) => this.renderAnnotation(msgContainer, ann));
51+
.receive("ok", (resp) => {
52+
let ids = resp.annotations.map((ann) => ann.id);
53+
if (ids.length > 0) {
54+
lastSeenId = Math.max(...ids);
55+
}
56+
this.scheduleMessages(msgContainer, resp.annotations);
3857
})
3958
.receive("error", (reason) => console.log("join failed", reason));
4059
},
@@ -47,15 +66,41 @@ let Video = {
4766

4867
renderAnnotation(msgContainer, { user, body, at }) {
4968
let template = document.createElement("div");
50-
5169
template.innerHTML = `
5270
<a href="#" data-seek="${this.esc(at)}">
71+
[${this.formatTime(at)}]
5372
<b>${this.esc(user.username)}</b>: ${this.esc(body)}
5473
</a>
5574
`;
5675
msgContainer.appendChild(template);
5776
msgContainer.scrollTop = msgContainer.scrollHeight;
5877
},
78+
79+
scheduleMessages(msgContainer, annotations) {
80+
clearTimeout(this.scheduleTimer);
81+
this.schedulerTimer = setTimeout(() => {
82+
let ctime = Player.getCurrentTime();
83+
let remaining = this.renderAtTime(annotations, ctime, msgContainer);
84+
this.scheduleMessages(msgContainer, remaining);
85+
}, 1000);
86+
},
87+
88+
renderAtTime(annotations, seconds, msgContainer) {
89+
return annotations.filter((ann) => {
90+
if (ann.at > seconds) {
91+
return true;
92+
} else {
93+
this.renderAnnotation(msgContainer, ann);
94+
return false;
95+
}
96+
});
97+
},
98+
99+
formatTime(at) {
100+
let date = new Date(null);
101+
date.setSeconds(at / 1000);
102+
return date.toISOString().substr(14, 5);
103+
},
59104
};
60105

61106
export default Video;

lib/rumbl/multimedia.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ defmodule Rumbl.Multimedia do
7373
|> Repo.insert()
7474
end
7575

76-
def list_annotations(%Video{} = video) do
76+
def list_annotations(%Video{} = video, since_id \\ 0) do
7777
Repo.all(
7878
from a in Ecto.assoc(video, :annotations),
79+
where: a.id > ^since_id,
7980
order_by: [asc: a.at, asc: a.id],
8081
limit: 500,
8182
preload: [:user]

lib/rumbl_web/channels/video_channel.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ defmodule RumblWeb.VideoChannel do
33
alias Rumbl.{Accounts, Multimedia}
44
alias RumblWeb.AnnotationView
55

6-
def join("videos:" <> video_id, _params, socket) do
6+
def join("videos:" <> video_id, params, socket) do
7+
last_seen_id = params["last_seen_id"] || 0
78
video_id = String.to_integer(video_id)
89
video = Multimedia.get_video!(video_id)
910

1011
annotations =
1112
video
12-
|> Multimedia.list_annotations()
13+
|> Multimedia.list_annotations(last_seen_id)
1314
|> Phoenix.View.render_many(AnnotationView, "annotation.json")
1415

1516
{:ok, %{annotations: annotations}, assign(socket, :video_id, video_id)}

0 commit comments

Comments
 (0)