Skip to content

Commit

Permalink
merging updates from ui lib repo to calling hero sample (#221)
Browse files Browse the repository at this point in the history
* merging updates from ui lib repo to calling hero sample

* adding in files from public/assets

* fixing lint/prettier suggestions
  • Loading branch information
alkwa-msft authored Mar 22, 2024
1 parent cbd1ad6 commit c5b155b
Show file tree
Hide file tree
Showing 62 changed files with 1,847 additions and 2,999 deletions.
2 changes: 1 addition & 1 deletion Calling/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module.exports = {
}
],
eqeqeq: 'warn',
'header/header': ['error', 'line', ' Copyright (c) Microsoft Corporation.\n Licensed under the MIT license.'],
'header/header': ['error', 'line', ' Copyright (c) Microsoft Corporation.\n Licensed under the MIT License.'],
'react/display-name': 'off',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unused-vars': ['warn', { varsIgnorePattern: '^_' }],
Expand Down
3,747 changes: 1,321 additions & 2,426 deletions Calling/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Calling/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@azure/communication-calling": "^1.22.1",
"@azure/communication-common": "^2.3.0",
"@azure/communication-identity": "^1.3.0",
"@azure/communication-react": "^1.13.0",
"@azure/communication-react": "^1.14.0",
"@azure/core-util": "1.5.0",
"@azure/logger": "^1.0.4",
"@babel/preset-react": "^7.12.7",
Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added Calling/public/assets/sounds/callBusy.mp3
Binary file not shown.
Binary file added Calling/public/assets/sounds/callEnded.mp3
Binary file not shown.
Binary file added Calling/public/assets/sounds/callRinging.mp3
Binary file not shown.
2 changes: 1 addition & 1 deletion Calling/public/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- Copyright (c) Microsoft Corporation. -->
<!-- Licensed under the MIT license. -->
<!-- Licensed under the MIT License. -->

<!DOCTYPE html>
<html lang="en">
Expand Down
73 changes: 47 additions & 26 deletions Calling/src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { CommunicationUserIdentifier } from '@azure/communication-common';
import { ParticipantRole } from '@azure/communication-calling';
import { fromFlatCommunicationIdentifier, StartCallIdentifier } from '@azure/communication-react';

import { setLogLevel } from '@azure/logger';
import { initializeIcons, Spinner } from '@fluentui/react';
import { CallAdapterLocator } from '@azure/communication-react';
import React, { useEffect, useState } from 'react';
import {
addUserToRoom,
buildTime,
callingSDKVersion,
communicationReactSDKVersion,
createGroupId,
createRoom,
fetchTokenResponse,
getGroupIdFromUrl,
getRoomIdFromUrl,
getTeamsLinkFromUrl,
isLandscape,
isOnIphoneAndNotSafari,
navigateToHomePage,
WEB_APP_TITLE
} from './utils/AppUtils';

import { createRoom, getRoomIdFromUrl, addUserToRoom } from './utils/AppUtils';
import { useIsMobile } from './utils/useIsMobile';
import { useSecondaryInstanceCheck } from './utils/useSecondaryInstanceCheck';
import { CallError } from './views/CallError';
import { CallScreen } from './views/CallScreen';
import { HomeScreen } from './views/HomeScreen';
import { PageOpenInAnotherTab } from './views/PageOpenInAnotherTab';
import { UnsupportedBrowserPage } from './views/UnsupportedBrowserPage';

setLogLevel('verbose');
setLogLevel('error');

console.log(
`ACS sample calling app. Last Updated ${buildTime} using @azure/communication-calling:${callingSDKVersion} and @azure/communication-react:${communicationReactSDKVersion}`
);

initializeIcons();

