@fortawesome/free-regular-svg-icons#faClock TypeScript Examples

The following examples show how to use @fortawesome/free-regular-svg-icons#faClock. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: fontawesome-config.ts    From covidnet_ui with GNU Affero General Public License v3.0 6 votes vote down vote up
// Description: add icons to be used in the app as needed
// Some are solid and some are from regular svg (hollow icons)
library.add(
  faSearch,
  faSearchPlus,
  faHome,
  faSpinner,
  faExclamationTriangle,
  faTrash,
  faTrashAlt,
  faEdit,
  faUser,
  faUserEdit,
  faUserPlus,
  faUserTimes,
  faUserMinus,
  faKey,
  faCheck,
  faCheckCircle,
  faCalendarDay,
  faClock,
  faCalendarAlt,
  farUser,
  faFileAlt
);
Example #2
Source File: icon.service.ts    From WowUp with GNU General Public License v3.0 5 votes vote down vote up
public constructor(private _matIconRegistry: MatIconRegistry, private _sanitizer: DomSanitizer) {
    this.addSvg(faAngleDoubleDown);
    this.addSvg(faArrowUp);
    this.addSvg(faArrowDown);
    this.addSvg(faSyncAlt);
    this.addSvg(faTimes);
    this.addSvg(faExternalLinkAlt);
    this.addSvg(faQuestionCircle);
    this.addSvg(faPlay);
    this.addSvg(faClock);
    this.addSvg(faBug);
    this.addSvg(faLink);
    this.addSvg(faDiscord);
    this.addSvg(faGithub);
    this.addSvg(faInfoCircle);
    this.addSvg(faCodeBranch);
    this.addSvg(faCaretDown);
    this.addSvg(faExclamationTriangle);
    this.addSvg(faCode);
    this.addSvg(faPatreon);
    this.addSvg(faCoins);
    this.addSvg(faCompressArrowsAlt);
    this.addSvg(faPencilAlt);
    this.addSvg(faCheckCircle);
    this.addSvg(faDiceD6);
    this.addSvg(faSearch);
    this.addSvg(faInfoCircle);
    this.addSvg(faNewspaper);
    this.addSvg(faCog);
    this.addSvg(faAngleUp);
    this.addSvg(faAngleDown);
    this.addSvg(faChevronRight);
    this.addSvg(faUserCircle);
    this.addSvg(faEllipsisV);
    this.addSvg(faCopy);
    this.addSvg(farCheckCircle);
    this.addSvg(faExclamation);
    this.addSvg(faTrash);
    this.addSvg(faHistory);
    this.addSvg(faCaretSquareRight);
    this.addSvg(faCaretSquareLeft);
    this.addSvg(faMinimize);
    this.addSvg(faUpRightFromSquare);
  }
