2021-01-14 03:15:07 +03:00
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
import {
|
|
|
|
fluentPadServiceId,
|
|
|
|
notifyOnlineFnName,
|
|
|
|
notifyUserAddedFnName,
|
|
|
|
notifyUserRemovedFnName,
|
2021-01-16 13:24:26 +03:00
|
|
|
} from 'src/app/constants';
|
|
|
|
import { useFluenceClient } from '../app/FluenceClientContext';
|
2021-01-16 16:28:00 +03:00
|
|
|
import * as api from 'src/app/api';
|
2021-01-17 20:22:10 +03:00
|
|
|
import { PeerIdB58, subscribeToEvent } from '@fluencelabs/fluence';
|
2021-01-16 16:25:28 +03:00
|
|
|
|
2021-01-14 03:15:07 +03:00
|
|
|
interface User {
|
2021-01-17 20:22:10 +03:00
|
|
|
id: PeerIdB58;
|
2021-01-14 03:15:07 +03:00
|
|
|
name: string;
|
|
|
|
isOnline: boolean;
|
|
|
|
shouldBecomeOnline: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
const turnUserAsOfflineCandidate = (u: User): User => {
|
|
|
|
return {
|
|
|
|
...u,
|
|
|
|
isOnline: u.shouldBecomeOnline,
|
|
|
|
shouldBecomeOnline: false,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-01-14 21:52:33 +03:00
|
|
|
const refreshTimeoutMs = 2000;
|
2021-01-14 03:15:07 +03:00
|
|
|
|
2021-01-14 12:17:36 +03:00
|
|
|
export const UserList = (props: { selfName: string }) => {
|
2021-01-14 03:15:07 +03:00
|
|
|
const client = useFluenceClient()!;
|
2021-01-17 20:22:10 +03:00
|
|
|
const [users, setUsers] = useState<Map<PeerIdB58, User>>(new Map());
|
2021-01-14 03:15:07 +03:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const listRefreshTimer = setInterval(() => {
|
|
|
|
setUsers((prev) => {
|
|
|
|
const newUsers = Array.from(prev).map(
|
|
|
|
([key, user]) => [key, turnUserAsOfflineCandidate(user)] as const,
|
|
|
|
);
|
|
|
|
return new Map(newUsers);
|
|
|
|
});
|
|
|
|
|
|
|
|
// don't block
|
2021-01-16 16:28:00 +03:00
|
|
|
api.updateOnlineStatuses(client);
|
2021-01-14 03:15:07 +03:00
|
|
|
}, refreshTimeoutMs);
|
|
|
|
|
2021-01-14 12:17:36 +03:00
|
|
|
const unsub1 = subscribeToEvent(client, fluentPadServiceId, notifyUserAddedFnName, (args, _) => {
|
2021-01-16 19:32:26 +03:00
|
|
|
const [users, setOnline] = args as [api.User[], boolean];
|
2021-01-14 03:15:07 +03:00
|
|
|
setUsers((prev) => {
|
|
|
|
const result = new Map(prev);
|
|
|
|
for (let u of users) {
|
|
|
|
if (result.has(u.peer_id)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-01-17 20:22:10 +03:00
|
|
|
const isCurrentUser = u.peer_id === client.selfPeerId;
|
2021-01-14 12:17:36 +03:00
|
|
|
|
2021-01-14 03:15:07 +03:00
|
|
|
result.set(u.peer_id, {
|
|
|
|
name: u.name,
|
|
|
|
id: u.peer_id,
|
2021-01-16 19:32:26 +03:00
|
|
|
isOnline: isCurrentUser || setOnline,
|
|
|
|
shouldBecomeOnline: isCurrentUser || setOnline,
|
2021-01-14 03:15:07 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-01-14 12:17:36 +03:00
|
|
|
const unsub2 = subscribeToEvent(client, fluentPadServiceId, notifyUserRemovedFnName, (args, _) => {
|
2021-01-17 20:22:10 +03:00
|
|
|
const [userLeft] = args as [PeerIdB58];
|
2021-01-14 03:15:07 +03:00
|
|
|
setUsers((prev) => {
|
|
|
|
const result = new Map(prev);
|
2021-01-17 20:22:10 +03:00
|
|
|
result.delete(userLeft);
|
2021-01-14 03:15:07 +03:00
|
|
|
return result;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-01-14 12:17:36 +03:00
|
|
|
const unsub3 = subscribeToEvent(client, fluentPadServiceId, notifyOnlineFnName, (args, _) => {
|
2021-01-17 20:22:10 +03:00
|
|
|
const [userOnline] = args as [PeerIdB58[]];
|
2021-01-14 03:15:07 +03:00
|
|
|
setUsers((prev) => {
|
|
|
|
const result = new Map(prev);
|
|
|
|
|
2021-01-17 20:22:10 +03:00
|
|
|
for (let u of userOnline) {
|
2021-01-16 19:32:26 +03:00
|
|
|
const toSetOnline = result.get(u);
|
|
|
|
if (toSetOnline) {
|
|
|
|
toSetOnline.shouldBecomeOnline = true;
|
2021-01-14 03:15:07 +03:00
|
|
|
toSetOnline.isOnline = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// don't block
|
2021-01-16 16:28:00 +03:00
|
|
|
api.getUserList(client);
|
|
|
|
api.notifySelfAdded(client, props.selfName);
|
2021-01-14 03:15:07 +03:00
|
|
|
|
|
|
|
return () => {
|
|
|
|
clearTimeout(listRefreshTimer);
|
2021-01-14 12:17:36 +03:00
|
|
|
unsub1();
|
|
|
|
unsub2();
|
|
|
|
unsub3();
|
2021-01-14 03:15:07 +03:00
|
|
|
};
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
const usersArray = Array.from(users)
|
|
|
|
.map((x) => x[1])
|
|
|
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
|
|
|
|
|
|
return (
|
2021-01-16 16:25:28 +03:00
|
|
|
<div className="userlist">
|
2021-01-14 03:15:07 +03:00
|
|
|
<ul>
|
2021-01-14 21:52:33 +03:00
|
|
|
{usersArray.map((x) => (
|
2021-01-14 03:15:07 +03:00
|
|
|
<li key={x.id}>
|
2021-01-17 20:22:10 +03:00
|
|
|
<span className={x.id === client.selfPeerId ? 'bold' : ''}>{x.name}</span>
|
2021-01-16 16:25:28 +03:00
|
|
|
<span className={x.isOnline ? 'green' : 'red'}> ({x.isOnline ? 'online' : 'offline'})</span>
|
2021-01-14 03:15:07 +03:00
|
|
|
</li>
|
|
|
|
))}
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|