Skip to content

Commit

Permalink
1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Mendoza committed Dec 17, 2021
1 parent d2bdb26 commit af436a2
Show file tree
Hide file tree
Showing 102 changed files with 44,501 additions and 0 deletions.
42,367 changes: 42,367 additions & 0 deletions dist/browser/twilio-video-room-monitor.js

Large diffs are not rendered by default.

169 changes: 169 additions & 0 deletions dist/browser/twilio-video-room-monitor.min.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions dist/node/App.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="react" />
export default function App(): JSX.Element;
25 changes: 25 additions & 0 deletions dist/node/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const AppContainer_1 = __importDefault(require("./components/AppContainer/AppContainer"));
const ParticipantInfo_1 = __importDefault(require("./components/ParticipantInfo/ParticipantInfo"));
const RoomInfo_1 = __importDefault(require("./components/RoomInfo/RoomInfo"));
const RoomProvider_1 = __importDefault(require("./components/RoomProvider/RoomProvider"));
const RoomStatsProvider_1 = __importDefault(require("./components/RoomStatsProvider/RoomStatsProvider"));
const ReceiveBandwidthChart_1 = __importDefault(require("./components/StatsCharts/ReceiveBandwidth/ReceiveBandwidthChart"));
const SentBandwidthChart_1 = __importDefault(require("./components/StatsCharts/SentBandwidthChart/SentBandwidthChart"));
function App() {
return (react_1.default.createElement(RoomProvider_1.default, null,
react_1.default.createElement(RoomStatsProvider_1.default, null,
react_1.default.createElement(AppContainer_1.default, null, (activeTab) => (react_1.default.createElement(react_1.default.Fragment, null,
activeTab === 'info' && (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(RoomInfo_1.default, null),
react_1.default.createElement(ParticipantInfo_1.default, null))),
activeTab === 'stats' && (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(ReceiveBandwidthChart_1.default, null),
react_1.default.createElement(SentBandwidthChart_1.default, null)))))))));
}
exports.default = App;
4 changes: 4 additions & 0 deletions dist/node/components/AppContainer/AppContainer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import React from 'react';
export default function AppContainer({ children }: {
children: (activeTab: 'info' | 'stats') => React.ReactNode;
}): JSX.Element;
65 changes: 65 additions & 0 deletions dist/node/components/AppContainer/AppContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const styled_components_1 = require("styled-components");
const useDrag_1 = __importDefault(require("../../hooks/useDrag/useDrag"));
const useRoom_1 = __importDefault(require("../../hooks/useRoom/useRoom"));
const useWindowDimensions_1 = __importDefault(require("../../hooks/useWindowDimensions/useWindowDimensions"));
const CopyButton_1 = require("./CopyButton/CopyButton");
const styles_1 = require("./styles");
const index_1 = require("../../index");
const theme_1 = require("../theme");
styled_components_1.createGlobalStyle `
@import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');
`;
function AppContainer({ children }) {
const { draggableRef, dragContainerRef } = useDrag_1.default();
const [activeTab, setActiveTab] = react_1.useState('info');
const room = useRoom_1.default();
const { width, height } = useWindowDimensions_1.default();
let styles = {};
if (width < theme_1.theme.monitorWidth) {
// For mobile devices, we have the Monitor cover the entire screen using transform: scale().
const scale = width / theme_1.theme.monitorWidth;
styles = {
transform: `scale(${scale})`,
height: height * (1 / scale) + 'px',
};
}
return (react_1.default.createElement(styles_1.Container, { ref: dragContainerRef, style: styles },
react_1.default.createElement(styles_1.Bar, { ref: draggableRef },
react_1.default.createElement("span", { style: { padding: '0.57em' } }, "Twilio Video Room Monitor"),
react_1.default.createElement(styles_1.RightBarContainer, null,
react_1.default.createElement(styles_1.TabSelector, { isActive: activeTab === 'info', onClick: () => setActiveTab('info') }, "Info"),
react_1.default.createElement(styles_1.TabSelector, { isActive: activeTab === 'stats', onClick: () => setActiveTab('stats') }, "Stats"),
react_1.default.createElement(CopyButton_1.CopyButton, null),
react_1.default.createElement(styles_1.CloseIconContainer, { onClick: () => index_1.VideoRoomMonitor.closeMonitor() },
react_1.default.createElement("svg", { width: "20", height: "20", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
react_1.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M1.768 1.768a.347.347 0 01.491 0l15.973 15.973a.347.347 0 01-.492.49L1.768 2.26a.347.347 0 010-.49z", fill: "#DDD" }),
react_1.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M18.232 1.768a.347.347 0 010 .491L2.258 18.232a.347.347 0 11-.49-.491L17.74 1.768a.347.347 0 01.492", fill: "#DDD" }))))),
react_1.default.createElement(styles_1.OverflowContainer, null,
react_1.default.createElement(styles_1.ChildrenContainer, null, room ? children(activeTab) : react_1.default.createElement("span", null, "No Twilio Room detected.")))));
}
exports.default = AppContainer;
6 changes: 6 additions & 0 deletions dist/node/components/AppContainer/CopyButton/CopyButton.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// <reference types="react" />
export declare const CopyButtonContainer: import("styled-components").StyledComponent<"div", any, {
hasRoom: boolean;
}, never>;
export declare const Tooltip: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare function CopyButton(): JSX.Element;
101 changes: 101 additions & 0 deletions dist/node/components/AppContainer/CopyButton/CopyButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CopyButton = exports.Tooltip = exports.CopyButtonContainer = void 0;
const cloneDeepWith_1 = __importDefault(require("lodash/cloneDeepWith"));
const react_1 = __importStar(require("react"));
const styled_components_1 = __importDefault(require("styled-components"));
const useRoom_1 = __importDefault(require("../../../hooks/useRoom/useRoom"));
const theme_1 = require("../../theme");
exports.CopyButtonContainer = styled_components_1.default.div `
display: flex;
position: relative;
margin: 0 1em;
cursor: ${({ hasRoom }) => (hasRoom ? 'pointer' : 'initial')};
& svg {
stroke: ${({ hasRoom }) => (hasRoom ? theme_1.theme.borderColor : '#333')};
}
`;
exports.Tooltip = styled_components_1.default.div `
position: absolute;
background: #4f4f4f;
font-size: 0.75rem;
white-space: nowrap;
padding: 0.2em 0.6em;
top: 2.7em;
left: 0%;
visibility: hidden;
&:before {
content: '';
width: 0;
height: 0;
left: 5px;
top: -5px;
position: absolute;
border: 5px solid #4f4f4f;
transform: rotate(135deg);
}
${exports.CopyButtonContainer}: hover & {
visibility: visible;
}
@media (max-width: ${theme_1.theme.monitorWidth}px) {
left: auto;
right: 0;
&:before {
content: '';
right: 5px;
left: auto;
}
}
`;
const removeProcessors = (value, key) => {
if (key === 'processor') {
return Boolean(value);
}
};
function CopyButton() {
const room = useRoom_1.default();
const [hasCopiedRoomInfo, setHasCopiedRoomInfo] = react_1.useState(false);
const handleRoomCopy = () => {
if (room) {
const newRoom = cloneDeepWith_1.default(room, removeProcessors);
const newOptions = cloneDeepWith_1.default(room._options, removeProcessors);
const text = JSON.stringify(Object.assign(Object.assign({}, newRoom), { connectionOptions: newOptions }), null, 2);
navigator.clipboard.writeText(text).then(() => {
setHasCopiedRoomInfo(true);
});
}
};
return (react_1.default.createElement(exports.CopyButtonContainer, { onClick: handleRoomCopy, onMouseLeave: () => setHasCopiedRoomInfo(false), hasRoom: !!room },
react_1.default.createElement(exports.Tooltip, null, hasCopiedRoomInfo ? 'Room information copied to clipboard' : 'Copy Room Information'),
react_1.default.createElement("svg", { width: "20", height: "20", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
react_1.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.917.413c0-.274.223-.496.5-.496h6.666c.133 0 .26.052.354.145l5 4.959c.093.093.146.219.146.35v11.57a.498.498 0 01-.5.496H5.417a.498.498 0 01-.5-.495V.412zm1 .495v15.538h10.666V5.576L11.876.909h-5.96z", fill: "#DDD" }),
react_1.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M12.083-.083c.276 0 .5.222.5.496v4.462h4.5c.276 0 .5.222.5.496a.498.498 0 01-.5.496h-5a.498.498 0 01-.5-.496V.413c0-.274.224-.496.5-.496zM2.417 2.892c0-.274.223-.496.5-.496h2.5c.276 0 .5.222.5.496a.498.498 0 01-.5.496h-2v15.537h10.666v-1.983c0-.274.224-.496.5-.496s.5.222.5.495v2.48a.498.498 0 01-.5.496H2.917a.498.498 0 01-.5-.496V2.89z", fill: "#DDD" }))));
}
exports.CopyButton = CopyButton;
10 changes: 10 additions & 0 deletions dist/node/components/AppContainer/styles.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export declare const Container: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const BAR_HEIGHT = "2.8em";
export declare const Bar: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const OverflowContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const ChildrenContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const CloseIconContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const RightBarContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const TabSelector: import("styled-components").StyledComponent<"span", any, {
isActive: boolean;
}, never>;
94 changes: 94 additions & 0 deletions dist/node/components/AppContainer/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TabSelector = exports.RightBarContainer = exports.CloseIconContainer = exports.ChildrenContainer = exports.OverflowContainer = exports.Bar = exports.BAR_HEIGHT = exports.Container = void 0;
const styled_components_1 = __importDefault(require("styled-components"));
const theme_1 = require("../theme");
exports.Container = styled_components_1.default.div `
width: ${theme_1.theme.monitorWidth}px;
height: 85vh;
position: fixed;
top: 0;
transform-origin: 0 0;
z-index: 10000;
border: 1px solid ${theme_1.theme.borderColor};
color: ${theme_1.theme.borderColor};
& h1,
& h2,
& h3,
& h4,
& h5,
& h6,
& span,
& p,
& text {
font-family: 'Inter', sans-serif;
}
@media (max-width: ${theme_1.theme.monitorWidth}px) {
/* !important is used here to override the style attributes used for dragging */
top: 0 !important;
left: 0 !important;
}
`;
exports.BAR_HEIGHT = '2.8em';
exports.Bar = styled_components_1.default.div `
height: ${exports.BAR_HEIGHT};
cursor: move;
background: black;
position: absolute;
top: 0;
left: 0;
right: 0;
border-bottom: 1px solid ${theme_1.theme.borderColor};
display: flex;
justify-content: space-between;
align-items: center;
z-index: 20000;
`;
exports.OverflowContainer = styled_components_1.default.div `
overflow: hidden;
height: 100%;
padding-top: ${exports.BAR_HEIGHT};
`;
exports.ChildrenContainer = styled_components_1.default.div `
height: 100%;
overflow-y: auto;
padding: 0.4em 0.8em 0.4em;
background: black;
opacity: 0.8;
`;
exports.CloseIconContainer = styled_components_1.default.div `
border-left: 1px solid ${theme_1.theme.borderColor};
height: 2.7em;
width: 2.7em;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
& svg {
stroke: ${theme_1.theme.borderColor};
}
&:hover {
background: rgba(50, 50, 50, 0.9);
}
`;
exports.RightBarContainer = styled_components_1.default.div `
display: flex;
align-items: center;
`;
exports.TabSelector = styled_components_1.default.span `
position: relative;
margin: 0px 6px;
color: ${(props) => (props.isActive ? theme_1.theme.textColor : '#555')};
cursor: pointer;
padding: 8px;
border-bottom: ${(props) => (props.isActive ? '2px solid white' : '')};
&:hover {
background: rgba(50, 50, 50, 0.9);
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import { LocalAudioTrack, LocalAudioTrackPublication, RemoteAudioTrack, RemoteAudioTrackPublication } from 'twilio-video';
export declare const AudioTrackInfo: React.FC<{
track: LocalAudioTrack | RemoteAudioTrack;
trackSid: string;
}>;
export declare const AudioTrackPublicationInfo: React.FC<{
publication: LocalAudioTrackPublication | RemoteAudioTrackPublication;
}>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AudioTrackPublicationInfo = exports.AudioTrackInfo = void 0;
const react_1 = __importDefault(require("react"));
const useIsTrackEnabled_1 = __importDefault(require("../../../hooks/useIsTrackEnabled/useIsTrackEnabled"));
const useMediaStreamTrack_1 = __importDefault(require("../../../hooks/useMediaStreamTrack/useMediaStreamTrack"));
const useStatsUtils_1 = require("../../../hooks/useStats/useStatsUtils");
const useTrack_1 = __importDefault(require("../../../hooks/useTrack/useTrack"));
const Datum_1 = __importDefault(require("../../typography/common/Datum/Datum"));
const MediaStreamTrackInfo_1 = __importDefault(require("../../typography/trackInformation/MediaStreamTrackInfo/MediaStreamTrackInfo"));
const StatsContainer_1 = __importDefault(require("../../typography/common/StatsContainer/StatsContainer"));
const AudioTrackInfo = ({ track, trackSid }) => {
const isEnabled = useIsTrackEnabled_1.default(track);
const trackBandwidth = useStatsUtils_1.useTrackBandwidth(trackSid);
const trackData = useStatsUtils_1.useTrackData(trackSid);
const mediaStreamTrack = useMediaStreamTrack_1.default(track);
let lossPercentage = '';
if (trackData) {
const { packetsReceived, packetsSent, packetsLost } = trackData;
const totalPackets = packetsReceived !== null && packetsReceived !== void 0 ? packetsReceived : packetsSent;
lossPercentage =
totalPackets && packetsLost !== null ? `${((packetsLost / totalPackets) * 100).toLocaleString()}%` : null;
}
return (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(Datum_1.default, { label: "isEnabled", value: isEnabled }),
react_1.default.createElement(Datum_1.default, { label: "Bandwidth", value: (trackBandwidth === null || trackBandwidth === void 0 ? void 0 : trackBandwidth.toLocaleString()) + 'kbps' }),
trackData && (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(Datum_1.default, { label: "Codec", value: trackData.codec }),
react_1.default.createElement(Datum_1.default, { label: "Jitter", value: trackData.jitter }),
react_1.default.createElement(Datum_1.default, { label: "Packets Lost", value: trackData.packetsLost }),
react_1.default.createElement(Datum_1.default, { label: "Packet Loss Percentage", value: lossPercentage }))),
react_1.default.createElement(MediaStreamTrackInfo_1.default, { track: mediaStreamTrack })));
};
exports.AudioTrackInfo = AudioTrackInfo;
const AudioTrackPublicationInfo = ({ publication }) => {
const track = useTrack_1.default(publication);
return (react_1.default.createElement(StatsContainer_1.default, null,
react_1.default.createElement(Datum_1.default, { label: "Name", value: publication.trackName }),
react_1.default.createElement(Datum_1.default, { label: "SID", value: publication.trackSid }),
react_1.default.createElement(Datum_1.default, { label: "isSubscribed", value: !!track }),
track && react_1.default.createElement(exports.AudioTrackInfo, { track: track, trackSid: publication.trackSid })));
};
exports.AudioTrackPublicationInfo = AudioTrackPublicationInfo;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import { LocalDataTrack, LocalDataTrackPublication, RemoteDataTrack, RemoteDataTrackPublication } from 'twilio-video';
export declare const DataTrackInfo: React.FC<{
track: LocalDataTrack | RemoteDataTrack;
}>;
export declare const DataTrackPublicationInfo: React.FC<{
publication: LocalDataTrackPublication | RemoteDataTrackPublication;
}>;
Loading

0 comments on commit af436a2

Please sign in to comment.