Skip to content

Commit

Permalink
Feat: added attachment icon, drag media to editor and other minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
harshithmullapudi committed Dec 23, 2024
1 parent 6786541 commit a2af216
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ import { ActivityLine, AI, SendLine } from '@tegonhq/ui/icons';
import { ArrowDown, ArrowUp } from 'lucide-react';
import React from 'react';

import { useLocalCommonState } from 'hooks/use-local-state';

import { CommentsActivity } from './comments-activity';
import { IssueActivity } from './issue-activity';
import { SubscribeView } from './issue-activity/subscribe-view';
import { IssueSummary } from './summary';

export function Activity() {
const [showSummary, setShowSummary] = React.useState(false);
const [commentsOrder, setCommentsOrder] = React.useState(-1);
const [commentsOrder, setCommentsOrder] = useLocalCommonState(
'issue_comments_order',
-1,
);
const [activeTab, setActiveTab] = React.useState('comments'); // Track active tab

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,18 @@ export const CommentsActivity = observer(

useEffect(() => {
// Fetch and sort comments whenever the order or comments change
const comments = commentsStore.getComments(issue.id);
let sorted = [...comments];
sorted = sort(sorted)[
const comments = commentsStore.getComments(
issue.id,
) as IssueCommentType[];
const sortedComments = sort(comments)[
commentOrder > 0 ? 'desc' : commentOrder === 0 ? 'asc' : 'asc'
]((comment) =>
commentOrder >= 0
? new Date(comment.updatedAt).getTime()
: new Date(comment.createdAt).getTime(),
);

setSortedComments(sorted); // Update state with sorted comments
setSortedComments(sortedComments); // Update state with sorted comments
}, [commentOrder, commentsStore, commentsStore.comments.length, issue.id]);

function getUserData(userId: string) {
Expand All @@ -63,6 +64,7 @@ export const CommentsActivity = observer(
return (
<div className="my-2 w-full flex flex-col gap-4">
{commentOrder === 1 && <IssueComment />}

<Timeline>
{sortedComments
.filter((comment: IssueCommentType) => !comment.parentId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {

import { useUpdateIssueCommentMutation } from 'services/issues';

import { FileUpload } from '../../file-upload';

interface EditCommentProps {
value: string;
comment: IssueCommentType;
Expand Down Expand Up @@ -65,26 +67,28 @@ export function EditComment({ value, onCancel, comment }: EditCommentProps) {
}),
]}
onChange={(e) => setCommentValue(e)}
className="w-full bg-transparent p-3 pt-0 pl-0"
className="w-full bg-transparent min-h-[44px] p-2 pt-0 pl-0 relative"
>
<div className="absolute right-1 bottom-2 flex items-center gap-1">
<FileUpload withPosition={false} />

<Button
variant="ghost"
className="my-2 transition-all duration-500 ease-in-out"
onClick={onCancel}
>
Cancel
</Button>
<Button
variant="secondary"
className="my-2 transition-all duration-500 ease-in-out"
onClick={onSubmit}
>
Save
</Button>
</div>
<EditorExtensions suggestionItems={suggestionItems} />
</Editor>
<div className="flex justify-end items-center gap-2">
<Button
variant="ghost"
className="my-2 transition-all duration-500 ease-in-out"
onClick={onCancel}
>
Cancel
</Button>
<Button
variant="secondary"
className="my-2 transition-all duration-500 ease-in-out"
onClick={onSubmit}
>
Save
</Button>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { useIssueData } from 'hooks/issues';

import { useCreateIssueCommentMutation } from 'services/issues';

import { FileUpload } from '../../file-upload';

export function IssueComment() {
const issueData = useIssueData();
const [commentValue, setCommentValue] = React.useState('');
Expand Down Expand Up @@ -53,7 +55,7 @@ export function IssueComment() {

return (
<div className="flex items-start w-full">
<div className="w-full relative">
<div className="w-full ">
<Editor
value={commentValue}
onChange={(e) => {
Expand All @@ -66,15 +68,16 @@ export function IssueComment() {
]}
placeholder="Leave your comment..."
onSubmit={onSubmit}
className="w-full min-h-[44px] mb-0 p-2 border-border border"
className="w-full min-h-[44px] mb-0 p-2 border-border border relative"
>
<div className="absolute right-1 bottom-2 flex items-center gap-1">
<FileUpload withPosition={false} />
<Button variant="ghost" type="submit" onClick={onSubmit}>
<SendLine size={20} />
</Button>
</div>
<EditorExtensions suggestionItems={suggestionItems} />
</Editor>
<div className="absolute right-1 bottom-2 flex items-center gap-1">
<Button variant="ghost" type="submit" onClick={onSubmit}>
<SendLine size={20} />
</Button>
</div>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { useCreateIssueCommentMutation } from 'services/issues';

import { UserContext } from 'store/user-context';

import { FileUpload } from '../../file-upload';

interface ReplyCommentProps {
issueCommentId: string;
}
Expand Down Expand Up @@ -82,24 +84,26 @@ export function ReplyComment({ issueCommentId }: ReplyCommentProps) {
!commentValue && setShowReplyButton(false);
}}
onChange={(e) => setCommentValue(e)}
className="w-full bg-transparent px-3 py-2 pt-0 grow text-foreground"
className="w-full min-h-[44px] bg-transparent mb-0 p-2 pt-0 grow text-foreground relative"
>
<div className="absolute right-1 bottom-2 flex items-center gap-1">
{showReplyButton && (
<>
<FileUpload withPosition={false} />

<Button
variant="ghost"
className="transition-all duration-500 ease-in-out my-2"
type="submit"
onClick={onSubmit}
>
<SendLine size={20} />
</Button>
</>
)}
</div>
<EditorExtensions suggestionItems={suggestionItems} />
</Editor>
<div className="flex justify-end items-center">
{showReplyButton && (
<>
<Button
variant="ghost"
className="transition-all duration-500 ease-in-out my-2"
type="submit"
onClick={onSubmit}
>
<SendLine size={20} />
</Button>
</>
)}
</div>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,48 @@
import type { Editor } from '@tiptap/core';

import { RiAttachmentLine } from '@remixicon/react';
import { Button } from '@tegonhq/ui/components/button';
import { uploadFileFn } from '@tegonhq/ui/components/editor/utils';
import { uploadFileFn, uploadFn } from '@tegonhq/ui/components/editor/utils';
import { useEditor } from '@tegonhq/ui/components/ui/editor/editor';
import { Paperclip } from 'lucide-react';

interface FileUploadProps {
editor: Editor;
withPosition?: boolean;
}

export function FileUpload({ editor }: FileUploadProps) {
export function FileUpload({ withPosition = true }: FileUploadProps) {
const { editor } = useEditor();

const onClick = () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'file/*';
input.onchange = async () => {
if (input.files?.length) {
const file = input.files[0];
const pos = editor.view.state.selection.from;
uploadFileFn(file, editor, pos);
const pos = editor.state.doc.content.size;

// Check if the file is an image
if (file.type.startsWith('image/')) {
uploadFn(file, editor, pos);
} else {
uploadFileFn(file, editor, pos);
}
}
};
input.click();
};

if (!withPosition) {
return (
<Button variant="ghost" onClick={onClick}>
<Paperclip size={16} />
</Button>
);
}

return (
<Button variant="ghost">
<RiAttachmentLine size={16} onClick={onClick} />
</Button>
<div className="absolute bottom-2 right-2 px-6">
<Button variant="secondary" onClick={onClick}>
<Paperclip size={16} />
</Button>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './file-upload';
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { useTeamWorkflows } from 'hooks/workflows';
import { useUpdateIssueMutation } from 'services/issues';

import { Activity } from './activity';
import { FileUpload } from './file-upload';
import { IssueSubIssueSelector } from './issue-sub-issue-selector';
import { IssueTitle } from './issue-title';
import { LinkedIssuesView } from './linked-issues-view';
Expand All @@ -30,6 +31,7 @@ import { SubIssueView } from './sub-issue-view';
export const LeftSide = observer(() => {
const issue = useIssueData();
const team = useTeamWithId(issue.teamId);

const workflows = useTeamWorkflows(team.identifier);
const triageWorkflow = workflows.find(
(workflow: WorkflowType) =>
Expand Down Expand Up @@ -83,6 +85,7 @@ export const LeftSide = observer(() => {
extensions={[tegonIssueExtension]}
className="min-h-[50px] mb-8 px-6 mt-3 text-md"
>
<FileUpload />
<EditorExtensions suggestionItems={suggestionItems}>
<IssueSubIssueSelector />
</EditorExtensions>
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/src/services/team/update-team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function useUpdateTeamMutation({
const team = teamsStore.getTeamWithId(teamId);

try {
teamsStore.update(otherParams, team.id);
teamsStore.update({ ...otherParams, preferences: {} }, team.id);
return updateTeam({ ...otherParams, teamId });
} catch (e) {
teamsStore.update(team, team.id);
Expand Down
7 changes: 4 additions & 3 deletions packages/ui/src/components/ui/editor/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useDebouncedCallback } from 'use-debounce';
import { defaultExtensions, getPlaceholder } from './editor-extensions';
import { LinkSelector, NodeSelector, TextButtons } from './selectors';
import { slashCommand } from './slash-command';
import { handleMarkAndImagePaste, uploadFn } from './utils';
import { handleDrop, handleMarkAndImagePaste, uploadFn } from './utils';
import {
EditorRoot,
EditorCommand,
Expand Down Expand Up @@ -117,7 +117,6 @@ export const Editor = ({
onCreate,
onSubmit,
children,

extensions = [],
editable = true,
handlePaste,
Expand Down Expand Up @@ -177,7 +176,7 @@ export const Editor = ({
initialContent={getInitialValue()}
extensions={getExtensions()}
className={cn(
'editor-container w-full min-w-full text-base sm:rounded-lg',
'editor-container w-full min-w-full text-base sm:rounded-lg relative',
className,
)}
onCreate={({ editor }) => {
Expand All @@ -190,6 +189,8 @@ export const Editor = ({
autoFocus && editor.commands.focus();
}}
editorProps={{
handleDrop: (_view, event, _slice, moved) =>
handleDrop(editor, event, moved),
handlePaste: (_, event) => {
const pasteResponse = handlePaste && handlePaste(editor, event);

Expand Down
27 changes: 27 additions & 0 deletions packages/ui/src/components/ui/editor/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,30 @@ function updateNodeAttrs(editor: any, url: string, updatedAttrs: any) {
}
});
}

export const handleDrop = (
editor: Editor,
event: DragEvent,
moved: boolean,
) => {
if (!moved && event.dataTransfer?.files.length) {
event.preventDefault();
const [file] = Array.from(event.dataTransfer.files);
const coordinates = editor.view.posAtCoords({
left: event.clientX,
top: event.clientY,
});
// here we deduct 1 from the pos or else the image will create an extra node

if (file) {
// Check if the file is an image
if (file.type.startsWith('image/')) {
uploadFn(file, editor, coordinates?.pos ?? 0 - 1);
} else {
uploadFileFn(file, editor, coordinates?.pos ?? 0 - 1);
}
}
return true;
}
return false;
};

0 comments on commit a2af216

Please sign in to comment.