creating and retrieving links successfully
This commit is contained in:
@@ -1,16 +1,27 @@
|
||||
import { Link } from "@nirvana/common/models/conversation";
|
||||
import { conversationService } from "@nirvana/common/services";
|
||||
import Modal from "antd/lib/modal/Modal";
|
||||
import { useState, useEffect } from "react";
|
||||
import Image from "next/image";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import LinkIcon from "./LinkIcon";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { useAuth } from "../../contexts/authContext";
|
||||
import { selectedConvoAtom } from "../../recoil/main";
|
||||
import LinkIcon, { getFavicon } from "./LinkIcon";
|
||||
|
||||
export default function CreateItemModal(props: {
|
||||
pastedLink: string;
|
||||
show: boolean;
|
||||
handleClose: () => void;
|
||||
}) {
|
||||
const { currUser } = useAuth();
|
||||
|
||||
const [linkVal, setLinkVal] = useState<string>("");
|
||||
const [linkDesc, setLinkDesc] = useState<string>("");
|
||||
const linkInput = useRef<HTMLInputElement>();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
const selectedConvoId = useRecoilValue(selectedConvoAtom);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.pastedLink) {
|
||||
@@ -18,9 +29,55 @@ export default function CreateItemModal(props: {
|
||||
}
|
||||
}, [props.pastedLink]);
|
||||
|
||||
const handleCreate = () => {
|
||||
console.log("added drawer item");
|
||||
toast.success("added drawer item to conversation");
|
||||
useEffect(() => {
|
||||
linkInput.current?.focus();
|
||||
}, [props.show]);
|
||||
|
||||
const handleCreate = async () => {
|
||||
if (loading) {
|
||||
toast("in the process of sharing...");
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
// validations
|
||||
if (!linkVal) {
|
||||
toast.error("must put a link");
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
if (!linkDesc) {
|
||||
toast.error("must put a name of some sort");
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// service to add link to the collection
|
||||
// change the cacheddraweritem on the convo doc
|
||||
const newLink = new Link(linkDesc, linkVal, currUser!.uid);
|
||||
|
||||
await conversationService.shareLink(
|
||||
currUser!.uid,
|
||||
newLink,
|
||||
selectedConvoId!
|
||||
);
|
||||
|
||||
toast.success("shared");
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error("problem in sharing link");
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
resetForm();
|
||||
props.handleClose();
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
setLinkDesc("");
|
||||
setLinkVal("");
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
@@ -28,15 +85,44 @@ export default function CreateItemModal(props: {
|
||||
props.handleClose();
|
||||
};
|
||||
|
||||
const handleChangeLinkInput = (e) => {
|
||||
setLinkVal(e.target.value);
|
||||
|
||||
// todo: find the tab name of the url
|
||||
};
|
||||
|
||||
function addDefaultSrc(ev) {
|
||||
ev.target.src = getFavicon("www.com");
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="Share"
|
||||
onOk={handleCreate}
|
||||
onCancel={handleCancel}
|
||||
footer={
|
||||
<span className="flex flex-row justify-end space-x-2">
|
||||
<button
|
||||
onClick={handleCancel}
|
||||
className="rounded-lg p-2 border space-x-2
|
||||
text-slate-400 text-xs hover:bg-slate-50"
|
||||
>
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={handleCreate}
|
||||
type="submit"
|
||||
className="rounded-lg font-semibold bg-teal-600 p-2 text-white shadow-lg"
|
||||
>
|
||||
<span>Share</span>
|
||||
</button>
|
||||
</span>
|
||||
}
|
||||
visible={props.show}
|
||||
{...props}
|
||||
>
|
||||
<span className="flex flex-col space-y-5">
|
||||
<form onSubmit={handleCreate} className="flex flex-col space-y-5">
|
||||
<span className="flex flex-col items-start">
|
||||
<span className="text-lg font-semibold">Link</span>
|
||||
<span className="text-gray-300 text-sm mb-2">
|
||||
@@ -44,17 +130,22 @@ export default function CreateItemModal(props: {
|
||||
</span>
|
||||
{/* icon and link input */}
|
||||
<span className="flex flex-row items-center space-x-2 w-full">
|
||||
<LinkIcon
|
||||
className="text-3xl"
|
||||
linkType={Link.getLinkType(linkVal)}
|
||||
/>
|
||||
{linkVal && (
|
||||
<img
|
||||
height="30"
|
||||
width="30"
|
||||
src={getFavicon(linkVal)}
|
||||
onError={addDefaultSrc}
|
||||
/>
|
||||
)}
|
||||
|
||||
<input
|
||||
ref={linkInput}
|
||||
autoFocus
|
||||
className="flex-1 rounded-lg bg-gray-50 p-3"
|
||||
value={linkVal}
|
||||
placeholder="https://jira.atlassian.com/team/xxx"
|
||||
onChange={(e) => setLinkVal(e.target.value)}
|
||||
onChange={handleChangeLinkInput}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
@@ -72,7 +163,7 @@ export default function CreateItemModal(props: {
|
||||
onChange={(e) => setLinkDesc(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ import Link, { LinkType } from "@nirvana/common/models/conversation";
|
||||
|
||||
import { SiGooglemeet, SiZoom } from "react-icons/si";
|
||||
|
||||
const faviconGrabberAPI = "https://api.statvoo.com/favicon/?url=";
|
||||
export function getFavicon(url: string): string {
|
||||
return faviconGrabberAPI + url;
|
||||
}
|
||||
|
||||
export default function LinkIcon(props: {
|
||||
className?: string;
|
||||
linkType: LinkType;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Link } from "@nirvana/common/models/conversation";
|
||||
import { Tooltip } from "antd";
|
||||
import { linkWithCredential } from "firebase/auth";
|
||||
import moment from "moment";
|
||||
import link from "next/link";
|
||||
import { FaImages, FaExternalLinkAlt } from "react-icons/fa";
|
||||
import { getFavicon } from "./LinkIcon";
|
||||
|
||||
export default function SharedItemsRow(props: { link: Link }) {
|
||||
const { link } = props;
|
||||
|
||||
function addDefaultSrc(ev) {
|
||||
ev.target.src = getFavicon("www.com");
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
className="group flex flex-row items-center border-t
|
||||
p-2 hover:bg-slate-50 transition-all shrink-0 text-ellipsis last:border-b w-[18rem]"
|
||||
>
|
||||
{/* <span className="rounded-lg bg-slate-200 p-2 hover:cursor-pointer"></span> */}
|
||||
|
||||
<img
|
||||
height="30"
|
||||
width="30"
|
||||
src={getFavicon(link.url)}
|
||||
onError={addDefaultSrc}
|
||||
/>
|
||||
|
||||
<Tooltip title={link.name}>
|
||||
<span className="flex flex-col ml-2 max-w-[10rem]">
|
||||
<span className="text-slate-400 text-sm truncate">{link.name}</span>
|
||||
<span className="text-slate-300 text-xs">
|
||||
{moment(link.createdDate.toDate()).fromNow()}
|
||||
</span>
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
||||
<span className="flex flex-row ml-auto space-x-1 group-hover:visible invisible">
|
||||
<Tooltip title={"Add to personal drawer."}>
|
||||
<span className="p-2 rounded-full hover:cursor-pointer hover:bg-slate-200 ">
|
||||
<FaImages className="text-xl text-slate-400" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title={link.url}>
|
||||
<span
|
||||
onClick={() => window.open(link.url, "_blank")}
|
||||
className="p-2 rounded-full hover:cursor-pointer hover:bg-slate-200 "
|
||||
>
|
||||
<FaExternalLinkAlt className="text-lg text-slate-400" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user