@ant-design/icons#CameraOutlined TypeScript Examples
The following examples show how to use
@ant-design/icons#CameraOutlined.
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: CoverPhotoOverlay.tsx From foodie with MIT License | 5 votes |
CoverPhotoOverlay: React.FC<IProps> = (props) => {
return (
<div
className={`w-full h-full laptop:bg-black laptop:bg-opacity-50 absolute flex items-center justify-center laptop:invisible transition-all ${props.coverPhoto.imageFile.file ? 'z-10' : 'z-0'}`}
ref={props.coverPhotoOverlayRef}
>
<input
type="file"
hidden
accept="image/*"
onChange={props.coverPhoto.onFileChange}
readOnly={props.isUploadingCoverPhoto}
id="cover"
/>
{props.isOwnProfile && (
<>
{props.isUploadingCoverPhoto ? <Loader mode="light" /> : (
<>
{props.coverPhoto.imageFile.file ? (
<div className="flex">
<button className="button--danger !rounded-full" onClick={props.coverPhoto.clearFiles}>
<CloseOutlined className="text-xl text-white" />
</button>
<label
className="button--muted !rounded-full cursor-pointer"
htmlFor="cover"
>
Change
</label>
<button onClick={props.handleSaveCoverPhoto}>Save</button>
</div>
) : (
<label
className="p-3 laptop:p-4 bg-indigo-700 absolute right-4 top-4 laptop:relative text-white font-medium rounded-full cursor-pointer hover:bg-indigo-800"
htmlFor="cover"
>
{window.screen.width > 800 ? 'Change Cover Photo' : (
<CameraOutlined className="text-xl text-white" />
)}
</label>
)}
</>
)}
</>
)}
</div>
);
}
Example #2
Source File: Icon.tsx From html2sketch with MIT License | 4 votes |
IconSymbol: FC = () => {
return (
<Row>
{/*<CaretUpOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/1.CaretUpOutlined'}*/}
{/*/>*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.MailOutlined'}*/}
{/*/>*/}
{/*<StepBackwardOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
{/*/>*/}
{/*<StepForwardOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
{/*/>*/}
<StepForwardOutlined />
<ShrinkOutlined />
<ArrowsAltOutlined />
<DownOutlined />
<UpOutlined />
<LeftOutlined />
<RightOutlined />
<CaretUpOutlined />
<CaretDownOutlined />
<CaretLeftOutlined />
<CaretRightOutlined />
<VerticalAlignTopOutlined />
<RollbackOutlined />
<FastBackwardOutlined />
<FastForwardOutlined />
<DoubleRightOutlined />
<DoubleLeftOutlined />
<VerticalLeftOutlined />
<VerticalRightOutlined />
<VerticalAlignMiddleOutlined />
<VerticalAlignBottomOutlined />
<ForwardOutlined />
<BackwardOutlined />
<EnterOutlined />
<RetweetOutlined />
<SwapOutlined />
<SwapLeftOutlined />
<SwapRightOutlined />
<ArrowUpOutlined />
<ArrowDownOutlined />
<ArrowLeftOutlined />
<ArrowRightOutlined />
<LoginOutlined />
<LogoutOutlined />
<MenuFoldOutlined />
<MenuUnfoldOutlined />
<BorderBottomOutlined />
<BorderHorizontalOutlined />
<BorderInnerOutlined />
<BorderOuterOutlined />
<BorderLeftOutlined />
<BorderRightOutlined />
<BorderTopOutlined />
<BorderVerticleOutlined />
<PicCenterOutlined />
<PicLeftOutlined />
<PicRightOutlined />
<RadiusBottomleftOutlined />
<RadiusBottomrightOutlined />
<RadiusUpleftOutlined />
<RadiusUprightOutlined />
<FullscreenOutlined />
<FullscreenExitOutlined />
<QuestionOutlined />
<PauseOutlined />
<MinusOutlined />
<PauseCircleOutlined />
<InfoOutlined />
<CloseOutlined />
<ExclamationOutlined />
<CheckOutlined />
<WarningOutlined />
<IssuesCloseOutlined />
<StopOutlined />
<EditOutlined />
<CopyOutlined />
<ScissorOutlined />
<DeleteOutlined />
<SnippetsOutlined />
<DiffOutlined />
<HighlightOutlined />
<AlignCenterOutlined />
<AlignLeftOutlined />
<AlignRightOutlined />
<BgColorsOutlined />
<BoldOutlined />
<ItalicOutlined />
<UnderlineOutlined />
<StrikethroughOutlined />
<RedoOutlined />
<UndoOutlined />
<ZoomInOutlined />
<ZoomOutOutlined />
<FontColorsOutlined />
<FontSizeOutlined />
<LineHeightOutlined />
<SortAscendingOutlined />
<SortDescendingOutlined />
<DragOutlined />
<OrderedListOutlined />
<UnorderedListOutlined />
<RadiusSettingOutlined />
<ColumnWidthOutlined />
<ColumnHeightOutlined />
<AreaChartOutlined />
<PieChartOutlined />
<BarChartOutlined />
<DotChartOutlined />
<LineChartOutlined />
<RadarChartOutlined />
<HeatMapOutlined />
<FallOutlined />
<RiseOutlined />
<StockOutlined />
<BoxPlotOutlined />
<FundOutlined />
<SlidersOutlined />
<AndroidOutlined />
<AppleOutlined />
<WindowsOutlined />
<IeOutlined />
<ChromeOutlined />
<GithubOutlined />
<AliwangwangOutlined />
<DingdingOutlined />
<WeiboSquareOutlined />
<WeiboCircleOutlined />
<TaobaoCircleOutlined />
<Html5Outlined />
<WeiboOutlined />
<TwitterOutlined />
<WechatOutlined />
<AlipayCircleOutlined />
<TaobaoOutlined />
<SkypeOutlined />
<FacebookOutlined />
<CodepenOutlined />
<CodeSandboxOutlined />
<AmazonOutlined />
<GoogleOutlined />
<AlipayOutlined />
<AntDesignOutlined />
<AntCloudOutlined />
<ZhihuOutlined />
<SlackOutlined />
<SlackSquareOutlined />
<BehanceSquareOutlined />
<DribbbleOutlined />
<DribbbleSquareOutlined />
<InstagramOutlined />
<YuqueOutlined />
<AlibabaOutlined />
<YahooOutlined />
<RedditOutlined />
<SketchOutlined />
<AccountBookOutlined />
<AlertOutlined />
<ApartmentOutlined />
<ApiOutlined />
<QqOutlined />
<MediumWorkmarkOutlined />
<GitlabOutlined />
<MediumOutlined />
<GooglePlusOutlined />
<AppstoreAddOutlined />
<AppstoreOutlined />
<AudioOutlined />
<AudioMutedOutlined />
<AuditOutlined />
<BankOutlined />
<BarcodeOutlined />
<BarsOutlined />
<BellOutlined />
<BlockOutlined />
<BookOutlined />
<BorderOutlined />
<BranchesOutlined />
<BuildOutlined />
<BulbOutlined />
<CalculatorOutlined />
<CalendarOutlined />
<CameraOutlined />
<CarOutlined />
<CarryOutOutlined />
<CiCircleOutlined />
<CiOutlined />
<CloudOutlined />
<ClearOutlined />
<ClusterOutlined />
<CodeOutlined />
<CoffeeOutlined />
<CompassOutlined />
<CompressOutlined />
<ContactsOutlined />
<ContainerOutlined />
<ControlOutlined />
<CopyrightCircleOutlined />
<CopyrightOutlined />
<CreditCardOutlined />
<CrownOutlined />
<CustomerServiceOutlined />
<DashboardOutlined />
<DatabaseOutlined />
<DeleteColumnOutlined />
<DeleteRowOutlined />
<DisconnectOutlined />
<DislikeOutlined />
<DollarCircleOutlined />
<DollarOutlined />
<DownloadOutlined />
<EllipsisOutlined />
<EnvironmentOutlined />
<EuroCircleOutlined />
<EuroOutlined />
<ExceptionOutlined />
<ExpandAltOutlined />
<ExpandOutlined />
<ExperimentOutlined />
<ExportOutlined />
<EyeOutlined />
<FieldBinaryOutlined />
<FieldNumberOutlined />
<FieldStringOutlined />
<DesktopOutlined />
<DingtalkOutlined />
<FileAddOutlined />
<FileDoneOutlined />
<FileExcelOutlined />
<FileExclamationOutlined />
<FileOutlined />
<FileImageOutlined />
<FileJpgOutlined />
<FileMarkdownOutlined />
<FilePdfOutlined />
<FilePptOutlined />
<FileProtectOutlined />
<FileSearchOutlined />
<FileSyncOutlined />
<FileTextOutlined />
<FileUnknownOutlined />
<FileWordOutlined />
<FilterOutlined />
<FireOutlined />
<FlagOutlined />
<FolderAddOutlined />
<FolderOutlined />
<FolderOpenOutlined />
<ForkOutlined />
<FormatPainterOutlined />
<FrownOutlined />
<FunctionOutlined />
<FunnelPlotOutlined />
<GatewayOutlined />
<GifOutlined />
<GiftOutlined />
<GlobalOutlined />
<GoldOutlined />
<GroupOutlined />
<HddOutlined />
<HeartOutlined />
<HistoryOutlined />
<HomeOutlined />
<HourglassOutlined />
<IdcardOutlined />
<ImportOutlined />
<InboxOutlined />
<InsertRowAboveOutlined />
<InsertRowBelowOutlined />
<InsertRowLeftOutlined />
<InsertRowRightOutlined />
<InsuranceOutlined />
<InteractionOutlined />
<KeyOutlined />
<LaptopOutlined />
<LayoutOutlined />
<LikeOutlined />
<LineOutlined />
<LinkOutlined />
<Loading3QuartersOutlined />
<LoadingOutlined />
<LockOutlined />
<MailOutlined />
<ManOutlined />
<MedicineBoxOutlined />
<MehOutlined />
<MenuOutlined />
<MergeCellsOutlined />
<MessageOutlined />
<MobileOutlined />
<MoneyCollectOutlined />
<MonitorOutlined />
<MoreOutlined />
<NodeCollapseOutlined />
<NodeExpandOutlined />
<NodeIndexOutlined />
<NotificationOutlined />
<NumberOutlined />
<PaperClipOutlined />
<PartitionOutlined />
<PayCircleOutlined />
<PercentageOutlined />
<PhoneOutlined />
<PictureOutlined />
<PoundCircleOutlined />
<PoundOutlined />
<PoweroffOutlined />
<PrinterOutlined />
<ProfileOutlined />
<ProjectOutlined />
<PropertySafetyOutlined />
<PullRequestOutlined />
<PushpinOutlined />
<QrcodeOutlined />
<ReadOutlined />
<ReconciliationOutlined />
<RedEnvelopeOutlined />
<ReloadOutlined />
<RestOutlined />
<RobotOutlined />
<RocketOutlined />
<SafetyCertificateOutlined />
<SafetyOutlined />
<ScanOutlined />
<ScheduleOutlined />
<SearchOutlined />
<SecurityScanOutlined />
<SelectOutlined />
<SendOutlined />
<SettingOutlined />
<ShakeOutlined />
<ShareAltOutlined />
<ShopOutlined />
<ShoppingCartOutlined />
<ShoppingOutlined />
<SisternodeOutlined />
<SkinOutlined />
<SmileOutlined />
<SolutionOutlined />
<SoundOutlined />
<SplitCellsOutlined />
<StarOutlined />
<SubnodeOutlined />
<SyncOutlined />
<TableOutlined />
<TabletOutlined />
<TagOutlined />
<TagsOutlined />
<TeamOutlined />
<ThunderboltOutlined />
<ToTopOutlined />
<ToolOutlined />
<TrademarkCircleOutlined />
<TrademarkOutlined />
<TransactionOutlined />
<TrophyOutlined />
<UngroupOutlined />
<UnlockOutlined />
<UploadOutlined />
<UsbOutlined />
<UserAddOutlined />
<UserDeleteOutlined />
<UserOutlined />
<UserSwitchOutlined />
<UsergroupAddOutlined />
<UsergroupDeleteOutlined />
<VideoCameraOutlined />
<WalletOutlined />
<WifiOutlined />
<BorderlessTableOutlined />
<WomanOutlined />
<BehanceOutlined />
<DropboxOutlined />
<DeploymentUnitOutlined />
<UpCircleOutlined />
<DownCircleOutlined />
<LeftCircleOutlined />
<RightCircleOutlined />
<UpSquareOutlined />
<DownSquareOutlined />
<LeftSquareOutlined />
<RightSquareOutlined />
<PlayCircleOutlined />
<QuestionCircleOutlined />
<PlusCircleOutlined />
<PlusSquareOutlined />
<MinusSquareOutlined />
<MinusCircleOutlined />
<InfoCircleOutlined />
<ExclamationCircleOutlined />
<CloseCircleOutlined />
<CloseSquareOutlined />
<CheckCircleOutlined />
<CheckSquareOutlined />
<ClockCircleOutlined />
<FormOutlined />
<DashOutlined />
<SmallDashOutlined />
<YoutubeOutlined />
<CodepenCircleOutlined />
<AliyunOutlined />
<PlusOutlined />
<LinkedinOutlined />
<AimOutlined />
<BugOutlined />
<CloudDownloadOutlined />
<CloudServerOutlined />
<CloudSyncOutlined />
<CloudUploadOutlined />
<CommentOutlined />
<ConsoleSqlOutlined />
<EyeInvisibleOutlined />
<FileGifOutlined />
<DeliveredProcedureOutlined />
<FieldTimeOutlined />
<FileZipOutlined />
<FolderViewOutlined />
<FundProjectionScreenOutlined />
<FundViewOutlined />
<MacCommandOutlined />
<PlaySquareOutlined />
<OneToOneOutlined />
<RotateLeftOutlined />
<RotateRightOutlined />
<SaveOutlined />
<SwitcherOutlined />
<TranslationOutlined />
<VerifiedOutlined />
<VideoCameraAddOutlined />
<WhatsAppOutlined />
{/*</Col>*/}
</Row>
);
}
Example #3
Source File: index.tsx From foodie with MIT License | 4 votes |
Header: React.FC<IProps> = ({ profile, auth }) => {
const [isUploadingProfileImage, setIsUploadingProfileImage] = useState(false);
const [isUploadingCoverPhoto, setIsUploadingCoverPhoto] = useState(false);
const history = useHistory();
const { isOpen, openModal, closeModal } = useModal();
const dispatch = useDispatch();
const coverPhotoOverlayRef = useRef<HTMLDivElement | null>(null);
const coverPhotoRef = useRef<HTMLDivElement | null>(null);
const coverPhoto = useFileHandler<IImage>('single', initImageState);
const profilePicture = useFileHandler<IImage>('single', initImageState);
useEffect(() => {
const cp = coverPhotoRef.current;
const cpo = coverPhotoOverlayRef.current;
if (cp && cpo && profile.isOwnProfile && window.screen.width > 800) {
cp.addEventListener('mouseover', overlayOnMouseOver);
cp.addEventListener('mouseout', overlayOnMouseOut);
}
return () => {
if (cp && cpo) {
cp.removeEventListener('mouseover', overlayOnMouseOver);
cp.removeEventListener('mouseout', overlayOnMouseOut);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [coverPhoto.imageFile.file, isUploadingCoverPhoto, profile.isOwnProfile]);
const overlayOnMouseOver = () => {
if (!isUploadingCoverPhoto && coverPhotoOverlayRef.current) {
coverPhotoOverlayRef.current.style.visibility = 'visible';
}
}
const overlayOnMouseOut = () => {
if (!isUploadingCoverPhoto && !coverPhoto.imageFile.file && coverPhotoOverlayRef.current) {
coverPhotoOverlayRef.current.style.visibility = 'hidden';
}
}
const handleProfilePictureFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
profilePicture.onFileChange(e, () => {
openModal();
});
};
const onCropSuccessCallback = async (file: File) => {
const formData = new FormData();
formData.append('photo', file);
try {
setIsUploadingProfileImage(true);
toast('Uploading...', { hideProgressBar: true, bodyStyle: { color: '#1a1a1a' } });
const { image } = await uploadPhoto(formData, 'picture');
dispatch(updateProfilePicture(image));
dispatch(updateAuthPicture(image));
setIsUploadingProfileImage(false);
toast.dismiss();
toast.dark('Profile picture successfully changed.', { hideProgressBar: true });
} catch (e) {
console.log(e);
setIsUploadingProfileImage(false);
toast.error(e.error.message);
}
};
const handleSaveCoverPhoto = async () => {
if (coverPhoto.imageFile.file) {
const formData = new FormData();
formData.append('photo', coverPhoto.imageFile.file);
try {
setIsUploadingCoverPhoto(true);
toast('Uploading Cover Photo...', { hideProgressBar: true, bodyStyle: { color: '#1a1a1a' } });
const { image } = await uploadPhoto(formData, 'cover');
dispatch(updateCoverPhoto(image));
setIsUploadingCoverPhoto(false);
coverPhoto.clearFiles();
toast.dismiss();
toast.dark('Cover photo successfully changed.', { hideProgressBar: true });
} catch (e) {
console.log(e);
setIsUploadingCoverPhoto(false);
toast.error(e.error.message);
}
}
}
const onClickMessage = () => {
dispatch(initiateChat({
username: profile.username,
id: profile.id,
fullname: profile.fullname || '',
profilePicture: profile.profilePicture?.url || ''
}));
if (window.screen.width < 1024) {
history.push(`/chat/${profile.username}`);
}
}
return (
<div>
<CropProfileModal
isOpen={isOpen}
closeModal={closeModal}
openModal={openModal}
file={profilePicture.imageFile}
onCropSuccessCallback={onCropSuccessCallback}
/>
{/* ----- COVER PHOTO ------- */}
<div className="w-full h-60 mb-8 laptop:mb-0 laptop:h-80 bg-gray-200 dark:bg-gray-800 relative overflow-hidden" ref={coverPhotoRef}>
{/* ---- OVERLAY FOR CHOOSING PHOTO AND SHOWING LOADER ----- */}
<CoverPhotoOverlay
coverPhotoOverlayRef={coverPhotoOverlayRef}
coverPhoto={coverPhoto}
isUploadingCoverPhoto={isUploadingCoverPhoto}
isOwnProfile={profile.isOwnProfile}
handleSaveCoverPhoto={handleSaveCoverPhoto}
/>
{/* ---- ACTUAL COVER PHOTO ---- */}
<img
alt=""
className="w-full h-full object-cover"
src={coverPhoto.imageFile.url || profile.coverPhoto?.url || `https://source.unsplash.com/oDhGIbegZNI/1400x900`}
/>
</div>
<div className="laptop:px-6% w-full relative flex mt-2 laptop:transform laptop:-translate-y-2/4">
{/* --- PROFILE PICTURE */}
<div className="absolute left-0 right-0 mx-auto w-40 h-40 transform -translate-y-44 laptop:transform-none laptop:relative laptop:w-1/3 laptop:h-60 laptop:mr-2 flex justify-center">
{(!coverPhoto.imageFile.file) && (
<>
<div
className="w-full h-full laptop:w-60 laptop:h-60 !bg-cover !bg-no-repeat rounded-full border-4 border-white dark:border-indigo-1000 overflow-hidden"
style={{
background: `#f7f7f7 url(${profile.profilePicture?.url || avatar_placeholder})`
}}
>
{isUploadingProfileImage && (
<div className="w-full h-full bg-black bg-opacity-50 flex items-center justify-center">
<Loader mode="light" />
</div>
)}
</div>
{/* ---- UPDLOAD PROFILE PICTURE ---- */}
{profile.isOwnProfile && (
<div>
<input
type="file"
hidden
accept="image/*"
onChange={handleProfilePictureFileChange}
readOnly={isUploadingProfileImage}
id="picture"
/>
<label
htmlFor="picture"
>
<div className="flex items-center w-10 h-10 justify-center cursor-pointer p-4 bg-indigo-700 rounded-full absolute -bottom-2 laptop:bottom-0 left-14 hover:bg-indigo-800">
<CameraOutlined className="text-xl flex items-center justify-center text-white" />
</div>
</label>
</div>
)}
</>
)}
</div>
<div className="flex w-full flex-col self-end">
<div className="px-4 laptop:px-0 w-full flex items-center flex-col laptop:flex-row justify-between mb-2 laptop:ml-2 laptop:mr-14">
{/* ---- NAME AND USERNAME */}
<div className="text-center laptop:text-left mb-4 laptop:mb-0">
<h2 className="text-3xl dark:text-white">{profile.fullname || `@${profile.username}`}</h2>
<span className="text-indigo-700 dark:text-indigo-400">{profile.fullname && `@${profile.username}`}</span>
</div>
{/* ---- FOLLOW/UNFOLLOW/MESSAGE BUTTON */}
{!profile.isOwnProfile ? (
<div className="flex justify-center laptop:justify-start space-x-4 items-start">
<FollowButton isFollowing={profile.isFollowing} userID={profile.id} />
<button
className="button--muted !border-gray-400 !rounded-full flex items-center dark:bg-indigo-1100 dark:text-white dark:hover:text-white dark:hover:bg-indigo-900 dark:!border-gray-800"
onClick={onClickMessage}
>
<MessageOutlined className="flex items-center justify-center mr-2" />
Message
</button>
</div>
) : (
<button
className="button--muted !rounded-full !border !border-gray-400 !focus:bg-gray-200 !py-2 flex items-center justify-center dark:bg-indigo-1100 dark:text-white dark:hover:text-white dark:hover:bg-indigo-900 dark:!border-gray-800"
onClick={() => history.push(`/user/${profile.username}/edit`)}
>
<EditOutlined className="text-xl mr-4" />
Edit Profile
</button>
)}
</div>
{/* ---- PROFILE NAVS ----- */}
<Tabs
username={profile.username}
isOwnProfile={profile.id === auth.id}
followersCount={profile.followersCount}
followingCount={profile.followingCount}
/>
</div>
</div>
</div>
);
}
Example #4
Source File: index.tsx From nanolooker with MIT License | 4 votes |
Search = ({ isHome = false }) => {
const { t } = useTranslation();
const { theme } = React.useContext(PreferencesContext);
const { knownAccounts } = React.useContext(KnownAccountsContext);
const { bookmarks } = React.useContext(BookmarksContext);
const hasAccountBookmarks = !!Object.keys(bookmarks?.account || {}).length;
const [isExpanded, setIsExpanded] = React.useState(isHome);
const [isError, setIsError] = React.useState(false);
const [filteredResults, setFilteredResults] = React.useState([] as any);
const { searchValue, setSearchValue } = useSearch();
const [accountBookmarks, setAccountBookmarks] = React.useState<
{ alias: string; account: string }[]
>([]);
const {
searchHistory,
addSearchHistory,
removeSearchHistory,
} = useSearchHistory();
const searchRef = React.useRef(null);
const [isOpen, setIsOpen] = React.useState(false);
const [invalidQrCode, setInvalidQrCode] = React.useState("");
let history = useHistory();
const validateSearch = React.useCallback(
async (value: any) => {
if (!value) {
setIsError(false);
setFilteredResults([]);
} else {
const isValidAccount = isValidAccountAddress(value);
const isValidBlock = isValidBlockHash(value);
setIsError(!isValidAccount && !isValidBlock && value.length > 30);
if (isValidBlock) {
addSearchHistory(value.toUpperCase());
history.push(`/block/${value.toUpperCase()}`);
} else if (isValidAccount) {
let account = getPrefixedAccount(value);
setSearchValue(account);
addSearchHistory(account);
history.push(`/account/${account}`);
} else {
const filteredKnownAccounts = knownAccounts
.filter(({ alias }) =>
alias.toLowerCase().includes(value.toLowerCase()),
)
.map(item => renderItem(item));
const filteredAccountBookmarks = accountBookmarks
.filter(({ alias }) =>
alias.toLowerCase().includes(value.toLowerCase()),
)
.map(item => renderItem(item as KnownAccount));
setFilteredResults(
filteredAccountBookmarks.concat(filteredKnownAccounts),
);
}
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[addSearchHistory, knownAccounts, accountBookmarks],
);
React.useEffect(() => {
if (hasAccountBookmarks) {
setAccountBookmarks(
Object.entries(bookmarks?.account).map(([account, alias]) => ({
account,
alias,
})),
);
} else {
setAccountBookmarks([]);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasAccountBookmarks]);
React.useEffect(() => {
validateSearch(searchValue);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchValue]);
React.useEffect(() => {
if (!isOpen) return;
function onScanSuccess(qrMessage: any) {
if (isValidAccountAddress(qrMessage)) {
setIsOpen(false);
setSearchValue(getPrefixedAccount(qrMessage));
document.getElementById("html5-qrcode-scan-stop-btn")?.click();
} else {
setInvalidQrCode(qrMessage);
}
}
const html5QrcodeScanner = new window.Html5QrcodeScanner(
`qrcode-reader-search${isHome ? "-home" : ""}`,
{
fps: 10,
qrbox: 250,
},
);
html5QrcodeScanner.render(onScanSuccess);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isOpen]);
const renderItem = ({ alias, account }: KnownAccount) => ({
value: account,
label: (
<>
<strong style={{ display: "block" }}>{alias}</strong>
{account}
</>
),
});
return (
<>
<AutoComplete
style={{
float: isExpanded ? "right" : "none",
maxWidth: "calc(100vw - 24px)",
width: isExpanded ? "650px" : "100%",
// transitionDelay: `${isExpanded ? 0 : 0.2}s`,
}}
dropdownClassName={`search-autocomplete-dropdown ${
theme === Theme.DARK ? "theme-dark" : ""
}`}
dropdownStyle={{
maxWidth: "calc(100vw - 40px)",
}}
options={filteredResults}
// @ts-ignore
onSelect={validateSearch}
onChange={value => {
setSearchValue(value);
}}
// @ts-ignore
onPaste={e => {
e.preventDefault();
// @ts-ignore
const paste = (e.clipboardData || window.clipboardData).getData(
"text",
);
const account = getAccountAddressFromText(paste);
const hash = getAccountBlockHashFromText(paste);
if (account || hash) {
setSearchValue(account || hash);
} else {
setSearchValue(paste);
}
}}
value={searchValue}
>
<Input
ref={searchRef}
allowClear
suffix={
<>
<CameraOutlined
onClick={() => setIsOpen(true)}
className="search-history-icon"
style={{ padding: "6px", marginRight: "3px" }}
/>
<Dropdown
key="search-history-dropdown"
overlayStyle={{ zIndex: 1050 }}
overlayClassName={theme === Theme.DARK ? "theme-dark" : ""}
overlay={
<Menu>
{!searchHistory.length ? (
<Menu.Item disabled>{t("search.noHistory")}</Menu.Item>
) : (
searchHistory.map(history => (
<Menu.Item
onClick={() => setSearchValue(history)}
key={history}
>
<div
className="color-normal"
style={{
display: "flex",
alignItems: "flex-start",
}}
>
<div>
{isValidAccountAddress(history) ? (
<WalletOutlined />
) : (
<BlockOutlined />
)}
</div>
<div
className="break-word"
style={{ margin: "0 6px", whiteSpace: "normal" }}
>
{history}
</div>
<DeleteButton
onClick={(e: Event) => {
e.stopPropagation();
removeSearchHistory(history);
}}
/>
</div>
</Menu.Item>
))
)}
</Menu>
}
placement="bottomRight"
>
<HistoryOutlined
className="search-history-icon"
style={{ padding: "6px", marginRight: "6px" }}
/>
</Dropdown>
<SearchOutlined />
</>
}
className={`ant-input-search ${isError ? "has-error" : ""}`}
placeholder={t("search.searchBy")}
onFocus={({ target: { value } }) => {
validateSearch(value);
setIsExpanded(true);
}}
onBlur={() => setIsExpanded(isHome || false)}
size={isHome ? "large" : "middle"}
spellCheck={false}
/>
</AutoComplete>
<Modal
title={t("search.scanWallet")}
visible={isOpen}
onCancel={() => setIsOpen(false)}
footer={[
<Button key="back" onClick={() => setIsOpen(false)}>
{t("common.cancel")}
</Button>,
]}
>
{invalidQrCode ? (
<Alert
message={t("pages.nanoquakejs.invalidAccount")}
description={invalidQrCode}
type="error"
showIcon
style={{ marginBottom: 12 }}
/>
) : null}
<div
id={`qrcode-reader-search${isHome ? "-home" : ""}`}
className="qrcode-reader"
></div>
</Modal>
</>
);
}
Example #5
Source File: Register.tsx From nanolooker with MIT License | 4 votes |
Register: React.FC = () => {
const { t } = useTranslation();
const [isOpen, setIsOpen] = React.useState(false);
const [isSending, setIsSending] = React.useState(false);
const [registerError, setRegisterError] = React.useState("");
const [invalidQrCode, setInvalidQrCode] = React.useState("");
const [section, setSection] = React.useState(Sections.REGISTER);
const {
nanoQuakeJSUsername,
setNanoQuakeJSUsername,
nanoQuakeJSAccount,
setNanoQuakeJSAccount,
} = React.useContext(PreferencesContext);
const {
control,
handleSubmit,
trigger,
setValue,
getValues,
formState: { errors, isValid },
} = useForm({
defaultValues: {
username: nanoQuakeJSUsername || "",
account: nanoQuakeJSAccount || "",
},
mode: "onChange",
});
const onSubmit = async ({
username,
account,
}: {
username: string;
account: string;
}) => {
setIsSending(true);
setRegisterError("");
// Prefix account with nano_
const address = getPrefixedAccount(account);
try {
const res = await fetch("/api/nanoquakejs/register", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username,
address,
}),
});
const json = await res.json();
if (!json.error) {
setNanoQuakeJSUsername(username);
setNanoQuakeJSAccount(address);
setIsOpen(false);
Tracker.ga4?.gtag("event", "NanoQuakeJS - Register");
} else {
setRegisterError(
json.error === "already_registered"
? t("pages.nanoquakejs.registerErrorUsername")
: t("pages.nanoquakejs.registerError"),
);
}
} catch (err) {
setRegisterError(t("pages.nanoquakejs.registerError"));
}
setIsSending(false);
};
React.useEffect(() => {
if (!isOpen) {
setSection(Sections.REGISTER);
setInvalidQrCode("");
setRegisterError("");
}
}, [isOpen]);
React.useEffect(() => {
if (section !== Sections.SCAN) return;
function onScanSuccess(qrMessage: any) {
if (isValidAccountAddress(qrMessage)) {
setValue("account", getPrefixedAccount(qrMessage));
trigger("account");
document.getElementById("html5-qrcode-scan-stop-btn")?.click();
setSection(Sections.REGISTER);
} else {
setInvalidQrCode(qrMessage);
}
}
const html5QrcodeScanner = new window.Html5QrcodeScanner("qrcode-reader", {
fps: 10,
qrbox: 250,
});
html5QrcodeScanner.render(onScanSuccess);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [section]);
return (
<>
<Row
style={{
textAlign: "center",
paddingBottom: "3px",
border: "none",
marginTop: -12,
}}
>
<Col xs={24}>
<Space size={12} align="center" direction="vertical">
{nanoQuakeJSUsername && nanoQuakeJSAccount ? (
<Play />
) : (
<Button
type="primary"
size="large"
shape="round"
onClick={() => setIsOpen(true)}
>
{t("pages.nanoquakejs.register")}
</Button>
)}
<QRCodeModal
account={NANOQUAKEJS_DONATION_ACCOUNT}
header={<Text>NanoQuakeJS</Text>}
>
<Button ghost type="primary" size="small" shape="round">
{t("pages.nanoquakejs.donatePrizePool")}
</Button>
</QRCodeModal>
<p className="default-color" style={{ textAlign: "left" }}>
{t("pages.nanoquakejs.payoutDescription")}
</p>
</Space>
</Col>
</Row>
<Modal
title={
section === Sections.REGISTER
? t("pages.nanoquakejs.register")
: t("pages.nanoquakejs.scanWallet")
}
visible={isOpen}
// @ts-ignore
onOk={
Sections.REGISTER
? handleSubmit(onSubmit)
: setSection(Sections.REGISTER)
}
okText={t("pages.nanoquakejs.register")}
okButtonProps={{
disabled: !isValid,
}}
confirmLoading={isSending}
onCancel={() => {
section === Sections.REGISTER
? setIsOpen(false)
: setSection(Sections.REGISTER);
}}
cancelText={t("common.cancel")}
>
{section === Sections.REGISTER ? (
<>
{registerError ? (
<Alert
message={registerError}
type="error"
showIcon
style={{ marginBottom: 12 }}
/>
) : null}
<form onSubmit={handleSubmit(onSubmit)}>
<Space size={12} direction="vertical" style={{ width: "100%" }}>
<Text>{t("pages.nanoquakejs.registerDescription")}</Text>
<Space size={3} direction="vertical" style={{ width: "100%" }}>
<Text>{t("pages.nanoquakejs.inGameUsername")}</Text>
<Controller
render={({ field }) => (
<Input
{...field}
type="text"
readOnly={isSending}
maxLength={32}
autoFocus={!!getValues("username")}
suffix={
getValues("username") && !errors?.username ? (
<CheckCircleTwoTone twoToneColor={"#52c41a"} />
) : (
" "
)
}
/>
)}
rules={{
validate: (value: string) =>
value.length >= 3 && !/\s/.test(value),
}}
control={control}
name="username"
defaultValue={getValues("username")}
/>
</Space>
<Space size={3} direction="vertical" style={{ width: "100%" }}>
<Text>{t("pages.nanoquakejs.accountReceivePayouts")}</Text>
<Controller
render={({ field }) => (
<Input
{...field}
readOnly={isSending}
placeholder="nano_"
suffix={
getValues("account") && !errors?.account ? (
<CheckCircleTwoTone twoToneColor={"#52c41a"} />
) : (
<Button
size="small"
type="text"
style={{ margin: "-1px -7px -1px" }}
onClick={() => setSection(Sections.SCAN)}
>
<CameraOutlined />
</Button>
)
}
/>
)}
rules={{
validate: (value: string) => isValidAccountAddress(value),
}}
control={control}
name="account"
defaultValue={getValues("account")}
/>
</Space>
<Text style={{ fontSize: 12 }} className="color-muted">
* {t("pages.nanoquakejs.registerNote")}
</Text>
</Space>
</form>
</>
) : null}
{section === Sections.SCAN ? (
<>
{invalidQrCode ? (
<Alert
message={t("pages.nanoquakejs.invalidAccount")}
description={invalidQrCode}
type="error"
showIcon
style={{ marginBottom: 12 }}
/>
) : null}
<div id="qrcode-reader" className="qrcode-reader"></div>
</>
) : null}
</Modal>
</>
);
}