react-bootstrap#Container TypeScript Examples

The following examples show how to use react-bootstrap#Container. 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: CreatorStudioView.tsx    From 3Speak-app with GNU General Public License v3.0 6 votes vote down vote up
export function CreatorStudioView() {
  useEffect(() => {
    document.title = '3Speak - Tokenised video communities'
  }, [])
  return (
    <Container fluid>
      <Row>
        <webview
          id="foo"
          src="https://studio.3speak.tv"
          style={{ width: '100%', height: '600px' }}
        ></webview>
      </Row>
    </Container>
  )
}
Example #2
Source File: GroupMembersGrid.tsx    From rcsb-saguaro-app with MIT License 6 votes vote down vote up
render():JSX.Element {
        if(this.state.itemList.length >0){
            return (
                    <Container fluid={"md"}>
                        {
                            Array(this.props.nRows).fill(null).map((none,i)=>(
                                <Row>
                                    {
                                        Array(this.props.nColumns).fill(null).map((none,j)=>{
                                            const ei: ItemFeaturesInterface = this.state.itemList[i*this.props.nColumns+j];
                                            if(ei)
                                                return (
                                                    <Col className={"p-0"}>
                                                        <GroupMemberItem item={ei} groupProvenanceId={this.props.groupProvenanceId}/>
                                                    </Col>
                                                );
                                            else
                                                return null;
                                        })

                                    }
                                </Row>)
                            )
                        }
                    </Container>
            );
        }else
            return null;
    }
Example #3
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 6 votes vote down vote up
Section: React.FC<{ fullWidth: boolean; className?: string }> = props => {
  const { fullWidth, className, children } = props;
  return (
    <div className={`${classes.container} ${className}`}>
      <Container fluid={fullWidth ? true : 'lg'}>
        <Row className="align-items-center">{children}</Row>
      </Container>
    </div>
  );
}
Example #4
Source File: UploadTypeChoiceModal.tsx    From bada-frame with GNU General Public License v3.0 6 votes vote down vote up
function UploadTypeRow({ uploadFunc, Icon, uploadName }) {
    return (
        <Row className="justify-content-sm-center py-2">
            <Button
                variant="light"
                onClick={uploadFunc}
                style={{ width: '90%', height: '50px' }}>
                <Container>
                    <Row>
                        <div>
                            <Icon />
                            <b className="ml-2">{uploadName}</b>
                        </div>
                        <div className="ml-auto d-flex align-items-center">
                            <IoIosArrowForward />
                        </div>
                    </Row>
                </Container>
            </Button>
        </Row>
    );
}
Example #5
Source File: TestimoniesTable.tsx    From advocacy-maps with MIT License 6 votes vote down vote up
TestimoniesTable = (
  props: UsePublishedTestimonyListing & { search?: boolean }
) => {
  const { pagination, items, setFilter } = props
  const testimonies = items.result ?? []
  return (
    <Container>
      {props.search && <TestimonySearch setFilter={setFilter} />}
      <Table responsive striped bordered hover>
        <thead>
          <tr>
            <th>Bill</th>
            <th>Position</th>
            <th>
              Submitter
              <QuestionTooltip text="Submitters without links have chosen to make their profile private." />
            </th>
            <th>Date Submitted</th>
            <th>Text</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {testimonies.map((testimony, index) => (
            <TestimonyRow key={index} testimony={testimony} />
          ))}
        </tbody>
      </Table>
      <PaginationButtons pagination={pagination} />
    </Container>
  )
}
Example #6
Source File: App.tsx    From apps with MIT License 6 votes vote down vote up
render() {
        return (
            <div>
                <Navigation />
                <Container fluid>
                    <BattleSetup />
                    <PlayerActorConfigModal />
                    <EnemyActorConfigModal />
                    <BattleDisplay />
                </Container>
            </div>
        );
    }
Example #7
Source File: Dropzone.tsx    From devex with GNU General Public License v3.0 6 votes vote down vote up
Dropzone: React.FC<IProps> = ({ dropCb, fromJson }) => {

  const onDrop = useCallback((acceptedFiles: Blob[]) => {
    acceptedFiles.forEach((file: Blob) => {
      const reader = new FileReader()

      reader.onload = () => {
        const parsedFile = JSON.parse(reader.result as string)
        dropCb(fromJson(parsedFile))
      }
      reader.readAsText(file)
    })
  }, [dropCb, fromJson])

  const { getRootProps, getInputProps } = useDropzone({ accept: 'application/json', onDrop })

  return (
    <Container>
      <div {...getRootProps({ className: 'dropzone' })}>
        <input {...getInputProps()} />
        <span className='dropzone-prompt'>Drag and drop or click to load file</span>
      </div>
    </Container>
  )
}
Example #8
Source File: TelegramSection.tsx    From website with MIT License 6 votes vote down vote up
TelegramSection = () => {
    var theme = useTheme();
    const locale = LocalizationService.strings();

    const buttonStyle = { maxWidth: 300, height: 40, borderRadius: 3, boxShadow: theme.effects.elevation8 };
    const buttonIconProps: IIconProps = { iconName: 'ChevronRightSmall', styles: { root: { fontSize: 12 } } };

    return (
        <div className="pb-4 pt-4" style={{ backgroundColor: theme.palette.themePrimary }}>
            <Container>
                <Row>
                    <Col lg={10} className="mb-2 center-mobile">
                        <div><Text variant="xLarge" styles={semibold} style={{color:theme.palette.white}}>{locale?.homepage.telegramText}</Text></div>
                    </Col>
                
                    <Col lg={2} className="text-right center-mobile">
                        <DefaultButton href="https://youtu.be/kgNxRZghkkA?t=133" text={locale?.homepage.telegramButton} iconProps={buttonIconProps} className="text-decoration-none" allowDisabledFocus style={buttonStyle} />
                    </Col>
                </Row>
            </Container>
        </div>
    )
}
Example #9
Source File: CommunitiesView.tsx    From 3Speak-app with GNU General Public License v3.0 6 votes vote down vote up
export function CommunitiesView() {
  const [data, setData] = useState([])

  const generate = async () => {
    const res = await client.call('bridge', 'list_communities', {
      last: '',
      limit: 100,
    })
    setData(res)
  }
  useEffect(() => {
    document.title = '3Speak - Tokenised video communities'
    generate()
  }, [])
  return (
    <Container fluid>
      <Row>
        <div className="col-12">
          <h3 style={{ display: 'inline-block' }}>Communities</h3>
          <span className="float-right mb-3">
            <Button id="communityCreate" variant="primary" disabled>
              Create +
            </Button>
          </span>
        </div>
      </Row>
      <Row>
        {data.map((value) => (
          <CommunityTile key={value.name} reflink={`hive:${value.name}`} info={value} />
        ))}
      </Row>
    </Container>
  )
}
Example #10
Source File: LoadingSpinner.tsx    From website with MIT License 6 votes vote down vote up
LoadingSpinner = (props: Props) => {
    var theme = useTheme();
    const locale = LocalizationService.strings();
    const [showError, setShowError] = React.useState<boolean>(false);
    
    const updateError = React.useCallback(() => {
        setShowError(props.error);
    }, [setShowError, props.error]);

    React.useEffect(() => {
        updateError();
    }, [updateError]);

    const messageBarStyles = { backgroundColor: 'rgb(253, 231, 233)', color: theme.palette.redDark, padding: 20 };

    const ErrorExample = (p: IExampleProps) => (
        <div style={messageBarStyles} className="text-center">
            <Text variant="medium" styles={semibold} style={{ color: theme.palette.redDark }}>
                <Icon iconName="ErrorBadge" style={{ fontSize: 12, marginRight: 10 }} />
                {locale?.errorOccured}
            </Text>
            <div style={{ marginLeft: 'auto', marginRight: 'auto' }}>
                <Image id="not-found" src={process.env.PUBLIC_URL + '/images/message/error.png'} style={{ display: 'inline', width: '35%', marginBottom: 5 }} />
            </div>
            <JsxParser bindings={{ theme: theme, semibold: semibold }} components={{ Text, Link, Icon }} jsx={locale?.errorContactAdmin} />
        </div>
    );

    return (
        <>
            { props.error ? <Container style={{ display: showError ? 'block' : 'none', marginLeft: 'auto', marginRight: 'auto', maxWidth: 400 }}><ErrorExample /></Container> :
                props.loading ? 
                <Container>
                    <Spinner label={locale?.loading} ariaLive="assertive" labelPosition="right" size={SpinnerSize.large} theme={theme} />
                </Container> : <></>
            }
        </>
    )
}
Example #11
Source File: NetworksPage.tsx    From devex with GNU General Public License v3.0 5 votes vote down vote up
NetworksPage: React.FC = () => {

  const userPrefContext = useContext(UserPrefContext)
  const { networkMap, setNetworkMap } = userPrefContext!
  const [show, setShow] = useState(false)

  const handleCloseModal = () => setShow(false)
  const handleShowModal = () => setShow(true)

  const addNetwork = (networkUrl: string, networkName: string) => {
    const temp = new Map(networkMap)
    temp.set(networkUrl, networkName)
    setNetworkMap(temp)
    handleCloseModal()
  }

  return (
    <>
      <NetworkModal show={show} handleCloseModal={handleCloseModal} cb={addNetwork} />
      <Container>
        <Row className='m-0'>
          <h4>
            Networks
          </h4>
        </Row>
        <Row className='m-0 pb-3'>
          <span className='subtext'>
            Network data is stored in your browser&apos;s local storage.
            Default network is highlighted in green.
            <br />
            Use the network selector in the top-right to toggle between different networks.
            </span>
        </Row>
        <Row className='m-0 pb-3'>
          <Button className='mr-3' onClick={handleShowModal}>Add Network</Button>
          <Button className='mr-3' onClick={() => setNetworkMap(new Map())}>Clear Networks</Button>
          <Button className='mr-auto' onClick={() => setNetworkMap(defaultNetworks)}>Reset to default</Button>
          <ImportExport
            type='networks'
            map={networkMap}
            setMapCb={setNetworkMap}
            fromJson={(json: any) => new Map(json.networks.map((x: { [url: string]: string }) => Object.entries(x)[0]))}
            toJson={(map: NetworkMap) => ({ networks: Array.from(map).map(([k, v]) => ({ [k]: v })) })} />
        </Row>
        <Row>
          <NetworksList />
        </Row>
      </Container>
    </>
  )
}
Example #12
Source File: AdminsList.tsx    From website with MIT License 5 votes vote down vote up
AdminsList = (props: Props) => {
    var theme = useTheme();
    const locale = LocalizationService.strings();
    let [admins, setAdmins] = React.useState<Admin[]>([]); // Amministratori
    const [loadingAdmins, setLoadingAdmins] = React.useState<boolean>(false);
    const [errorLoadingAdmins, setErrorLoadingAdmins] = React.useState<boolean>(false);

    /* Admins callBack */
    const updateAdmins = React.useCallback(async () => {
        if (props.degree?.slug === '' || props.degree?.slug === undefined) return;
        setErrorLoadingAdmins(false);
        setLoadingAdmins(true);
        let adminsResult = await getDegreeAdmins(props.degree?.slug);

        if (adminsResult.status !== 200) {
            setLoadingAdmins(false);
            setErrorLoadingAdmins(true);
            return;
        }

        setLoadingAdmins(false);
        setAdmins(adminsResult.value ?? []);
    }, [props.degree?.slug]);


    React.useEffect(() => {
        updateAdmins();
    }, [props.degree, updateAdmins]);

    return (
        <div className="mb-2">
            <div className="pb-2 pt-2 mb-4" style={{ backgroundColor: theme.palette.neutralLight }}>
                <Container>
                    <div><Text variant="medium" styles={semibold}><Icon iconName="WorkforceManagement" /> {locale?.groups.availableAdmins}</Text></div>
                </Container>
            </div>

            {
                loadingAdmins || errorLoadingAdmins ? <LoadingSpinner loading={loadingAdmins} error={errorLoadingAdmins} />
                    : admins.length === 0 ?
                        <div className="justify-content-center">
                            <Message text={locale?.groups.adminsNotFound!} />
                        </div> : <></>
            }

            {admins.length !== 0 && !errorLoadingAdmins && !loadingAdmins ?
                <Container>
                    <Row className="admin-list" style={{ justifyContent: admins?.length === 0 ? 'center' : ""}}>
                        {admins?.length !== 0 ? admins?.map((x,i) =>
                            <Col key={i} xl={3} lg={3} md={4} sm={6} xs={12} className="mb-3 col-persona">
                                {(() => {
                                    var imageUrl = `https://studentiunimi-groups-propics.marcoaceti.workers.dev/${x.id}.png`;
                                    return <Persona imageUrl={imageUrl} onRenderPrimaryText={() => (<><Icon iconName="Send" style={{ color: theme.palette.themePrimary }}/>&nbsp;<Link href={`https://t.me/${x.username}`}>{`${x.first_name ?? ""} ${x.last_name ?? ""}`}</Link></>)} text={`@${x.first_name ?? ""} ${x.last_name ?? ""}`} secondaryText={`@${x.username}`} size={PersonaSize.size40} />
                                })()}
                            </Col>
                        ) : <Message text={locale?.groups.adminsNotFound!} />
                        }
                    </Row>
                </Container> : <></>
            }
        </div>
    )
}
Example #13
Source File: my-created-projects.tsx    From microsoft-teams-apps-growyourskills with MIT License 5 votes vote down vote up
/**
    *Get wrapper for page which acts as container for all child components
    */
    private getWrapperPage = () => {
        if (this.state.loader) {
            return (
                <div className="container-div">
                    <div className="container-subdiv">
                        <div className="loader">
                            <Loader />
                        </div>
                    </div>
                </div>
            );
        } else {

            // Cards component array to be rendered in grid.
            const cards = new Array<any>();

            this.state.projectDetails!.map((value: IProjectDetails, index) => {
                if (!value.isRemoved) {
                    cards.push(<Col lg={3} sm={6} md={4} className="grid-column d-flex justify-content-center">
                        <Card loggedInUserId={this.loggedInUserObjectId} projectDetails={this.state.projectDetails} onJoinMenuItemClick={this.onProjectJoin} onCloseProjectButtonClick={this.handleCloseProjectButtonClick} onLeaveButtonClick={this.handleDeleteButtonClick} showLeaveProjects={false} showJoinProjectMenu={false} index={index} cardDetails={value} onCardUpdate={this.onCardUpdate} onDeleteButtonClick={this.handleDeleteButtonClick} />
                    </Col>)
                }
            });

            let scrollViewStyle = { height: this.state.isFilterApplied === true ? "84vh" : "92vh" };
            return (
                <div className="container-div">
                    <div className="container-subdiv-cardview">
                        <Container fluid className="container-fluid-overriden">
                            <NotificationMessage
                                onClose={this.hideAlert}
                                showAlert={this.state.showAlert}
                                content={this.state.alertMessage}
                                notificationType={this.state.alertprojectStatus}
                            />
                            <div key={this.state.infiniteScrollParentKey} className="scroll-view scroll-view-mobile" style={scrollViewStyle}>
                                <InfiniteScroll
                                    pageStart={this.state.pageLoadStart}
                                    loadMore={this.loadMoreProjects}
                                    hasMore={this.state.hasMoreProjects && !this.filterSearchText.trim().length}
                                    initialLoad={this.state.isPageInitialLoad}
                                    useWindow={false}
                                    loader={<div className="loader"><Loader /></div>}>

                                    <Row>
                                        {
                                            cards.length ? cards : this.state.hasMoreProjects === true ? <></> : <FilterNoPostContentPage />
                                        }
                                    </Row>

                                </InfiniteScroll>
                            </div>

                        </Container>
                    </div>
                </div>
            );
        }
    }
