adding a bunch of linting and starting project over with nothing

This commit is contained in:
talksik
2022-05-12 17:01:27 -05:00
parent f7646c4350
commit 3b1df3173c
34 changed files with 31766 additions and 1058 deletions
+30667
View File
File diff suppressed because it is too large Load Diff
+13 -11
View File
@@ -1,17 +1,19 @@
{
"env": {
"browser": true,
"es6": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/electron",
"plugin:import/typescript",
"plugin:reac/recommended"
],
"parser": "@typescript-eslint/parser"
"extends": ["plugin:react/recommended", "airbnb", "airbnb/hooks", "airbnb-typescript"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": ["react", "@typescript-eslint"],
"rules": {
"no-shadow": "off",
"@typescript-eslint/no-shadow": ["error"],
"no-unused-vars": "warn",
"@typescript-eslint/no-unused-vars": "warn"
}
}
+9 -4
View File
@@ -74,14 +74,19 @@
"@electron-forge/plugin-webpack": "6.0.0-beta.63",
"@types/react": "^17.0.40",
"@types/react-dom": "^17.0.13",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^5.13.0",
"@typescript-eslint/parser": "^5.0.0",
"@vercel/webpack-asset-relocator-loader": "1.7.0",
"autoprefixer": "^10.4.4",
"css-loader": "^6.0.0",
"electron": "17.1.2",
"eslint": "^8.0.1",
"eslint-plugin-import": "^2.25.0",
"eslint": "^8.15.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.5.0",
"fork-ts-checker-webpack-plugin": "^6.0.1",
"mini-css-extract-plugin": "^2.6.0",
"node-loader": "^2.0.0",
@@ -98,8 +103,8 @@
},
"dependencies": {
"@getstation/electron-google-oauth2": "^2.1.0",
"@nirvana/core": "*",
"@nirvana/components": "*",
"@nirvana/core": "*",
"antd": "^4.20.2",
"axios": "^0.26.1",
"electron-squirrel-startup": "^1.0.0",
-12
View File
@@ -1,12 +0,0 @@
import "./styles/index.css";
import * as React from "react";
import * as ReactDOM from "react-dom";
import NirvanaApp from "./pages/nirvanaApp";
function render() {
ReactDOM.render(<NirvanaApp />, document.getElementById("root"));
}
render();
+10 -11
View File
@@ -1,23 +1,24 @@
// NOTE: DO NOT ADD ANY ELECTRON RELATED TYPESCRIPT HERE...KEEP IT ONLY TYPESCRIPT OTHERWISE
// THE RENDERER WONT BE ABLE TO ACCESS THIS AS IT WILL THINK ITS PART OF MAIN PROCESS SINCE RENDERER CAN'T ACCESS NODE STUFF
// THE RENDERER WONT BE ABLE TO ACCESS THIS AS IT WILL THINK ITS PART
// OF MAIN PROCESS SINCE RENDERER CAN'T ACCESS NODE STUFF
// SINCE IT's NOT A NODE PROCESS
enum Channels {
ACTIVATE_LOG_IN = "ACTIVATE_LOG_IN",
GOOGLE_AUTH_TOKENS = "GOOGLE_AUTH_TOKENS",
RESIZE_WINDOW = "RESIZE_WINDOW",
ON_WINDOW_BLUR = "ON_WINDOW_BLUR",
export enum Channels {
ACTIVATE_LOG_IN = 'ACTIVATE_LOG_IN',
GOOGLE_AUTH_TOKENS = 'GOOGLE_AUTH_TOKENS',
RESIZE_WINDOW = 'RESIZE_WINDOW',
ON_WINDOW_BLUR = 'ON_WINDOW_BLUR',
}
export enum STORE_ITEMS {
AUTH_SESSION_JWT = "AUTH_SESSION_JWT",
export enum StoreItems {
AUTH_SESSION_JWT = 'AUTH_SESSION_JWT',
}
export type Dimensions = { height: number; width: number };
export interface DimensionChangeRequest {
setAlwaysOnTop: boolean;
setPosition?: "topRight" | "center";
setPosition?: 'topRight' | 'center';
dimensions: Dimensions;
addDimensions: boolean;
}
@@ -28,5 +29,3 @@ export const OVERLAY_ONLY_INITIAL_PRESET: Dimensions = {
height: 50,
width: 325,
};
export default Channels;
+2 -2
View File
@@ -1,5 +1,5 @@
import { Dimensions, DimensionChangeRequest } from "./constants";
import { electronAPI } from "./preload";
/* eslint-disable no-unused-vars */
import { DimensionChangeRequest, STORE_ITEMS, Channels } from './constants';
export {};
declare global {
@@ -1,20 +0,0 @@
import Channels, { STORE_ITEMS } from "./constants";
import ElectronGoogleOAuth2 from "@getstation/electron-google-oauth2";
import { browserWindow } from "../index";
import { ipcMain } from "electron";
import store from "./store";
const myApiOauth = new ElectronGoogleOAuth2(
"423533244953-banligobgbof8hg89i6cr1l7u0p7c2pk.apps.googleusercontent.com",
"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",
[""],
{ successRedirectURL: "http://localhost:3000/auth/success" }
);
// FRESH GOOGLE LOGIN...either no json web tokens or trying to sign in with another account.
export async function handleGoogleLogin() {
const tokens = await myApiOauth.openAuthWindowAndGetTokens();
browserWindow.webContents.send(Channels.GOOGLE_AUTH_TOKENS, tokens);
}
+9 -10
View File
@@ -1,7 +1,6 @@
import Channels, { Dimensions } from "./constants";
import { contextBridge, ipcRenderer } from "electron";
import { STORE_ITEMS } from "./constants";
// eslint-disable-next-line import/no-extraneous-dependencies
import { contextBridge, ipcRenderer } from 'electron';
import { Channels, Dimensions, StoreItems } from './constants';
const electronAPI = {
auth: {
@@ -10,11 +9,11 @@ const electronAPI = {
},
},
store: {
get(val: STORE_ITEMS) {
return ipcRenderer.invoke("electron-store-get", val);
get(val: StoreItems) {
return ipcRenderer.invoke('electron-store-get', val);
},
set(property: STORE_ITEMS, val: any) {
ipcRenderer.send("electron-store-set", property, val);
set(property: StoreItems, val: any) {
ipcRenderer.send('electron-store-set', property, val);
},
// Other method you want to add like has(), reset(), etc.
},
@@ -26,7 +25,7 @@ const electronAPI = {
},
on(channel: Channels, func: any) {
const validChannels = ["ipc-example"];
// const validChannels = ['ipc-example'];
// if (validChannels.includes(channel)) {
// // Deliberately strip event as it includes `sender`
// ipcRenderer.on(channel, (event, ...args) => func(...args));
@@ -45,6 +44,6 @@ const electronAPI = {
},
};
contextBridge.exposeInMainWorld("electronAPI", electronAPI);
contextBridge.exposeInMainWorld('electronAPI', electronAPI);
export default electronAPI;
+11
View File
@@ -0,0 +1,11 @@
/* eslint-disable react/jsx-filename-extension */
import './styles/index.css';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
function render() {
ReactDOM.render(<div>this is the electron app</div>, document.getElementById('root'));
}
render();
+44 -43
View File
@@ -1,19 +1,12 @@
import {
BrowserWindow,
Display,
Menu,
app,
dialog,
globalShortcut,
ipcMain,
screen,
} from "electron";
import Channels, { DEFAULT_APP_PRESET } from "./electron/constants";
/* eslint-disable import/no-extraneous-dependencies */
// eslint-disable-next-line object-curly-newline
import { BrowserWindow, Display, app, ipcMain, screen } from 'electron';
import { DimensionChangeRequest } from "./electron/constants";
import { handleGoogleLogin } from "./electron/handleLogin";
import path from "path";
import store from "./electron/store";
import path from 'path';
import ElectronGoogleOAuth2 from '@getstation/electron-google-oauth2';
import { Channels, DEFAULT_APP_PRESET, DimensionChangeRequest } from './electron/constants';
import store from './electron/store';
// This allows TypeScript to pick up the magic constant that's auto-generated by Forge's Webpack
// plugin that tells the Electron app where to look for the Webpack-bundled app code (depending on
@@ -22,14 +15,29 @@ declare const MAIN_WINDOW_WEBPACK_ENTRY: string;
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string;
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require("electron-squirrel-startup")) {
// eslint-disable-next-line global-require
if (require('electron-squirrel-startup')) {
// eslint-disable-line global-require
app.quit();
}
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
export let browserWindow: BrowserWindow;
let browserWindow: BrowserWindow;
const myApiOauth = new ElectronGoogleOAuth2(
'423533244953-banligobgbof8hg89i6cr1l7u0p7c2pk.apps.googleusercontent.com',
'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',
[''],
{ successRedirectURL: 'http://localhost:3000/auth/success' },
);
// FRESH GOOGLE LOGIN...either no json web tokens or trying to sign in with another account.
export default async function handleGoogleLogin() {
const tokens = await myApiOauth.openAuthWindowAndGetTokens();
browserWindow.webContents.send(Channels.GOOGLE_AUTH_TOKENS, tokens);
}
let display: Display;
@@ -41,7 +49,7 @@ const createWindow = (): void => {
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
sandbox: true,
},
icon: "./assets/1024x1024.icns",
icon: './assets/1024x1024.icns',
// transparent: true,
@@ -60,7 +68,7 @@ const createWindow = (): void => {
browserWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);
// Open the DevTools.
browserWindow.webContents.openDevTools({ mode: "detach" });
browserWindow.webContents.openDevTools({ mode: 'detach' });
display = screen.getPrimaryDisplay();
};
@@ -74,15 +82,15 @@ app
.then(() => {
// activate login
ipcMain.on(Channels.ACTIVATE_LOG_IN, async (event, arg) => {
console.log("initiating log in");
console.log('initiating log in');
await handleGoogleLogin();
});
// access storage/cookies
ipcMain.on("electron-store-set", async (event, key, val) => {
ipcMain.on('electron-store-set', async (event, key, val) => {
store.set(key, val);
});
ipcMain.handle("electron-store-get", async (event, val) => {
ipcMain.handle('electron-store-get', async (event, val) => {
const result = await store.get(val);
return result;
});
@@ -90,7 +98,7 @@ app
// dynamically changing the window bounds
ipcMain.on(Channels.RESIZE_WINDOW, (event, req: DimensionChangeRequest) => {
if (req.setAlwaysOnTop) {
browserWindow.setAlwaysOnTop(true, "floating");
browserWindow.setAlwaysOnTop(true, 'floating');
} else {
browserWindow.setAlwaysOnTop(false);
}
@@ -100,26 +108,19 @@ app
browserWindow.setSize(
currentDimensions[0] + req.dimensions.width,
currentDimensions[1] + req.dimensions.height,
false
false,
);
} else {
browserWindow.setSize(
req.dimensions.width,
req.dimensions.height,
false
);
browserWindow.setSize(req.dimensions.width, req.dimensions.height, false);
}
if (req.setPosition) {
if (req.setPosition === "center") {
if (req.setPosition === 'center') {
browserWindow.center();
}
if (req.setPosition === "topRight") {
browserWindow.setPosition(
display.bounds.width - req.dimensions.width,
0
);
if (req.setPosition === 'topRight') {
browserWindow.setPosition(display.bounds.width - req.dimensions.width, 0);
}
}
});
@@ -130,7 +131,7 @@ app
// });
// on blur, show overlay, and tell app to trigger overlay mode
browserWindow.on("blur", () => {
browserWindow.on('blur', () => {
browserWindow.webContents.send(Channels.ON_WINDOW_BLUR);
});
});
@@ -138,13 +139,13 @@ app
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on("activate", () => {
app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
@@ -158,17 +159,17 @@ app.on("activate", () => {
// open deep links from nirvana web app
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient("nirvana-desktop", process.execPath, [
app.setAsDefaultProtocolClient('nirvana-desktop', process.execPath, [
path.resolve(process.argv[1]),
]);
}
} else {
app.setAsDefaultProtocolClient("nirvana-desktop");
app.setAsDefaultProtocolClient('nirvana-desktop');
}
// Handle the protocol. In this case, we choose to show an Error Box.
app.on("open-url", (event, url) => {
console.log("welcome back, you arrived from: ", url);
app.on('open-url', (event, url) => {
console.log('welcome back, you arrived from: ', url);
browserWindow.focus();
});
+2 -4
View File
@@ -28,8 +28,6 @@
// import './index.css';
import "./app";
import './electronApp';
console.log(
'👋 This message is being logged by "renderer.js", included via webpack'
);
console.log('👋 This message is being logged by "renderer.js", included via webpack');
+10 -9
View File
@@ -1,19 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"module": "commonjs",
"skipLibCheck": true,
"esModuleInterop": true,
"noImplicitAny": false,
"sourceMap": true,
"baseUrl": ".",
"outDir": "dist",
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"paths": {
"*": ["node_modules/*"]
},
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src/**/*"]
"include": ["src/"]
}
@@ -1,12 +1,12 @@
import { useAuthCheck, useServerCheck } from "../../controller/index";
import { useAuthCheck, useServerCheck } from '../../../src/controller/index';
import { $jwtToken } from "../../controller/recoil";
import Login from "../../pages/Login";
import NirvanaApi from "../../controller/nirvanaApi";
import { STORE_ITEMS } from "../../electron/constants";
import SkeletonLoader from "../loading/skeleton";
import { useEffect } from "react";
import { useRecoilState } from "recoil";
import { $jwtToken } from '../../../src/controller/recoil';
import Login from '../../Login';
import NirvanaApi from '../../../src/controller/nirvanaApi';
import { STORE_ITEMS } from '../../../src/electron/constants';
import SkeletonLoader from '../loading/skeleton';
import { useEffect } from 'react';
import { useRecoilState } from 'recoil';
export default function ProtectedRoute({
children,
@@ -47,7 +47,7 @@ export default function ProtectedRoute({
// }, []);
useEffect(() => {
console.log("change in jwt token", jwtToken);
console.log('change in jwt token', jwtToken);
if (jwtToken) {
window.electronAPI.store.set(STORE_ITEMS.AUTH_SESSION_JWT, jwtToken);
@@ -64,7 +64,7 @@ export default function ProtectedRoute({
// first time loading
if (serverLoading)
return (
<span className="text-md text-gray-400 flex items-center justify-center flex-1 text-center p-5 h-screen">
<span className='text-md text-gray-400 flex items-center justify-center flex-1 text-center p-5 h-screen'>
Sorry...this is our bad. Our servers are loading. We are trying our best
to back up and running! :) <br /> Please contact me for urgent concerns:
arjunpatel@berkeley.edu
@@ -73,7 +73,7 @@ export default function ProtectedRoute({
if (isLoading) {
return (
<div className="container h-screen w-screen flex flex-col justify-center mx-10">
<div className='container h-screen w-screen flex flex-col justify-center mx-10'>
<SkeletonLoader />
</div>
);
@@ -1,4 +1,4 @@
import { FiActivity, FiSun } from "react-icons/fi";
import { FiActivity, FiSun } from 'react-icons/fi';
import {
RtcAnswerRequest,
RtcCallRequest,
@@ -6,21 +6,21 @@ import {
RtcReceiveAnswerResponse,
ServerResponseChannels,
SomeoneUntunedFromLineResponse,
} from "@nirvana/core/sockets/channels";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
} from '@nirvana/core/sockets/channels';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { $selectedLineId } from "../../../controller/recoil";
import { Avatar } from "antd";
import LineIcon from "../lineIcon";
import { LineMemberState } from "@nirvana/core/models/line.model";
import MasterLineData from "@nirvana/core/models/masterLineData.model";
import Peer from "simple-peer";
import { ServerRequestChannels } from "../../../../../core/sockets/channels";
import moment from "moment";
import toast from "react-hot-toast";
import { useGetUserDetails } from "../../../controller/index";
import { useLineDataProvider } from "../../../controller/lineDataProvider";
import { useRecoilState } from "recoil";
import { $selectedLineId } from '../../../controller/recoil';
import { Avatar } from 'antd';
import LineIcon from '../lineIcon';
import { LineMemberState } from '@nirvana/core/models/line.model';
import MasterLineData from '@nirvana/core/models/masterLineData.model';
import Peer from 'simple-peer';
import { ServerRequestChannels } from '@nirvana/core/sockets/channels';
import moment from 'moment';
import toast from 'react-hot-toast';
import { useGetUserDetails } from '../../../controller/index';
import { useLineDataProvider } from '../../../controller/lineDataProvider';
import { useRecoilState } from 'recoil';
// todo: send a much more comprehensive master line object? or just add properties to the
// masterLineData object so that we don't have different models to maintain between client and server
@@ -36,9 +36,9 @@ export default function LineRow({
const { data: userData } = useGetUserDetails();
useEffect(() => {
console.warn("mounting linerow");
console.warn('mounting linerow');
return () => console.warn("UNMOUNTING line row");
return () => console.warn('UNMOUNTING line row');
}, []);
// take the source of truth list of memeberIds tuned in, and see if I'm in it
@@ -54,19 +54,19 @@ export default function LineRow({
const renderActivityIcon = useMemo(() => {
// if there is someone or me broadcasting here
if (masterLineData.currentBroadcastersUserIds?.length > 0)
return <FiSun className="text-teal-500 animate-pulse" />;
return <FiSun className='text-teal-500 animate-pulse' />;
if (isUserTunedIn)
return <FiActivity className="text-black animate-pulse" />;
return <FiActivity className='text-black animate-pulse' />;
// if there is new activity blocks for me
if (masterLineData.currentUserMember.lastVisitDate)
return (
<span className="h-2 w-2 rounded-full bg-slate-800 animate-pulse"></span>
<span className='h-2 w-2 rounded-full bg-slate-800 animate-pulse'></span>
);
return (
<span className="h-2 w-2 rounded-full bg-white animate-pulse"></span>
<span className='h-2 w-2 rounded-full bg-white animate-pulse'></span>
);
}, [masterLineData, isUserTunedIn]);
@@ -77,22 +77,22 @@ export default function LineRow({
<Avatar.Group
key={`lineRowRightActivityGroup-${masterLineData.lineDetails._id.toString()}`}
maxCount={2}
maxPopoverTrigger="click"
size="small"
maxPopoverTrigger='click'
size='small'
maxStyle={{
color: "#f56a00",
backgroundColor: "#fde3cf",
cursor: "pointer",
borderRadius: "0",
color: '#f56a00',
backgroundColor: '#fde3cf',
cursor: 'pointer',
borderRadius: '0',
}}
className="shadow-lg"
className='shadow-lg'
>
{masterLineData.otherUserObjects?.map((otherUser, index) => (
<Avatar
key={`lineListActivitySection-${otherUser._id.toString()}-${index}`}
src={otherUser.picture ?? ""}
shape="square"
size={"small"}
src={otherUser.picture ?? ''}
shape='square'
size={'small'}
/>
))}
</Avatar.Group>
@@ -137,11 +137,11 @@ export default function LineRow({
className={`flex flex-row items-center justify-start gap-2 p-2 px-4 h-14 hover:bg-gray-200 cursor-pointer transition-all
last:border-b-0 border-b border-b-gray-200 relative z-50 rounded ${
selectedLineId === masterLineData.lineDetails._id.toString() &&
"bg-gray-200 scale-110 shadow-2xl translate-x-3"
'bg-gray-200 scale-110 shadow-2xl translate-x-3'
}`}
>
{/* status dot */}
<div className="flex-shrink-0 h-4 w-4">{renderActivityIcon}</div>
<div className='flex-shrink-0 h-4 w-4'>{renderActivityIcon}</div>
{profilePictures && (
<LineIcon grayscale={!isUserTunedIn} sourceImages={profilePictures} />
@@ -150,15 +150,15 @@ export default function LineRow({
<h2
className={`text-inherit text-md max-w-[220px] truncate text-slate-800 ${
masterLineData.currentUserMember.lastVisitDate
? "font-semibold"
: ""
? 'font-semibold'
: ''
}`}
>
{masterLineData.lineDetails.name ||
masterLineData.otherUserObjects[0].givenName}
</h2>
<div className="ml-auto flex-shrink-0">{renderRightActivity}</div>
<div className='ml-auto flex-shrink-0'>{renderRightActivity}</div>
</div>
{/* mounts and unmounts based on if in the room or now */}
@@ -249,7 +249,7 @@ function StreamRoom({
localPeerConnections[otherTunedInUserId] = localPeerInitiator;
// notify each one with specific signal
localPeerInitiator.on("signal", (signal) => {
localPeerInitiator.on('signal', (signal) => {
$ws.emit(
ServerRequestChannels.RTC_CALL_REQUEST,
new RtcCallRequest(lineId, otherTunedInUserId, signal)
@@ -266,7 +266,7 @@ function StreamRoom({
// create a local peer connection for this new user
console.log(
"ooo newbie joined room, I guess I will accept it and send him my signal"
'ooo newbie joined room, I guess I will accept it and send him my signal'
);
console.log(res);
@@ -276,9 +276,9 @@ function StreamRoom({
stream: userStream, // add in my own stream that I got before
});
peerForMeAndNewbie.on("signal", (signal) => {
peerForMeAndNewbie.on('signal', (signal) => {
console.log(
"as the answerer, I am going to send back my signal so that the newbie can update his local peer for me"
'as the answerer, I am going to send back my signal so that the newbie can update his local peer for me'
);
$ws.emit(
ServerRequestChannels.RTC_ANSWER_REQUEST,
@@ -315,7 +315,7 @@ function StreamRoom({
const newUserPeerMap = { ...previousUserPeersMap };
console.log(
"here is the current peers map",
'here is the current peers map',
previousUserPeersMap
);
@@ -325,7 +325,7 @@ function StreamRoom({
peerForAnswerer.signal(res.simplePeerSignal);
} else {
console.error(
"could not find the peer we created before for this master"
'could not find the peer we created before for this master'
);
}
@@ -347,7 +347,7 @@ function StreamRoom({
console.error(error);
toast.error(
"Make sure that you have permissions enabled and microphone connected"
'Make sure that you have permissions enabled and microphone connected'
);
});
}
@@ -368,7 +368,7 @@ function StreamRoom({
useEffect(() => {}, [tunedInUsers]);
useEffect(() => {
console.log("keeping an eye on user peers map");
console.log('keeping an eye on user peers map');
console.log(userPeers);
}, [userPeers]);
@@ -376,7 +376,7 @@ function StreamRoom({
// TODO: p1...when the peer map user count > tunedIn.length, then we get rid of the right person from list cuzz they have officially left or disconnected
useEffect(() => {
console.log("change in tuned in users in the streaming room!!!");
console.log('change in tuned in users in the streaming room!!!');
setUserPeers((prevUserPeersMap) => {
// go through the userIds here
@@ -389,7 +389,7 @@ function StreamRoom({
otherUserIdsPeers.forEach((otherUserId) => {
// problem if we are trying to show stream of someone who is not tuned in
if (!tunedInUsers.includes(otherUserId)) {
console.log("user left with id:", otherUserId);
console.log('user left with id:', otherUserId);
const disconnectedLocalPeer = newMap[otherUserId];
if (disconnectedLocalPeer) {
@@ -436,9 +436,9 @@ function PeerStreamRenderer({
const streamRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
peer.on("stream", (remotePeerStream: MediaStream) => {
peer.on('stream', (remotePeerStream: MediaStream) => {
console.log(
"stream coming in from remote peer...BUT, only going to show once they broadcast"
'stream coming in from remote peer...BUT, only going to show once they broadcast'
);
if (streamRef?.current) streamRef.current.srcObject = remotePeerStream;
@@ -1,9 +1,9 @@
import NirvanaApi, { ApiCalls } from "./nirvanaApi";
import { useMutation, useQuery } from "react-query";
import NirvanaApi, { ApiCalls } from './nirvanaApi';
import { useMutation, useQuery } from 'react-query';
import { $jwtToken } from "./recoil";
import { queryClient } from "../pages/nirvanaApp";
import { useRecoilValue } from "recoil";
import { $jwtToken } from './recoil';
import { queryClient } from '../../legacy/nirvanaApp';
import { useRecoilValue } from 'recoil';
// ====== QUERIES
@@ -11,7 +11,7 @@ import { useRecoilValue } from "recoil";
* ensure that the server is up
*/
export function useServerCheck() {
return useQuery("SERVER_CHECK", ApiCalls.serverCheck, {
return useQuery('SERVER_CHECK', ApiCalls.serverCheck, {
retry: true,
refetchOnWindowFocus: false,
@@ -22,7 +22,7 @@ export function useServerCheck() {
export function useAuthCheck(enabled: boolean = true) {
const jwtToken = useRecoilValue($jwtToken);
return useQuery("AUTH_CHECK", ApiCalls.authCheck, {
return useQuery('AUTH_CHECK', ApiCalls.authCheck, {
retry: false,
refetchOnWindowFocus: false,
@@ -32,11 +32,11 @@ export function useAuthCheck(enabled: boolean = true) {
}
export function useLogin() {
return useMutation("LOGIN", ApiCalls.login, {});
return useMutation('LOGIN', ApiCalls.login, {});
}
export function useGetUserDetails() {
return useQuery("USER_DETAILS", ApiCalls.getUserDetails, {
return useQuery('USER_DETAILS', ApiCalls.getUserDetails, {
retry: false,
refetchOnWindowFocus: false,
onError: (err) => {
@@ -46,7 +46,7 @@ export function useGetUserDetails() {
}
export function useUserSearch(searchQuery: string) {
return useQuery("USER_SEARCH", () => ApiCalls.userSearch(searchQuery), {
return useQuery('USER_SEARCH', () => ApiCalls.userSearch(searchQuery), {
enabled: searchQuery ? true : false,
refetchOnWindowFocus: false,
});
@@ -57,7 +57,7 @@ export function useUserLines() {
// todo: base/source of truth for getting all of the lines for the user
// merge with sockets + audio clip data + master data + convomember data
return useQuery("USER_LINES", ApiCalls.getUserLines, {
return useQuery('USER_LINES', ApiCalls.getUserLines, {
refetchOnWindowFocus: false,
refetchIntervalInBackground: false,
staleTime: Infinity,
@@ -72,7 +72,7 @@ export function useGetDmByUserId() {
export function useCreateLine() {
return useMutation(ApiCalls.createLine, {
onSuccess: (res, req) => {
queryClient.invalidateQueries(["USER_LINES"]);
queryClient.invalidateQueries(['USER_LINES']);
},
});
}
@@ -1,4 +1,4 @@
import { $desktopMode, $jwtToken, $selectedLineId } from "./recoil";
import { $desktopMode, $jwtToken, $selectedLineId } from './recoil';
import {
ConnectToLineRequest,
ServerRequestChannels,
@@ -12,18 +12,18 @@ import {
UntuneFromLineRequest,
UserStartedBroadcastingResponse,
UserStoppedBroadcastingResponse,
} from "@nirvana/core/sockets/channels";
import React, { useContext, useState } from "react";
import { Socket, io } from "socket.io-client";
import { useCallback, useEffect } from "react";
import { useRecoilValue, useSetRecoilState } from "recoil";
} from '@nirvana/core/sockets/channels';
import React, { useContext, useState } from 'react';
import { Socket, io } from 'socket.io-client';
import { useCallback, useEffect } from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { LineMemberState } from "@nirvana/core/models/line.model";
import MasterLineData from "@nirvana/core/models/masterLineData.model";
import { User } from "@nirvana/core/models";
import { queryClient } from "../pages/nirvanaApp";
import toast from "react-hot-toast";
import { useUserLines } from "./index";
import { LineMemberState } from '@nirvana/core/models/line.model';
import MasterLineData from '@nirvana/core/models/masterLineData.model';
import { User } from '@nirvana/core/models';
import { queryClient } from '../../legacy/nirvanaApp';
import toast from 'react-hot-toast';
import { useUserLines } from './index';
let $ws: Socket;
@@ -44,19 +44,19 @@ function useSocketHandler(linesData: MasterLineData[]) {
// https://socket.io/docs/v4/client-options/#reconnection
useEffect(() => {
$ws = io("http://localhost:5000", {
$ws = io('http://localhost:5000', {
query: { token: jwtToken },
transports: ["websocket"],
transports: ['websocket'],
upgrade: false,
forceNew: true,
reconnection: false, // ! TESTING THE PROBLEM WITH RECONNECTION CLIENT LISTENERS NOT ACTIVATING
});
$ws.on("connect", () => {
$ws.on('connect', () => {
console.log(
"SOCKETS | CLIENT CONNECTED in socket handler, setting up client side listeners for requests"
'SOCKETS | CLIENT CONNECTED in socket handler, setting up client side listeners for requests'
);
toast.success("you are connected");
toast.success('you are connected');
/**
* initiate listeners
@@ -160,7 +160,7 @@ function useSocketHandler(linesData: MasterLineData[]) {
$ws.on(
ServerResponseChannels.SOMEONE_STARTED_BROADCASTING,
(res: UserStartedBroadcastingResponse) => {
console.log("someone is starting to broadcast");
console.log('someone is starting to broadcast');
setLinesMap((prevLinesMap) => {
const newMap = { ...prevLinesMap };
@@ -198,28 +198,28 @@ function useSocketHandler(linesData: MasterLineData[]) {
// on disconnections, just switch it to flow state?
// what if there was another problem?
$ws.io.on("close", () => {
$ws.io.on('close', () => {
console.error(
"SOCKET | there was a problem with your app...connection closed likely due to idling or manual disconnect"
'SOCKET | there was a problem with your app...connection closed likely due to idling or manual disconnect'
);
// todo: figure out the right thing based on the situation whether it's a problem or user unplugs
// toast(
// "Disconnected due to idling or some other issue. Please reconnect or refresh to fix the problem."
// );
toast("unplugging");
setDesktopMode("flowState");
toast('unplugging');
setDesktopMode('flowState');
});
// client-side errors
$ws.on("connect_error", (err) => {
$ws.on('connect_error', (err) => {
console.error(`SOCKETS | ${err.message}`); // prints the message associated with the error
toast.error("sorry...this is our bad...please refresh with cmd + r");
toast.error('sorry...this is our bad...please refresh with cmd + r');
// force refetch of server status as well as these generally go hand in hand
// this should overall remount this component currently which is what we want for new data
queryClient.invalidateQueries("SERVER_CHECK");
queryClient.invalidateQueries('SERVER_CHECK');
});
// on unmounting this component, we want to disconnect
@@ -412,9 +412,9 @@ export function LineDataProvider({ children }) {
// and then disconnect
useEffect(() => {
return () => {
if (desktopMode === "flowState" && $ws) {
if (desktopMode === 'flowState' && $ws) {
console.log(
"SOCKETS | telling all of my connected rooms that I am unplugging"
'SOCKETS | telling all of my connected rooms that I am unplugging'
);
$ws.emit(ServerRequestChannels.GOING_INTO_FLOW_STATE);
@@ -1,58 +1,58 @@
import { atom } from "recoil";
import { atom } from 'recoil';
export const $searchQuery = atom<string>({
key: "SEARCH_QUERY",
default: "",
key: 'SEARCH_QUERY',
default: '',
});
export const $jwtToken = atom<string>({
key: "JWT_TOKEN",
key: 'JWT_TOKEN',
default: null,
});
// conversation id
export const $selectedConversation = atom<string>({
key: "SELECTED_CONVERSATION",
key: 'SELECTED_CONVERSATION',
default: null,
});
// new convo page trigger
export const $newConvoPage = atom<boolean>({
key: "NEW_CONVO_PAGE",
key: 'NEW_CONVO_PAGE',
default: false,
});
// number of active lines
export const $numberActiveLines = atom<number>({
key: "NUMBER_ACTIVE_LINES",
key: 'NUMBER_ACTIVE_LINES',
default: 0,
});
// max number of active streams
export const $maxNumberActiveStreams = atom<number>({
key: "MAX_NUMBER_ACTIVE_STREAMS",
key: 'MAX_NUMBER_ACTIVE_STREAMS',
default: 0,
});
// ============
type DesktopMode = "flowState" | "overlayOnly" | "terminal";
type DesktopMode = 'flowState' | 'overlayOnly' | 'terminal';
export const $desktopMode = atom<DesktopMode>({
key: "DESKTOP_MODE",
default: "terminal",
key: 'DESKTOP_MODE',
default: 'terminal',
});
export const $selectedLineId = atom<string>({
key: "SELECTED_LINE_ID",
key: 'SELECTED_LINE_ID',
default: null,
});
interface MediaSettings {
mode: "audio" | "video" | "screen";
mode: 'audio' | 'video' | 'screen';
isMuted: boolean;
}
export const $mediaSettings = atom<MediaSettings>({
key: "MEDIA_SETTINGS",
default: { isMuted: false, mode: "audio" },
key: 'MEDIA_SETTINGS',
default: { isMuted: false, mode: 'audio' },
});
@@ -1,21 +1,21 @@
import { useCallback, useEffect, useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { LogoType } from '@nirvana/components/logo/full';
import {
$desktopMode,
$maxNumberActiveStreams,
$numberActiveLines,
$selectedLineId,
} from "../../controller/recoil";
} from '../../src/controller/recoil';
import Channels, {
DEFAULT_APP_PRESET,
Dimensions,
} from "../../electron/constants";
import { useCallback, useEffect, useState } from "react";
import { useRecoilState, useRecoilValue } from "recoil";
} from '../../src/electron/constants';
import FullMottoLogo from "../../../../components/logo/fullMotto";
import { LineDataProvider } from "../../controller/lineDataProvider";
import { LogoType } from "@nirvana/components/logo/full";
import NirvanaHeader from "../../components/header/index";
import NirvanaTerminal from "../terminal";
import FullMottoLogo from '@nirvana/components/logo/fullMotto';
import { LineDataProvider } from '../../src/controller/lineDataProvider';
import NirvanaHeader from '../components/header/index';
import NirvanaTerminal from '../terminal';
export default function NirvanaRouter() {
const [selectedLineId, setSelectedLineId] = useRecoilState($selectedLineId);
@@ -27,16 +27,16 @@ export default function NirvanaRouter() {
useEffect(() => {
// add dimensions if it's not overlay only mode
let finalDimensions: Dimensions = { height: 0, width: 0 };
let finalPosition: "center" | "topRight";
let finalPosition: 'center' | 'topRight';
const setAlwaysOnTop = desktopMode === "overlayOnly";
const setAlwaysOnTop = desktopMode === 'overlayOnly';
// go hunting for which dimensions to have
if (desktopMode === "terminal" || desktopMode == "flowState") {
if (desktopMode === 'terminal' || desktopMode == 'flowState') {
finalDimensions = DEFAULT_APP_PRESET;
}
if (desktopMode === "overlayOnly") {
if (desktopMode === 'overlayOnly') {
finalDimensions = {
height: 68 + numberOfOverlayRows * 200,
width: 360 + 360 * numberOfOverlayColumns,
@@ -44,7 +44,7 @@ export default function NirvanaRouter() {
}
console.log(
"setting new dimensions",
'setting new dimensions',
desktopMode,
numberOfOverlayColumns,
numberOfOverlayRows,
@@ -70,7 +70,7 @@ export default function NirvanaRouter() {
useEffect(() => {
window.electronAPI.on(Channels.ON_WINDOW_BLUR, () => {
console.log(
"window blurring now, should be always on top and then ill tell main process to change dimensions"
'window blurring now, should be always on top and then ill tell main process to change dimensions'
);
// TODO: testing mode... uncomment both instructions below
// setDesktopMode("overlayOnly");
@@ -82,15 +82,15 @@ export default function NirvanaRouter() {
}, [setDesktopMode, setSelectedLineId]);
return (
<div className="flex flex-col flex-1">
<NirvanaHeader onHeaderFocus={() => setDesktopMode("terminal")} />
<div className='flex flex-col flex-1'>
<NirvanaHeader onHeaderFocus={() => setDesktopMode('terminal')} />
{desktopMode === "flowState" && <FlowState />}
{desktopMode === 'flowState' && <FlowState />}
{/* remount nirvana terminal */}
{(desktopMode === "terminal" || desktopMode === "overlayOnly") && (
{(desktopMode === 'terminal' || desktopMode === 'overlayOnly') && (
<LineDataProvider>
<NirvanaTerminal overlayOnly={desktopMode === "overlayOnly"} />
<NirvanaTerminal overlayOnly={desktopMode === 'overlayOnly'} />
</LineDataProvider>
)}
</div>
@@ -109,7 +109,7 @@ function FlowState() {
const [quote, setQuote] = useState<Quote>(null);
useEffect(() => {
fetch("https://api.quotable.io/random")
fetch('https://api.quotable.io/random')
.then((res) => res.json())
.then((data: Quote) => {
console.warn(data);
@@ -123,19 +123,19 @@ function FlowState() {
}, []);
return (
<div className="flex flex-col flex-1 justify-center items-center relative">
<div className='flex flex-col flex-1 justify-center items-center relative'>
{/* <img src="https://source.unsplash.com/random/?nature" /> */}
<FullMottoLogo
type={LogoType.small}
className={"absolute bottom-2 mx-auto"}
className='absolute bottom-2 mx-auto'
/>
{quote && (
<span className="flex flex-col justify-center items-center max-w-screen-sm">
<span className="text-xl text-gray-800 font-semibold text-center">
<span className='flex flex-col justify-center items-center max-w-screen-sm'>
<span className='text-xl text-gray-800 font-semibold text-center'>
"{quote.content}"
</span>
<span className="tex-md italic text-gray-400">{quote.author}</span>
<span className='tex-md italic text-gray-400'>{quote.author}</span>
</span>
)}
</div>
@@ -1,19 +1,19 @@
import { $desktopMode, $selectedLineId } from "../../controller/recoil";
import { Avatar, Skeleton, Tooltip } from "antd";
import { FiActivity, FiHeadphones, FiSettings, FiSun } from "react-icons/fi";
import { GlobalHotKeys, KeyMap } from "react-hotkeys";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useGetUserDetails, useUserLines } from "../../controller/index";
import { useRecoilState, useSetRecoilState } from "recoil";
import { $desktopMode, $selectedLineId } from '../../src/controller/recoil';
import { Avatar, Skeleton, Tooltip } from 'antd';
import { FiActivity, FiHeadphones, FiSettings, FiSun } from 'react-icons/fi';
import { GlobalHotKeys, KeyMap } from 'react-hotkeys';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useGetUserDetails, useUserLines } from '../../src/controller/index';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { FaPlus } from "react-icons/fa";
import LineIcon from "../../components/lines/lineIcon/index";
import { LineMemberState } from "@nirvana/core/models/line.model";
import LineRow from "../../components/lines/lineRow.tsx/index";
import MasterLineData from "@nirvana/core/models/masterLineData.model";
import NewLineModal from "./newLine";
import toast from "react-hot-toast";
import { useLineDataProvider } from "../../controller/lineDataProvider";
import { FaPlus } from 'react-icons/fa';
import LineIcon from '../components/lines/lineIcon/index';
import { LineMemberState } from '@nirvana/core/models/line.model';
import LineRow from '../components/lines/lineRow.tsx/index';
import MasterLineData from '@nirvana/core/models/masterLineData.model';
import NewLineModal from './newLine';
import toast from 'react-hot-toast';
import { useLineDataProvider } from '../../src/controller/lineDataProvider';
/**
* Socket Provider
@@ -93,7 +93,7 @@ export default function NirvanaTerminal({
// todo: sort/order based on activity and activity date and currently broadcasting/live
const handleEscape = useCallback(() => {
console.log("deselecting line");
console.log('deselecting line');
setSelectedLineId((prevSelectedLineId) => {
// ! only want to untune if it's a temporarily tuned line
@@ -128,7 +128,7 @@ export default function NirvanaTerminal({
(lineId: string, turnToggleOn: boolean) => {
// inhibit if they are trying to turn on and already have 3 toggle tuned
if (toggleTunedLines?.length >= 3 && turnToggleOn) {
toast.error("You cannot toggle more than 3 lines!");
toast.error('You cannot toggle more than 3 lines!');
return;
}
@@ -162,14 +162,14 @@ export default function NirvanaTerminal({
const keyMap: KeyMap = useMemo(
() => ({
DESELECT_LINE: "esc",
DESELECT_LINE: 'esc',
START_BROADCAST: {
sequence: "`",
action: "keydown",
sequence: '`',
action: 'keydown',
},
STOP_BROADCAST: {
sequence: "`",
action: "keyup",
sequence: '`',
action: 'keyup',
},
}),
[]
@@ -188,8 +188,8 @@ export default function NirvanaTerminal({
<>
<GlobalHotKeys handlers={handlers} keyMap={keyMap} allowChanges />
<div className="flex flex-row flex-1">
<div className="flex flex-col bg-white w-[400px] relative group">
<div className='flex flex-row flex-1'>
<div className='flex flex-col bg-white w-[400px] relative group'>
{/* modal for creating new line */}
<NewLineModal
open={isModalVisible}
@@ -197,17 +197,17 @@ export default function NirvanaTerminal({
/>
{/* tuned in lines block */}
<div className="bg-gray-100 flex flex-col shadow-lg">
<div className='bg-gray-100 flex flex-col shadow-lg'>
{/* tuned in header + general controls */}
<Tooltip placement="right" title={"These are your active rooms..."}>
<div className="flex flex-row items-center py-3 px-4 pb-0">
<span className="flex flex-row gap-2 items-center justify-start text-gray-400 animate-pulse">
<FiActivity className="text-sm" />
<Tooltip placement='right' title={'These are your active rooms...'}>
<div className='flex flex-row items-center py-3 px-4 pb-0'>
<span className='flex flex-row gap-2 items-center justify-start text-gray-400 animate-pulse'>
<FiActivity className='text-sm' />
<h2 className="text-inherit text-sm">Rooms</h2>
<h2 className='text-inherit text-sm'>Rooms</h2>
<p className="text-slate-300 text-xs">{`${
<p className='text-slate-300 text-xs'>{`${
toggleTunedLines?.length || 0
}/3`}</p>
</span>
@@ -215,7 +215,7 @@ export default function NirvanaTerminal({
</Tooltip>
{/* list of toggle tuned lines */}
<div className="flex flex-col mt-2">
<div className='flex flex-col mt-2'>
{toggleTunedLines.map((masterLineData) => (
<LineRow
key={`terminalListLines-${masterLineData.lineDetails._id.toString()}`}
@@ -227,14 +227,14 @@ export default function NirvanaTerminal({
</div>
{!(allLines.length > 0) && !(toggleTunedLines.length > 0) && (
<span className="text-gray-300 text-sm my-5 text-center">
<span className='text-gray-300 text-sm my-5 text-center'>
You have no lines! <br /> Create one to connect to your team
instantly.
</span>
)}
{/* rest of the lines */}
<div className={"flex flex-col"}>
<div className={'flex flex-col'}>
{isLoadingInitialLines ? (
<Skeleton />
) : (
@@ -250,12 +250,12 @@ export default function NirvanaTerminal({
<div
onClick={() => setIsModalVisible(true)}
className="absolute bottom-3 right-3 z-10 scale-0
group-hover:scale-100 ease-in-out hover:transition group-hover:transition delay-100 duration-200"
className='absolute bottom-3 right-3 z-10 scale-0
group-hover:scale-100 ease-in-out hover:transition group-hover:transition delay-100 duration-200'
>
<button
className="flex flex-row gap-2 items-center justify-evenly
shadow-xl bg-gray-800 p-2 text-white text-xs"
className='flex flex-row gap-2 items-center justify-evenly
shadow-xl bg-gray-800 p-2 text-white text-xs'
>
<FaPlus />
<span>New line</span>
@@ -270,13 +270,13 @@ export default function NirvanaTerminal({
/>
) : (
<div
className="flex flex-col flex-1 justify-center items-center bg-gray-100
border-l border-l-gray-200"
className='flex flex-col flex-1 justify-center items-center bg-gray-100
border-l border-l-gray-200'
>
<span className="text-xl text-gray-800">
<span className='text-xl text-gray-800'>
{`Hi ${userDetails?.user?.givenName}!`}
</span>
<span className="text-md text-gray-400">You're all set!</span>
<span className='text-md text-gray-400'>You're all set!</span>
</div>
)}
</div>
@@ -293,7 +293,7 @@ function LineDetailsTerminal({
}) {
const { data: userDetails } = useGetUserDetails();
console.log("selected line", selectedLine);
console.log('selected line', selectedLine);
const isUserToggleTuned = useMemo(
() => selectedLine?.currentUserMember?.state === LineMemberState.TUNED,
@@ -357,20 +357,20 @@ function LineDetailsTerminal({
return (
<div
className="flex flex-col flex-1 bg-gray-100
border-l border-l-gray-200 relative"
className='flex flex-col flex-1 bg-gray-100
border-l border-l-gray-200 relative'
>
{/* line details */}
<div
className="p-4
flex flex-row items-center gap-2 justify-end border-b-gray-200 border-b"
className='p-4
flex flex-row items-center gap-2 justify-end border-b-gray-200 border-b'
>
{profilePictures && (
<LineIcon grayscale={false} sourceImages={profilePictures} />
)}
<div className="flex flex-col items-start mr-auto group">
<span className="flex flex-row gap-2 items-center">
<div className='flex flex-col items-start mr-auto group'>
<span className='flex flex-row gap-2 items-center'>
<h2 className={`text-lg text-slate-800 font-semibold`}>
{selectedLine.lineDetails.name ||
selectedLine.otherUserObjects[0].givenName}
@@ -380,16 +380,16 @@ function LineDetailsTerminal({
className={`p-1 hidden group-hover:flex justify-center items-center hover:bg-gray-300
transition-all hover:scale-105`}
>
<FiSettings className="text-gray-400 text-xs" />
<FiSettings className='text-gray-400 text-xs' />
</button>
</span>
<span className="flex flex-row gap-2 items-center">
<span className="text-gray-300 text-xs">{`${
<span className='flex flex-row gap-2 items-center'>
<span className='text-gray-300 text-xs'>{`${
selectedLine.otherMembers?.length + 1 ?? 0
} members`}</span>
<span className="h-1 w-1 bg-gray-800 rounded-full"></span>
<span className="text-teal-500 text-xs">{`${
<span className='h-1 w-1 bg-gray-800 rounded-full'></span>
<span className='text-teal-500 text-xs'>{`${
selectedLine.tunedInMemberIds?.length ?? 0
} in this room`}</span>
</span>
@@ -397,15 +397,15 @@ function LineDetailsTerminal({
{/* TODO: move to on hover of line row */}
<Tooltip
placement="left"
placement='left'
title={`${
isUserToggleTuned ? "click to untoggle" : "click to stay tuned in"
isUserToggleTuned ? 'click to untoggle' : 'click to stay tuned in'
}`}
>
<button
className={`p-2 flex justify-center items-center shadow-lg
hover:scale-105 transition-all animate-pulse ${
isUserToggleTuned ? "bg-gray-800 text-white" : "text-black"
isUserToggleTuned ? 'bg-gray-800 text-white' : 'text-black'
}`}
onClick={() =>
isUserToggleTuned
@@ -419,101 +419,101 @@ function LineDetailsTerminal({
)
}
>
<FiActivity className="text-md" />
<FiActivity className='text-md' />
</button>
</Tooltip>
</div>
{/* line timeline */}
<div className="flex flex-col items-center gap-2 my-2 mx-auto max-w-lg w-full">
<div className='flex flex-col items-center gap-2 my-2 mx-auto max-w-lg w-full'>
<span
className={"text-gray-300 text-sm cursor-pointer hover:underline"}
className={'text-gray-300 text-sm cursor-pointer hover:underline'}
>
load more
</span>
<span className={"text-gray-300 text-sm"}>yesterday</span>
<span className={'text-gray-300 text-sm'}>yesterday</span>
<div className={"rounded border border-gray-200 flex flex-col w-full"}>
<div className={'rounded border border-gray-200 flex flex-col w-full'}>
{selectedLine.otherUserObjects.map((otherUser) => (
<div
className="flex flex-row p-2 gap-2 items-center bg-transparent
border-b border-b-gray-200 last:border-b-0"
className='flex flex-row p-2 gap-2 items-center bg-transparent
border-b border-b-gray-200 last:border-b-0'
>
<Avatar
key={`linehistory-${1}`}
src={otherUser.picture}
shape="square"
size={"default"}
shape='square'
size={'default'}
// grayscale if not playing?
className={`${true && "grayscale"}`}
className={`${true && 'grayscale'}`}
/>
<span className="text-gray-500">{otherUser.givenName}</span>
<span className='text-gray-500'>{otherUser.givenName}</span>
<span className="ml-auto text-xs text-gray-300">{`${
<span className='ml-auto text-xs text-gray-300'>{`${
Math.floor(Math.random() * 10) + 1
}:${Math.floor(Math.random() * 100) + 10}pm |`}</span>
<span className="text-gray-400 text-md">{`${
<span className='text-gray-400 text-md'>{`${
Math.floor(Math.random() * 60) + 1
} seconds`}</span>
</div>
))}
<div
className="flex flex-row p-2 gap-2 items-center bg-transparent
border-b border-b-gray-200 last:border-b-0"
className='flex flex-row p-2 gap-2 items-center bg-transparent
border-b border-b-gray-200 last:border-b-0'
>
<Avatar
key={`linehistory-${1}`}
src={userDetails.user.picture}
shape="square"
size={"default"}
shape='square'
size={'default'}
// grayscale if not playing?
className={`${true && "grayscale"}`}
className={`${true && 'grayscale'}`}
/>
<span className="text-gray-500">{"Arjun Patel"}</span>
<span className='text-gray-500'>{'Arjun Patel'}</span>
<span className="ml-auto text-xs text-gray-300">{`${
<span className='ml-auto text-xs text-gray-300'>{`${
Math.floor(Math.random() * 10) + 1
}:${Math.floor(Math.random() * 100) + 10}pm |`}</span>
<span className="text-gray-400 text-md">{`${
<span className='text-gray-400 text-md'>{`${
Math.floor(Math.random() * 60) + 1
} seconds`}</span>
</div>
</div>
<span className={"text-gray-300 text-sm"}>today</span>
<span className={'text-gray-300 text-sm'}>today</span>
<div
className={
"rounded border border-gray-400 flex flex-col w-full shadow-xl"
'rounded border border-gray-400 flex flex-col w-full shadow-xl'
}
>
{selectedLine.otherUserObjects.map((otherUser) => (
// TODO: show the shadow if it's unheard
<div
className="flex flex-row p-2 gap-2 items-center bg-transparent
border-b border-b-gray-400 last:border-b-0"
className='flex flex-row p-2 gap-2 items-center bg-transparent
border-b border-b-gray-400 last:border-b-0'
>
<Avatar
key={`linehistory-${1}`}
src={otherUser.picture}
shape="square"
size={"default"}
shape='square'
size={'default'}
// grayscale if not playing?
className={`${false && "grayscale"}`}
className={`${false && 'grayscale'}`}
/>
<span className="text-gray-600 font-semibold">
<span className='text-gray-600 font-semibold'>
{otherUser.name}
</span>
<span className="ml-auto text-xs text-gray-400">{`${
<span className='ml-auto text-xs text-gray-400'>{`${
Math.floor(Math.random() * 10) + 1
}:${Math.floor(Math.random() * 100) + 10}pm |`}</span>
<span className="text-gray-500 text-md">{`${
<span className='text-gray-500 text-md'>{`${
Math.floor(Math.random() * 60) + 1
} seconds`}</span>
</div>
@@ -522,32 +522,32 @@ function LineDetailsTerminal({
{/* live broadcasters */}
<span
className={"flex flex-row gap-2 items-center text-teal-500 text-sm"}
className={'flex flex-row gap-2 items-center text-teal-500 text-sm'}
>
<FiSun className="animate-ping" />
<FiSun className='animate-ping' />
<span>right now</span>
</span>
<div
className={
"rounded border border-teal-500 flex flex-col w-full shadow-2xl"
'rounded border border-teal-500 flex flex-col w-full shadow-2xl'
}
>
{selectedLine.otherUserObjects.map((otherUser) => (
<div className="flex flex-row p-2 gap-2 items-center bg-transparent">
<div className='flex flex-row p-2 gap-2 items-center bg-transparent'>
<Avatar
key={`linehistory-${1}`}
src={otherUser.picture}
shape="square"
size={"large"}
shape='square'
size={'large'}
// grayscale if not playing?
className={`shadow-lg`}
/>
<span className="text-gray-600 font-semibold">
<span className='text-gray-600 font-semibold'>
{otherUser.name}
</span>
<Tooltip title={"audio only"}>
<FiHeadphones className="text-gray-600 text-md ml-auto" />
<Tooltip title={'audio only'}>
<FiHeadphones className='text-gray-600 text-md ml-auto' />
</Tooltip>
</div>
))}
@@ -558,11 +558,11 @@ function LineDetailsTerminal({
className={`p-3 absolute right-3 bottom-3 flex justify-center items-center shadow-2xl
hover:scale-105 transition-all ${
isUserBroadcasting
? "bg-teal-800 text-white"
: "text-teal-800 border-teal-800 border"
? 'bg-teal-800 text-white'
: 'text-teal-800 border-teal-800 border'
}`}
>
<FiSun className="text-lg" />
<FiSun className='text-lg' />
</button>
</div>
);
@@ -1,12 +1,12 @@
import { Avatar, Modal } from "antd";
import { HotKeys, KeyMap } from "react-hotkeys";
import { useCallback, useEffect, useState } from "react";
import { useCreateLine, useUserSearch } from "../../../controller/index";
import { Avatar, Modal } from 'antd';
import { HotKeys, KeyMap } from 'react-hotkeys';
import { useCallback, useEffect, useState } from 'react';
import { useCreateLine, useUserSearch } from '../../../src/controller/index';
import BasicUserRow from "../../../components/User/basicUserDetailsRow";
import { FiSearch } from "react-icons/fi";
import { User } from "@nirvana/core/models";
import toast from "react-hot-toast";
import BasicUserRow from '../../components/User/basicUserDetailsRow';
import { FiSearch } from 'react-icons/fi';
import { User } from '@nirvana/core/models';
import toast from 'react-hot-toast';
export default function NewLineModal({
open,
@@ -17,25 +17,25 @@ export default function NewLineModal({
}) {
const [selectedPeople, setSelectedPeople] = useState<User[]>([]);
const [peopleSearchValue, setPeopleSearchValue] = useState<string>("");
const [peopleSearchValue, setPeopleSearchValue] = useState<string>('');
// the actual state that goes to query...the debounced one so to speak
const [searchQuery, setSearchQuery] = useState<string>("");
const [searchQuery, setSearchQuery] = useState<string>('');
const { refetch, data: searchRes } = useUserSearch(searchQuery);
const { mutateAsync, isLoading } = useCreateLine();
const [lineName, setLineName] = useState<string>("");
const [lineName, setLineName] = useState<string>('');
useEffect(() => {
if (searchQuery) refetch();
}, [searchQuery]);
const onSearch = useCallback(() => {
console.log("enter key pressed");
console.log('enter key pressed');
if (peopleSearchValue) {
console.log("searching for people in database");
console.log('searching for people in database');
setSearchQuery(peopleSearchValue);
}
}, [setSearchQuery, peopleSearchValue]);
@@ -52,7 +52,7 @@ export default function NewLineModal({
return [...prevSelectedUsers, userToAdd];
}
toast.error("you already selected this person below!");
toast.error('you already selected this person below!');
return prevSelectedUsers;
});
},
@@ -78,11 +78,11 @@ export default function NewLineModal({
// make sure that the list of lines updates for this client and others so that it shows this new line
// select the line so that it shows up in the line details for this client
console.log("trying to create line now!");
console.log('trying to create line now!');
try {
if (!selectedPeople?.length) {
toast.error("you must select at least one person");
toast.error('you must select at least one person');
return;
}
@@ -95,7 +95,7 @@ export default function NewLineModal({
otherMemberIds: selectedMemberIds,
});
toast.success("created line!");
toast.success('created line!');
// handle close once the new line is created
handleClose();
@@ -103,7 +103,7 @@ export default function NewLineModal({
toast.error(error);
console.error(error);
} finally {
console.log("done");
console.log('done');
}
}, [lineName, selectedPeople]);
@@ -112,7 +112,7 @@ export default function NewLineModal({
};
const keyMap: KeyMap = {
HANDLE_SEARCH: "enter",
HANDLE_SEARCH: 'enter',
};
const handlers = {
HANDLE_SEARCH: onSearch,
@@ -123,49 +123,49 @@ export default function NewLineModal({
return (
<>
<Modal
title="Create a Line"
title='Create a Line'
visible={open}
onCancel={handleCancel}
footer={
<div className="flex flex-row text-white">
<div className='flex flex-row text-white'>
<button
className="flex-1 bg-gray-500 pb-3 pt-2 text-left pl-2"
className='flex-1 bg-gray-500 pb-3 pt-2 text-left pl-2'
onClick={handleCancel}
>
Cancel
</button>
<button
className="flex-1 bg-teal-500 pb-3 pt-2 text-left pl-2"
className='flex-1 bg-teal-500 pb-3 pt-2 text-left pl-2'
onClick={handleSubmit}
>
Connect
</button>
</div>
}
className={"flex flex-col gap-5"}
className={'flex flex-col gap-5'}
>
<HotKeys handlers={handlers} keyMap={keyMap} allowChanges={true}>
<div className="flex flex-col items-start gap-2 mb-5">
<p className="text-gray-300 text-sm">People</p>
<div className='flex flex-col items-start gap-2 mb-5'>
<p className='text-gray-300 text-sm'>People</p>
<span className="flex flex-row gap-1 w-full items-center border border-gray-200 p-2 shadow">
<FiSearch className="text-gray-300" />
<span className='flex flex-row gap-1 w-full items-center border border-gray-200 p-2 shadow'>
<FiSearch className='text-gray-300' />
<input
className="placeholder:text-gray-300 outline-none placeholder:text-sm border-0 flex-1"
className='placeholder:text-gray-300 outline-none placeholder:text-sm border-0 flex-1'
value={peopleSearchValue}
onChange={(e) => setPeopleSearchValue(e.target.value)}
placeholder="search by name or email"
placeholder='search by name or email'
/>
<span className="text-xs text-gray-200 ml-auto">
<span className='text-xs text-gray-200 ml-auto'>
enter to search
</span>
</span>
{/* search results */}
{searchRes?.users?.length > 0 && (
<div className="flex flex-col border border-gray-200 shadow-md max-h-[500px] w-full overflow-y-auto">
<div className='flex flex-col border border-gray-200 shadow-md max-h-[500px] w-full overflow-y-auto'>
{searchRes?.users?.map((searchedUser) => (
<BasicUserRow
key={`searchResUser-${searchedUser.googleId}`}
@@ -183,10 +183,10 @@ export default function NewLineModal({
{/* selected people */}
{selectedPeople?.length > 0 && (
<div className="flex flex-col gap-2 mb-5">
<p className="text-gray-300 text-sm">Selected People</p>
<div className='flex flex-col gap-2 mb-5'>
<p className='text-gray-300 text-sm'>Selected People</p>
<div className="flex flex-col w-full">
<div className='flex flex-col w-full'>
{selectedPeople.map((selectedUser) => (
<BasicUserRow
key={`selectedUser-${selectedUser.googleId}`}
@@ -206,14 +206,14 @@ export default function NewLineModal({
</div>
)}
<div className="flex flex-col gap-2">
<p className="text-gray-300 text-sm">Line Name (optional)</p>
<div className='flex flex-col gap-2'>
<p className='text-gray-300 text-sm'>Line Name (optional)</p>
<input
value={lineName}
onChange={(e) => setLineName(e.target.value)}
className="placeholder:text-gray-300 outline-none placeholder:text-sm flex-1
border p-2 border-gray-200"
placeholder={"ex. Engineering, Sprint 7, Follow up on present..."}
className='placeholder:text-gray-300 outline-none placeholder:text-sm flex-1
border p-2 border-gray-200'
placeholder={'ex. Engineering, Sprint 7, Follow up on present...'}
/>
</div>
</HotKeys>
+710 -653
View File
File diff suppressed because it is too large Load Diff