ci_newbies.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. const sinceInput = document.querySelector('#since') as HTMLInputElement;
  2. const newbies = document.querySelector('textarea#newbies') as HTMLTextAreaElement;
  3. {
  4. const twoDaysAgo = new Date();
  5. twoDaysAgo.setUTCDate(twoDaysAgo.getUTCDate() - 2);
  6. twoDaysAgo.setUTCHours(0, 0, 0, 0);
  7. sinceInput.value = twoDaysAgo.toISOString().slice(0, 10);
  8. }
  9. sinceInput.addEventListener('change', () => void render());
  10. render();
  11. async function render(): Promise<void> {
  12. const loader = document.querySelector('#loader') as HTMLElement;
  13. loader.style.display = 'block';
  14. try {
  15. await _render();
  16. } catch (e) {
  17. console.error(e);
  18. }
  19. loader.style.display = 'none';
  20. }
  21. async function _render(): Promise<void> {
  22. if (sinceInput.valueAsDate === null) {
  23. console.warn(sinceInput.value, 'is not a valid date');
  24. newbies.value = '';
  25. return;
  26. }
  27. newbies.style.display = 'none';
  28. const planets = ['Katoa'];
  29. const joined: Map<string, Join> = new Map();
  30. for (const planet of planets) {
  31. const messages: Message[] = await fetchJSON('https://api.fnar.net/chat/messages?' + new URLSearchParams({
  32. 'channel_names': planet + ' Global Site Owners',
  33. 'updated_since': sinceInput.valueAsDate?.toISOString(),
  34. }).toString());
  35. for (const message of messages)
  36. if (message.Type == 'JOINED') {
  37. const old_join = joined.get(message.SenderUserName)
  38. if (old_join === undefined || old_join.timestamp > message.MessageTimestamp)
  39. joined.set(message.SenderUserName, {timestamp: message.MessageTimestamp, planet});
  40. }
  41. }
  42. const sortedJoined = Array.from(joined.entries()).sort((a, b) => a[1].timestamp - b[1].timestamp);
  43. const lines: string[] = [];
  44. for (const [username, join] of sortedJoined) {
  45. const dtStr = new Date(join.timestamp).toISOString().replace('T', ' ').replace('Z', '');
  46. lines.push(`${username}\t${dtStr}\t${join.planet}`);
  47. }
  48. newbies.value = lines.join('\n');
  49. newbies.style.display = 'block';
  50. }
  51. document.querySelector('#copy')!.addEventListener('click', () => {
  52. navigator.clipboard.writeText(newbies.value);
  53. });
  54. async function fetchJSON(url: string, options: RequestInit = {}): Promise<any> {
  55. const controller = new AbortController();
  56. const timeoutId = setTimeout(() => controller.abort(), 5000);
  57. const doc = await fetch(url, {...options, signal: controller.signal}).then((r) => r.json());
  58. clearTimeout(timeoutId);
  59. return doc;
  60. }
  61. interface Message {
  62. Type: string;
  63. MessageTimestamp: number;
  64. SenderUserName: string;
  65. }
  66. interface Join {
  67. timestamp: number;
  68. planet: string;
  69. }