Example #14
Source File: landing-page.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 5 votes vote down vote up
LandingPage = (props: any) => {

    const context = React.useContext(AppContext);
    const { t } = useTranslation();

    const { keycloak } = useKeycloak();

    const [isInit, setIsInit] = React.useState(false)
    const [storedLandingDisclaimerShow, setStoredLandingDisclaimerShow] = useLocalStorage('landingDisclaimerShow', true);

    React.useEffect(() => {
        if (context) {
            setIsInit(true);
        }
    }, [context])

    return (!(isInit && context && context.navigation) ? <CwaSpinner /> :
        <Fade appear={true} in={true} >
            <Container className='center-content'>

                <h1 className='mx-auto mb-5 d-flex'>
                    {t('translation:welcome')}
                    {utils.hasRole(keycloak, 'c19_quick_test_admin')
                        ? <DisclamerButton
                            firstTimeShow={props.disclaimerShow}
                            checked={!storedLandingDisclaimerShow}
                            onInit={() => { props.setDisclaimerShow(false) }}
                            onCheckChange={(checked: boolean) => { setStoredLandingDisclaimerShow(!checked) }}
                            disclaimerText={
                                <>
                                    {t('translation:disclaimer-text1-part1')}
                                    <a
                                        href={t('translation:disclaimer-link')}
                                        target='blank'
                                    >
                                        {t('translation:disclaimer-link')}
                                    </a>
                                    {t('translation:disclaimer-text1-part2')}
                                </>
                            }
                        />
                        : <></>
                    }
                </h1>

                {utils.hasRole(keycloak, 'c19_quick_test_counter')
                    ? <Button block className='landing-btn' onClick={context.navigation.toRecordPatient}>{t('translation:record-patient-data')}</Button>
                    : <></>
                }
                {utils.hasRole(keycloak, 'c19_quick_test_lab')
                    ? <Button block className='landing-btn' onClick={context.navigation.toRecordTestResult}>{t('translation:record-result')}</Button>
                    : <></>}
                {utils.hasRole(keycloak, 'c19_quick_test_counter')
                    ? <Button block className='landing-btn' onClick={context.navigation.toQRScan}>{t('translation:record-qr-scan')}</Button>
                    : <></>}
                {utils.hasRole(keycloak, 'c19_quick_test_lab')
                    ? <>
                        <Button block className='landing-btn' onClick={context.navigation.toReports}>{t('translation:failed-report')}</Button>
                        <Button block className='landing-btn' onClick={context.navigation.toStatistics}>{t('translation:statistics-menu-item')}</Button>
                    </>
                    : <></>}
                {utils.hasRole(keycloak, 'c19_quick_test_admin')
                    ? <Button block className='landing-btn' onClick={context.navigation.toUserManagement}>{t('translation:user-management')}</Button>
                    : <></>}
            </Container>
        </Fade >
    )
}
Example #15
Source File: my-joined-projects.tsx    From microsoft-teams-apps-growyourskills with MIT License 5 votes vote down vote up
/**
    *Get wrapper for page which acts as container for all child components
    */
    private getWrapperPage = () => {
        // Cards component array to be rendered in grid.
        const cards = new Array<any>();

        this.state.projectDetails!.map((value: IProjectDetails, index) => {
            if (!value.isRemoved) {
                cards.push(<Col lg={3} sm={6} md={4} className="grid-column d-flex justify-content-center">
                    <Card loggedInUserId={this.loggedInUserObjectId} projectDetails={this.state.projectDetails} onJoinMenuItemClick={this.onProjectJoin} onCloseProjectButtonClick={this.handleCloseProjectButtonClick} onLeaveButtonClick={this.handleLeaveButtonClick} showLeaveProjects={true} showJoinProjectMenu={false} index={index} cardDetails={value} onCardUpdate={this.onCardUpdate} onDeleteButtonClick={this.handleDeleteButtonClick} />
                </Col>)
            }
        });

        let scrollViewStyle = { height: this.state.isFilterApplied === true ? "84vh" : "92vh" };
        return (
            <div className="container-subdiv">
                <div className="container-subdiv-cardview">
                    <Container fluid className="container-fluid-overriden">
                        <NotificationMessage
                            onClose={this.hideAlert}
                            showAlert={this.state.showAlert}
                            content={this.state.alertMessage}
                            notificationType={this.state.alertprojectStatus}
                        />
                        <div key={this.state.infiniteScrollParentKey} className="scroll-view scroll-view-mobile" style={scrollViewStyle}>
                            <InfiniteScroll
                                pageStart={this.state.pageLoadStart}
                                loadMore={this.loadMoreProjects}
                                hasMore={this.state.hasMoreProjects}
                                initialLoad={this.state.isPageInitialLoad}
                                useWindow={false}
                                loader={<div className="loader"><Loader /></div>}>

                                <Row>
                                    {
                                        cards.length ? cards : this.state.hasMoreProjects ? <></> : <FilterNoPostContentPage />
                                    }
                                </Row>

                            </InfiniteScroll>
                        </div>
                    </Container>
                </div>
            </div>
        );
    }