Expand All @@ -44,7 +48,8 @@ const App = (): JSX.Element => {
const [userCredentialFetchError, setUserCredentialFetchError] = useState<boolean>(false);

// Call details to join a call - these are collected from the user on the home screen
const [callLocator, setCallLocator] = useState<CallAdapterLocator>(createGroupId());
const [callLocator, setCallLocator] = useState<CallAdapterLocator>();
const [targetCallees, setTargetCallees] = useState<StartCallIdentifier[]>([]);
const [displayName, setDisplayName] = useState<string>('');

// Get Azure Communications Service token from the server
Expand All @@ -63,18 +68,13 @@ const App = (): JSX.Element => {

const isMobileSession = useIsMobile();
const isLandscapeSession = isLandscape();
const isAppAlreadyRunningInAnotherTab = useSecondaryInstanceCheck();

useEffect(() => {
if (isMobileSession && isLandscapeSession) {
console.log('ACS Calling sample: Mobile landscape view is experimental behavior');
}
}, [isMobileSession, isLandscapeSession]);

if (isMobileSession && isAppAlreadyRunningInAnotherTab) {
return <PageOpenInAnotherTab />;
}

const supportedBrowser = !isOnIphoneAndNotSafari();
if (!supportedBrowser) {
return <UnsupportedBrowserPage />;
Expand All @@ -85,20 +85,32 @@ const App = (): JSX.Element => {
document.title = `home - ${WEB_APP_TITLE}`;
// Show a simplified join home screen if joining an existing call
const joiningExistingCall: boolean = !!getGroupIdFromUrl() || !!getTeamsLinkFromUrl() || !!getRoomIdFromUrl();

return (
<HomeScreen
joiningExistingCall={joiningExistingCall}
startCallHandler={async (callDetails) => {
setDisplayName(callDetails.displayName);

let callLocator: CallAdapterLocator | undefined =
callDetails.callLocator || getTeamsLinkFromUrl() || getGroupIdFromUrl();

callLocator = callLocator || getRoomIdFromUrl();
callDetails.callLocator ||
getRoomIdFromUrl() ||
getTeamsLinkFromUrl() ||
getGroupIdFromUrl() ||
createGroupId();

if (callDetails.option === 'Rooms') {
callLocator = getRoomIdFromUrl() || callDetails.callLocator;
}

callLocator = callLocator || createGroupId();
if (callDetails.option === 'TeamsAdhoc') {
const outboundTeamsUsers = callDetails.outboundTeamsUsers?.map((user) => {
return fromFlatCommunicationIdentifier(user) as StartCallIdentifier;
});
callLocator = undefined;
setTargetCallees(outboundTeamsUsers ?? []);
}

// There is an API call involved with creating a room so lets only create one if we know we have to
if (callDetails.option === 'StartRooms') {
let roomId = '';
try {
Expand All @@ -110,9 +122,13 @@ const App = (): JSX.Element => {
callLocator = { roomId: roomId };
}

if ('roomId' in callLocator) {
if (callLocator && 'roomId' in callLocator) {
if (userId && 'communicationUserId' in userId) {
await addUserToRoom(userId.communicationUserId, callLocator.roomId, callDetails.role ?? 'Presenter');
await addUserToRoom(
userId.communicationUserId,
callLocator.roomId,
callDetails.role as ParticipantRole
);
} else {
throw 'Invalid userId!';
}
Expand All @@ -121,7 +137,7 @@ const App = (): JSX.Element => {
setCallLocator(callLocator);

// Update window URL to have a joinable link
if (!joiningExistingCall) {
if (callLocator && !joiningExistingCall) {
window.history.pushState({}, document.title, window.location.origin + getJoinParams(callLocator));
}

Expand All @@ -144,14 +160,18 @@ const App = (): JSX.Element => {
);
}

if (!token || !userId || !displayName || !callLocator) {
if (!token || !userId || !displayName || (!targetCallees && !callLocator)) {
document.title = `credentials - ${WEB_APP_TITLE}`;
return <Spinner label={'Getting user credentials from server'} ariaLive="assertive" labelPosition="top" />;
}
return (
<React.StrictMode>
<CallScreen token={token} userId={userId} displayName={displayName} callLocator={callLocator} />
</React.StrictMode>
<CallScreen
token={token}
userId={userId}
displayName={displayName}
callLocator={callLocator}
targetCallees={targetCallees}
/>
);
}
default:
Expand All @@ -167,6 +187,7 @@ const getJoinParams = (locator: CallAdapterLocator): string => {
if ('roomId' in locator) {
return '?roomId=' + encodeURIComponent(locator.roomId);
}

return '?groupId=' + encodeURIComponent(locator.groupId);
};

Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/styles/CallScreen.styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { IStackItemStyles, IStackStyles } from '@fluentui/react';

Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/styles/DisplayNameField.styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { mergeStyles } from '@fluentui/react';

Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/styles/EndCall.styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { IButtonStyles, IStackTokens, mergeStyles } from '@fluentui/react';

Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/styles/Footer.styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { IButtonStyles, IStackStyles, IStackTokens, ITextFieldStyles, mergeStyles } from '@fluentui/react';

Expand Down
5 changes: 4 additions & 1 deletion Calling/src/app/styles/HomeScreen.styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { IStackTokens, mergeStyles } from '@fluentui/react';

Expand Down Expand Up @@ -59,3 +59,6 @@ export const buttonStyle = mergeStyles({
borderRadius: 3,
padding: '0.625rem'
});
export const outboundTextField = mergeStyles({
paddingTop: '0.5rem'
});
2 changes: 1 addition & 1 deletion Calling/src/app/styles/StartCallButton.styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { mergeStyles } from '@fluentui/react';

Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/theming/SwitchableFluentThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import React, { useState, useMemo, createContext, useContext } from 'react';
import { FluentThemeProvider, lightTheme, darkTheme } from '@azure/communication-react';
Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/theming/ThemeSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import React from 'react';
import { ChoiceGroup, IChoiceGroupOption, concatStyleSets } from '@fluentui/react';
Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/utils/AppUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { createRandomDisplayName, getGroupIdFromUrl } from './AppUtils';

Expand Down
50 changes: 30 additions & 20 deletions Calling/src/app/utils/AppUtils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { GroupLocator, ParticipantRole, RoomLocator, TeamsMeetingLinkLocator } from '@azure/communication-calling';
import { GroupLocator, TeamsMeetingLinkLocator } from '@azure/communication-calling';
import { ParticipantRole, RoomCallLocator } from '@azure/communication-calling';

import { v1 as generateGUID } from 'uuid';

Expand Down Expand Up @@ -38,24 +39,6 @@ export const getGroupIdFromUrl = (): GroupLocator | undefined => {

export const createGroupId = (): GroupLocator => ({ groupId: generateGUID() });

/**
* Get teams meeting link from the url's query params.
*/
export const getTeamsLinkFromUrl = (): TeamsMeetingLinkLocator | undefined => {
const urlParams = new URLSearchParams(window.location.search);
const teamsLink = urlParams.get('teamsLink');
return teamsLink ? { meetingLink: teamsLink } : undefined;
};

/**
* Get room id from the url's query params.
*/
export const getRoomIdFromUrl = (): RoomLocator | undefined => {
const urlParams = new URLSearchParams(window.location.search);
const roomId = urlParams.get('roomId');
return roomId ? { roomId } : undefined;
};

/**
* Create an ACS room
*/
Expand Down Expand Up @@ -89,6 +72,24 @@ export const addUserToRoom = async (userId: string, roomId: string, role: Partic
}
};

/**
* Get teams meeting link from the url's query params.
*/
export const getTeamsLinkFromUrl = (): TeamsMeetingLinkLocator | undefined => {
const urlParams = new URLSearchParams(window.location.search);
const teamsLink = urlParams.get('teamsLink');
return teamsLink ? { meetingLink: teamsLink } : undefined;
};

/**
* Get room id from the url's query params.
*/
export const getRoomIdFromUrl = (): RoomCallLocator | undefined => {
const urlParams = new URLSearchParams(window.location.search);
const roomId = urlParams.get('roomId');
return roomId ? { roomId } : undefined;
};

/*
* TODO:
* Remove this method once the SDK improves error handling for unsupported browser.
Expand All @@ -107,3 +108,12 @@ export const navigateToHomePage = (): void => {
};

export const WEB_APP_TITLE = document.title;

declare let __BUILDTIME__: string; // Injected by webpack
export const buildTime = __BUILDTIME__;

declare let __CALLINGVERSION__: string; // Injected by webpack
export const callingSDKVersion = __CALLINGVERSION__;

declare let __COMMUNICATIONREACTVERSION__: string; //Injected by webpack
export const communicationReactSDKVersion = __COMMUNICATIONREACTVERSION__;
2 changes: 1 addition & 1 deletion Calling/src/app/utils/credential.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { AzureCommunicationTokenCredential, CommunicationTokenRefreshOptions } from '@azure/communication-common';
import { AbortSignalLike } from '@azure/abort-controller';
Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/utils/localStorage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

export const localStorageAvailable = typeof Storage !== 'undefined';

Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/utils/useIsMobile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { useEffect, useState } from 'react';
import MobileDetect from 'mobile-detect';
Expand Down
2 changes: 1 addition & 1 deletion Calling/src/app/utils/useSecondaryInstanceCheck.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Licensed under the MIT License.

import { useEffect, useState } from 'react';

Expand Down
8 changes: 8 additions & 0 deletions Calling/src/app/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

/**
* Function to detect iOS devices like IPhones, IPads, and IPods
*/
export const isIOS = (): boolean =>
/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
Loading

0 comments on commit c5b155b

Please sign in to comment.