have a roster and a whoami
This commit is contained in:
parent
db6d244cb6
commit
08c0119ae0
8
priv/static/js/dist/webrtc.d.ts
vendored
8
priv/static/js/dist/webrtc.d.ts
vendored
@ -9,7 +9,13 @@
|
|||||||
*
|
*
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
type state = {
|
||||||
|
whoami: string;
|
||||||
|
roster: Array<string>;
|
||||||
|
};
|
||||||
|
declare let st: state;
|
||||||
declare function main(): Promise<void>;
|
declare function main(): Promise<void>;
|
||||||
type ws_msg = ["join", string] | ["down", string];
|
type ws_msg = ["whoami", string] | ["roster", Array<string>];
|
||||||
declare function handle_ws_msg(message: ws_msg): void;
|
declare function handle_ws_msg(message: ws_msg): void;
|
||||||
declare function ws_send_json(ws: WebSocket, x: any): void;
|
declare function ws_send_json(ws: WebSocket, x: any): void;
|
||||||
|
declare function render_state(): void;
|
||||||
|
|||||||
28
priv/static/js/dist/webrtc.js
vendored
28
priv/static/js/dist/webrtc.js
vendored
@ -10,6 +10,8 @@
|
|||||||
*
|
*
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
let st = { whoami: "",
|
||||||
|
roster: [] };
|
||||||
main();
|
main();
|
||||||
async function main() {
|
async function main() {
|
||||||
// start websocket immediately
|
// start websocket immediately
|
||||||
@ -19,6 +21,7 @@ async function main() {
|
|||||||
// handle button click
|
// handle button click
|
||||||
init_join.addEventListener('click', function () {
|
init_join.addEventListener('click', function () {
|
||||||
init.hidden = true;
|
init.hidden = true;
|
||||||
|
document.getElementById('run').hidden = false;
|
||||||
ws = new WebSocket('/ws/webrtc');
|
ws = new WebSocket('/ws/webrtc');
|
||||||
ws.onopen = function (e) { console.log('ws open'); };
|
ws.onopen = function (e) { console.log('ws open'); };
|
||||||
ws.onclose = function (e) { console.warn('ws closed'); };
|
ws.onclose = function (e) { console.warn('ws closed'); };
|
||||||
@ -33,10 +36,35 @@ async function main() {
|
|||||||
}
|
}
|
||||||
function handle_ws_msg(message) {
|
function handle_ws_msg(message) {
|
||||||
console.log('message from server:', message);
|
console.log('message from server:', message);
|
||||||
|
switch (message[0]) {
|
||||||
|
case "whoami":
|
||||||
|
st.whoami = message[1];
|
||||||
|
break;
|
||||||
|
case "roster":
|
||||||
|
st.roster = message[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.warn("unknown message", message);
|
||||||
|
}
|
||||||
|
render_state();
|
||||||
}
|
}
|
||||||
function ws_send_json(ws, x) {
|
function ws_send_json(ws, x) {
|
||||||
let s = JSON.stringify(x, undefined, 4);
|
let s = JSON.stringify(x, undefined, 4);
|
||||||
console.log('sending:\n', s);
|
console.log('sending:\n', s);
|
||||||
ws.send(s);
|
ws.send(s);
|
||||||
}
|
}
|
||||||
|
function render_state() {
|
||||||
|
console.log('st', st);
|
||||||
|
// whoami
|
||||||
|
document.getElementById('whoami').innerText = st.whoami;
|
||||||
|
//
|
||||||
|
let roster_ul = document.getElementById('roster-ul');
|
||||||
|
let newChildren = [];
|
||||||
|
for (let nick of st.roster) {
|
||||||
|
let li = document.createElement('li');
|
||||||
|
li.innerText = nick;
|
||||||
|
newChildren.push(li);
|
||||||
|
}
|
||||||
|
roster_ul.replaceChildren(...newChildren);
|
||||||
|
}
|
||||||
//# sourceMappingURL=webrtc.js.map
|
//# sourceMappingURL=webrtc.js.map
|
||||||
2
priv/static/js/dist/webrtc.js.map
vendored
2
priv/static/js/dist/webrtc.js.map
vendored
@ -1 +1 @@
|
|||||||
{"version":3,"file":"webrtc.js","sourceRoot":"","sources":["../ts/webrtc.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;AAEH,IAAI,EAAE,CAAC;AAEP,KAAK,UACL,IAAI;IAIA,8BAA8B;IAC9B,IAAI,EAAa,CAAC;IAClB,IAAI,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAmB,CAAC;IAC7D,IAAI,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAsB,CAAC;IAE1E,sBAAsB;IACtB,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAC9B;QACI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,EAAE,GAAG,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC;QACjC,EAAE,CAAC,MAAM,GAAM,UAAS,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,EAAE,CAAC,OAAO,GAAK,UAAS,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,EAAE,CAAC,OAAO,GAAK,UAAS,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,EAAE,CAAC,SAAS;YACR,UAAS,CAAC;gBACN,sCAAsC;gBACtC,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAW,CAAC;gBAC3C,aAAa,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC,CAAC;IACV,CAAC,CACJ,CAAC;AACN,CAAC;AAKD,SACA,aAAa,CACR,OAAe;IAGhB,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAID,SACA,YAAY,CACP,EAAc,EACd,CAAQ;IAGT,IAAI,CAAC,GAAW,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAE7B,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACf,CAAC"}
|
{"version":3,"file":"webrtc.js","sourceRoot":"","sources":["../ts/webrtc.ts"],"names":[],"mappings":"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"}
|
||||||
@ -10,6 +10,14 @@
|
|||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
type state =
|
||||||
|
{whoami: string,
|
||||||
|
roster: Array<string>};
|
||||||
|
|
||||||
|
let st: state =
|
||||||
|
{whoami: "",
|
||||||
|
roster: []};
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
||||||
async function
|
async function
|
||||||
@ -26,6 +34,7 @@ main
|
|||||||
init_join.addEventListener('click',
|
init_join.addEventListener('click',
|
||||||
function() {
|
function() {
|
||||||
init.hidden = true;
|
init.hidden = true;
|
||||||
|
document.getElementById('run')!.hidden = false;
|
||||||
ws = new WebSocket('/ws/webrtc');
|
ws = new WebSocket('/ws/webrtc');
|
||||||
ws.onopen = function(e) { console.log('ws open'); };
|
ws.onopen = function(e) { console.log('ws open'); };
|
||||||
ws.onclose = function(e) { console.warn('ws closed'); };
|
ws.onclose = function(e) { console.warn('ws closed'); };
|
||||||
@ -40,8 +49,8 @@ main
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
type ws_msg = ["join", string]
|
type ws_msg = ["whoami", string]
|
||||||
| ["down", string];
|
| ["roster", Array<string>];
|
||||||
|
|
||||||
function
|
function
|
||||||
handle_ws_msg
|
handle_ws_msg
|
||||||
@ -49,6 +58,18 @@ handle_ws_msg
|
|||||||
: void
|
: void
|
||||||
{
|
{
|
||||||
console.log('message from server:', message);
|
console.log('message from server:', message);
|
||||||
|
switch(message[0]) {
|
||||||
|
case "whoami":
|
||||||
|
st.whoami = message[1];
|
||||||
|
break;
|
||||||
|
case "roster":
|
||||||
|
st.roster = (message[1] as Array<string>);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.warn("unknown message", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
render_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,3 +85,24 @@ ws_send_json
|
|||||||
|
|
||||||
ws.send(s);
|
ws.send(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function
|
||||||
|
render_state
|
||||||
|
()
|
||||||
|
: void
|
||||||
|
{
|
||||||
|
console.log('st', st);
|
||||||
|
// whoami
|
||||||
|
document.getElementById('whoami')!.innerText = st.whoami;
|
||||||
|
//
|
||||||
|
let roster_ul = document.getElementById('roster-ul') as HTMLUListElement;
|
||||||
|
let newChildren : Array<HTMLElement> = [];
|
||||||
|
for (let nick of st.roster) {
|
||||||
|
let li = document.createElement('li');
|
||||||
|
li.innerText = nick;
|
||||||
|
newChildren.push(li);
|
||||||
|
}
|
||||||
|
roster_ul.replaceChildren(...newChildren);
|
||||||
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div id="roster" hidden>
|
<div id="run" hidden>
|
||||||
<h2>Whoami: <span id="whoami"></span></h2>
|
<h2>Whoami: <span id="whoami"></span></h2>
|
||||||
|
|
||||||
<h2>Roster</h2>
|
<h2>Roster</h2>
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
-record(u, {pid :: pid()}).
|
-record(u, {pid :: pid()}).
|
||||||
-type user() :: #u{}.
|
-type user() :: #u{}.
|
||||||
|
|
||||||
-record(s, {users = [] :: [user()]}).
|
-record(s, {roster = [] :: [user()]}).
|
||||||
-type state() :: #s{}.
|
-type state() :: #s{}.
|
||||||
|
|
||||||
|
|
||||||
@ -104,19 +104,20 @@ terminate(_, _) ->
|
|||||||
NewState :: state().
|
NewState :: state().
|
||||||
% @private join a user to a pool
|
% @private join a user to a pool
|
||||||
|
|
||||||
do_join(PID, State = #s{users = Users}) ->
|
do_join(PID, State = #s{roster = Users}) ->
|
||||||
% see if pid is already there
|
% see if pid is already there
|
||||||
case lists:keymember(PID, #u.pid, Users) of
|
case lists:keymember(PID, #u.pid, Users) of
|
||||||
true -> {error, already_joined};
|
true -> {error, already_joined};
|
||||||
false -> do_join2(PID, State)
|
false -> do_join2(PID, State)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_join2(PID, State = #s{users = Users}) ->
|
do_join2(PID, State = #s{roster = Users}) ->
|
||||||
monitor(process, PID),
|
monitor(process, PID),
|
||||||
NewUser = #u{pid = PID},
|
NewUser = #u{pid = PID},
|
||||||
NewRoster = usort([NewUser | Users]),
|
NewRoster = usort([NewUser | Users]),
|
||||||
NewState = State#s{users = NewRoster},
|
NewState = State#s{roster = NewRoster},
|
||||||
ok = gossip({join, PID}, NewState),
|
ok = whisper(whoami, PID),
|
||||||
|
ok = gossip(roster, NewState),
|
||||||
{ok, NewState}.
|
{ok, NewState}.
|
||||||
|
|
||||||
usort(Users) ->
|
usort(Users) ->
|
||||||
@ -129,17 +130,25 @@ usort(Users) ->
|
|||||||
NewState :: state().
|
NewState :: state().
|
||||||
% @private handle a user dying
|
% @private handle a user dying
|
||||||
|
|
||||||
do_down(PID, State = #s{users = Users}) ->
|
do_down(PID, State = #s{roster = Users}) ->
|
||||||
% remove from users
|
% remove from roster
|
||||||
NewUsers = lists:keydelete(PID, #u.pid, Users),
|
NewUsers = lists:keydelete(PID, #u.pid, Users),
|
||||||
NewState = State#s{users = NewUsers},
|
NewState = State#s{roster = NewUsers},
|
||||||
% broadcast username
|
% broadcast username
|
||||||
ok = gossip({down, PID}, NewState),
|
ok = gossip(roster, NewState),
|
||||||
NewState.
|
NewState.
|
||||||
|
|
||||||
|
|
||||||
gossip({join, PID}, State) -> gossip_json(["join", pidstr(PID)], State);
|
% @doc send a message to a specific person
|
||||||
gossip({down, PID}, State) -> gossip_json(["down", pidstr(PID)], State).
|
whisper(whoami, PID) ->
|
||||||
|
PID ! {webrtc, ["whoami", pidstr(PID)]},
|
||||||
|
ok.
|
||||||
|
|
||||||
|
|
||||||
|
% @doc send a message to everyone
|
||||||
|
gossip(roster, State = #s{roster = Us}) ->
|
||||||
|
Pids = [pidstr(PID) || #u{pid = PID} <- Us],
|
||||||
|
gossip_json(["roster", Pids], State).
|
||||||
|
|
||||||
pidstr(PID) ->
|
pidstr(PID) ->
|
||||||
unicode:characters_to_list(io_lib:format("~tp", [PID])).
|
unicode:characters_to_list(io_lib:format("~tp", [PID])).
|
||||||
@ -148,7 +157,7 @@ pidstr(PID) ->
|
|||||||
-spec gossip_json(zj:value(), state()) -> ok.
|
-spec gossip_json(zj:value(), state()) -> ok.
|
||||||
% @private gossip a message to everyone
|
% @private gossip a message to everyone
|
||||||
|
|
||||||
gossip_json(Message, #s{users = Users}) ->
|
gossip_json(Message, #s{roster = Users}) ->
|
||||||
GossipTo =
|
GossipTo =
|
||||||
fun(#u{pid = PID}) ->
|
fun(#u{pid = PID}) ->
|
||||||
PID ! {webrtc, Message}
|
PID ! {webrtc, Message}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user