Example #16
Source File: UploadTypeChoiceModal.tsx    From bada-frame with GNU General Public License v3.0 5 votes vote down vote up
export default function UploadTypeChoiceModal({
    onHide,
    show,
    uploadFiles,
    uploadFolders,
    uploadGoogleTakeoutZips,
}) {
    return (
        <Modal
            show={show}
            aria-labelledby="contained-modal-title-vcenter"
            centered
            dialogClassName="file-type-choice-modal">
            <Modal.Header
                onHide={onHide}
                style={{
                    borderBottom: 'none',
                    height: '4em',
                }}>
                <Modal.Title
                    id="contained-modal-title-vcenter"
                    style={{
                        fontSize: '1.8em',
                        marginLeft: '5%',
                        color: 'white',
                    }}>
                    <b>{constants.CHOOSE_UPLOAD_TYPE}</b>
                </Modal.Title>
                <IoMdClose
                    size={30}
                    onClick={onHide}
                    style={{ cursor: 'pointer' }}
                />
            </Modal.Header>
            <Modal.Body>
                <Container>
                    <UploadTypeRow
                        uploadFunc={uploadFiles}
                        Icon={FileUploadIcon}
                        uploadName={constants.UPLOAD_FILES}
                    />
                    <UploadTypeRow
                        uploadFunc={uploadFolders}
                        Icon={FolderUploadIcon}
                        uploadName={constants.UPLOAD_DIRS}
                    />
                    <UploadTypeRow
                        uploadFunc={uploadGoogleTakeoutZips}
                        Icon={GoogleIcon}
                        uploadName={constants.UPLOAD_GOOGLE_TAKEOUT}
                    />
                </Container>
            </Modal.Body>
        </Modal>
    );
}
Example #17
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 5 votes vote down vote up
Auction: React.FC<AuctionProps> = props => {
  const { auction: currentAuction } = props;

  const history = useHistory();
  const dispatch = useAppDispatch();
  let stateBgColor = useAppSelector(state => state.application.stateBackgroundColor);
  const lastNounId = useAppSelector(state => state.onDisplayAuction.lastAuctionNounId);

  const loadedNounHandler = (seed: INounSeed) => {
    dispatch(setStateBackgroundColor(seed.background === 0 ? grey : beige));
  };

  const prevAuctionHandler = () => {
    dispatch(setPrevOnDisplayAuctionNounId());
    currentAuction && history.push(`/noun/${currentAuction.nounId.toNumber() - 1}`);
  };
  const nextAuctionHandler = () => {
    dispatch(setNextOnDisplayAuctionNounId());
    currentAuction && history.push(`/noun/${currentAuction.nounId.toNumber() + 1}`);
  };

  const nounContent = currentAuction && (
    <div className={classes.nounWrapper}>
      <StandaloneNounWithSeed
        nounId={currentAuction.nounId}
        onLoadSeed={loadedNounHandler}
        shouldLinkToProfile={false}
      />
    </div>
  );

  const loadingNoun = (
    <div className={classes.nounWrapper}>
      <LoadingNoun />
    </div>
  );

  const currentAuctionActivityContent = currentAuction && lastNounId && (
    <AuctionActivity
      auction={currentAuction}
      isFirstAuction={currentAuction.nounId.eq(0)}
      isLastAuction={currentAuction.nounId.eq(lastNounId)}
      onPrevAuctionClick={prevAuctionHandler}
      onNextAuctionClick={nextAuctionHandler}
      displayGraphDepComps={true}
    />
  );
  const nounderNounContent = currentAuction && lastNounId && (
    <NounderNounContent
      mintTimestamp={currentAuction.startTime}
      nounId={currentAuction.nounId}
      isFirstAuction={currentAuction.nounId.eq(0)}
      isLastAuction={currentAuction.nounId.eq(lastNounId)}
      onPrevAuctionClick={prevAuctionHandler}
      onNextAuctionClick={nextAuctionHandler}
    />
  );

  return (
    <div style={{ backgroundColor: stateBgColor }} className={classes.wrapper}>
      <Container fluid="xl">
        <Row>
          <Col lg={{ span: 6 }} className={classes.nounContentCol}>
            {currentAuction ? nounContent : loadingNoun}
          </Col>
          <Col lg={{ span: 6 }} className={classes.auctionActivityCol}>
            {currentAuction &&
              (isNounderNoun(currentAuction.nounId)
                ? nounderNounContent
                : currentAuctionActivityContent)}
          </Col>
        </Row>
      </Container>
    </div>
  );
}
Example #18
Source File: more-menu-content.tsx    From microsoft-teams-apps-growyourskills with MIT License 5 votes vote down vote up
/**
	* Renders the component
	*/
    public render(): JSX.Element {
        let className = this.state.theme === Resources.dark ? "dark-menu-items-wrapper" : this.state.theme === Resources.contrast ? "contrast-menu-items-wrapper" : "default-menu-items-wrapper";
        return (
            <Provider>
                {
                    this.props.showLeaveProjects ?
                        <Container fluid className="popup-menu-content-wrapper">
                            <Dialog
                                className="dialog-container-discover-posts"
                                cancelButton={this.localize("cancel")}
                                confirmButton={this.localize("Confirm")}
                                content={this.localize("leaveConfirmBodyText")}
                                header={this.localize("leaveConfirmTitleText")}
                                trigger={<Flex vAlign="center" className={className}><LeaveIcon outline /> <Text className="popup-menu-item-text" content={this.localize("leaveProject")} /></Flex>}
                                onConfirm={() => this.props.onMenuItemClick(4)}
                            />
                        </Container>
                        :
                        <Container fluid className="popup-menu-content-wrapper">
                            {
                                this.props.showJoinProjectMenu &&
                                    !this.props.cardDetails.isCurrentUserProject &&
                                    (this.props.cardDetails.status === 2 || this.props.cardDetails.status === 1)
                                    ?
                                    <JoinProjectDialog
                                        index={1}
                                        cardDetails={this.props.cardDetails}
                                        onSubmit={this.props.onJoinMenuItemClick}
                                        onCancel={this.props.onCancel}
                                    /> : <></>
                            }
                            {this.props.cardDetails.isCurrentUserProject && <>
                                {
                                    this.props.cardDetails.status === 2
                                        ?
                                        <>
                                            <CloseProjectDialog cardDetails={this.props.cardDetails} onCloseProjectButtonClick={this.props.onCloseProjectButtonClick} />
                                            <Divider /> 
                                        </>
                                        :
                                        <></>
                                }
                                <Dialog
                                    className="dialog-container-discover-posts"
                                    cancelButton={this.localize("cancel")}
                                    confirmButton={this.localize("Confirm")}
                                    content={this.localize("deleteConfirmBodyText")}
                                    header={this.localize("deleteConfirmTitleText")}
                                    trigger={<Flex vAlign="center" className={className}><TrashCanIcon outline /> <Text className="popup-menu-item-text" content={this.localize("delete")} /></Flex>}
                                    onConfirm={() => this.props.onMenuItemClick(3)}
                                /></>}
                        </Container>
                }
            </Provider>
        );
    }
Example #19
Source File: LeaderboardView.tsx    From 3Speak-app with GNU General Public License v3.0 5 votes vote down vote up
export function LeaderboardView() {
  const [first, setFirst] = useState<any>()
  const [second, setSecond] = useState<any>()
  const [third, setThird] = useState<any>()
  const [bronze, setBronze] = useState<any[]>([])

  useEffect(() => {
    document.title = '3Speak - Tokenised video communities'
    void load()

    async function load() {
      const data = (await axios.get('https://3speak.tv/apiv2/leaderboard')).data
      let step = 1
      for (const ex of data) {
        if (step >= 30) {
          break
        }
        if (step === 1) {
          setFirst(ex)
        } else if (step === 2) {
          setSecond(ex)
        } else if (step === 3) {
          setThird(ex)
        } else {
          setBronze([...bronze, ex])
        }
        step++
      }
    }
  }, [])

  useEffect(() => {
    console.log(`first is now `, first)
  }, [first])

  return (
    <div>
      <div className="header_sec">
        <Container fluid className="header_sec">
          <div className="row">
            <div className="col-lg-6 col-md-6 col-xs-12 header_dist1">
              <h1 className="white_col">Content Creator Leaderboard</h1>
            </div>
          </div>
        </Container>
      </div>
      <section className="content_home">
        <Container fluid>
          <Row className="justify-content-md-center">
            <div className="col-xl-8 col-sm-8 col-12 mb-3">
              {first && <LeaderTile info={first} reflink={`hive:${first.username}`} />}
            </div>
          </Row>
          <Row className="justify-content-md-center">
            <div className="col-xl-5 col-sm-8 col-12 mb-3">
              {second ? <LeaderTile info={second} reflink={`hive:${second.username}`} /> : null}
            </div>
            <div className="col-xl-5 col-sm-8 col-12 mb-3">
              {third ? <LeaderTile info={third} reflink={`hive:${third.username}`} /> : null}
            </div>
            <Row>
              {bronze.map((value) => (
                <div key={value.username} className="col-xl-2 col-sm-4 mb-3">
                  <LeaderTile info={value} reflink={`hive:${value.username}`} />
                </div>
              ))}
            </Row>
          </Row>
        </Container>
      </section>
    </div>
  )
}
Example #20
Source File: DegreeInformations.tsx    From website with MIT License 5 votes vote down vote up
DegreeInformations= (props: Props) => {
    const theme = useTheme();
    const locale = LocalizationService.strings();
    var language: string | undefined = LocalizationService.getLanguage();
    const iconProps: any = { fontSize: '24px' };

    const degreeInformations: any[] = getDegreeInformations(props.degree?.slug!);
    /* Workaround to not show selected choicegroup */
    const [selectedChoiceGroup, setSelectedChoiceGroup] = React.useState<string>("");
    const selectionChanged = (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, option?: IChoiceGroupOption): void => { setSelectedChoiceGroup(""); }
     
    const options: IChoiceGroupOption[] = [];

    const itemSize = 100;
    const choiceGroupOptionsStyle: IChoiceGroupOptionStyles = {
        choiceFieldWrapper: {
            width: itemSize + "px",
            height: itemSize + "px"
        },
        labelWrapper: {
            maxWidth: itemSize / (3 / 4) + "px",
            height: "auto",
        },
        field: {
            height: "100%",
            padding: "0px"
        }
    };

    degreeInformations?.map((x) => {
        return options.push({ 
            key: x.name![language!], 
            text: x.name![language!], 
            styles: choiceGroupOptionsStyle, 
            iconProps: { iconName: x.icon!, className: iconProps, color: theme.palette.themePrimary }, 
            onClick: () => {redirectToLink(x.link!)} 
        });
    });

    return (   
        <div className='degree-informations mb-4'>
            <div className="pb-2 pt-2 mb-4" style={{ backgroundColor: theme.palette.neutralLight }}>
                <Container>
                    <div><Text variant="medium" styles={semibold}><Icon iconName="Link12" /> {locale?.groups.availableRedirects}</Text></div>
                </Container>
            </div>

            {
                options.length === 0 ? <Message text={locale?.noRedirectsAvailable!} />
                :
                <div className="text-center justify-content-center" style={{ marginLeft: 'auto', marginRight: 'auto' }}>
                    <ChoiceGroup options={options} onChange={selectionChanged} selectedKey={selectedChoiceGroup} />
                </div>
            }
        </div>
    );
}
Example #21
Source File: discover-wrapper-page.tsx    From microsoft-teams-apps-growyourskills with MIT License 4 votes vote down vote up
/**
    *Get wrapper for page which acts as container for all child components
    */
    private getWrapperPage = () => {
        if (this.state.loader) {
            return (
                <div className="container-div">
                    <div className="container-subdiv">
                        <div className="loader">
                            <Loader />
                        </div>
                    </div>
                </div>
            );
        } else {

            // Cards component array to be rendered in grid.
            const cards = new Array<any>();

            this.state.projectDetails!.map((value: IProjectDetails, index) => {
                if (!value.isRemoved) {
                    cards.push(<Col lg={3} sm={6} md={4} className="grid-column d-flex justify-content-center">
                        <Card loggedInUserId={this.loggedInUserObjectId} projectDetails={this.state.projectDetails} onJoinMenuItemClick={this.onProjectJoin} onCloseProjectButtonClick={this.handleCloseProjectButtonClick} onLeaveButtonClick={this.handleLeaveButtonClick} showLeaveProjects={false} showJoinProjectMenu={true} index={index} cardDetails={value} onCardUpdate={this.onCardUpdate} onDeleteButtonClick={this.handleDeleteButtonClick} />
                    </Col>)
                }
            });

            if (this.state.initialProjects.length === 0) {
                return (
                    <div className="container-div">
                        <div className="container-subdiv">
                            <NotificationMessage onClose={this.hideAlert} showAlert={this.state.showAlert} content={this.state.alertMessage} notificationType={this.state.alertprojectStatus} />
                            <NoPostAddedPage showAddPost={true} onNewPostSubmit={this.onNewPost} />
                        </div>
                    </div>
                )
            }
            let scrollViewStyle = { height: this.state.isFilterApplied === true ? "84vh" : "92vh" };
            return (
                <div className="container-div">
                    <div className="container-subdiv-cardview">
                        <Container fluid className="container-fluid-overriden">
                            <NotificationMessage
                                onClose={this.hideAlert}
                                showAlert={this.state.showAlert}
                                content={this.state.alertMessage}
                                notificationType={this.state.alertprojectStatus}
                            />
                            <TitleBar
                                projectDetails={this.state.projectDetails}
                                showFilter={true}
                                teamId={this.teamId}
                                commandBarSearchText={this.state.searchText}
                                searchFilterProjectsUsingAPI={this.invokeApiSearch}
                                onFilterClear={this.handleFilterClear}
                                hideFilterbar={!this.state.isFilterApplied}
                                onSortByChange={this.onSortByChange}
                                onFilterSearchChange={this.onFilterSearchTextChange}
                                onSearchInputChange={this.handleSearchInputChange}
                                onNewPostSubmit={this.onNewPost}
                                onSharedByCheckboxStateChange={this.onSharedByCheckboxStateChange}
                                onTypeCheckboxStateChange={this.onprojectStatusCheckboxStateChange}
                                onSkillsStateChange={this.onskillsStateChange}
                            />
                            <div key={this.state.infiniteScrollParentKey} className="scroll-view scroll-view-mobile" style={scrollViewStyle}>
                                <InfiniteScroll
                                    pageStart={this.state.pageLoadStart}
                                    loadMore={this.loadMoreProjects}
                                    hasMore={this.state.hasMoreProjects && !this.filterSearchText.trim().length}
                                    initialLoad={this.state.isPageInitialLoad}
                                    useWindow={false}
                                    loader={<div className="loader"><Loader /></div>}>

                                    <Row>
                                        {
                                            cards.length ? cards : this.state.hasMoreProjects === true ? <></> : <FilterNoPostContentPage />
                                        }
                                    </Row>

                                </InfiniteScroll>
                            </div>

                        </Container>
                    </div>
                </div>
            );
        }
    }
