nice action icons now and changing the state of the user convo assoc
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
import { ConversationMemberState } from "@nirvana/common/models/conversation";
|
||||||
|
import { FaStream, FaRegClock, FaRocket, FaCheck } from "react-icons/fa";
|
||||||
|
|
||||||
|
export default function ConversationMemberStateIcon(props: {
|
||||||
|
convoUserAssocState: ConversationMemberState;
|
||||||
|
}) {
|
||||||
|
switch (props.convoUserAssocState) {
|
||||||
|
case ConversationMemberState.default:
|
||||||
|
return <FaStream className="text-teal-600" />;
|
||||||
|
case ConversationMemberState.later:
|
||||||
|
return <FaRegClock className="text-purple-500" />;
|
||||||
|
case ConversationMemberState.priority:
|
||||||
|
return <FaRocket className="text-sky-500" />;
|
||||||
|
case ConversationMemberState.done:
|
||||||
|
return <FaCheck className="text-emerald-500" />;
|
||||||
|
default:
|
||||||
|
return <FaStream className="text-teal-600" />;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,16 +14,23 @@ import {
|
|||||||
FaPlay,
|
FaPlay,
|
||||||
FaRegClock,
|
FaRegClock,
|
||||||
FaRocket,
|
FaRocket,
|
||||||
|
FaStream,
|
||||||
} from "react-icons/fa";
|
} from "react-icons/fa";
|
||||||
import LinkIcon from "../Drawer/LinkIcon";
|
import LinkIcon from "../Drawer/LinkIcon";
|
||||||
import UserAvatar, { UserAvatarSizes } from "../UserDetails/UserAvatar";
|
import UserAvatar, { UserAvatarSizes } from "../UserDetails/UserAvatar";
|
||||||
import { useRecoilValue } from "recoil";
|
import { useRecoilValue } from "recoil";
|
||||||
import { allRelevantConversationsAtom } from "../../recoil/main";
|
import {
|
||||||
|
allRelevantConversationsAtom,
|
||||||
|
userConvoAssociationSelector,
|
||||||
|
} from "../../recoil/main";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Conversation from "@nirvana/common/models/conversation";
|
import Conversation from "@nirvana/common/models/conversation";
|
||||||
import { useAuth } from "../../contexts/authContext";
|
import { useAuth } from "../../contexts/authContext";
|
||||||
import { QueryRoutes, Routes } from "@nirvana/common/helpers/routes";
|
import { QueryRoutes, Routes } from "@nirvana/common/helpers/routes";
|
||||||
import { MasterAvatarGroupWithUserFetch } from "../UserDetails/MasterAvatarGroup";
|
import { MasterAvatarGroupWithUserFetch } from "../UserDetails/MasterAvatarGroup";
|
||||||
|
import { ConversationMemberState } from "../../../common/models/conversation";
|
||||||
|
import { conversationService } from "@nirvana/common/services";
|
||||||
|
import ConversationMemberStateIcon from "../Conversations/ConversationMemberStateIcon";
|
||||||
|
|
||||||
const testDrawerItems: {
|
const testDrawerItems: {
|
||||||
linkType: LinkType;
|
linkType: LinkType;
|
||||||
@@ -129,6 +136,10 @@ export default function ViewConvo(props: { conversationId: string }) {
|
|||||||
props.conversationId
|
props.conversationId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const userConvoAssoc = useRecoilValue(
|
||||||
|
userConvoAssociationSelector(props.conversationId)
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!convo || !convo.activeMembers.includes(currUser!.uid)) {
|
if (!convo || !convo.activeMembers.includes(currUser!.uid)) {
|
||||||
toast.error("Not authorized for this conversation");
|
toast.error("Not authorized for this conversation");
|
||||||
@@ -140,6 +151,24 @@ export default function ViewConvo(props: { conversationId: string }) {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleOrganizeConversation = async (
|
||||||
|
toState: ConversationMemberState
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
// use service to make change in database which will change local data
|
||||||
|
await conversationService.updateUserConvoRelationship(
|
||||||
|
currUser!.uid,
|
||||||
|
props.conversationId,
|
||||||
|
toState
|
||||||
|
);
|
||||||
|
|
||||||
|
toast.success("Moved conversation to " + toState);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
toast.error("Problem in moving conversation");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-col items-stretch mt-5 space-y-10">
|
<div className="flex flex-col items-stretch mt-5 space-y-10">
|
||||||
@@ -151,21 +180,20 @@ export default function ViewConvo(props: { conversationId: string }) {
|
|||||||
<span className="flex flex-row items-center group">
|
<span className="flex flex-row items-center group">
|
||||||
<span
|
<span
|
||||||
className="text-lg tracking-widest font-semibold
|
className="text-lg tracking-widest font-semibold
|
||||||
text-slate-500 uppercase"
|
text-slate-500 uppercase mr-2"
|
||||||
>
|
>
|
||||||
{convo?.name}
|
{convo?.name}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<ConversationMemberStateIcon
|
||||||
|
convoUserAssocState={userConvoAssoc?.state}
|
||||||
|
/>
|
||||||
|
|
||||||
<span className="p-2 rounded-full hover:cursor-pointer hover:bg-slate-200 group-hover:visible invisible">
|
<span className="p-2 rounded-full hover:cursor-pointer hover:bg-slate-200 group-hover:visible invisible">
|
||||||
<FaEdit className="ml-auto text-md text-slate-400" />
|
<FaEdit className="ml-auto text-md text-slate-400" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{convo?.tldr && (
|
|
||||||
<span className="max-w-md text-lg text-teal-800 mb-2">
|
|
||||||
tldr: {convo?.tldr}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<span className="flex flex-row items-center space-x-2 hover:cursor-pointer group">
|
<span className="flex flex-row items-center space-x-2 hover:cursor-pointer group">
|
||||||
<MasterAvatarGroupWithUserFetch
|
<MasterAvatarGroupWithUserFetch
|
||||||
listOfUserIds={convo?.activeMembers}
|
listOfUserIds={convo?.activeMembers}
|
||||||
@@ -180,31 +208,64 @@ export default function ViewConvo(props: { conversationId: string }) {
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span className="flex flex-row items-center space-x-3">
|
<span className="flex flex-row items-center space-x-3">
|
||||||
<button
|
{userConvoAssoc?.state != ConversationMemberState.later && (
|
||||||
className="rounded-lg p-2 flex flex-row items-center space-x-2
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
handleOrganizeConversation(ConversationMemberState.later)
|
||||||
|
}
|
||||||
|
className="rounded-lg p-2 border flex flex-row items-center space-x-2
|
||||||
text-slate-400 text-xs hover:bg-slate-50"
|
text-slate-400 text-xs hover:bg-slate-50"
|
||||||
>
|
>
|
||||||
<FaRocket className="text-sky-500" />
|
<FaRegClock />
|
||||||
<span>Priority</span>
|
<span>Later</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
)}
|
||||||
className="rounded-lg p-2 border flex flex-row items-center space-x-2
|
|
||||||
text-slate-400 text-xs hover:bg-slate-50"
|
|
||||||
>
|
|
||||||
<FaRegClock />
|
|
||||||
<span>Later</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
{userConvoAssoc?.state != ConversationMemberState.priority && (
|
||||||
className="rounded-lg p-2 border flex flex-row items-center space-x-2
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
handleOrganizeConversation(ConversationMemberState.priority)
|
||||||
|
}
|
||||||
|
className="rounded-lg p-2 border flex flex-row items-center space-x-2
|
||||||
text-slate-400 text-xs hover:bg-slate-50"
|
text-slate-400 text-xs hover:bg-slate-50"
|
||||||
>
|
>
|
||||||
<FaCheck />
|
<FaRocket />
|
||||||
<span>Done</span>
|
<span>Priority</span>
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{userConvoAssoc?.state == ConversationMemberState.done ? (
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
handleOrganizeConversation(ConversationMemberState.default)
|
||||||
|
}
|
||||||
|
className="rounded-lg p-2 border flex flex-row items-center space-x-2
|
||||||
|
text-slate-400 text-xs hover:bg-slate-50"
|
||||||
|
>
|
||||||
|
<FaStream />
|
||||||
|
<span>Inbox</span>
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
handleOrganizeConversation(ConversationMemberState.done)
|
||||||
|
}
|
||||||
|
className="rounded-lg p-2 border flex flex-row items-center space-x-2
|
||||||
|
text-slate-400 text-xs hover:bg-slate-50"
|
||||||
|
>
|
||||||
|
<FaCheck />
|
||||||
|
<span>Done</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
{convo?.tldr && (
|
||||||
|
<span className="max-w-md text-lg text-teal-800 mb-2">
|
||||||
|
tldr: {convo?.tldr}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* have one row, but just translate it along y downward to put it in it's own place */}
|
{/* have one row, but just translate it along y downward to put it in it's own place */}
|
||||||
<span className="flex flex-row flex-nowrap pb-[10rem] py-[5rem] overflow-auto min-h-max">
|
<span className="flex flex-row flex-nowrap pb-[10rem] py-[5rem] overflow-auto min-h-max">
|
||||||
{testAudioClips.map((audClip, index) => {
|
{testAudioClips.map((audClip, index) => {
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ export enum RecoilActions {
|
|||||||
|
|
||||||
ALL_COMPLETE_CONVERSATIONS = "ALL_COMPLETE_CONVERSATIONS",
|
ALL_COMPLETE_CONVERSATIONS = "ALL_COMPLETE_CONVERSATIONS",
|
||||||
ALL_USERS_CONVERSATION_RELATIONSHIPS = "ALL_USERS_CONVERSATION_RELATIONSHIPS",
|
ALL_USERS_CONVERSATION_RELATIONSHIPS = "ALL_USERS_CONVERSATION_RELATIONSHIPS",
|
||||||
|
USER_CONVO_ASSOCIATION_SELECTOR = "USER_CONVO_ASSOCIATION_SELECTOR",
|
||||||
|
|
||||||
ALL_RELEVANT_CONVERSATIONS = "ALL_RELEVANT_CONVERSATIONS",
|
ALL_RELEVANT_CONVERSATIONS = "ALL_RELEVANT_CONVERSATIONS",
|
||||||
|
|
||||||
SORTED_CONVERSATIONS = "SORTED_CONVERSATIONS",
|
SORTED_CONVERSATIONS = "SORTED_CONVERSATIONS",
|
||||||
@@ -66,11 +68,23 @@ import { earlierThisMonth } from "@nirvana/common/helpers/dateTime";
|
|||||||
|
|
||||||
// approach: fill in all "bottom" level atoms, and then build the tree later with selectors
|
// approach: fill in all "bottom" level atoms, and then build the tree later with selectors
|
||||||
// convo id -> userMember object
|
// convo id -> userMember object
|
||||||
export const allUsersConversationsAtom = atom({
|
export const allUsersConversationsAtom = atom<Map<string, ConversationMember>>({
|
||||||
key: RecoilActions.ALL_USERS_CONVERSATION_RELATIONSHIPS,
|
key: RecoilActions.ALL_USERS_CONVERSATION_RELATIONSHIPS,
|
||||||
default: new Map<string, ConversationMember>(),
|
default: new Map<string, ConversationMember>(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const userConvoAssociationSelector = selectorFamily({
|
||||||
|
key: RecoilActions.USER_CONVO_ASSOCIATION_SELECTOR,
|
||||||
|
get:
|
||||||
|
(convoId: string) =>
|
||||||
|
({ get }) => {
|
||||||
|
const userConvoMap = get(allUsersConversationsAtom);
|
||||||
|
const userConvoAssoc = userConvoMap.get(convoId);
|
||||||
|
|
||||||
|
return userConvoAssoc;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const allRelevantConversationsAtom = atom({
|
export const allRelevantConversationsAtom = atom({
|
||||||
key: RecoilActions.ALL_RELEVANT_CONVERSATIONS,
|
key: RecoilActions.ALL_RELEVANT_CONVERSATIONS,
|
||||||
default: new Map<string, Conversation>(),
|
default: new Map<string, Conversation>(),
|
||||||
|
|||||||
Reference in New Issue
Block a user