diff --git a/css/cards.css b/css/cards.css index b8c45f1..08d1459 100644 --- a/css/cards.css +++ b/css/cards.css @@ -149,8 +149,9 @@ } @media (max-width: 500px) { - #col-users { - display: none!important; + #col-users, + #resetRow { + display: none !important; } } @@ -159,7 +160,7 @@ } .kickBtn { - color: var(--danger)!important; + color: var(--danger) !important; margin-left: 5px; } @@ -170,3 +171,43 @@ .row { flex-shrink: 0; } + +.clickable:hover { + cursor: pointer; +} + +.kickIcon:before { + content: ""; + display: inline-block; + vertical-align: middle; + margin: 0 0.2em; + height: 1em; + width: 1em; + background: url("data:image/png;base64,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") + no-repeat left center; + background-size: contain; +} + +.promoteIcon:before { + content: ""; + display: inline-block; + vertical-align: middle; + margin: 0 0.2em; + height: 1em; + width: 1em; + background: url("data:image/png;base64,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") + no-repeat left center; + background-size: contain; +} + +.demoteIcon:before { + content: ""; + display: inline-block; + vertical-align: middle; + margin: 0 0.2em; + height: 1em; + width: 1em; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABmJLR0QA/wD/AP+gvaeTAAAcQklEQVR4nO3bXYym533X8f89s+tkN4nV3ZklkSsCqmibSAk0EhJEsRvHQUJJJBRxABaNVFMRAWc5AI5RUTlBSlsOqqptQkUdqQghNamIIlqpjYIAVYUeVYKSd5u0682M13Hccex95uZgvLOzu/PyvNwv1/+6Pp8z2+uZa57nvvf33XtnuljO5d3d3Y/0ff/3+4gnI+KxM37dKxHx3/qI37rz2mv/4eWXX95b8uMDAKd7ZHd39wN9338gIt4dET/cR7w1+v5adN2LfcRzEfHHXd9/eX9//8sR8doyH7S74L9f2tnZ+Sd9xD+PiHeueOA/7yM++8ilS//q5s2bL6z4/wJA027cuPGjh4eHn+ojno6I60v+b/sR8Rv94eGnX3zxxW+f9wvPDIAfunHjfVuHh/8+It6z/HFPdTv6/p/t7+9/ZsOPAwDVe/TRR69fvnz55/qIT0bE9pof5rUu4tNXrlz52eeff/7gtF9wagDs7Ow8ExG/3Ee8ac1P/JA+4jde3Nv7R7HkowkAaM0P7e5+cKvvPxcRPzzQh/yf0fcf39/ff/7B//BQAFy/fv1T0XWfPu2/DeB33vymN338O9/5zp+P8LEBIK1ru7v/oOv7X4+IywN/6D/tIj6+t7f3Byf/5X0jf2139+nuqDy2Bv7k9/T9V7a3tz9669at74/2OQAgkevXr/9MdN2vxnj7u7+9tfU3bt269dW7/+I4AHZ2dt7VR/yviLgy0ie/RwQAQERMMv53/e/DxeL9t2/fvh0nPlnXR/y7mGL8IyK67onF4eHnH3vssauTfD4AKNCE4x8R8a6t7e2fv/sPXUTEzs7O3+0j/tMEn/x+ngQA0KiJx/+uw8Otrb9++9atP9qKiOgj/sWEn/weTwIAaNBM4x8RsbXV9z8XEdHduHHjrywOD/8kxvmu/+V4EgBAI2Yc/2NdxLu3FovF34k5xz/CkwAAmlDC+EdE9H3/97ai6x6f8xAnPPXqD37w2yIAgBqVMv5v+FtbEfGuuU9xgggAoDqFjX9E171vKyL+4tzneIAIAKAaxY3/kbduRUSJQ/vUq6+++qUbN268de6DAMC6Ch3/iDg6UD/3IU7lGwMBSKzk8Y84OtR35z7EOTwJACCd0sc/ovwA8CQAgFQyjH/E0eEO5z7EEjwJAKB4WcY/IsEBj3XdE4vF4osiAIASZRr/iCSHPCYCAChQtvGPSHTQYyIAgIJkHP+IZIc9JgIAKEDW8Y9IeOBjIgCAGWUe/4ikhz4mAgCYQfbxj0h88GMiAIAJ1TD+EckPf0wEADCBWsY/ooIv4JgIAGBENY1/RCVfxDERAMAIahv/iIq+kGMiAIAB1Tj+EZV9McdEAAADqHX8Iyr8go6JAAA2UPP4R1T6RR0TAQCs4fr16/+w5vGPqPgLOyYCAFjBG+P/a1H5Rlb9xR0TAQAsoZXxj2jgCzwmAgA4R0vjH9HIF3lMBABwitbGP6KhL/SYCADghBbHP6KxL/aYCAAg2h3/iAa/4GMiAKBpLY9/RKNf9DERANCk1sc/ouEv/JgIAGiK8T/S9Bd/TAQANMH439P8C3BMBABUzfjfz4twkggAqJLxf5gX4kEiAKAqxv90XozTiACAKhj/s3lBziICAFIz/ufzopxHBACkZPwv5oW5iAgASMX4L8eLswwRAJCC8V+eF2hZIgCgaMZ/NV6kVYgAgCIZ/9V5oVYlAgCKYvzXU8KL9YdzH2BlXffE4vDw84899tjVuY8C0LLr16//TNLxfy4inp/zALO/YFtd90+7iGfnPscannr11Ve/5EkAwDze+JP/r0YBW7ai5xbb2x/qIm7NeYjZX7Q7XbfY29t7JmUE+OsAgFkkfuz/3GJ7+0MvvfDC1+Y+SCkvnAgAYCnGfxglvXgiAIBzGf/hlPYCigAATmX8h1XiiygCALiP8R9eqS+kCAAgIoz/WEp+MUUAQOOM/3hKf0FFAECjjP+4MryoIgCgMcZ/fFleWBEA0AjjP41ML64IAKic8Z9OthdYBABUyvhPK9uLHCECAKpj/KeX7YW+SwQAVML4zyPbi32SCABIzvjPJ9sL/iARAJCU8Z9Xthf9NCIAIBnjP79sL/xZRABAEsa/DNle/POIAIDCGf9yZHsDLiICAApl/MuS7U1YhggAKIzxL0+2N2JZIgCgEMa/TNnejFWIAICZGf9yZXtDViUCAGZi/MuW7U1ZhwgAmJjxL1+2N2ZdIgBgIsY/h2xvziZEAMDIjH8e2d6gTYkAgJEY/1yyvUlDEAEAAzP++WR7o4YiAgAGYvxzyvZmDUkEAGzI+OeV7Q0bmggAWJPxzy3bmzYGEQCwIuOfX7Y3biwiAGBJxr8O2d68MYkAgAsY/3pkewPHJgIAzmD865LtTZyCCAB4gPGvT7Y3cioiAOANxr9O2d7MKYkAoHnGv17Z3tCpiQCgWca/btne1DmIAKA5xr9+2d7YuYgAoBnGvw3Z3tw5iQCgesa/Hdne4LmJAKBaxr8t2d7kEogAoDrGvz3Z3uhSiACgGsa/Tdne7JKIACA949+ubG94aUQAkJbxb1u2N71EIgBIx/iT7Y0vlQgA0jD+ROR780smAoDiGX/uynYBlE4EAMUy/pyU7SLIQAQAxTH+PCjbhZCFCACKYfw5TbaLIRMRAMzO+HOWbBdENiIAmI3x5zzZLoqMRAAwOePPRbJdGFmJAGAyxp9lZLs4MhMBwOiMP8vKdoFkJwKA0Rh/VpHtIqmBCAAGZ/xZVbYLpRYiABiM8Wcd2S6WmogAYGPGn3Vlu2BqIwKAtRl/NpHtoqmRCABWZvzZVLYLp1YiAFia8WcI2S6emokA4ELGn6Fku4BqJwKAMxl/hpTtImqBCAAeYvwZWrYLqRUiADhm/BlDtoupJSIAMP6MJtsF1RoRAA0z/owp20XVIhEADTL+jC3bhdUqEQANMf5MIdvF1TIRAA0w/kwl2wXWOhEAFTP+TCnbRYYIgCoZf6aW7ULjiAiAihh/5pDtYuMeEQAVMP7MJdsFx/1EACRm/JlTtouOh4kASMj4M7dsFx6nEwGQiPGnBNkuPs4mAiAB408psl2AnE8EQMGMPyXJdhFyMREABTL+lCbbhchyRAAUxPhTomwXI8sTAVAA40+psl2QrEYEwIyMPyXLdlGyOhEAMzD+lC7bhcl6RABMyPiTQbaLk/WJAJjAzs7OM8afDLJdoGxGBMCIdnZ2nukjPhP5fm81/g3KdpGyOREAIzD+ZJPtQmUYIgAGZPzJKNvFynBEAAzA+JNVtguWYYkA2IDxJ7NsFy3DEwGwBuNPdtkuXMYhAmAFxp8aZLt4GY8IgCUYf2qR7QJmXCIAzmH8qUm2i5jxiQA4hfGnNtkuZKYhAuAE40+Nsl3MTEcEQBh/6pXtgmZaIoCmGX9qlu2iZnoigCYZf2qX7cJmHiKAphh/WpDt4mY+IoAmGH9ake0CZ14igKoZf1qS7SJnfiKAKhl/WpPtQqcMIoCqGH9alO1ipxwigCoYf1qV7YKnLCKA1Iw/Lct20VMeEUBKxp/WZbvwKZMIIBXjD/kufsolAkjB+MORbDcAZRMBFM34wz3ZbgLKJwIokvGH+2W7EchBBFAU4w8Py3YzkIcIoAjGH06X7YYgFxHArIw/nC3bTUE+IoBZGH84X7Ybg5xEAJMy/nCxbDcHeYkAJmH8YTnZbhByEwGMyvjD8rLdJOQnAhiF8YfVZLtRqIMIYFDGH1aX7WahHiKAQRh/WE+2G4a6iAA2YvxhfdluGuojAliL8YfNZLtxqJMIYCXGHzaX7eahXiKApSQe/28bf0qS7QaibiKAc6Ue/0uXjD9FyXYTUT8RwKnSj//Nm1+f+yBwUrYbiTaIAO5j/GF42W4m2iECiAjjD2PJdkPRFhHQOOMP48l2U9EeEdAo4w/jynZj0SYR0BjjD+PLdnPRLhHQCOMP08h2g9E2EVA54w/TyXaTgQiolPGHaWW70SBCBFTH+MP0st1scJcIqITxh3lku+HgJBGQnPGH+WS76eBBIiAp4w/zynbjwWlEQDLGH+aX7eaDs4iAJIw/lCHbDQjnEQGFM/5Qjmw3IVxEBBTK+ENZst2IsAwRUBjjD+XJdjPCskRAIYw/lCnbDQmrEAEzM/5Qrmw3JaxKBMzE+EPZst2YsA4RMDHjD+XLdnPCukTARIw/5JDtBoVNiICRXdvdfbqP+LXI93uL8ac52W5S2JQIGMm13d2nu75/NiK25z7Liow/TRIAtEgEDMz4Qz4CgFaJgIEYf8hJANAyEbAh4w95CQBaJwLWZPwhNwEAImBlxh/yEwBwRAQsyfhDHQQA3CMCLmD8oR4CAO4nAs5g/KEuAgAeJgIeYPyhPgIATicC3mD8oU4CAM7WfAQYf6iXAIDzNRsBxh/qJgDgYs1FgPGH+gkAWE4zEWD8oQ0CAJZXfQQYf2iHAIDVVBsBxh/aIgBgddVFgPGH9ggAWE81EWD8oU0CANa32Nvbeyb6/jfnPsjKuu6JxeHh56/t7v7jru8/F/nG/1uLO3eeNP6wPgEAm1ns7+9/IuWTgIinur7/5cj3+8C3F5cuPfXSSy99Y+6DQGbZbnwoUd6/DsjHY38YiACAYYiA8Rl/GJAAgOGIgPEYfxiYAIBhiYDhGX8YgQCA4YmA4Rh/GIkAgHGIgM0ZfxiRAIDxiID1GX8YmQCAcYmA1Rl/mIAAgPGJgOUZf5iIAIBpiICLGX+YkACA6YiAsxl/mJgAgGmJgIcZf5iBAIDpiYB7jD/MRADAPESA8YdZzR4Al/q+m/sMMJPF3t7eM9H3vzn3QWbwrcPF4oPGn5b1M+/f7AFwGPGLu7u7b5v7HDCTxf7+/icaexLw7cWlS0/dvn37m3MfBOZybXf36ei69855htkDIPr+8cOIL4oAGtbSXwd47E/zru3uPt31/bMRsT3nOeYPgAgRAG1EgPGneaWMf0QpARAhAqDuCDD+NK+k8Y84CoByvgmv7x/v+/633/72t79l7qPATGr8xkDf8EfzdnZ2frrr+89FIeMfcRQA1+Y+xEl9xAdfXyy+5EkADavpGwN9wx/Nu7a7+3Qf8Zko6al7HB3mL8x9iId4EgA1PAnwJ3+aV+Kf/O/aisKK5K4+4oN37tz5zyKAhi329/c/kTQCvnW4WDzpT/60bGdn56f7iM9GoTu7FRGvzX2Is4gASBkBxp/mlT7+ERFbXcR35j7EeUQApIoA40/zMox/RNzZ6iO+OvcpLiICIEUEGH+al2T8o4/45lb0/X+f+yDL8NMBUPRPB/huf5pX6nf7n2Yr4n9sdV33pbkPsjQ/HQAl/nSA7/aneSV/t/8Z/ksXEXF9Z+dPIuJHZz7M0rqIL1+6dOljN2/efGXus8BMtq9fv/5sdN3TM5/DY3+al+Wx/wkH0ffv2IqI6CN+Ye7TrMJfB0ARfx3gsT/Ny/TY/64+4rP7+/vf24qIePHatc9E131j7kOtxF8HwJx/HeCxP81L+Ng/IuKgXyz+TcTdYvnqV3/Q9f0nI6Kf81Sr8tMBMMtPB3jsT/MSPvaPiIgu4l/fvn37WxEnquXg4OAbb7569ZEu4on5jraWv9wfHn7g0Ucf/Y+vvPLK63MfBmbQHxwc/NaVK1d+LLruPSN/LuNP87KOf/T9V/b39z8ZEYcRDzy2ePXg4PfefPXqj3QRf22Ww61PBNC6owi4evWdEfETI32O/3O4WHz47p8eoEVZx7+L+Nrly5f/9iuvvPLy3X/30N9bvHpw8IWJ/iQxNBFA6/qDo/v3MLruJ2PY36B+9/XXXvvo9773vT8d8GNCKlnHPyKeW1y69OG9mzefP/kvuzN+cSk/YrQyPyIIEdeuXXu829r6pYh474Yf6qXo+3+5v7//b+ONx4bQouTj/+Rp37B7VgBEiADIbntnZ+enIuJTfcT7Vvkfu4hbhxG/8vrly7/4/T/7s1sjnQ9SqHH8I84PgAgRAFXY2dl5d991H4u+f39E/HhEvCMi3hYRj0TEi9F1t/u+/+ZWxB9ExO/u7e39fkTcme/EUIZaxz/i4gCIOPpTxK/3EZ8Y8GDT6Lr/ut11H7l169b35z4KALlc2919uuv7ZyPXz/lHRDy32N7+0EsvvPC1837RMgEQIQIAaEjt4x+xfABEiAAAGtDC+EesFgARIgCAirUy/hGrB0CECACgQi2Nf8R6ARAhAgCoSGvjH7F+AESIAAAq0OL4R2wWABEiAIDEWh3/iM0DIEIEAJBQy+MfMUwARIgAABJpffwjhguACBEAQALG/8iQARAhAgAomPG/Z+gAiBABABTI+N9vjACIEAEAFMT4P2ysAIgQAQAUwPifbswAiBABAMzI+J9t7ACIEAEAzMD4n2+KAIgQAQBMyPhfbKoAiBABAEzA+C9nygCIEAEAjMj4L2/qAIgQAQCMwPivZo4AiBABAAzI+K9urgCIEAEADMD4r2fOAIgQAQBswPivb+4AiBABAKzB+G+mhACIEAEArMD4b66UAIgQAQAswfgPo6QAiBABAJzD+A+ntACIEAEAnML4D6vEAIgQAQCcYPyHV2oARIgAAML4j6XkAIgQAQBNM/7jKT0AIkQAQJOM/7gyBECECABoivEfX5YAiBABAE0w/tPIFAARIgCgasZ/OtkCIEIEAFTJ+E8rYwBEiACAqhj/6WUNgAgRAFAF4z+PzAEQIQIAUjP+88keABEiACAl4z+vGgIgQgQApGL851dLAESIAIAUjH8ZagqACBEAUDTjX47aAiBCBAAUyfiXpcYAiBABAEUx/uWpNQAiRABAEYx/mWoOgAgRADAr41+u2gMgQgQAzML4l62FAIgQAQCTMv7layUAIkQAwCSMfw4tBUCECAAYlfHPo7UAiBABAKMw/rm0GAARIgBgUMY/n1YDIEIEAAzC+OfUcgBEiACAjRj/vFoPgAgRALAW45+bADgiAgBWYPzzEwD3iACAJRj/OgiA+4kAgHMY/3oIgIeJAIBTGP+6CIDTiQCAE4x/fQTA2UQAQBj/WgmA84kAoGnGv14C4GIiAGiS8a+bAFiOCACaYvzrJwCWJwKAJhj/NgiA1YgAoGrGvx0CYHUiAKiS8W+LAFiPCACqYvzbIwDWJwKAKhj/NgmAzYgAIDXj3y4BsDkRAKRk/NsmAIYhAoBUjD8CYDgiAEjB+BMhAIYmAoCiGX/uEgDDEwFAkYw/JwmAcYgAoCjGnwcJgPGIAKAIxp/TCIBxiQBgVsafswiA8YkAYBbGn/MIgGmIAGBSxp+LCIDpiABgEsafZQiAaYkAYFTGn2UJgOmJAGAUxp9VCIB5iABgUMafVQmA+YgAYBDGn3UIgHmJAGAjxp91CYD5iQBgLcafTWzNfQBisbe390wX8ezcB1lZ3z++WCy+eOPGjbfOfRRojfFnU54AlCPvk4C+/8r29vZHPQmAaRh/hiAAyiICgHMZf4YiAMojAoBTGX+GJADKJAKA+xh/hiYAyiUCgIgw/oxDAJRNBEDjjD9jEQDlEwHQKOPPmARADiIAGmP8GZsAyEMEQCOMP1MQALmIAKic8WcqAiAfEQCVMv5MSQDkJAKgMsafqQmAvEQAVML4MwcBkJsIgOSMP3MRAPmJAEjK+DMnAVAHEQDJGH/mJgDqIQIgCeNPCQRAXUQAFM74UwoBUB8RAIUy/pREANRJBEBhjD+lEQD1EgFQCONPiQRA3UQAzMz4UyoBUD8RADMx/pRMALRBBMDEjD+lEwDtEAEwEeNPBgKgLSIARmb8yUIAtEcEwEiMP5kIgDaJABiY8ScbAdAuEQADMf5kJADaJgJgQ8afrAQAIgDWZPzJTAAQIQJgZcaf7AQAd4kAWJLxpwYCgJNEAFzA+FMLAcCDRACcwfhTEwHAaUQAPMD4UxsBwFlEALzB+FMjAcB5RADNM/7USgBwERFAs4w/NRMALEME0BzjT+0EAMsSATTD+NMCAcAqRADVM/60QgCwKhFAtYw/LREArEMEUB3jT2sEAOsSAVTD+NMiAcAmRADpGX9aJQDYlAggLeNPywQAQxABpGP8aZ0AYCgigDSMPwgAhiUCKJ7xhyMCgKGJAIpl/OEeAcAYRADFMf5wPwHAWEQAxTD+8DABwJhEALMz/nA6AcDYRACzMf5wNgHAFEQAkzP+cD4BwFREAJMx/nAxAcCURACjM/6wHAHA1EQAozH+sDwBwBxEAIMz/rAaAcBcRACDMf6wOgHAnEQAGzP+sB4BwNxEAGsz/rA+AUAJRAArM/6wGQFAKUQASzP+sDkBQElEABcy/jAMAUBpRABnMv4wHAFAiUQADzH+MCwBQKlEAMeMPwxPAFAyEYDxh5EIAEonAhpm/GE8AoAMRECDjD+MSwCQhQhoiPGH8QkAMhEBDTD+MA0BQDYioGLGH6YjAMhIBFTI+MO0BABZiYCKGH+YngAgMxFQAeMP8xAAZCcCEjP+MB8BQA1EQELGH+YlAKiFCEjE+MP8BAA1EQEJGH8ogwCgNiKgYMYfyiEAqJEIKJDxh7IIAGolAgpi/KE8AoCaiYACGH8okwCgdiJgRsYfyiUAaIEImIHxh7IJAFohAiZk/KF8AoCWiIAJGH/IQQDQGhEwIuMPeQgAWiQCRmD8IRcBQKtEwICMP+QjAGiZCBiA8YecBACtEwEbMP6QlwAAEbAW4w+5CQA4IgJWYPwhPwEA94iAJRh/qIMAgPuJgHMYf6iHAICHiYBTGH+oiwCA04mAE4w/1EcAwNlEQBh/qJUAgPM1HQHGH+olAOBiTUaA8Ye6CQBYTlMRYPyhfgIAltdEBBh/aIMAgNVUHQHGH9ohAGB1VUaA8Ye2CABYT1URYPyhPQIA1ldFBBh/aFO2Gx5K0h8cHHzhypUrPxZd9565D7OSrvtLfd//zTe/5S1Xur7/bOT7veC5xaVLT770wgtfn/sgkJUnALC5vE8CcvInfxhAtuqHEvUHBwdfuHr16o9ExF+d+zCVM/4wEAEAwxAB4zP+MCABAMMRAeMx/jAwAQDDEgHDM/4wAgEAwxMBwzH+MBIBAOMQAZsz/jAiAQDjEQHrM/4wMgEA4xIBqzP+MAEBAOMTAcsz/jARAQDTEAEXM/4wIQEA0xEBZzP+MDEBANMSAQ8z/jADAQDTEwH3GH+YiQCAeYgA4w+zEgAwn5YjwPjDzAQAzKvFCDD+UAABAPNrKQKMPxRCAEAZWogA4w8FEQBQjpojwPhDYQQAlKXGCDD+UCABAOWpKQKMPxRKAECZaogA4w8FEwBQrswRYPyhcAIAypYxAow/JCAAoHyZIsD4QxICAHLIEAHGHxIRAJBHyRFg/CEZAQC5lBgBxh8SEgCQT0kRYPwhKQEAOZUQAcYfEhMAkNecEWD8ITkBALnNEQHGHyogACC/KSPA+EMlBADUoT84OPjClatX3xkRPzHS5/i/izt3PvzS/v7XR/r4wIQEANTjKAKuXDmMrvvJiNga7ANH/N7rly9/5OW9vf831McE5tXNfQBgeNeuXXu829r6pYh474Yf6nvRdT+7/93v/nxEHA5wNKAQAgDqtb2zs/NTEfGpPuJ9K/6/e33Erzxy6dIv3Lx584UxDgfMSwBAA3Z2dt7dd93Hou/fHxE/HhHviIi3RcQjEfFSRLzYR3yj6/s/jIjf2d/f//2IeH22AwOj+//r3DWaVjTaQgAAAABJRU5ErkJggg==") + no-repeat left center; + background-size: contain; +} diff --git a/index.ts b/index.ts index 428d01c..c6574de 100644 --- a/index.ts +++ b/index.ts @@ -86,7 +86,7 @@ function getPropertyByPath(obj: object, path: string) { const oauthEnabled = !!process.env.OAUTH_CLIENT_ID; function checkAuth(req: express.Request, res: express.Response, next: express.NextFunction) { - if (req.body.name && !oauthEnabled) { + if (req.body.name && !oauthEnabled && !req.session.uid) { req.session.name = req.body.name; req.session.uid = generateId(); } @@ -245,8 +245,10 @@ let wss = new websocket.server({ }); interface Room { + id: string; connections: Connection[]; cards: Card[]; + hosts: string[]; } interface Connection { @@ -288,8 +290,10 @@ wss.on("request", async function (request) { if (!joinRooms[roomId]) { let newRoom = { + id: roomId, connections: [], cards: [], + hosts: [] }; let viewId = crypto.createHash('sha256').update(roomId).digest('hex'); joinRooms[roomId] = newRoom; @@ -315,21 +319,30 @@ wss.on("request", async function (request) { let data = JSON.parse(message.utf8Data); // console.log(`Inbound: ${message.utf8Data}`); let card: Card; - let msg: string; + let msg: string = undefined; switch (data.type) { case "join": - room.connections.push({name, connection, id, participate}); + if (room.connections.length === 0 && room.hosts.length === 0) { + room.hosts.push(id); + } + room.connections.push({ name, connection, id, participate }); let connectedMsg = JSON.stringify({ type: "connected", - connected: room.connections.reduce((rv, cv) => { - if (cv.participate && !rv.find((item) => item.id == cv.id)) { - rv.push({name: cv.name, id: cv.id}); - } - return rv; - }, []).map((item) => { - return {name: item.name, id: item.id}; - }), + connected: room.connections + .reduce((rv, cv) => { + if (cv.participate && !rv.find((item) => item.id == cv.id)) { + rv.push({ + name: cv.name, + id: cv.id, + host: room.hosts.indexOf(cv.id) > -1, + }); + } + return rv; + }, []) + .map((item) => { + return { name: item.name, id: item.id, host: item.host }; + }), }); if (participate) { msg = connectedMsg; @@ -373,15 +386,82 @@ wss.on("request", async function (request) { } break; case "reset": - if (participate) { + if (participate && room.hosts.indexOf(id) > -1) { room.cards = []; msg = JSON.stringify({type: "reset"}); } break; case "kick": - if (participate) { - room.connections.filter((conn) => conn.id == data.id) - .map((conn) => conn.connection.close()); + if (participate && room.hosts.indexOf(id) > -1) { + room.connections + .filter((conn) => conn.id == data.id) + .map((conn) => conn.connection.close()); + } + break; + case "promote": + if (room.hosts.indexOf(id) > -1) { + room.hosts.push(data.id); + let connectedMsg = JSON.stringify({ + type: "connected", + connected: room.connections + .reduce((rv, cv) => { + if (cv.participate && !rv.find((item) => item.id == cv.id)) { + rv.push({ + name: cv.name, + id: cv.id, + host: room.hosts.indexOf(cv.id) > -1, + }); + } + return rv; + }, []) + .map((item) => { + return { name: item.name, id: item.id, host: item.host }; + }), + }); + if (participate) { + msg = connectedMsg; + } else { + connection.send(connectedMsg); + } + connection.send( + JSON.stringify({ + type: "all", + cards: room.cards, + }) + ); + } + break; + case "demote": + if (room.hosts.indexOf(id) > -1) { + room.hosts = room.hosts.filter((e) => e !== data.id); + let connectedMsg = JSON.stringify({ + type: "connected", + connected: room.connections + .reduce((rv, cv) => { + if (cv.participate && !rv.find((item) => item.id == cv.id)) { + rv.push({ + name: cv.name, + id: cv.id, + host: room.hosts.indexOf(cv.id) > -1, + }); + } + return rv; + }, []) + .map((item) => { + return { name: item.name, id: item.id, host: item.host }; + }), + }); + if (participate) { + msg = connectedMsg; + } else { + connection.send(connectedMsg); + } + connection.send( + JSON.stringify({ + type: "all", + cards: room.cards, + }) + ); } break; } @@ -420,16 +500,25 @@ wss.on("request", async function (request) { type: "connected", connected: room.connections.reduce((rv, cv) => { if (cv.participate && !rv.find((item) => item.id == cv.id)) { - rv.push({name: cv.name, id: cv.id}); + rv.push({ + name: cv.name, + id: cv.id, + host: room.hosts.indexOf(cv.id) > -1, + }); } return rv; - }, []).map((item) => { - return {name: item.name, id: item.id}; + }, []) + .map((item) => { + return { name: item.name, id: item.id, host: item.host }; }), }) ); } }); + + if (room.connections.length === 0) { + joinRooms[room.id] = undefined; + } } }); }); diff --git a/js/cards.js b/js/cards.js index 4036759..135291a 100644 --- a/js/cards.js +++ b/js/cards.js @@ -12,8 +12,10 @@ $(document).ready(() => { (location.protocol == "https:" ? "wss://" : "ws://") + location.hostname + (location.port ? ":" + location.port : "") + - '/' + (participate ? "stimmung" : "zuschauer") + - '/' + (participate ? joinId : viewId); + "/" + + (participate ? "stimmung" : "zuschauer") + + "/" + + (participate ? joinId : viewId); let socket = new WebSocket(wsUrl, "stimmung"); // "ws://localhost:8080/" socket.onopen = function () { socket.send( @@ -61,6 +63,14 @@ $(document).ready(() => { .forEach((dot) => dot.remove()); break; case "connected": + if (participate) { + let self = data.connected.filter((c) => c.id === uid); + if (self && self.length === 1) { + renderHostTools(self[0].host); + } else { + renderHostTools(false); // force hide + } + } renderUsers(data); data.connected.forEach((user) => { renderIfUserHasRaised(user.id); @@ -77,6 +87,7 @@ $(document).ready(() => { $("#cards").append( '