Example #22
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 4 votes vote down vote up
NavBar = () => {
  const activeAccount = useAppSelector(state => state.account.activeAccount);
  const stateBgColor = useAppSelector(state => state.application.stateBackgroundColor);
  const isCool = useAppSelector(state => state.application.isCoolBackground);
  const history = useHistory();
  const ethBalance = useEtherBalance(config.addresses.nounsDaoExecutor);
  const lidoBalanceAsETH = useLidoBalance();
  const treasuryBalance = ethBalance && lidoBalanceAsETH && ethBalance.add(lidoBalanceAsETH);
  const daoEtherscanLink = buildEtherscanHoldingsLink(config.addresses.nounsDaoExecutor);
  const [isNavExpanded, setIsNavExpanded] = useState(false);

  const useStateBg =
    history.location.pathname === '/' ||
    history.location.pathname.includes('/noun/') ||
    history.location.pathname.includes('/auction/');

  const nonWalletButtonStyle = !useStateBg
    ? NavBarButtonStyle.WHITE_INFO
    : isCool
    ? NavBarButtonStyle.COOL_INFO
    : NavBarButtonStyle.WARM_INFO;

  const closeNav = () => setIsNavExpanded(false);

  return (
    <>
      <Navbar
        expand="xl"
        style={{ backgroundColor: `${useStateBg ? stateBgColor : 'white'}` }}
        className={classes.navBarCustom}
        expanded={isNavExpanded}
      >
        <Container style={{ maxWidth: 'unset' }}>
          <div className={classes.brandAndTreasuryWrapper}>
            <Navbar.Brand as={Link} to="/" className={classes.navBarBrand}>
              <img src={logo} className={classes.navBarLogo} alt="Nouns DAO logo" />
            </Navbar.Brand>
            {Number(CHAIN_ID) !== 1 && (
              <Nav.Item>
                <img className={classes.testnetImg} src={testnetNoun} alt="testnet noun" />
                TESTNET
              </Nav.Item>
            )}
            <Nav.Item>
              {treasuryBalance && (
                <Nav.Link
                  href={daoEtherscanLink}
                  className={classes.nounsNavLink}
                  target="_blank"
                  rel="noreferrer"
                >
                  <NavBarTreasury
                    treasuryBalance={Number(utils.formatEther(treasuryBalance)).toFixed(0)}
                    treasuryStyle={nonWalletButtonStyle}
                  />
                </Nav.Link>
              )}
            </Nav.Item>
          </div>
          <Navbar.Toggle className={classes.navBarToggle} aria-controls="basic-navbar-nav" onClick={() => setIsNavExpanded(!isNavExpanded)} />
          <Navbar.Collapse className="justify-content-end">
            <Nav.Link as={Link} to="/vote" className={classes.nounsNavLink} onClick={closeNav} >
              <NavBarButton
                buttonText={<Trans>DAO</Trans>}
                buttonIcon={<FontAwesomeIcon icon={faUsers} />}
                buttonStyle={nonWalletButtonStyle}
              />
            </Nav.Link>
            <Nav.Link
              href={externalURL(ExternalURL.notion)}
              className={classes.nounsNavLink}
              target="_blank"
              rel="noreferrer"
              onClick={closeNav}
            >
              <NavBarButton
                buttonText={<Trans>Docs</Trans>}
                buttonIcon={<FontAwesomeIcon icon={faBookOpen} />}
                buttonStyle={nonWalletButtonStyle}
              />
            </Nav.Link>
            <Nav.Link
              href={externalURL(ExternalURL.discourse)}
              className={classes.nounsNavLink}
              target="_blank"
              rel="noreferrer"
              onClick={closeNav}
            >
              <NavBarButton
                buttonText={<Trans>Discourse</Trans>}
                buttonIcon={<FontAwesomeIcon icon={faComments} />}
                buttonStyle={nonWalletButtonStyle}
              />
            </Nav.Link>
            <Nav.Link as={Link} to="/playground" className={classes.nounsNavLink}  onClick={closeNav}>
              <NavBarButton
                buttonText={<Trans>Playground</Trans>}
                buttonIcon={<FontAwesomeIcon icon={faPlay} />}
                buttonStyle={nonWalletButtonStyle}
              />
            </Nav.Link>
            <NavLocaleSwitcher buttonStyle={nonWalletButtonStyle} />
            <NavWallet address={activeAccount || '0'} buttonStyle={nonWalletButtonStyle} />{' '}
          </Navbar.Collapse>
        </Container>
      </Navbar>
    </>
  );
}
Example #23
Source File: discover-teams-wrapper-page.tsx    From microsoft-teams-apps-growyourskills with MIT License 4 votes vote down vote up
/**
    *Get wrapper for page which acts as container for all child components
    */
    private getWrapperPage = () => {
        if (this.state.loader) {
            return (
                <div className="container-div">
                    <div className="container-subdiv">
                        <div className="loader">
                            <Loader />
                        </div>
                    </div>
                </div>
            );
        } else {

            // Cards component array to be rendered in grid.
            const cards = new Array<any>();

            this.state.projectDetails!.map((value: IProjectDetails, index) => {
                if (!value.isRemoved) {
                    cards.push(<Col lg={3} sm={6} md={4} className="grid-column d-flex justify-content-center">
                        <Card loggedInUserId={this.loggedInUserObjectId} projectDetails={this.state.projectDetails} onJoinMenuItemClick={this.onProjectJoin} onCloseProjectButtonClick={this.handleCloseProjectButtonClick} onLeaveButtonClick={this.handleLeaveButtonClick} showLeaveProjects={false} showJoinProjectMenu={true} index={index} cardDetails={value} onCardUpdate={this.onCardUpdate} onDeleteButtonClick={this.handleDeleteButtonClick} />
                    </Col>)
                }
            });

            if (this.state.initialProjects.length === 0) {
                return (
                    <div className="container-div">
                        <div className="container-subdiv">
                            <NotificationMessage onClose={this.hideAlert} showAlert={this.state.showAlert} content={this.state.alertMessage} notificationType={this.state.alertprojectStatus} />
                            <FilterNoPostContentPage />
                        </div>
                    </div>
                )
            }
            let scrollViewStyle = { height: this.state.isFilterApplied === true ? "84vh" : "92vh" };
            return (
                <div className="container-div">
                    <div className="container-subdiv-cardview">
                        <Container fluid className="container-fluid-overriden">
                            <NotificationMessage
                                onClose={this.hideAlert}
                                showAlert={this.state.showAlert}
                                content={this.state.alertMessage}
                                notificationType={this.state.alertprojectStatus}
                            />
                            <TitleBar
                                projectDetails={this.state.projectDetails}
                                showFilter={true}
                                teamId={this.teamId}
                                commandBarSearchText={this.state.searchText}
                                searchFilterProjectsUsingAPI={this.invokeApiSearch}
                                onFilterClear={this.handleFilterClear}
                                hideFilterbar={!this.state.isFilterApplied}
                                onSortByChange={this.onSortByChange}
                                onFilterSearchChange={this.onFilterSearchTextChange}
                                onSearchInputChange={this.handleSearchInputChange}
                                onNewProjectSubmit={this.onNewPost}
                                onSharedByCheckboxStateChange={this.onSharedByCheckboxStateChange}
                                onTypeCheckboxStateChange={this.onprojectStatusCheckboxStateChange}
                                onSkilsStateChange={this.onskillsStateChange}
                            />
                            <div key={this.state.infiniteScrollParentKey} className="scroll-view scroll-view-mobile" style={scrollViewStyle}>
                                <InfiniteScroll
                                    pageStart={this.state.pageLoadStart}
                                    loadMore={this.loadMoreProjects}
                                    hasMore={this.state.hasMoreProjects && !this.filterSearchText.trim().length}
                                    initialLoad={this.state.isPageInitialLoad}
                                    useWindow={false}
                                    loader={<div className="loader"><Loader /></div>}>

                                    <Row>
                                        {
                                            cards.length ? cards : this.state.hasMoreProjects === true ? <></> : <FilterNoPostContentPage />
                                        }
                                    </Row>

                                </InfiniteScroll>
                            </div>

                        </Container>
                    </div>
                </div>
            );
        }
    }
