import { Avatar, Button, Col, Dropdown, Input, Row, Select } from "antd";
import { UserReadPrivateResponse } from "@newstackdev/iosdk-newgraph-client-js";
import type { SizeType } from "antd/es/config-provider/SizeContext";
import { Callback, NLView } from "../../types";
import { ContentImage } from "../../Components/Image";
import { Searchicon } from "../../Components/Icons/Searchicon";
import { Tag } from "antd-latest";
import { UsersList } from "../../Components/UserWidget";
import { VerifiedIcon } from "../..//Components/Icons/VerifiedIcon";
import { isEmpty, map, uniqBy } from "lodash";
import { json } from "overmind";
import { useActions, useAppState } from "../../overmind";
import { useEffect, useRef, useState } from "react";
import { useVerified } from "../../hooks/useVerified";
import OutsideClickHandler from "react-outside-click-handler";
export const UserSearchResultsWidget: NLView<{ query: string }> = ({ query }) => {
const state = useAppState();
const actions = useActions();
const res = state.lists.search.users.results;
useEffect(() => {
actions.lists.searchUsers({ query });
}, [query]);
return (
{res && res?.value?.length ? (
) : res && !res?.value?.length ? (
"No results"
) : (
""
)}
);
};
export const TagsAutosuggestWidget: NLView<{ query: string }> = ({ query }) => {
const state = useAppState();
const actions = useActions();
const res = uniqBy(json(state.lists.search.tags.results)?.value || [], (t: any) => t.tag);
useEffect(() => {
actions.lists.searchTags({ query });
}, [query]);
return (
{res.length
? res.map((t: any) => (
actions.routing.historyPush({
location: `/search?tags=${t.tag}`,
})
}
>
{t.tag}
))
: res && !res?.length
? "No results"
: ""}
);
};
type SearchResultsWidget = typeof UserSearchResultsWidget;
const SearchResultsByMode = {
"@": UserSearchResultsWidget,
"#": TagsAutosuggestWidget,
};
export const SearchWidget: NLView<{
user?: UserReadPrivateResponse;
searchUsers?: boolean;
searchTags?: boolean;
noNavigation?: boolean;
onChange?: Callback;
showSearch?: boolean;
setSelection?: React.Dispatch>;
selection?: string;
visibleBar?: boolean;
hidePrefixIcon?: boolean;
searchSize?: SizeType;
noAutoHide?: boolean;
disablePlaceholder?: boolean;
suffixIcon?: React.ReactNode;
hideClearBtn?: boolean;
// search: boolean;
// setSearch: React.Dispatch>;
}> = ({
user,
searchUsers,
searchTags,
noNavigation,
onChange,
showSearch,
setSelection,
selection,
visibleBar,
hidePrefixIcon,
searchSize,
noAutoHide,
disablePlaceholder = false,
suffixIcon,
hideClearBtn = false,
}) => {
const state = useAppState();
const actions = useActions();
const [query, setQuery] = useState("");
const [visible, setVisible] = useState(false);
const maybeSetVisible = (visible: boolean) => (visible || !noAutoHide) && setVisible(visible);
const [mouseVisible, setMouseVisible] = useState(false);
const [open, _setOpen] = useState(true);
const setOpen = (v) => {
_setOpen(v);
console.log();
};
const [loading, setLoading] = useState(false);
const [filterState, setFilterState] = useState<"Member" | "Tag" | undefined>(undefined);
const foundUsers = state.lists.search.users?.results?.value || [];
const foundTags = Array.from(new Set((state.lists.search.tags?.results?.value || []).map((t) => t.tag))) || [];
const { verifiedUsers } = useVerified(map(foundUsers, "username"));
const [currVal, setCurrVal] = useState("");
useEffect(() => {
const searchForResults = async () => {
if (query.length < 3) return;
setLoading(true);
const queryUsers = searchUsers && actions.lists.searchUsers({ query });
const queryTags = searchTags && actions.lists.searchTags({ query });
await Promise.all([queryUsers, queryTags]);
setLoading(false);
};
searchForResults();
}, [query]);
const _setSelection = (v: string = "") => {
setSelection && setSelection(v);
onChange && onChange(v);
setCurrVal(v);
};
const setInitialState = () => {
setQuery("");
maybeSetVisible(false);
setOpen(false);
// _setSelection && _setSelection("");
};
const onSearch = (query: string) => {
setQuery(query);
setOpen(true);
};
const onSelect = (value: string) => {
setOpen(false);
const mode = /^[@#]/.test(value[0]) ? value[0] : "#";
const v = value.replace(/^[@#]/, "");
const path = mode === "#" ? `/search?tags=${v}` : `/user/${v}`;
if (v === selection?.toString()) {
return;
}
if (!noNavigation)
actions.routing.historyPush({
location: path,
});
maybeSetVisible(false);
_setSelection(v);
setQuery("");
};
// const onDeselect = (value: string) => {
// const v = value.replace(/^[@#]/, "");
// setSelection && setSelection((p) => [...p.filter((pVal) => pVal !== v)]);
// };
const tagRender = (props) => {
const { label, value, closable, onClose } = props;
const onPreventMouseDown = (event) => {
event.preventDefault();
event.stopPropagation();
};
return (
{
_setSelection();
onClose();
}}
>
{label}
);
};
const refWrapper = useRef();
const refDropdown = useRef();
useEffect(() => {
const outsideClick = (e) => {
let el = e.target;
const rs = [refWrapper.current, refDropdown.current];
while (el) {
if (rs.includes(el)) return;
el = el.parentNode;
}
setInitialState();
};
document.body.addEventListener("click", outsideClick);
return () => document.body.removeEventListener("click", outsideClick);
});
return (
{!hidePrefixIcon && (
maybeSetVisible(!visible)}>
)}
setMouseVisible(false)}
onMouseOver={() => setMouseVisible(true)}
>
{visibleBar || mouseVisible || visible ? (
) : (
<>>
)
}
// value={selection ? undefined : []}
// tagRender={tagRender}
searchValue={query}
loading={loading}
open={open && !isEmpty(query)}
placeholder={disablePlaceholder ? "" : "Search..."}
onSearch={(query) => onSearch(query)}
suffixIcon={suffixIcon && isEmpty(query) ? suffixIcon : null}
onFocus={() => setVisible(true)}
size={searchSize}
onSelect={(value: string) => onSelect(value)}
// onDeselect={onDeselect}
dropdownRender={(menu) => (
<>
{foundUsers.length > 0 && foundTags.length > 0 && searchTags && searchUsers ? (
<>
{
setFilterState("Member");
setVisible(true);
}}
>
Member
{
setFilterState("Tag");
setVisible(true);
}}
>
Hashtag
>
) : (
<>>
)}
{menu}
>
)}
>
{foundUsers?.map((u) => {
const isUserVerified = verifiedUsers && u.username && verifiedUsers.includes(u.username);
if (filterState === "Tag") return;
return (
} />
{u.username}
{isUserVerified && }
);
})}
{foundTags.map((t) => {
if (filterState === "Member") return;
return (
#
}
/>
{t}
);
})}
) : (
)}
);
};