Example #3
Source File: MediaPlayerContainer.tsx    From sync-party with GNU General Public License v3.0 4 votes vote down vote up
export default function MediaPlayerContainer({ socket }: Props): JSX.Element {
    // Constants
    const uiTimeoutIntervalResolution = 500;
    const uiTimeoutShortDelay = 5000;
    const uiTimeoutLongDelay = 30000;
    const syncStatusIntervalDelay = 1000;
    const syncStatusIntervalTolerance = 1500;
    const actionMessageDelay = 3000;
    const seekStepSize = 5;
    const volumeStepSize = 0.05;

    // Utilities
    const dispatch = useDispatch();
    const { t } = useTranslation();

    // Data from global state
    const party = useSelector((state: RootAppState) => state.globalState.party);
    const user = useSelector((state: RootAppState) => state.globalState.user);
    const uiVisible = useSelector(
        (state: RootAppState) => state.globalState.uiVisible
    );
    const initialServerTimeOffset = useSelector(
        (state: RootAppState) => state.globalState.initialServerTimeOffset
    );
    const webRtcGlobalState = useSelector(
        (state: RootAppState) => state.globalState.webRtc
    );

    // Local states & their refs
    const [reactPlayer, setReactPlayer] = useState<ReactPlayer>();
    const [joinedParty, setJoinedParty] = useState(false);
    const [freshlyJoined, setFreshlyJoined] = useState(true);
    const [windowHeight, setWindowHeight] = useState(window.innerHeight);
    const [hasLastPosition, setHasLastPosition] = useState(false);

    const initialPlayerState = {
        playOrder: null,
        isPlaying: false,
        isFocused: true,
        isSeeking: false,
        isFullScreen: false,
        isSyncing: false,
        isBuffering: false,
        playlistIndex: 0,
        playingItem: useSelector(
            (state: RootAppState) => state.globalState.playingItem
        ),
        duration: 0,
        sourceUrl: '',
        volume: 1
    };
    const playerStateReducer = (
        playerState: PlayerState,
        updatedProperties: PlayerStateActionProperties
    ): PlayerState => {
        return { ...playerState, ...updatedProperties };
    };
    const [playerState, setPlayerState] = useReducer(
        playerStateReducer,
        initialPlayerState
    );
    const playerStateRef = useRef(playerState);
    playerStateRef.current = playerState;

    const initialPlayerTimeoutState = {
        actionMessageTimeoutId: null,
        actionMessageTimeoutDone: false,
        uiTimeoutId: null,
        uiTimeoutDelay: uiTimeoutShortDelay,
        uiTimeoutTimestamp: Date.now()
    };
    const playerTimeoutReducer = (
        playerTimeoutState: PlayerTimeoutState,
        updatedProperties: PlayerTimeoutStateActionProperties
    ): PlayerTimeoutState => {
        return { ...playerTimeoutState, ...updatedProperties };
    };
    const [playerTimeoutState, setPlayerTimeoutState] = useReducer(
        playerTimeoutReducer,
        initialPlayerTimeoutState
    );
    const playerTimeoutStateRef = useRef(playerTimeoutState);
    playerTimeoutStateRef.current = playerTimeoutState;

    // Clear all timeouts
    const clearAllTimeouts = (): void => {
        if (playerTimeoutStateRef.current.uiTimeoutId) {
            clearTimeout(playerTimeoutStateRef.current.uiTimeoutId);
        }
        if (playerTimeoutStateRef.current.actionMessageTimeoutId) {
            clearTimeout(playerTimeoutStateRef.current.actionMessageTimeoutId);
        }
    };

    // Player functions

    const handleKeyboardInput = (event: KeyboardEvent): void => {
        if (playerState.isFocused && reactPlayer) {
            handleKeyCommands(
                reactPlayer,
                event,
                handlePlayPause,
                handleFullScreen,
                playerState,
                volumeStepSize,
                setPlayerState,
                seekStepSize,
                emitPlayWish
            );
        }
    };

    const getCurrentPosition = (): number | undefined => {
        if (reactPlayer) {
            return reactPlayer.getCurrentTime() / reactPlayer.getDuration();
        } else {
            return undefined;
        }
    };

    // Playback functions

    const emitPlayWish = (
        mediaItem: MediaItem,
        isPlaying: boolean,
        lastPositionItemId: string | null,
        requestLastPosition: boolean,
        newPosition?: number,
        noIssuer?: boolean,
        direction?: 'left' | 'right'
    ): void => {
        if (socket && party && user) {
            const playWish: PlayWish = {
                partyId: party.id,
                issuer: noIssuer ? 'system' : user.id,
                mediaItemId: mediaItem.id,
                type: mediaItem.type,
                isPlaying: isPlaying,
                position:
                    newPosition !== undefined
                        ? newPosition
                        : reactPlayer
                        ? reactPlayer.getCurrentTime() /
                          reactPlayer.getDuration()
                        : 0,
                lastPosition: lastPositionItemId
                    ? {
                          itemId: lastPositionItemId,
                          position:
                              reactPlayer &&
                              reactPlayer.getDuration() > 300 &&
                              !noIssuer
                                  ? reactPlayer.getCurrentTime() /
                                    reactPlayer.getDuration()
                                  : 0
                      }
                    : null,
                requestLastPosition: requestLastPosition,
                timestamp: Date.now()
            };

            if (direction) {
                playWish.direction = direction;
            }

            socket.emit('playWish', playWish);
        }
    };

    // Point currently playing item index to the right item in the playlist
    const updatePlaylistIndex = useCallback(
        (playlistItem: MediaItem): void => {
            if (party && party.items.length) {
                const index = party.items.findIndex(
                    (listItem: MediaItem) => listItem.id === playlistItem.id
                );

                setPlayerState({ playlistIndex: index });
            }
        },
        [party]
    );

    // Effects

    // Attach key event listener
    useEffect(() => {
        document.addEventListener('keydown', handleKeyboardInput);

        return (): void => {
            document.removeEventListener('keydown', handleKeyboardInput);
        };
    });

    // Attach Fullscreen detector to window

    const handleResize = (): void => {
        setWindowHeight(window.innerHeight);
    };

    useEffect(() => {
        window.addEventListener('resize', handleResize);
        window.addEventListener('fullscreenchange', handleResize);

        return (): void => {
            window.removeEventListener('resize', handleResize);
            window.removeEventListener('fullscreenchange', handleResize);
        };
    }, []);

    useEffect(() => {
        if (
            windowHeight > screen.height - 5 &&
            windowHeight < screen.height + 5
        ) {
            setPlayerState({ isFullScreen: true });
        } else {
            setPlayerState({ isFullScreen: false });
        }
    }, [windowHeight]);

    // Update playlist index if playingItem in global state changes
    useEffect(() => {
        if (playerState.playingItem) {
            updatePlaylistIndex(playerState.playingItem);
        }
    }, [playerState.playingItem, updatePlaylistIndex]);

    // Emit joinParty when everything is set up; subscribe to play orders; subscribe to syncStatus updates
    useEffect(() => {
        if (socket && party && user) {
            if (!joinedParty) {
                socket.emit('joinParty', {
                    userId: user.id,
                    partyId: party.id,
                    timestamp: Date.now()
                });

                setJoinedParty(true);
            }

            // Socket 1/3: PlayOrders

            socket.off('playOrder');
            socket.on('playOrder', (playOrder: PlayOrder) => {
                setPlayerState({ playOrder: playOrder });
                setHasLastPosition(false);

                const playOrderItem = party.items.find((item: MediaItem) => {
                    return item.id === playOrder.mediaItemId;
                });

                if (playOrderItem) {
                    // Set React Player source URL
                    let newSourceUrl;
                    if (playOrder.type === 'file') {
                        newSourceUrl =
                            '/api/file/' +
                            playOrder.mediaItemId +
                            '?party=' +
                            party.id;
                    } else {
                        newSourceUrl = playOrderItem.url;
                    }

                    // Action message
                    let actionMessageIcon = faClock; // Default case: seeking
                    if (
                        !playerStateRef.current.playingItem ||
                        (playerStateRef.current.playingItem &&
                            playOrder.mediaItemId !==
                                playerStateRef.current.playingItem.id)
                    ) {
                        actionMessageIcon = faExchangeAlt; // Media item change
                    } else if (
                        playOrder.isPlaying !== playerStateRef.current.isPlaying
                    ) {
                        if (playOrder.isPlaying === true) {
                            actionMessageIcon = faPlay; // Pause -> Play
                        } else if (playOrder.isPlaying === false) {
                            actionMessageIcon = faPause; // Play -> Pause
                        }
                    } else {
                        if (playOrder.direction) {
                            if (playOrder.direction === 'left') {
                                actionMessageIcon = faLongArrowAltLeft; // Seek left
                            } else if (playOrder.direction === 'right') {
                                actionMessageIcon = faLongArrowAltRight; // Seek right
                            }
                        }
                    }

                    // None found if issuer === 'system' -> No action message
                    const memberInParty = party.members.find(
                        (member: ClientPartyMember) =>
                            member.id === playOrder.issuer
                    );

                    if (memberInParty) {
                        const actionMessageContent = (
                            <ActionMessageContent
                                text={memberInParty.username}
                                icon={actionMessageIcon}
                            ></ActionMessageContent>
                        );

                        dispatch(
                            setGlobalState({
                                actionMessage: {
                                    text: actionMessageContent
                                }
                            })
                        );
                    }

                    setPlayerState({
                        playingItem: playOrderItem,
                        sourceUrl: newSourceUrl,
                        isSyncing: true
                    });

                    dispatch(
                        setGlobalState({
                            playingItem: playOrderItem
                        })
                    );

                    updatePlaylistIndex(playOrderItem);
                }
            });

            // Socket 2/3: Receive Sync status

            socket.off('syncStatus');
            socket.on('syncStatus', (syncStatus: SyncStatusIncomingMessage) => {
                const syncStatusStateNew = [] as SyncStatusReceiveMember[];
                const memberStatusStateNew: MemberStatus = {};

                Object.keys(syncStatus).forEach((memberId) => {
                    // 1. Set online status of each member
                    memberStatusStateNew[memberId] = {
                        online: false,
                        serverTimeOffset: syncStatus[memberId].serverTimeOffset,
                        webRtc: syncStatus[memberId].webRtc
                    };

                    if (
                        syncStatus[user.id] &&
                        syncStatus[memberId] &&
                        syncStatus[memberId].timestamp +
                            syncStatus[memberId].serverTimeOffset >
                            Date.now() +
                                syncStatus[user.id].serverTimeOffset -
                                syncStatusIntervalTolerance
                    ) {
                        memberStatusStateNew[memberId].online = true;
                    }

                    // 2. Calculate delay for every party member who's not us
                    if (syncStatus[user.id] && memberId !== user.id) {
                        const delta = calculateSyncDelta(
                            syncStatus,
                            playerStateRef,
                            user,
                            memberId
                        );

                        const memberInParty = party.members.find(
                            (member: ClientPartyMember) =>
                                member.id === memberId
                        );

                        if (memberInParty) {
                            syncStatusStateNew.push({
                                id: memberId,
                                delta: delta,
                                username: memberInParty.username
                            });
                        }
                    }
                });

                dispatch(
                    setGlobalState({
                        syncStatus: syncStatusStateNew,
                        memberStatus: memberStatusStateNew
                    })
                );
            });
        }

        return (): void => {
            clearAllTimeouts();
        };
    }, [socket, party, user, joinedParty, dispatch, updatePlaylistIndex]);

    // Sync procedure finish: Seek, isPlaying, start buffering state
    useEffect(() => {
        if (
            reactPlayer &&
            reactPlayer.getInternalPlayer() &&
            playerState.duration &&
            playerState.playOrder &&
            playerState.isSyncing &&
            playerState.playingItem
        ) {
            let offset = 0;

            if (freshlyJoined) {
                if (playerState.playOrder.isPlaying) {
                    offset =
                        (Date.now() +
                            initialServerTimeOffset -
                            playerState.playOrder.timestamp) /
                        (playerState.duration * 1000);
                }

                setFreshlyJoined(false);
            }

            if (playerState.playOrder.lastPosition) {
                setHasLastPosition(true);
            } else {
                setHasLastPosition(false);
            }

            reactPlayer.seekTo(playerState.playOrder.position + offset);

            const site = getSite(playerState.playingItem.url);

            setPlayerState({
                isSeeking: false,
                isPlaying: playerState.playOrder.isPlaying,
                isSyncing: false,
                isBuffering:
                    playerState.playOrder.isPlaying &&
                    playerState.playOrder.type === 'web' &&
                    (site === 'youtube' ||
                        site === 'facebook' ||
                        playerState.playingItem.type === 'file')
            });
        }
    }, [
        reactPlayer,
        playerState,
        initialServerTimeOffset,
        freshlyJoined,
        dispatch
    ]);

    // Socket 3/3: Emit syncStatus in intervals
    useInterval(() => {
        if (socket && user && party) {
            const syncStatus: SyncStatusOutgoingMessage = {
                partyId: party.id,
                userId: user.id,
                timestamp: Date.now(),
                position: reactPlayer
                    ? reactPlayer.getCurrentTime() / reactPlayer.getDuration()
                    : 0,
                isPlaying: playerStateRef.current.isPlaying,
                webRtc: webRtcGlobalState
            };

            socket.emit('syncStatus', syncStatus);
        }
    }, syncStatusIntervalDelay);

    // React Player Event handlers

    const handleDuration = (duration: number): void => {
        setPlayerState({ duration: duration });
    };

    const handleProgress = (reactPlayerState: ReactPlayerState): void => {
        if (!playerState.isSeeking) {
            dispatch(setGlobalState({ position: reactPlayerState.played }));
        }
    };

    const handleVolumeChange = (
        event: React.ChangeEvent<HTMLInputElement>
    ): void => {
        setPlayerState({
            volume: parseFloat(event.target.value)
        });
    };

    const handlePlayPause = (): void => {
        if (playerState.playingItem) {
            if (playerState.isPlaying) {
                emitPlayWish(
                    playerState.playingItem,
                    false,
                    playerState.playingItem.id,
                    false,
                    getCurrentPosition()
                );
            } else {
                emitPlayWish(
                    playerState.playingItem,
                    true,
                    null,
                    false,
                    getCurrentPosition()
                );
            }
        }
    };

    const handleSeekMouseDown = (): void => {
        setPlayerState({ isSeeking: true });
    };

    const handleSeekChange = (
        event: React.ChangeEvent<HTMLInputElement>
    ): void => {
        if (reactPlayer) {
            dispatch(
                setGlobalState({ position: parseFloat(event.target.value) })
            );
        }
    };

    const handleSeekMouseUp = (
        event: React.MouseEvent<HTMLInputElement, MouseEvent>
    ): void => {
        if (playerState.playingItem) {
            emitPlayWish(
                playerState.playingItem,
                playerState.isPlaying,
                null,
                false,
                parseFloat((event.target as HTMLInputElement).value)
            );
        }
    };

    const handleFullScreen = async (): Promise<void> => {
        if (!playerState.isFullScreen) {
            await screenfull.request();
        } else {
            await screenfull.exit();
        }
    };

    const handleReady = (reactPlayer: ReactPlayer): void => {
        setReactPlayer(reactPlayer);
    };

    const handleBufferEnd = (): void => {
        setPlayerState({ isBuffering: false });
    };

    const handleEnd = async (): Promise<void> => {
        if (party && playerState && socket) {
            // 1. Emit playWish for next item in playlist
            if (party.items.length > playerState.playlistIndex + 1) {
                emitPlayWish(
                    party.items[playerState.playlistIndex + 1],
                    playerState.isPlaying,
                    playerState.playingItem ? playerState.playingItem.id : null,
                    true,
                    0,
                    true
                );
            } else {
                emitPlayWish(
                    party.items[0],
                    false,
                    playerState.playingItem ? playerState.playingItem.id : null,
                    true,
                    0,
                    true
                );

                setPlayerState({
                    isPlaying: false
                });
            }

            // 2. Update party meta data: Mark item as played && emit party update order
            if (playerState.playingItem) {
                try {
                    const response = await Axios.put(
                        '/api/partyMetadata',
                        {
                            partyId: party.id,
                            metadata: {
                                ...party.metadata,
                                played: {
                                    ...party.metadata.played,
                                    [playerState.playingItem.id]: true
                                }
                            }
                        },
                        axiosConfig()
                    );

                    if (response.data.success) {
                        socket.emit('partyUpdate', { partyId: party.id });
                    } else {
                        dispatch(
                            setGlobalState({
                                errorMessage: t(
                                    `apiResponseMessages.${response.data.msg}`
                                )
                            })
                        );
                    }
                } catch (error) {
                    dispatch(
                        setGlobalState({
                            errorMessage: t('errors.metadataUpdateError')
                        })
                    );
                }
            }
        }
    };

    // UI Event handlers

    // UI movement detection
    const setUiVisible = useCallback(
        (visible: boolean): void => {
            dispatch(setGlobalState({ uiVisible: visible }));
        },
        [dispatch]
    );

    // Prevent UI from hiding when mouse moves
    const handleMouseMovementOverUi = (): void => {
        if (
            Date.now() >
            playerTimeoutStateRef.current.uiTimeoutTimestamp +
                uiTimeoutIntervalResolution
        ) {
            setUiVisible(true);

            if (playerTimeoutStateRef.current.uiTimeoutId) {
                clearTimeout(playerTimeoutStateRef.current.uiTimeoutId);
            }

            setPlayerTimeoutState({
                uiTimeoutId: setTimeout(() => {
                    setUiVisible(false);
                }, playerTimeoutStateRef.current.uiTimeoutDelay),
                uiTimeoutTimestamp: Date.now()
            });
        }
    };

    // Prevent UI from hiding on certain actions in subcomponents
    const freezeUiVisible = useCallback(
        (freeze: boolean): void => {
            const currentDelay = freeze
                ? uiTimeoutLongDelay
                : uiTimeoutShortDelay;

            if (playerTimeoutStateRef.current.uiTimeoutId) {
                clearTimeout(playerTimeoutStateRef.current.uiTimeoutId);
            }

            const newTimeoutId = setTimeout(() => {
                setUiVisible(false);
            }, currentDelay);

            setPlayerTimeoutState({
                uiTimeoutId: newTimeoutId,
                uiTimeoutDelay: currentDelay,
                uiTimeoutTimestamp: Date.now()
            });
        },
        [setUiVisible]
    );

    return (
        <div
            onMouseMove={(): void => {
                handleMouseMovementOverUi();
            }}
            className={'bg-transparent' + (uiVisible ? '' : ' noCursor')}
        >
            <div
                onMouseDown={handlePlayPause}
                className={
                    'flex w-full h-full reactPlayer bg-transparent' +
                    (webRtcGlobalState.isFullscreen ? ' z-40' : '')
                }
            >
                <MediaPlayerOverlay
                    playerState={playerState}
                    playerTimeoutState={playerTimeoutState}
                    setPlayerTimeoutState={(
                        playerTimeoutState: PlayerTimeoutStateActionProperties
                    ): void => setPlayerTimeoutState(playerTimeoutState)}
                    actionMessageDelay={actionMessageDelay}
                ></MediaPlayerOverlay>
                <div className="flex w-full h-full pointer-events-none">
                    <ReactPlayer
                        config={{
                            youtube: { playerVars: { disablekb: 1 } }
                        }}
                        url={playerState.sourceUrl}
                        playing={playerState.isPlaying}
                        playsinline={true}
                        volume={playerState.volume}
                        progressInterval={100}
                        onBufferEnd={handleBufferEnd}
                        onDuration={handleDuration}
                        onProgress={handleProgress}
                        onReady={handleReady}
                        onEnded={handleEnd}
                        width="100%"
                        height="100%"
                    ></ReactPlayer>
                </div>
            </div>
            {party && user && (
                <CommunicationContainer
                    socket={socket}
                    partyId={party.id}
                    webRtcIds={party.settings.webRtcIds}
                    ourUserId={user.id}
                    setPlayerState={setPlayerState}
                    uiVisible={uiVisible}
                    freezeUiVisible={freezeUiVisible}
                    handlePlayPause={handlePlayPause}
                ></CommunicationContainer>
            )}
            <MediaMenu
                socket={socket}
                playerState={playerState}
                isPlaying={playerState.isPlaying}
                emitPlayWish={emitPlayWish}
                setPlayerFocused={(focused: boolean): void =>
                    setPlayerState({ isFocused: focused })
                }
                freezeUiVisible={freezeUiVisible}
            ></MediaMenu>
            <BottomBar
                playerState={playerState}
                handlePlayPause={handlePlayPause}
                handleSeekMouseDown={handleSeekMouseDown}
                handleSeekChange={handleSeekChange}
                handleSeekMouseUp={handleSeekMouseUp}
                handleVolumeChange={handleVolumeChange}
                handleFullScreen={handleFullScreen}
            ></BottomBar>
            <TopBar socket={socket}></TopBar>
            <AlertContainer
                playerState={playerState}
                emitPlayWish={emitPlayWish}
                hasLastPosition={hasLastPosition}
                setHasLastPosition={setHasLastPosition}
            ></AlertContainer>
        </div>
    );
}