Example #24
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 4 votes vote down vote up
Playground: React.FC = () => {
  const [nounSvgs, setNounSvgs] = useState<string[]>();
  const [traits, setTraits] = useState<Trait[]>();
  const [modSeed, setModSeed] = useState<{ [key: string]: number }>();
  const [initLoad, setInitLoad] = useState<boolean>(true);
  const [displayNoun, setDisplayNoun] = useState<boolean>(false);
  const [indexOfNounToDisplay, setIndexOfNounToDisplay] = useState<number>();
  const [selectIndexes, setSelectIndexes] = useState<Record<string, number>>({});
  const [pendingTrait, setPendingTrait] = useState<PendingCustomTrait>();
  const [isPendingTraitValid, setPendingTraitValid] = useState<boolean>();

  const customTraitFileRef = useRef<HTMLInputElement>(null);

  const generateNounSvg = React.useCallback(
    (amount: number = 1) => {
      for (let i = 0; i < amount; i++) {
        const seed = { ...getRandomNounSeed(), ...modSeed };
        const { parts, background } = getNounData(seed);
        const svg = buildSVG(parts, encoder.data.palette, background);
        setNounSvgs(prev => {
          return prev ? [svg, ...prev] : [svg];
        });
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [pendingTrait, modSeed],
  );

  useEffect(() => {
    const traitTitles = ['background', 'body', 'accessory', 'head', 'glasses'];
    const traitNames = [
      ['cool', 'warm'],
      ...Object.values(ImageData.images).map(i => {
        return i.map(imageData => imageData.filename);
      }),
    ];
    setTraits(
      traitTitles.map((value, index) => {
        return {
          title: value,
          traitNames: traitNames[index],
        };
      }),
    );

    if (initLoad) {
      generateNounSvg(8);
      setInitLoad(false);
    }
  }, [generateNounSvg, initLoad]);

  const traitOptions = (trait: Trait) => {
    return Array.from(Array(trait.traitNames.length + 1)).map((_, index) => {
      const traitName = trait.traitNames[index - 1];
      const parsedTitle = index === 0 ? `Random` : parseTraitName(traitName);
      return (
        <option key={index} value={traitName}>
          {parsedTitle}
        </option>
      );
    });
  };

  const traitButtonHandler = (trait: Trait, traitIndex: number) => {
    setModSeed(prev => {
      // -1 traitIndex = random
      if (traitIndex < 0) {
        let state = { ...prev };
        delete state[trait.title];
        return state;
      }
      return {
        ...prev,
        [trait.title]: traitIndex,
      };
    });
  };

  const resetTraitFileUpload = () => {
    if (customTraitFileRef.current) {
      customTraitFileRef.current.value = '';
    }
  };

  let pendingTraitErrorTimeout: NodeJS.Timeout;
  const setPendingTraitInvalid = () => {
    setPendingTraitValid(false);
    resetTraitFileUpload();
    pendingTraitErrorTimeout = setTimeout(() => {
      setPendingTraitValid(undefined);
    }, 5_000);
  };

  const validateAndSetCustomTrait = (file: File | undefined) => {
    if (pendingTraitErrorTimeout) {
      clearTimeout(pendingTraitErrorTimeout);
    }
    if (!file) {
      return;
    }

    const reader = new FileReader();
    reader.onload = e => {
      try {
        const buffer = Buffer.from(e?.target?.result!);
        const png = PNG.sync.read(buffer);
        if (png.width !== 32 || png.height !== 32) {
          throw new Error('Image must be 32x32');
        }
        const filename = file.name?.replace('.png', '') || 'custom';
        const data = encoder.encodeImage(filename, {
          width: png.width,
          height: png.height,
          rgbaAt: (x: number, y: number) => {
            const idx = (png.width * y + x) << 2;
            const [r, g, b, a] = [
              png.data[idx],
              png.data[idx + 1],
              png.data[idx + 2],
              png.data[idx + 3],
            ];
            return {
              r,
              g,
              b,
              a,
            };
          },
        });
        setPendingTrait({
          data,
          filename,
          type: DEFAULT_TRAIT_TYPE,
        });
        setPendingTraitValid(true);
      } catch (error) {
        setPendingTraitInvalid();
      }
    };
    reader.readAsArrayBuffer(file);
  };

  const uploadCustomTrait = () => {
    const { type, data, filename } = pendingTrait || {};
    if (type && data && filename) {
      const images = ImageData.images as Record<string, EncodedImage[]>;
      images[type].unshift({
        filename,
        data,
      });
      const title = traitKeyToTitle[type];
      const trait = traits?.find(t => t.title === title);

      resetTraitFileUpload();
      setPendingTrait(undefined);
      setPendingTraitValid(undefined);
      traitButtonHandler(trait!, 0);
      setSelectIndexes({
        ...selectIndexes,
        [title]: 0,
      });
    }
  };

  return (
    <>
      {displayNoun && indexOfNounToDisplay !== undefined && nounSvgs && (
        <NounModal
          onDismiss={() => {
            setDisplayNoun(false);
          }}
          svg={nounSvgs[indexOfNounToDisplay]}
        />
      )}

      <Container fluid="lg">
        <Row>
          <Col lg={10} className={classes.headerRow}>
            <span>
              <Trans>Explore</Trans>
            </span>
            <h1>
              <Trans>Playground</Trans>
            </h1>
            <p>
              <Trans>
                The playground was built using the {nounsProtocolLink}. Noun's traits are determined
                by the Noun Seed. The seed was generated using {nounsAssetsLink} and rendered using
                the {nounsSDKLink}.
              </Trans>
            </p>
          </Col>
        </Row>
        <Row>
          <Col lg={3}>
            <Col lg={12}>
              <Button
                onClick={() => {
                  generateNounSvg();
                }}
                className={classes.primaryBtn}
              >
                <Trans>Generate Nouns</Trans>
              </Button>
            </Col>
            <Row>
              {traits &&
                traits.map((trait, index) => {
                  return (
                    <Col lg={12} xs={6}>
                      <Form className={classes.traitForm}>
                        <FloatingLabel
                          controlId="floatingSelect"
                          label={traitKeyToLocalizedTraitKeyFirstLetterCapitalized(trait.title)}
                          key={index}
                          className={classes.floatingLabel}
                        >
                          <Form.Select
                            aria-label="Floating label select example"
                            className={classes.traitFormBtn}
                            value={trait.traitNames[selectIndexes?.[trait.title]] ?? -1}
                            onChange={e => {
                              let index = e.currentTarget.selectedIndex;
                              traitButtonHandler(trait, index - 1); // - 1 to account for 'random'
                              setSelectIndexes({
                                ...selectIndexes,
                                [trait.title]: index - 1,
                              });
                            }}
                          >
                            {traitOptions(trait)}
                          </Form.Select>
                        </FloatingLabel>
                      </Form>
                    </Col>
                  );
                })}
            </Row>
            <label style={{ margin: '1rem 0 .25rem 0' }} htmlFor="custom-trait-upload">
              <Trans>Upload Custom Trait</Trans>
              <OverlayTrigger
                trigger="hover"
                placement="top"
                overlay={
                  <Popover>
                    <div style={{ padding: '0.25rem' }}>
                      <Trans>Only 32x32 PNG images are accepted</Trans>
                    </div>
                  </Popover>
                }
              >
                <Image
                  style={{ margin: '0 0 .25rem .25rem' }}
                  src={InfoIcon}
                  className={classes.voteIcon}
                />
              </OverlayTrigger>
            </label>
            <Form.Control
              type="file"
              id="custom-trait-upload"
              accept="image/PNG"
              isValid={isPendingTraitValid}
              isInvalid={isPendingTraitValid === false}
              ref={customTraitFileRef}
              className={classes.fileUpload}
              onChange={(e: ChangeEvent<HTMLInputElement>) =>
                validateAndSetCustomTrait(e.target.files?.[0])
              }
            />
            {pendingTrait && (
              <>
                <FloatingLabel label="Custom Trait Type" className={classes.floatingLabel}>
                  <Form.Select
                    aria-label="Custom Trait Type"
                    className={classes.traitFormBtn}
                    onChange={e => setPendingTrait({ ...pendingTrait, type: e.target.value })}
                  >
                    {Object.entries(traitKeyToTitle).map(([key, title]) => (
                      <option value={key}>{capitalizeFirstLetter(title)}</option>
                    ))}
                  </Form.Select>
                </FloatingLabel>
                <Button onClick={() => uploadCustomTrait()} className={classes.primaryBtn}>
                  <Trans>Upload</Trans>
                </Button>
              </>
            )}
            <p className={classes.nounYearsFooter}>
              <Trans>
                You've generated{' '}
                {i18n.number(parseInt(nounSvgs ? (nounSvgs.length / 365).toFixed(2) : '0'))} years
                worth of Nouns
              </Trans>
            </p>
          </Col>
          <Col lg={9}>
            <Row>
              {nounSvgs &&
                nounSvgs.map((svg, i) => {
                  return (
                    <Col xs={4} lg={3} key={i}>
                      <div
                        onClick={() => {
                          setIndexOfNounToDisplay(i);
                          setDisplayNoun(true);
                        }}
                      >
                        <Noun
                          imgPath={`data:image/svg+xml;base64,${btoa(svg)}`}
                          alt="noun"
                          className={classes.nounImg}
                          wrapperClassName={classes.nounWrapper}
                        />
                      </div>
                    </Col>
                  );
                })}
            </Row>
          </Col>
        </Row>
      </Container>
    </>
  );
}
Example #25
Source File: WatchView.tsx    From 3Speak-app with GNU General Public License v3.0 4 votes vote down vote up
export function WatchView(props: any) {
  const player = useRef<any>()
  const [videoInfo, setVideoInfo] = useState<any>({})
  const [postInfo, setPostInfo] = useState<any>({})
  const [profilePictureURL, setProfilePictureUrl] = useState(EmptyProfile)
  const [commentGraph, setCommentGraph] = useState()
  const [videoLink, setVideoLink] = useState('')
  const [recommendedVideos, setRecommendedVideos] = useState([])
  const [loaded, setLoaded] = useState(false)
  const [loadingMessage, setLoadingMessage] = useState('')
  const [rootCid, setRootCid] = useState()

  const reflink = useMemo(() => {
    return props.match.params.reflink
  }, [])

  const reflinkParsed = useMemo(() => {
    return RefLink.parse(reflink) as any
  }, [reflink])

  const generalFetch = async () => {
    const info = await AccountService.permalinkToVideoInfo(reflink, { type: 'video' })
    setVideoInfo(info)
    setPostInfo(await AccountService.permalinkToPostInfo(reflink))
    try {
      //Leave profileURL default if error is thrown when attempting to retrieve profile picture
      setProfilePictureUrl(await AccountService.getProfilePictureURL(reflink))
    } catch (ex) {
      console.error(ex)
      throw ex
    }
    document.title = `3Speak - ${info.title}`
    const cids = []
    for (const source of info.sources) {
      const url = new URL(source.url)
      try {
        new CID(url.host)
        cids.push(url.host)
      } catch {}
    }
    setRootCid(cids[0])
  }

  const mountPlayer = async () => {
    try {
      const playerType = 'standard'
      switch (playerType) {
        case 'standard': {
          setVideoLink(await VideoService.getVideoSourceURL(reflink))
        }
      }
      recordView()
    } catch (ex) {
      console.error(ex)
    }
  }

  const recordView = async () => {
    return
    /*let cids = [];
        for(const source of videoInfo.sources) {
            const url = new (require('url').URL)(source.url)
            try {
                new CID(url.host)
                cids.push(url.host)
            } catch  {

            }
        }
        console.log(`CIDs to cache ${JSON.stringify(cids)}`)

        if(cids.length !== 0) {
            await PromiseIpc.send("pins.add", {
                _id: reflink,
                source: "Watch Page",
                cids,
                expire: (new Date().getTime()) + convert("1").from("d").to("ms"),
                meta: {
                    title: videoInfo.title
                }
            })
        }*/
  }

  const gearSelect = async (eventKey) => {
    switch (eventKey) {
      case 'mute_post': {
        await PromiseIpc.send('blocklist.add', reflinkParsed.toString())
        break
      }
      case 'mute_user': {
        await PromiseIpc.send(
          'blocklist.add',
          `${reflinkParsed.source.value}:${reflinkParsed.root}` as any,
        )
        break
      }
    }
  }

  const retrieveRecommended = async () => {
    const query = knex.raw(
      `SELECT TOP 25 x.* FROM DBHive.dbo.Comments x WHERE CONTAINS(json_metadata , '3speak/video') AND category LIKE '${postInfo.category}' ORDER BY NEWID()`,
    )
    const blob = []
    query.stream().on('data', async (val) => {
      if (await PromiseIpc.send('blocklist.has', `hive:${val.author}:${val.permlink}` as any)) {
        console.log(`${val.author} is blocked`)
        return
      }
      val.json_metadata = JSON.parse(val.json_metadata)
      //console.log(val)
      if (!val.json_metadata.video) {
        val.json_metadata.video = {
          info: {},
        }
      }
      let thumbnail
      if (val.json_metadata.sourceMap) {
        thumbnail = Finder.one.in(val.json_metadata.sourceMap).with({ type: 'thumbnail' }).url
        console.log(thumbnail)
      }
      blob.push({
        reflink: `hive:${val.author}:${val.permlink}`,
        created: val.created,
        author: val.author,
        permlink: val.permlink,
        tags: val.json_metadata.tags,
        title: val.title,
        duration: val.json_metadata.video.info.duration || val.json_metadata.video.duration,
        isIpfs: val.json_metadata.video.info.ipfs || thumbnail ? true : false,
        ipfs: val.json_metadata.video.info.ipfs,
        images: {
          ipfs_thumbnail: thumbnail
            ? `/ipfs/${thumbnail.slice(7)}`
            : `/ipfs/${val.json_metadata.video.info.ipfsThumbnail}`,
          thumbnail: `https://threespeakvideo.b-cdn.net/${val.permlink}/thumbnails/default.png`,
          poster: `https://threespeakvideo.b-cdn.net/${val.permlink}/poster.png`,
          post: `https://threespeakvideo.b-cdn.net/${val.permlink}/post.png`,
        },
        views: val.total_vote_weight ? Math.log(val.total_vote_weight / 1000).toFixed(2) : 0,
      })

      setRecommendedVideos(blob)
    })
    query.on('query-response', (ret, det, aet) => {
      console.log(ret, det, aet)
    })
    query.on('end', (err) => {
      console.log(err)
    })
    /*
        let ref = RefLink.parse(reflink)
        let data = (await axios.get(`https://3speak.tv/apiv2/recommended?v=${ref.root}/${ref.permlink}`)).data
        data.forEach((value => {
            let link = value.link.split("=")[1].split("/")
            value.reflink = `hive:${link[0]}:${link[1]}`
        }))*/
  }

  const PinLocally = async () => {
    const cids = []
    for (const source of videoInfo.sources) {
      const url = new URL(source.url)
      try {
        new CID(url.host)
        cids.push(url.host)
      } catch {}
    }

    debug(`CIDs to store ${JSON.stringify(cids)}`)
    if (cids.length !== 0) {
      NotificationManager.info('Pinning in progress')
      await PromiseIpc.send('pins.add', {
        _id: reflink,
        source: 'Watch Page',
        cids,
        expire: null,
        meta: {
          title: videoInfo.title,
        },
      } as any)
      NotificationManager.success(
        `Video with reflink of ${reflink} has been successfully pinned! Thank you for contributing!`,
        'Pin Successful',
      )
    } else {
      NotificationManager.warning('This video is not available on IPFS')
    }
  }
  const showDebug = () => {
    const metadata = videoInfo
    Popup.registerPlugin('watch_debug', async function () {
      this.create({
        content: (
          <div>
            <Tabs defaultActiveKey="meta" id="uncontrolled-tab-example">
              <Tab eventKey="meta" title="Metadata">
                <Editor value={metadata} ace={ace} theme="ace/theme/github"></Editor>
              </Tab>
            </Tabs>
          </div>
        ),
        buttons: {
          right: [
            {
              text: 'Close',
              className: 'success',
              action: function () {
                Popup.close()
              },
            },
          ],
        },
      })
    })
    Popup.plugins().watch_debug()
  }

  useEffect(() => {
    const load = async () => {
      try {
        await generalFetch()
        setLoadingMessage('Loading: Mounting player...')
        await mountPlayer()
      } catch (ex) {
        setLoadingMessage('Loading resulted in error')
        throw ex
      }
      setLoaded(true)
      await retrieveRecommended()
    }

    void load()
  }, [])

  useEffect(() => {
    window.scrollTo(0, 0)

    const update = async () => {
      await generalFetch()
      await mountPlayer()
      await retrieveRecommended()
      player.current?.ExecUpdate()
    }

    void update()
  }, [reflink])

  return (
    <div>
      {loaded ? (
        <Container fluid>
          {/* <Container fluid pb={0}> */}
          {/* <Row fluid="md"> */}
          <Row>
            <Col md={8}>
              <div>
                <Player reflink={reflink}></Player>
              </div>
              <div className="single-video-title box mb-3 clearfix">
                <div className="float-left">
                  <h2 style={{ fontSize: '18px' }}>
                    <a>{videoInfo.title}</a>
                  </h2>
                  <DHTProviders rootCid={rootCid} />
                </div>
                <div
                  className="float-right"
                  style={
                    {
                      textAlign: 'right !important',
                      float: 'right !important',
                      display: 'inline-block !important',
                    } as any
                  }
                >
                  <span>
                    <VoteWidget reflink={reflink} />
                  </span>
                  <Dropdown onSelect={gearSelect} style={{ paddingTop: '10px' }}>
                    <Dropdown.Toggle
                      as={CustomToggle}
                      id="dropdown-custom-components"
                    ></Dropdown.Toggle>
                    <Dropdown.Menu>
                      <Dropdown.Item eventKey="mute_post">
                        <p style={{ color: 'red' }}>Mute Post</p>
                      </Dropdown.Item>
                      <Dropdown.Item eventKey="mute_user">
                        <p style={{ color: 'red' }}>Mute User</p>
                      </Dropdown.Item>
                    </Dropdown.Menu>
                  </Dropdown>
                </div>
              </div>
              <div className="single-video-author box mb-3">
                <div className="float-right">
                  <Row>
                    <FollowWidget reflink={reflink} />
                    <a
                      target="_blank"
                      style={{ marginRight: '5px', marginLeft: '5px' }}
                      className="btn btn-light btn-sm"
                      onClick={PinLocally}
                    >
                      <FaDownload /> Download to IPFS node
                    </a>
                    <a
                      target="_blank"
                      style={{ marginRight: '5px' }}
                      className="btn btn-light btn-sm"
                      href={(() => {
                        const videoSource = Finder.one.in(videoInfo.sources).with({
                          format: 'mp4',
                        })
                        if (videoSource) {
                          return videoSource.url
                        }
                      })()}
                    >
                      <FaDownload /> Download
                    </a>
                  </Row>
                </div>
                <img className="img-fluid" src={profilePictureURL} alt="" />
                <p>
                  <a href={`#/user/${reflinkParsed.source.value}:${reflinkParsed.root}`}>
                    <strong>{postInfo.author}</strong>
                  </a>
                </p>
                <small>
                  Published on{' '}
                  {(() => {
                    const pattern = DateTime.compile('MMMM D, YYYY')
                    return DateTime.format(new Date(videoInfo.creation), pattern)
                  })()}
                </small>
              </div>
              <div className="single-video-info-content box mb-3">
                <h6>About :</h6>
                <CollapsibleText>
                  <ReactMarkdown
                    escapeHtml={false}
                    source={DOMPurify.sanitize(videoInfo.description)}
                  ></ReactMarkdown>
                  <hr />
                  <Container style={{ marginBottom: '10px', textAlign: 'center' }}>
                    <a
                      target="_blank"
                      style={{ marginRight: '5px' }}
                      className="btn btn-light btn-sm"
                      onClick={() => showDebug()}
                    >
                      <BsInfoSquare /> Debug Info
                    </a>
                  </Container>
                </CollapsibleText>
                <h6>Tags: </h6>
                <p className="tags mb-0">
                  {(() => {
                    const out = []
                    if (videoInfo.tags) {
                      for (const tag of videoInfo.tags) {
                        out.push(
                          <span style={{ paddingLeft: '3px' }} key={tag}>
                            <a>{tag}</a>
                          </span>,
                        )
                      }
                    }
                    return out
                  })()}
                </p>
              </div>
              <CommentSection reflink={reflink.toString()} />
            </Col>
            <Col md={4}>
              <Row>
                <Col md={12}>
                  {recommendedVideos.map((value) => (
                    <VideoTeaser key={value.reflink} reflink={value.reflink} />
                  ))}
                </Col>
              </Row>
            </Col>
          </Row>
        </Container>
      ) : (
        <div>
          <LoopCircleLoading />
          <div
            style={{
              textAlign: 'center',
              margin: 'auto',
              position: 'absolute',
              left: '0px',
              right: '0px',
              top: '60%',
              bottom: '0px',
            }}
          >
            <h1 style={{ top: '60%', fontSize: '20px' }}>{loadingMessage}</h1>
          </div>
        </div>
      )}
    </div>
  )
}
Example #26
Source File: routing.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
Routing = () => {

    const { t } = useTranslation();
    const [quickTest, setQuickTest] = React.useState<IQuickTest>();
    const [error, setError] = React.useState<IError>();
    const [errorShow, setErrorShow] = React.useState(false);
    const [notificationShow, setNotificationShow] = React.useState(false);
    const [dataPrivacyShow, setDataPrivacyShow] = React.useState(false);
    const [imprintShow, setImprintShow] = React.useState(false);
    const [isInit, setIsInit] = React.useState(false);
    const [storedLandingDisclaimerShow] = useLocalStorage('landingDisclaimerShow', true);
    const [storedUserManagementDisclaimerShow] = useLocalStorage('userManagementDisclaimerShow', true);
    const [landingDisclaimerShow, setLandingDisclaimerShow] = React.useState(storedLandingDisclaimerShow);
    const [userManagementDisclaimerShow, setUserManagementDisclaimerShow] = React.useState(storedUserManagementDisclaimerShow);


    const context: IAppContext = {
        navigation: useNavigation(),
        valueSets: useGetValueSets(undefined, (msg) => { setError({ message: msg }) }),
        utils: utils
    }

    document.title = t('translation:title');

    React.useEffect(() => {
        if (error) {
            setErrorShow(true);
        }
    }, [error])

    const errorOnExit = () => {
        setError(undefined);
    }

    React.useEffect(() => {
        if (context.valueSets && Object.entries(context.valueSets).length > 0 && context.navigation)
            setIsInit(true);
    }, [context.navigation, context.valueSets])

    return (
        !(isInit && context.valueSets && context.navigation)
            ? <CwaSpinner />
            : <AppContext.Provider value={context}>
                {/*
    header, every time shown. fit its children
    */}
                <Route path={context.navigation.routes.root}>
                    <Header />
                    <ErrorPage error={error} show={errorShow} onCancel={error?.onCancel} onHide={() => setErrorShow(false)} onExit={errorOnExit} />
                    <NotificationToast show={notificationShow} setNotificationShow={setNotificationShow} />
                    <DataprivacyPage show={dataPrivacyShow} setShow={setDataPrivacyShow} />
                    <ImprintPage show={imprintShow} setShow={setImprintShow} />
                </Route>

                {/*
    Content area. fit the rest of screen and children
    */}
                <Container id='qt-body'>

                    {/* Landing */}
                    <Route
                        exact
                        path={context.navigation.routes.landing}
                    >
                        <LandingPage
                            disclaimerShow={landingDisclaimerShow}
                            setDisclaimerShow={(show: boolean) => { setLandingDisclaimerShow(show) }}
                            setNotificationShow={setNotificationShow} />
                    </Route>


                    {/* Record Patient Data */}
                    <PrivateRoute
                        exact
                        roles={['c19_quick_test_counter']}
                        path={context.navigation.routes.recordPatient}
                        component={RecordPatientData}
                        render={(props) => <RecordPatientData {...props} setQuickTest={setQuickTest} quickTest={quickTest} setError={setError} />}
                    />

                    {/* Show Patient Data */}
                    <PrivateRoute
                        roles={['c19_quick_test_counter']}
                        path={context.navigation.routes.showPatientRecord}
                        component={ShowPatientData}
                        render={(props) => <ShowPatientData {...props} setQuickTest={setQuickTest} quickTest={quickTest} setError={setError} setNotificationShow={setNotificationShow} />}
                    />

                    {/* Record Test Result */}
                    <PrivateRoute
                        roles={['c19_quick_test_lab']}
                        path={context.navigation.routes.recordTestResult}
                        component={RecordTestResult}
                        render={(props) => <RecordTestResult {...props} setError={setError} setNotificationShow={setNotificationShow} />}
                    />

                    {/* QR Scan */}
                    <PrivateRoute
                        exact
                        path={context.navigation.routes.qrScan}
                        roles={['c19_quick_test_counter']}
                        component={QrScan}
                        render={(props) => <QrScan {...props} setQuickTest={setQuickTest} />}
                    />

                    <PrivateRoute
                        exact
                        path={context.navigation.routes.statistics}
                        roles={['c19_quick_test_counter', 'c19_quick_test_lab']}
                        component={Statistics}
                        render={(props) => <Statistics {...props} setError={setError} />}
                    />

                    <PrivateRoute
                        exact
                        path={context.navigation.routes.reports}
                        roles={['c19_quick_test_counter', 'c19_quick_test_lab']}
                        component={Reports}
                        render={(props) => <Reports {...props} setError={setError} />}
                    />

                    <PrivateRoute
                        exact
                        path={context.navigation.routes.userManagement}
                        roles={['c19_quick_test_admin']}
                        component={UserManagement}
                        render={(props) =>
                            <UserManagement
                                {...props}
                                setError={setError}
                                disclaimerShow={userManagementDisclaimerShow}
                                setDisclaimerShow={(show: boolean) => { setUserManagementDisclaimerShow(show) }}
                            />}
                    />

                </Container>

                {/*
    footer, every time shown. fit its children
    */}
                <Route path={context.navigation.routes.root}>
                    <Footer setDataPrivacyShow={setDataPrivacyShow} setImprintShow={setImprintShow} />
                </Route>

            </AppContext.Provider>
    )
}
Example #27
Source File: GroupList.tsx    From website with MIT License 4 votes vote down vote up
CourseList= (props: Props) => {
    var theme = useTheme();
    const locale = LocalizationService.strings();
    const [filtersToggle, setFiltersToggle] = React.useState<boolean>(false);
    const columnCount = React.useRef(0);
    const rowHeight = React.useRef(0);
    const rowsPerPage = React.useRef(0);
    const MAX_ROW_HEIGHT = 265;
    
    var classNames = mergeStyleSets({
        listGrid: {
            overflow: 'hidden',
            fontSize: 0,
            position: 'relative',
            marginBottom: 10,
            margin: '1px'
        }
    });
    
    const getItemCountForPage = React.useCallback((itemIndex?: number, surfaceRect?: IRectangle) => {
        if (itemIndex === 0) {
            columnCount.current = Math.ceil(surfaceRect!.width / MAX_ROW_HEIGHT);
            rowHeight.current = MAX_ROW_HEIGHT;
            rowsPerPage.current = surfaceRect!.height / MAX_ROW_HEIGHT;
        }
        return columnCount.current * rowsPerPage.current;
    }, []);
    
    const getPageHeight = React.useCallback((): number => {
        return rowHeight.current * rowsPerPage.current;
    }, []); 
    
    const getCell = (e?: CourseDegree, index?: number, isScrolling?: boolean) => {
        return (
            <div data-is-focusable className="listGridTile" style={{ height: rowHeight.current + 'px', width: 100 / columnCount.current + '%' }}>
                <GroupItem key={index} data={e!} />
            </div>
        )
    };
    
    /* Filters inizialization */
    const [nameFilter, setNameFilter] = React.useState<string>("");
    const [yearFilter, setYearFilter] = React.useState<number>(0);
    const [semesterFilter, setSemesterFilter] = React.useState<number>(0);

    const onNameFilterChanged = (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, text?: string): void => {
        setNameFilter(text ?? "");
    };

    const onSemesterFilterChanged = (event: React.FormEvent<HTMLDivElement>, item?: IDropdownOption): void => {
        setSemesterFilter((item?.key ?? 0) as number);
    };

    const onYearFilterChanged = (event: React.FormEvent<HTMLDivElement>, item?: IDropdownOption): void => {
        setYearFilter((item?.key ?? 0) as number);
    };

    /* Filters gestion */
    let yearFilterOptions = props.degree?.type === 'M' || props.degree?.type === 'C' ? yearMasterDegreeFilterOptions : yearBachelorDegreeFilterOptions; 
    let filteredCourses = props.courses;

    if (nameFilter !== "") { filteredCourses = filteredCourses.filter(x => x.course?.name?.toLocaleLowerCase()?.includes(nameFilter.toLocaleLowerCase())); }
    if (semesterFilter !== 0) { filteredCourses = filteredCourses.filter(x => x.semester === semesterFilter); }
    if (yearFilter !== 0) { filteredCourses = filteredCourses.filter(x => x.year === yearFilter); }

    function toggleGroupsFilters(ev: React.MouseEvent<HTMLElement>, checked?: boolean) {
        setFiltersToggle(checked!);
        resetGroupsFilters();
    };

    function resetGroupsFilters() {
        setNameFilter("");
        setSemesterFilter(0);
        setYearFilter(0);
    };

    React.useEffect( () => {
        resetGroupsFilters();
    }, [props.loadingCourses, props.degree]);

    return (       
        <div className="groups-list mb-4">
            <div className="pb-2 pt-2 mb-4" style={{ backgroundColor: theme.palette.neutralLight }}>
                <Container style={{ display: 'flex', justifyContent: 'space-between' }}>
                    <div style={{ display: 'table' }}>
                        <Text variant="medium" styles={semibold} style={{  display: 'table-cell', verticalAlign: 'middle' }}><Icon iconName="Group"/> {locale?.groups.availableGroups}</Text>
                    </div>

                    <div className="filters-toggle">
                        <Toggle
                            label={<Text variant="medium" styles={semibold}>{locale?.groups.filtersToggle}</Text>}
                            inlineLabel
                            onText="On"
                            offText="Off"
                            onChange={toggleGroupsFilters}
                            checked={filtersToggle}
                        />
                    </div>
                </Container>
            </div>
            
            <Container>
                <FocusZone>
                    { filtersToggle ? 
                        <div className="mb-4 text-center">
                            <Row className="justify-content-center">
                                <Col xl={4} lg={4} md={4} sm={12} xs={12}>
                                    <TextField
                                        label={locale?.groups.nameFilter}
                                        onChange={onNameFilterChanged}   
                                        disabled={props.courses.length === 0 || props.loadingCourses}      
                                        value={nameFilter}      
                                    />
                                </Col>
                                <Col xl={4} lg={4} md={4} sm={12} xs={12}>
                                    {
                                        <Dropdown 
                                            options={yearFilterOptions}
                                            label={locale?.groups.yearFilter}
                                            onChange={onYearFilterChanged}
                                            selectedKey={yearFilter}
                                            disabled={props.courses.length === 0 || props.loadingCourses || props.degree?.slug === 'magistrale_informatica'} /* To-do: must decide if we need an apposite field to disable year selection */
                                        />
                                    }
                                </Col>
                                <Col xl={4} lg={4} md={4} sm={12} xs={12}>
                                    <Dropdown 
                                        options={semesterFilterOptions}
                                        label={locale?.groups.semesterFilter}
                                        onChange={onSemesterFilterChanged}
                                        selectedKey={semesterFilter}
                                        disabled={props.courses.length === 0 || props.loadingCourses}
                                    />
                                </Col>
                            </Row>
                        </div> : <></>
                    }

                    {
                        props.loadingCourses || props.errorLoadingCourses ? <LoadingSpinner loading={props.loadingCourses} error={props.errorLoadingCourses} />
                        : filteredCourses.length === 0 ?
                        <div className="justify-content-center">
                            <Message text={locale?.groups.groupsNotFound!} />
                        </div> : <></>
                    }
                    
                    {filteredCourses.length !== 0 && !props.errorLoadingCourses && !props.loadingCourses ? 
                        <div className="course-list">
                            <List
                                className={classNames.listGrid}
                                items={filteredCourses}
                                getItemCountForPage={getItemCountForPage}
                                getPageHeight={getPageHeight}
                                renderedWindowsAhead={15}
                                onRenderCell={getCell}
                                usePageCache={true}
                            />
                        </div> : <></>
                    }
                </FocusZone>
            </Container>
        </div>
    );
}
Example #28
Source File: GridFeedView.tsx    From 3Speak-app with GNU General Public License v3.0 4 votes vote down vote up
export function GridFeedView(props: GridFeedProps) {
  const [data, setData] = useState([])
  const [awaitingMoreData, setAwaitingMoreData] = useState(false)
  const reflink = useMemo(() => {
    return RefLink.parse(props.source || 'hive')
  }, [props.source])

  const [offset, setOffset] = useState(0)

  const handleScroll = useCallback(async () => {
    if (!awaitingMoreData) {
      const windowHeight =
        'innerHeight' in window ? window.innerHeight : document.documentElement.offsetHeight
      const body = document.body
      const html = document.documentElement
      const docHeight = Math.max(
        body.scrollHeight,
        body.offsetHeight,
        html.clientHeight,
        html.scrollHeight,
        html.offsetHeight,
      )
      const windowBottom = windowHeight + window.pageYOffset
      if (windowBottom + 200 >= docHeight) {
        setAwaitingMoreData(true)
        switch (reflink.source.value) {
          case 'hive': {
            //For now use the 3speak.tv API until a proper solution is devised
            if (props.type === 'home') {
              void fetch(`https://3speak.tv/api/trends/more?skip=${data.length}`)
                .then((res) => res.json())
                .then(async (json) => {
                  json = json.recommended ? json.recommended : json.trends
                  json.forEach((video) => {
                    video['author'] = video['owner']
                    delete video['owner']
                  })
                  json = data.concat(json)
                  json = json.filter((video, index, self) => {
                    return (
                      index ===
                      self.findIndex((v) => {
                        if (v) {
                          return v.author === video.author && v.permlink === video.permlink
                        }
                      })
                    )
                  })
                  for (const e in json) {
                    if (
                      await PromiseIpc.send(
                        'blocklist.has',
                        `hive:${json[e].author}:${json[e].permlink}` as any,
                      )
                    ) {
                      delete json[e]
                    }
                  }

                  setData(json)
                  setAwaitingMoreData(false)
                })
              return
            }

            const querySql = GridFeedQueryService.getFeedSql(props.type, offset)
            const query = knex.raw(querySql)

            query.on('query-response', (ret, det, aet) => {
              //       console.log(ret, det, aet)
            })
            const blob = data
            query
              .stream()
              .on('data', async (val) => {
                if (
                  await PromiseIpc.send(
                    'blocklist.has',
                    `hive:${val.author}:${val.permlink}` as any,
                  )
                ) {
                  console.log(`${val.author} is blocked`)
                  //return;
                }
                val.json_metadata = JSON.parse(val.json_metadata)
                //console.log(val)
                if (
                  !(await PromiseIpc.send(
                    'blocklist.has',
                    `hive:${val.author}:${val.permlink}` as any,
                  ))
                ) {
                  //console.log(val)
                  if (!val.json_metadata.video) {
                    val.json_metadata.video = {
                      info: {},
                    }
                  } else if (!val.json_metadata.video.info) {
                    val.json_metadata.video.info = {}
                  }
                  let thumbnail
                  if (val.json_metadata.sourceMap) {
                    const thumbnailOut = Finder.one
                      .in(val.json_metadata.sourceMap)
                      .with({ type: 'thumbnail' })
                    if (thumbnailOut) {
                      thumbnail = thumbnailOut.url
                    } else {
                      thumbnail = DefaultThumbnail
                    }
                    console.log(thumbnail)
                  }
                  console.log(val.json_metadata.sourceMap)
                  console.log(val)
                  blob.push({
                    created: val.created,
                    author: val.author,
                    permlink: val.permlink,
                    tags: val.json_metadata.tags,
                    title: val.title,
                    duration:
                      val.json_metadata.video.info.duration || val.json_metadata.video.duration,
                    isIpfs: val.json_metadata.video.info.ipfs || thumbnail ? true : false,
                    ipfs: val.json_metadata.video.info.ipfs,
                    images: {
                      ipfs_thumbnail: thumbnail
                        ? `/ipfs/${thumbnail.slice(7)}`
                        : `/ipfs/${val.json_metadata.video.info.ipfsThumbnail}`,
                      thumbnail: `https://threespeakvideo.b-cdn.net/${val.permlink}/thumbnails/default.png`,
                      poster: `https://threespeakvideo.b-cdn.net/${val.permlink}/poster.png`,
                      post: `https://threespeakvideo.b-cdn.net/${val.permlink}/post.png`,
                    },
                    views: val.total_vote_weight
                      ? Math.log(val.total_vote_weight / 1000).toFixed(2)
                      : 0,
                  })
                }
                setOffset(offset + 1)
                setData(blob)
              })
              .on('end', () => {
                setAwaitingMoreData(false)
              })
            break
          }
          default: {
            throw new Error(`Unrecognized feed type: ${reflink.source.value}`)
          }
        }
      }
    }
  }, [])

  // init tasks
  useEffect(() => {
    window.addEventListener('scroll', handleScroll)
  }, [])

  useEffect(() => {
    return () => {
      window.removeEventListener('scroll', handleScroll)
    }
  }, [])

  const retrieveData = useCallback(async () => {
    //For now use the 3speak.tv API until a proper solution is devised
    if (props.type === 'home') {
      void fetch(`https://3speak.tv/apiv2/feeds/${props.type}`)
        .then((res) => res.json())
        .then(async (json) => {
          for (const e in json) {
            if (
              await PromiseIpc.send(
                'blocklist.has',
                `hive:${json[e].author}:${json[e].permlink}` as any,
              )
            ) {
              delete json[e]
            }
          }
          setData(json)
        })
      return
    }

    //     let query
    const querySql = GridFeedQueryService.getFeedSql(props.type)
    const query = knex.raw(querySql)

    const blob = []
    query.stream().on('data', async (val) => {
      if (await PromiseIpc.send('blocklist.has', `hive:${val.author}:${val.permlink}` as any)) {
        console.log(`${val.author} is blocked`)
        return
      }
      val.json_metadata = JSON.parse(val.json_metadata)

      if (!val.json_metadata.video) {
        val.json_metadata.video = {
          info: {},
        }
      } else if (!val.json_metadata.video.info) {
        val.json_metadata.video.info = {}
      }
      let thumbnail
      if (val.json_metadata.sourceMap) {
        const thumbnailOut = Finder.one.in(val.json_metadata.sourceMap).with({ type: 'thumbnail' })
        if (thumbnailOut) {
          thumbnail = thumbnailOut.url
        } else {
          thumbnail = DefaultThumbnail
        }
      }

      try {
        blob.push({
          created: val.created,
          author: val.author,
          permlink: val.permlink,
          tags: val.json_metadata.tags,
          title: val.title,
          duration: val.json_metadata.video.info.duration || val.json_metadata.video.duration,
          isIpfs: val.json_metadata.video.info.ipfs || thumbnail ? true : false,
          ipfs: val.json_metadata.video.info.ipfs,
          images: {
            ipfs_thumbnail: thumbnail
              ? `/ipfs/${thumbnail.slice(7)}`
              : `/ipfs/${val.json_metadata.video.info.ipfsThumbnail}`,
            thumbnail: `https://threespeakvideo.b-cdn.net/${val.permlink}/thumbnails/default.png`,
            poster: `https://threespeakvideo.b-cdn.net/${val.permlink}/poster.png`,
            post: `https://threespeakvideo.b-cdn.net/${val.permlink}/post.png`,
          },
          views: val.total_vote_weight ? Math.log(val.total_vote_weight / 1000).toFixed(2) : 0,
        })
        // console.log(blob[blob.length - 1])
      } catch (ex) {
        console.error(`hive:${val.author}:${val.permlink} is bugged the fuck out`)
        console.error(val.json_metadata.video)
        console.error(ex)
      }
      setData(blob)
      setOffset(25)
    })

    query
      .then((rows) => {
        for (const val of rows) {
          val.json_metadata = JSON.parse(val.json_metadata)
        }
      })
      .catch((err) => {
        console.error(`Error connecting to hivesql!`)
        console.error(err)
        throw err
      })
      .finally(() => {})

    switch (reflink.source.value) {
      case 'hive': {
        void fetch(`https://3speak.tv/apiv2/feeds/${props.type}`)
          .then((res) => res.json())
          .then(async (json) => {
            for (const e in json) {
              if (
                await PromiseIpc.send(
                  'blocklist.has',
                  `hive:${json[e].author}:${json[e].permlink}` as any,
                )
              ) {
                delete json[e]
              }
            }
          })
        break
      }
      default: {
        throw new Error(`Unrecognized feed type ${reflink.source.value}`)
      }
    }
  }, [])

  useEffect(() => {
    if (props.data) {
      setData(props.data)
    } else {
      setData([])
      void retrieveData()
    }
    window.scrollTo(0, 0)
  }, [props.type, props.data])

  return (
    <div>
      {props.titleText !== undefined ? (
        <div className="header_sec">
          <Container fluid className="header_sec">
            <div className="row">
              <div className="col-lg-6 col-md-6 col-xs-12 header_dist1">
                <h1 className="white_col">{props.titleText}</h1>
              </div>
            </div>
          </Container>
        </div>
      ) : null}
      <section className="content_home">
        <div className={'row'}>
          {data.map((el) => (
            <VideoWidget
              key={el.author + '/' + el.permlink}
              reflink={`hive:${el.author}:${el.permlink}`}
              {...el}
            />
          ))}
        </div>
      </section>
    </div>
  )
}
Example #29
Source File: process-input.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
ProcessIdInput = (props: any) => {

    const { t } = useTranslation();
    const [processNo, setProcessNo] = React.useState('');
    const [btnOkDisabled, setBtnOkDisabled] = React.useState(false);
    const processIds = useGetPendingProcessIds(undefined, props.handleError);

    const handleCancel = () => {
        props.onCancel();
        // props.onHide();
    }

    const handleOk = () => {
        setBtnOkDisabled(true);
        props.onChange(processNo);
        // props.onHide();
    }

    const handleEnter = () => {
        setBtnOkDisabled(false);
    }

    return (
        <>
            <Modal
                contentClassName='data-modal'
                show={props.show}
                backdrop="static"
                keyboard={false}
                centered
                onEnter={handleEnter}
            >
                <Modal.Header id='data-header' className='pb-0' >
                    <Row>
                        <Col >
                            <Card.Title className='m-0 jcc-xs-jcfs-md' as={'h2'} >{t('translation:testId-input-header')}</Card.Title>
                        </Col>
                    </Row>
                </Modal.Header>

                {/*
    content area with process number input and radios
    */}
                <Modal.Body className='py-0 bg-light'>
                    <hr />

                    < FormGroupInput controlId='formProcessModalInput' title={t('translation:process-number')}
                        value={processNo}
                        onChange={(evt: any) => setProcessNo(evt.currentTarget.value)}
                        required
                        min={utils.shortHashLen}
                        maxLength={utils.shortHashLen}
                        pattern={utils.pattern.processNo}
                        datalistId='processId-list'
                        datalist={processIds ? processIds.map((i: IShortHashedGuid) => <option key={i.shortHashedGuid} value={i.shortHashedGuid} />) : undefined}
                    />

                    <hr />
                </Modal.Body>

                {/*
    footer with cancel and submit button
    */}
                <Modal.Footer id='data-footer'>
                    <Container className='p-0'>
                        <Row>
                            <Col xs='6' md='4' className='pl-0'>
                                <Button
                                    className='py-0'
                                    block
                                    variant='outline-primary'
                                    onClick={handleCancel}
                                >
                                    {t('translation:cancel')}
                                </Button>
                            </Col>
                            <Col xs='6' md='4' className='pr-0'>
                                <Button
                                    className='py-0'
                                    block
                                    onClick={handleOk}
                                    disabled={processNo.length !== utils.shortHashLen || btnOkDisabled}
                                >
                                    {t('translation:ok')}

                                    <Spinner
                                        as="span"
                                        className='btn-spinner'
                                        animation="border"
                                        hidden={!btnOkDisabled}
                                        size="sm"
                                        role="status"
                                        aria-hidden="true"
                                    />
                                </Button>
                            </Col>
                        </Row>
                    </Container>
                </Modal.Footer>
            </Modal>
        </>
    )
}