@ynput/ayon-frontend-shared 0.2.9 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/index.cjs5.js +3 -5
- package/dist/_virtual/index.cjs5.js.map +1 -1
- package/dist/_virtual/index.cjs6.js +5 -3
- package/dist/_virtual/index.cjs6.js.map +1 -1
- package/dist/_virtual/index.es5.js +2 -5
- package/dist/_virtual/index.es5.js.map +1 -1
- package/dist/_virtual/index.es6.js +5 -2
- package/dist/_virtual/index.es6.js.map +1 -1
- package/dist/node_modules/rehype-prism-plus/dist/index.es.cjs.js +1 -1
- package/dist/node_modules/rehype-prism-plus/dist/index.es.es.js +1 -1
- package/dist/node_modules/remove-accents/index.cjs.js +1 -1
- package/dist/node_modules/remove-accents/index.es.js +1 -1
- package/dist/shared/src/containers/Feed/Feed.cjs.js +21 -2
- package/dist/shared/src/containers/Feed/Feed.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/Feed.es.js +22 -3
- package/dist/shared/src/containers/Feed/Feed.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.cjs.js +18 -0
- package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.es.js +19 -1
- package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/CommentInput.cjs.js +7 -4
- package/dist/shared/src/containers/Feed/components/CommentInput/CommentInput.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/CommentInput.es.js +7 -4
- package/dist/shared/src/containers/Feed/components/CommentInput/CommentInput.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/helpers.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/helpers.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.cjs.js +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.es.js +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.cjs.js +27 -15
- package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.es.js +27 -15
- package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.cjs.js +40 -12
- package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.es.js +41 -13
- package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.styled.cjs.js +33 -19
- package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.styled.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.styled.es.js +33 -19
- package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.styled.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/FilesGrid/FilesGrid.cjs.js +14 -12
- package/dist/shared/src/containers/Feed/components/FilesGrid/FilesGrid.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/FilesGrid/FilesGrid.es.js +14 -12
- package/dist/shared/src/containers/Feed/components/FilesGrid/FilesGrid.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/Tooltips/EntityTooltip/EntityTooltip.cjs.js +8 -8
- package/dist/shared/src/containers/Feed/components/Tooltips/EntityTooltip/EntityTooltip.es.js +8 -8
- package/dist/shared/src/containers/Feed/helpers/mergeAnnotationAttachments.cjs.js +18 -0
- package/dist/shared/src/containers/Feed/helpers/mergeAnnotationAttachments.cjs.js.map +1 -0
- package/dist/shared/src/containers/Feed/helpers/mergeAnnotationAttachments.es.js +19 -0
- package/dist/shared/src/containers/Feed/helpers/mergeAnnotationAttachments.es.js.map +1 -0
- package/dist/shared/src/containers/Feed/hooks/useCommentMutations.cjs.js +12 -3
- package/dist/shared/src/containers/Feed/hooks/useCommentMutations.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/hooks/useCommentMutations.es.js +12 -3
- package/dist/shared/src/containers/Feed/hooks/useCommentMutations.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/hooks/useTransformActivities.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/hooks/useTransformActivities.es.js.map +1 -1
- package/dist/shared/src/context/DetailsPanelContext.cjs.js +3 -0
- package/dist/shared/src/context/DetailsPanelContext.cjs.js.map +1 -1
- package/dist/shared/src/context/DetailsPanelContext.es.js +3 -0
- package/dist/shared/src/context/DetailsPanelContext.es.js.map +1 -1
- package/dist/types/containers/Feed/components/CommentInput/CommentInput.d.ts +1 -1
- package/dist/types/containers/Feed/components/CommentInput/helpers.d.ts +6 -1
- package/dist/types/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.d.ts +1 -1
- package/dist/types/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.d.ts +5 -1
- package/dist/types/containers/Feed/components/FileUploadCard/FileUploadCard.d.ts +5 -2
- package/dist/types/containers/Feed/components/FileUploadCard/FileUploadCard.styled.d.ts +4 -0
- package/dist/types/containers/Feed/components/FilesGrid/FilesGrid.d.ts +1 -1
- package/dist/types/containers/Feed/helpers/mergeAnnotationAttachments.d.ts +2 -0
- package/dist/types/containers/Feed/hooks/useCommentMutations.d.ts +1 -1
- package/dist/types/containers/Feed/index.d.ts +6 -0
- package/dist/types/context/DetailsPanelContext.d.ts +4 -0
- package/package.json +1 -1
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const n = /* @__PURE__ */ _commonjsHelpers.getDefaultExportFromCjs(parseNumericRangeExports);
|
|
6
|
-
module.exports = n;
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
var removeAccents = { exports: {} };
|
|
4
|
+
exports.__module = removeAccents;
|
|
7
5
|
//# sourceMappingURL=index.cjs5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs5.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs5.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const _commonjsHelpers = require("./_commonjsHelpers.cjs.js");
|
|
3
|
+
const index = require("../node_modules/parse-numeric-range/index.cjs.js");
|
|
4
|
+
var parseNumericRangeExports = index.__require();
|
|
5
|
+
const n = /* @__PURE__ */ _commonjsHelpers.getDefaultExportFromCjs(parseNumericRangeExports);
|
|
6
|
+
module.exports = n;
|
|
5
7
|
//# sourceMappingURL=index.cjs6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs6.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs6.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import { __require as requireParseNumericRange } from "../node_modules/parse-numeric-range/index.es.js";
|
|
3
|
-
var parseNumericRangeExports = requireParseNumericRange();
|
|
4
|
-
const n = /* @__PURE__ */ getDefaultExportFromCjs(parseNumericRangeExports);
|
|
1
|
+
var removeAccents = { exports: {} };
|
|
5
2
|
export {
|
|
6
|
-
|
|
3
|
+
removeAccents as __module
|
|
7
4
|
};
|
|
8
5
|
//# sourceMappingURL=index.es5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es5.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es5.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { getDefaultExportFromCjs } from "./_commonjsHelpers.es.js";
|
|
2
|
+
import { __require as requireParseNumericRange } from "../node_modules/parse-numeric-range/index.es.js";
|
|
3
|
+
var parseNumericRangeExports = requireParseNumericRange();
|
|
4
|
+
const n = /* @__PURE__ */ getDefaultExportFromCjs(parseNumericRangeExports);
|
|
2
5
|
export {
|
|
3
|
-
|
|
6
|
+
n as default
|
|
4
7
|
};
|
|
5
8
|
//# sourceMappingURL=index.es6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es6.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es6.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
3
|
const index$1 = require("../../hast-util-to-string/index.cjs.js");
|
|
4
|
-
const index$2 = require("../../../_virtual/index.
|
|
4
|
+
const index$2 = require("../../../_virtual/index.cjs6.js");
|
|
5
5
|
require("../../refractor/lib/common.cjs.js");
|
|
6
6
|
require("../../refractor/lib/all.cjs.js");
|
|
7
7
|
const index = require("../node_modules/unist-util-visit/lib/index.cjs.js");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toString } from "../../hast-util-to-string/index.es.js";
|
|
2
|
-
import n from "../../../_virtual/index.
|
|
2
|
+
import n from "../../../_virtual/index.es6.js";
|
|
3
3
|
import "../../refractor/lib/common.es.js";
|
|
4
4
|
import "../../refractor/lib/all.es.js";
|
|
5
5
|
import { visit } from "../node_modules/unist-util-visit/lib/index.es.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const index = require("../../_virtual/index.
|
|
3
|
+
const index = require("../../_virtual/index.cjs5.js");
|
|
4
4
|
var hasRequiredRemoveAccents;
|
|
5
5
|
function requireRemoveAccents() {
|
|
6
6
|
if (hasRequiredRemoveAccents) return index.__module.exports;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as removeAccents } from "../../_virtual/index.
|
|
1
|
+
import { __module as removeAccents } from "../../_virtual/index.es5.js";
|
|
2
2
|
var hasRequiredRemoveAccents;
|
|
3
3
|
function requireRemoveAccents() {
|
|
4
4
|
if (hasRequiredRemoveAccents) return removeAccents.exports;
|
|
@@ -27,6 +27,7 @@ require("react-dom");
|
|
|
27
27
|
require("../../context/pip/PiPWrapper.cjs.js");
|
|
28
28
|
require("../../context/AddonProjectContext.cjs.js");
|
|
29
29
|
require("../../context/AddonContext.cjs.js");
|
|
30
|
+
const mergeAnnotationAttachments = require("./helpers/mergeAnnotationAttachments.cjs.js");
|
|
30
31
|
const activitiesLast = 30;
|
|
31
32
|
const Feed = ({ isMultiProjects, readOnly, statuses = [] }) => {
|
|
32
33
|
const {
|
|
@@ -45,11 +46,29 @@ const Feed = ({ isMultiProjects, readOnly, statuses = [] }) => {
|
|
|
45
46
|
users,
|
|
46
47
|
currentTab
|
|
47
48
|
} = FeedContext.useFeedContext();
|
|
48
|
-
const {
|
|
49
|
+
const {
|
|
50
|
+
openSlideOut,
|
|
51
|
+
highlightedActivities,
|
|
52
|
+
setHighlightedActivities,
|
|
53
|
+
onOpenImage,
|
|
54
|
+
setFeedAnnotations
|
|
55
|
+
} = DetailsPanelContext.useDetailsPanelContext();
|
|
49
56
|
const hideCommentInput = ["versions"].includes(currentTab);
|
|
57
|
+
const activitiesWithMergedAnnotations = React.useMemo(
|
|
58
|
+
() => mergeAnnotationAttachments(activitiesData),
|
|
59
|
+
[activitiesData]
|
|
60
|
+
);
|
|
61
|
+
React.useEffect(() => {
|
|
62
|
+
if (!activitiesWithMergedAnnotations.length) return;
|
|
63
|
+
const annotations = activitiesWithMergedAnnotations.map((activity) => {
|
|
64
|
+
var _a;
|
|
65
|
+
return (_a = activity.activityData) == null ? void 0 : _a.annotations;
|
|
66
|
+
}).filter(Boolean).flat();
|
|
67
|
+
setFeedAnnotations(annotations);
|
|
68
|
+
}, [activitiesWithMergedAnnotations]);
|
|
50
69
|
const transformedActivitiesData = useTransformActivities.default(
|
|
51
70
|
// @ts-ignore
|
|
52
|
-
|
|
71
|
+
activitiesWithMergedAnnotations,
|
|
53
72
|
users,
|
|
54
73
|
projectInfo,
|
|
55
74
|
entityType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Feed.cjs.js","sources":["../../../../../src/containers/Feed/Feed.tsx"],"sourcesContent":["import { useMemo, useRef } from 'react'\nimport ActivityItem from './components/ActivityItem'\nimport CommentInput from './components/CommentInput/CommentInput'\nimport * as Styled from './Feed.styled'\nimport useCommentMutations, { Activity } from './hooks/useCommentMutations'\nimport useTransformActivities from './hooks/useTransformActivities'\nimport { InView } from 'react-intersection-observer'\nimport useSaveScrollPos from './hooks/useSaveScrollPos'\nimport useScrollOnInputOpen from './hooks/useScrollOnInputOpen'\nimport { getLoadingPlaceholders } from './feedHelpers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport useScrollToHighlighted from './hooks/useScrollToHighlighted'\nimport { isFilePreviewable } from './components/FileUploadPreview/FileUploadPreview'\nimport EmptyPlaceholder from '@shared/components/EmptyPlaceholder'\nimport { useFeedContext, FEED_NEW_COMMENT } from './context/FeedContext'\nimport { Status } from '../ProjectTreeTable/types/project'\nimport { useDetailsPanelContext } from '@shared/context'\nimport { DetailsPanelEntityType } from '@shared/api'\n\n// number of activities to get\nexport const activitiesLast = 30\n\nexport type FeedProps = {\n isMultiProjects: boolean\n readOnly: boolean\n statuses: Status[]\n}\n\nexport const Feed = ({ isMultiProjects, readOnly, statuses = [] }: FeedProps) => {\n const {\n projectName,\n entities,\n entityType,\n editingId,\n projectInfo,\n setEditingId,\n userName,\n activitiesData,\n isLoadingNew,\n isLoadingNextPage,\n loadNextPage,\n hasNextPage,\n users,\n currentTab,\n } = useFeedContext()\n\n const { openSlideOut, highlightedActivities, setHighlightedActivities, onOpenImage } =\n useDetailsPanelContext()\n\n // hide comment input for specific filters\n const hideCommentInput = ['versions'].includes(currentTab)\n\n // do any transformation on activities data\n // 1. status change activities, attach status data based on projectName\n // 2. reverse the order\n // 3. is this activity from the current user?\n const transformedActivitiesData = useTransformActivities(\n // @ts-ignore\n activitiesData,\n users,\n projectInfo,\n entityType,\n userName,\n ) as any[]\n\n // REFS\n const feedRef = useRef(null)\n // const commentInputRef = useRef(null)\n\n // scroll by height of comment input when it opens or closes\n useScrollOnInputOpen({ feedRef, isInputOpen: editingId === FEED_NEW_COMMENT, height: 93 })\n\n // save scroll position of a feed\n useSaveScrollPos({\n entities,\n feedRef,\n filter: currentTab,\n disabled: !!highlightedActivities.length,\n isLoading: isLoadingNew,\n })\n\n // try and scroll to highlightedActivities activity\n useScrollToHighlighted({\n feedRef,\n highlighted: highlightedActivities,\n isLoading: isLoadingNew,\n loadNextPage,\n hasNextPage: !!loadNextPage,\n })\n\n // comment mutations here!\n const { submitComment, updateComment, deleteComment, isSaving } = useCommentMutations({\n projectName,\n entityType: entityType,\n entities,\n filter: currentTab,\n })\n\n // When a checkbox is clicked, update the body to add/remove \"x\" in [ ] markdown\n // Then update comment with new body\n const handleCommentChecked = (e: React.ChangeEvent<HTMLInputElement>, activity: Activity) => {\n const target = e?.target\n if (!target || !activity) return console.log('no target or activity')\n\n // the value that it's changing to\n const checked: boolean = target.checked\n const currentMarkdown: string = checked ? '[ ]' : '[x]'\n const newMarkdown: string = checked ? '[x]' : '[ ]'\n\n const { body } = activity\n\n // based on all li elements in the whole className 'comment-body' with className 'task-list-item'\n // find the index of the task that was checked\n const taskIndex: number = Array.from(\n target.closest('.comment-body')?.querySelectorAll('.task-list-item') || [],\n ).findIndex((li: Element) => li === target.closest('li'))\n\n let replaceIndex: number = taskIndex\n\n // count the number of current markdowns in the body\n const allMarkdowns: string[] = body.match(/\\[.\\]/g) || []\n\n allMarkdowns.forEach((markdown: string, index: number) => {\n // does it match the current markdown?\n if (markdown !== currentMarkdown && index < taskIndex) replaceIndex--\n })\n\n // now find the indexes of the current markdown to replace\n const indexesOfCurrentMarkdownInBody: number[] = []\n let index: number = -1\n while ((index = body.indexOf(currentMarkdown, index + 1)) > -1) {\n indexesOfCurrentMarkdownInBody.push(index)\n }\n\n const indexToReplaceInBody: number | undefined = indexesOfCurrentMarkdownInBody[replaceIndex]\n if (indexToReplaceInBody === undefined) return\n\n const endReplaceIndex: number = indexToReplaceInBody + currentMarkdown.length\n\n // replace the current markdown with the new markdown\n const newBody: string =\n body.slice(0, indexToReplaceInBody) + newMarkdown + body.slice(endReplaceIndex)\n\n if (!newBody) return\n\n updateComment(activity, newBody, activity.files)\n }\n\n const handleRefClick = (ref: {\n entityId: string\n entityType: DetailsPanelEntityType\n activityId: string\n }) => {\n const { entityId, entityType, activityId } = ref\n const supportedTypes = ['version', 'task', 'folder']\n\n if (!entityType || !supportedTypes.includes(entityType))\n return console.log('Entity type not supported yet')\n\n if (!entityId || !entityType || !projectName) return console.log('No entity id or type found')\n\n // open the slide out\n openSlideOut({ entityId, entityType, projectName })\n // set highlighted activity\n setHighlightedActivities([activityId])\n }\n\n const handleFileExpand = ({ index, activityId }: { index: number; activityId: string }) => {\n const previewableFiles = Object.values(transformedActivitiesData)\n .reverse()\n .filter((a) => a.activityType == 'comment')\n .map((a) => ({\n id: a.activityId,\n files: a.files.filter((file: any) => isFilePreviewable(file.mime, file.ext)),\n }))\n .filter((a) => a.files.length > 0)\n\n // open image callback\n onOpenImage?.({ files: previewableFiles, activityId, index, projectName })\n }\n\n const loadingPlaceholders = useMemo(() => getLoadingPlaceholders(10), [])\n\n let warningMessage\n\n // only viewing activities from one project\n if (isMultiProjects)\n warningMessage = `You are only viewing activities from one project: ${projectName}.`\n\n return (\n <>\n <Styled.FeedContainer className=\"feed\">\n {warningMessage && (\n <Styled.Warning>\n <Icon icon=\"info\" />\n {warningMessage}\n </Styled.Warning>\n )}\n <Styled.FeedContent ref={feedRef} className={clsx({ loading: isLoadingNew }, 'no-shimmer')}>\n {isLoadingNew\n ? loadingPlaceholders\n : transformedActivitiesData.map((activity) => (\n <ActivityItem\n key={activity.activityId}\n activity={activity}\n onCheckChange={handleCommentChecked}\n onDelete={deleteComment}\n onUpdate={async (value, files, _refs) =>\n await updateComment(activity, value, files)\n }\n projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={handleRefClick}\n createdAts={entities.map((e) => e.createdAt)}\n onFileExpand={handleFileExpand}\n showOrigin={entities.length > 1}\n filter={currentTab}\n editProps={{\n projectName,\n entities: entities,\n entityType,\n }}\n isHighlighted={highlightedActivities.includes(activity.activityId)}\n readOnly={readOnly}\n statuses={statuses}\n />\n ))}\n {/* message when no versions published */}\n {transformedActivitiesData.length === 1 && currentTab === 'versions' && !isLoadingNew && (\n <EmptyPlaceholder message=\"No versions published yet\" icon=\"layers\" />\n )}\n {hasNextPage && loadNextPage && (\n <InView\n root={feedRef.current}\n onChange={(inView) => inView && loadNextPage()}\n rootMargin={'400px 0px 0px 0px'}\n >\n <Styled.LoadMore style={{ height: 0 }} onClick={() => loadNextPage()}>\n {isLoadingNextPage ? 'Loading more...' : 'Click to load more'}\n </Styled.LoadMore>\n </InView>\n )}\n </Styled.FeedContent>\n {!hideCommentInput && (\n <CommentInput\n initValue={null}\n onSubmit={submitComment}\n isOpen={editingId === FEED_NEW_COMMENT}\n onClose={() => setEditingId(null)}\n onOpen={() => setEditingId(FEED_NEW_COMMENT)}\n disabled={isMultiProjects}\n isLoading={isLoadingNew || !entities.length || isSaving}\n />\n )}\n </Styled.FeedContainer>\n </>\n )\n}\n"],"names":["useFeedContext","useDetailsPanelContext","useTransformActivities","useRef","FEED_NEW_COMMENT","index","entityType","isFilePreviewable","useMemo","getLoadingPlaceholders","jsxs","Styled.FeedContainer","Styled.Warning","jsx","Icon","Styled.FeedContent","EmptyPlaceholder","InView","Styled.LoadMore","CommentInput"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Feed.cjs.js","sources":["../../../../../src/containers/Feed/Feed.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react'\nimport ActivityItem from './components/ActivityItem'\nimport CommentInput from './components/CommentInput/CommentInput'\nimport * as Styled from './Feed.styled'\nimport useCommentMutations, { Activity } from './hooks/useCommentMutations'\nimport useTransformActivities from './hooks/useTransformActivities'\nimport { InView } from 'react-intersection-observer'\nimport useSaveScrollPos from './hooks/useSaveScrollPos'\nimport useScrollOnInputOpen from './hooks/useScrollOnInputOpen'\nimport { getLoadingPlaceholders } from './feedHelpers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport useScrollToHighlighted from './hooks/useScrollToHighlighted'\nimport { isFilePreviewable } from './components/FileUploadPreview/FileUploadPreview'\nimport EmptyPlaceholder from '@shared/components/EmptyPlaceholder'\nimport { useFeedContext, FEED_NEW_COMMENT } from './context/FeedContext'\nimport { Status } from '../ProjectTreeTable/types/project'\nimport { useDetailsPanelContext } from '@shared/context'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport mergeAnnotationAttachments from './helpers/mergeAnnotationAttachments'\n\n// number of activities to get\nexport const activitiesLast = 30\n\nexport type FeedProps = {\n isMultiProjects: boolean\n readOnly: boolean\n statuses: Status[]\n}\n\nexport const Feed = ({ isMultiProjects, readOnly, statuses = [] }: FeedProps) => {\n const {\n projectName,\n entities,\n entityType,\n editingId,\n projectInfo,\n setEditingId,\n userName,\n activitiesData,\n isLoadingNew,\n isLoadingNextPage,\n loadNextPage,\n hasNextPage,\n users,\n currentTab,\n } = useFeedContext()\n\n const {\n openSlideOut,\n highlightedActivities,\n setHighlightedActivities,\n onOpenImage,\n setFeedAnnotations,\n } = useDetailsPanelContext()\n\n // hide comment input for specific filters\n const hideCommentInput = ['versions'].includes(currentTab)\n\n const activitiesWithMergedAnnotations = useMemo(\n () => mergeAnnotationAttachments(activitiesData),\n [activitiesData],\n )\n\n useEffect(() => {\n if (!activitiesWithMergedAnnotations.length) return\n const annotations = activitiesWithMergedAnnotations\n .map((activity) => activity.activityData?.annotations)\n .filter(Boolean)\n .flat()\n\n setFeedAnnotations(annotations)\n }, [activitiesWithMergedAnnotations])\n\n // do any transformation on activities data\n // 1. status change activities, attach status data based on projectName\n // 2. reverse the order\n // 3. is this activity from the current user?\n const transformedActivitiesData = useTransformActivities(\n // @ts-ignore\n activitiesWithMergedAnnotations,\n users,\n projectInfo,\n entityType,\n userName,\n ) as any[]\n\n // REFS\n const feedRef = useRef(null)\n // const commentInputRef = useRef(null)\n\n // scroll by height of comment input when it opens or closes\n useScrollOnInputOpen({ feedRef, isInputOpen: editingId === FEED_NEW_COMMENT, height: 93 })\n\n // save scroll position of a feed\n useSaveScrollPos({\n entities,\n feedRef,\n filter: currentTab,\n disabled: !!highlightedActivities.length,\n isLoading: isLoadingNew,\n })\n\n // try and scroll to highlightedActivities activity\n useScrollToHighlighted({\n feedRef,\n highlighted: highlightedActivities,\n isLoading: isLoadingNew,\n loadNextPage,\n hasNextPage: !!loadNextPage,\n })\n\n // comment mutations here!\n const { submitComment, updateComment, deleteComment, isSaving } = useCommentMutations({\n projectName,\n entityType: entityType,\n entities,\n filter: currentTab,\n })\n\n // When a checkbox is clicked, update the body to add/remove \"x\" in [ ] markdown\n // Then update comment with new body\n const handleCommentChecked = (e: React.ChangeEvent<HTMLInputElement>, activity: Activity) => {\n const target = e?.target\n if (!target || !activity) return console.log('no target or activity')\n\n // the value that it's changing to\n const checked: boolean = target.checked\n const currentMarkdown: string = checked ? '[ ]' : '[x]'\n const newMarkdown: string = checked ? '[x]' : '[ ]'\n\n const { body } = activity\n\n // based on all li elements in the whole className 'comment-body' with className 'task-list-item'\n // find the index of the task that was checked\n const taskIndex: number = Array.from(\n target.closest('.comment-body')?.querySelectorAll('.task-list-item') || [],\n ).findIndex((li: Element) => li === target.closest('li'))\n\n let replaceIndex: number = taskIndex\n\n // count the number of current markdowns in the body\n const allMarkdowns: string[] = body.match(/\\[.\\]/g) || []\n\n allMarkdowns.forEach((markdown: string, index: number) => {\n // does it match the current markdown?\n if (markdown !== currentMarkdown && index < taskIndex) replaceIndex--\n })\n\n // now find the indexes of the current markdown to replace\n const indexesOfCurrentMarkdownInBody: number[] = []\n let index: number = -1\n while ((index = body.indexOf(currentMarkdown, index + 1)) > -1) {\n indexesOfCurrentMarkdownInBody.push(index)\n }\n\n const indexToReplaceInBody: number | undefined = indexesOfCurrentMarkdownInBody[replaceIndex]\n if (indexToReplaceInBody === undefined) return\n\n const endReplaceIndex: number = indexToReplaceInBody + currentMarkdown.length\n\n // replace the current markdown with the new markdown\n const newBody: string =\n body.slice(0, indexToReplaceInBody) + newMarkdown + body.slice(endReplaceIndex)\n\n if (!newBody) return\n\n updateComment(activity, newBody, activity.files)\n }\n\n const handleRefClick = (ref: {\n entityId: string\n entityType: DetailsPanelEntityType\n activityId: string\n }) => {\n const { entityId, entityType, activityId } = ref\n const supportedTypes = ['version', 'task', 'folder']\n\n if (!entityType || !supportedTypes.includes(entityType))\n return console.log('Entity type not supported yet')\n\n if (!entityId || !entityType || !projectName) return console.log('No entity id or type found')\n\n // open the slide out\n openSlideOut({ entityId, entityType, projectName })\n // set highlighted activity\n setHighlightedActivities([activityId])\n }\n\n const handleFileExpand = ({ index, activityId }: { index: number; activityId: string }) => {\n const previewableFiles = Object.values(transformedActivitiesData)\n .reverse()\n .filter((a) => a.activityType == 'comment')\n .map((a) => ({\n id: a.activityId,\n files: a.files.filter((file: any) => isFilePreviewable(file.mime, file.ext)),\n }))\n .filter((a) => a.files.length > 0)\n\n // open image callback\n onOpenImage?.({ files: previewableFiles, activityId, index, projectName })\n }\n\n const loadingPlaceholders = useMemo(() => getLoadingPlaceholders(10), [])\n\n let warningMessage\n\n // only viewing activities from one project\n if (isMultiProjects)\n warningMessage = `You are only viewing activities from one project: ${projectName}.`\n\n return (\n <>\n <Styled.FeedContainer className=\"feed\">\n {warningMessage && (\n <Styled.Warning>\n <Icon icon=\"info\" />\n {warningMessage}\n </Styled.Warning>\n )}\n <Styled.FeedContent ref={feedRef} className={clsx({ loading: isLoadingNew }, 'no-shimmer')}>\n {isLoadingNew\n ? loadingPlaceholders\n : transformedActivitiesData.map((activity) => (\n <ActivityItem\n key={activity.activityId}\n activity={activity}\n onCheckChange={handleCommentChecked}\n onDelete={deleteComment}\n onUpdate={async (value, files, _refs) =>\n await updateComment(activity, value, files)\n }\n projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={handleRefClick}\n createdAts={entities.map((e) => e.createdAt)}\n onFileExpand={handleFileExpand}\n showOrigin={entities.length > 1}\n filter={currentTab}\n editProps={{\n projectName,\n entities: entities,\n entityType,\n }}\n isHighlighted={highlightedActivities.includes(activity.activityId)}\n readOnly={readOnly}\n statuses={statuses}\n />\n ))}\n {/* message when no versions published */}\n {transformedActivitiesData.length === 1 && currentTab === 'versions' && !isLoadingNew && (\n <EmptyPlaceholder message=\"No versions published yet\" icon=\"layers\" />\n )}\n {hasNextPage && loadNextPage && (\n <InView\n root={feedRef.current}\n onChange={(inView) => inView && loadNextPage()}\n rootMargin={'400px 0px 0px 0px'}\n >\n <Styled.LoadMore style={{ height: 0 }} onClick={() => loadNextPage()}>\n {isLoadingNextPage ? 'Loading more...' : 'Click to load more'}\n </Styled.LoadMore>\n </InView>\n )}\n </Styled.FeedContent>\n {!hideCommentInput && (\n <CommentInput\n initValue={null}\n onSubmit={submitComment}\n isOpen={editingId === FEED_NEW_COMMENT}\n onClose={() => setEditingId(null)}\n onOpen={() => setEditingId(FEED_NEW_COMMENT)}\n disabled={isMultiProjects}\n isLoading={isLoadingNew || !entities.length || isSaving}\n />\n )}\n </Styled.FeedContainer>\n </>\n )\n}\n"],"names":["useFeedContext","useDetailsPanelContext","useMemo","useEffect","useTransformActivities","useRef","FEED_NEW_COMMENT","index","entityType","isFilePreviewable","getLoadingPlaceholders","jsxs","Styled.FeedContainer","Styled.Warning","jsx","Icon","Styled.FeedContent","EmptyPlaceholder","InView","Styled.LoadMore","CommentInput"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { j as jsxRuntimeExports } from "../../../../_virtual/jsx-runtime.es.js";
|
|
2
|
-
import {
|
|
2
|
+
import { useMemo, useEffect, useRef } from "react";
|
|
3
3
|
import ActivityItem from "./components/ActivityItem.es.js";
|
|
4
4
|
import CommentInput from "./components/CommentInput/CommentInput.es.js";
|
|
5
5
|
import { FeedContainer, Warning, FeedContent, LoadMore } from "./Feed.styled.es.js";
|
|
@@ -25,6 +25,7 @@ import "react-dom";
|
|
|
25
25
|
import "../../context/pip/PiPWrapper.es.js";
|
|
26
26
|
import "../../context/AddonProjectContext.es.js";
|
|
27
27
|
import "../../context/AddonContext.es.js";
|
|
28
|
+
import mergeAnnotationAttachments from "./helpers/mergeAnnotationAttachments.es.js";
|
|
28
29
|
const activitiesLast = 30;
|
|
29
30
|
const Feed = ({ isMultiProjects, readOnly, statuses = [] }) => {
|
|
30
31
|
const {
|
|
@@ -43,11 +44,29 @@ const Feed = ({ isMultiProjects, readOnly, statuses = [] }) => {
|
|
|
43
44
|
users,
|
|
44
45
|
currentTab
|
|
45
46
|
} = useFeedContext();
|
|
46
|
-
const {
|
|
47
|
+
const {
|
|
48
|
+
openSlideOut,
|
|
49
|
+
highlightedActivities,
|
|
50
|
+
setHighlightedActivities,
|
|
51
|
+
onOpenImage,
|
|
52
|
+
setFeedAnnotations
|
|
53
|
+
} = useDetailsPanelContext();
|
|
47
54
|
const hideCommentInput = ["versions"].includes(currentTab);
|
|
55
|
+
const activitiesWithMergedAnnotations = useMemo(
|
|
56
|
+
() => mergeAnnotationAttachments(activitiesData),
|
|
57
|
+
[activitiesData]
|
|
58
|
+
);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (!activitiesWithMergedAnnotations.length) return;
|
|
61
|
+
const annotations = activitiesWithMergedAnnotations.map((activity) => {
|
|
62
|
+
var _a;
|
|
63
|
+
return (_a = activity.activityData) == null ? void 0 : _a.annotations;
|
|
64
|
+
}).filter(Boolean).flat();
|
|
65
|
+
setFeedAnnotations(annotations);
|
|
66
|
+
}, [activitiesWithMergedAnnotations]);
|
|
48
67
|
const transformedActivitiesData = useTransformActivities(
|
|
49
68
|
// @ts-ignore
|
|
50
|
-
|
|
69
|
+
activitiesWithMergedAnnotations,
|
|
51
70
|
users,
|
|
52
71
|
projectInfo,
|
|
53
72
|
entityType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Feed.es.js","sources":["../../../../../src/containers/Feed/Feed.tsx"],"sourcesContent":["import { useMemo, useRef } from 'react'\nimport ActivityItem from './components/ActivityItem'\nimport CommentInput from './components/CommentInput/CommentInput'\nimport * as Styled from './Feed.styled'\nimport useCommentMutations, { Activity } from './hooks/useCommentMutations'\nimport useTransformActivities from './hooks/useTransformActivities'\nimport { InView } from 'react-intersection-observer'\nimport useSaveScrollPos from './hooks/useSaveScrollPos'\nimport useScrollOnInputOpen from './hooks/useScrollOnInputOpen'\nimport { getLoadingPlaceholders } from './feedHelpers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport useScrollToHighlighted from './hooks/useScrollToHighlighted'\nimport { isFilePreviewable } from './components/FileUploadPreview/FileUploadPreview'\nimport EmptyPlaceholder from '@shared/components/EmptyPlaceholder'\nimport { useFeedContext, FEED_NEW_COMMENT } from './context/FeedContext'\nimport { Status } from '../ProjectTreeTable/types/project'\nimport { useDetailsPanelContext } from '@shared/context'\nimport { DetailsPanelEntityType } from '@shared/api'\n\n// number of activities to get\nexport const activitiesLast = 30\n\nexport type FeedProps = {\n isMultiProjects: boolean\n readOnly: boolean\n statuses: Status[]\n}\n\nexport const Feed = ({ isMultiProjects, readOnly, statuses = [] }: FeedProps) => {\n const {\n projectName,\n entities,\n entityType,\n editingId,\n projectInfo,\n setEditingId,\n userName,\n activitiesData,\n isLoadingNew,\n isLoadingNextPage,\n loadNextPage,\n hasNextPage,\n users,\n currentTab,\n } = useFeedContext()\n\n const { openSlideOut, highlightedActivities, setHighlightedActivities, onOpenImage } =\n useDetailsPanelContext()\n\n // hide comment input for specific filters\n const hideCommentInput = ['versions'].includes(currentTab)\n\n // do any transformation on activities data\n // 1. status change activities, attach status data based on projectName\n // 2. reverse the order\n // 3. is this activity from the current user?\n const transformedActivitiesData = useTransformActivities(\n // @ts-ignore\n activitiesData,\n users,\n projectInfo,\n entityType,\n userName,\n ) as any[]\n\n // REFS\n const feedRef = useRef(null)\n // const commentInputRef = useRef(null)\n\n // scroll by height of comment input when it opens or closes\n useScrollOnInputOpen({ feedRef, isInputOpen: editingId === FEED_NEW_COMMENT, height: 93 })\n\n // save scroll position of a feed\n useSaveScrollPos({\n entities,\n feedRef,\n filter: currentTab,\n disabled: !!highlightedActivities.length,\n isLoading: isLoadingNew,\n })\n\n // try and scroll to highlightedActivities activity\n useScrollToHighlighted({\n feedRef,\n highlighted: highlightedActivities,\n isLoading: isLoadingNew,\n loadNextPage,\n hasNextPage: !!loadNextPage,\n })\n\n // comment mutations here!\n const { submitComment, updateComment, deleteComment, isSaving } = useCommentMutations({\n projectName,\n entityType: entityType,\n entities,\n filter: currentTab,\n })\n\n // When a checkbox is clicked, update the body to add/remove \"x\" in [ ] markdown\n // Then update comment with new body\n const handleCommentChecked = (e: React.ChangeEvent<HTMLInputElement>, activity: Activity) => {\n const target = e?.target\n if (!target || !activity) return console.log('no target or activity')\n\n // the value that it's changing to\n const checked: boolean = target.checked\n const currentMarkdown: string = checked ? '[ ]' : '[x]'\n const newMarkdown: string = checked ? '[x]' : '[ ]'\n\n const { body } = activity\n\n // based on all li elements in the whole className 'comment-body' with className 'task-list-item'\n // find the index of the task that was checked\n const taskIndex: number = Array.from(\n target.closest('.comment-body')?.querySelectorAll('.task-list-item') || [],\n ).findIndex((li: Element) => li === target.closest('li'))\n\n let replaceIndex: number = taskIndex\n\n // count the number of current markdowns in the body\n const allMarkdowns: string[] = body.match(/\\[.\\]/g) || []\n\n allMarkdowns.forEach((markdown: string, index: number) => {\n // does it match the current markdown?\n if (markdown !== currentMarkdown && index < taskIndex) replaceIndex--\n })\n\n // now find the indexes of the current markdown to replace\n const indexesOfCurrentMarkdownInBody: number[] = []\n let index: number = -1\n while ((index = body.indexOf(currentMarkdown, index + 1)) > -1) {\n indexesOfCurrentMarkdownInBody.push(index)\n }\n\n const indexToReplaceInBody: number | undefined = indexesOfCurrentMarkdownInBody[replaceIndex]\n if (indexToReplaceInBody === undefined) return\n\n const endReplaceIndex: number = indexToReplaceInBody + currentMarkdown.length\n\n // replace the current markdown with the new markdown\n const newBody: string =\n body.slice(0, indexToReplaceInBody) + newMarkdown + body.slice(endReplaceIndex)\n\n if (!newBody) return\n\n updateComment(activity, newBody, activity.files)\n }\n\n const handleRefClick = (ref: {\n entityId: string\n entityType: DetailsPanelEntityType\n activityId: string\n }) => {\n const { entityId, entityType, activityId } = ref\n const supportedTypes = ['version', 'task', 'folder']\n\n if (!entityType || !supportedTypes.includes(entityType))\n return console.log('Entity type not supported yet')\n\n if (!entityId || !entityType || !projectName) return console.log('No entity id or type found')\n\n // open the slide out\n openSlideOut({ entityId, entityType, projectName })\n // set highlighted activity\n setHighlightedActivities([activityId])\n }\n\n const handleFileExpand = ({ index, activityId }: { index: number; activityId: string }) => {\n const previewableFiles = Object.values(transformedActivitiesData)\n .reverse()\n .filter((a) => a.activityType == 'comment')\n .map((a) => ({\n id: a.activityId,\n files: a.files.filter((file: any) => isFilePreviewable(file.mime, file.ext)),\n }))\n .filter((a) => a.files.length > 0)\n\n // open image callback\n onOpenImage?.({ files: previewableFiles, activityId, index, projectName })\n }\n\n const loadingPlaceholders = useMemo(() => getLoadingPlaceholders(10), [])\n\n let warningMessage\n\n // only viewing activities from one project\n if (isMultiProjects)\n warningMessage = `You are only viewing activities from one project: ${projectName}.`\n\n return (\n <>\n <Styled.FeedContainer className=\"feed\">\n {warningMessage && (\n <Styled.Warning>\n <Icon icon=\"info\" />\n {warningMessage}\n </Styled.Warning>\n )}\n <Styled.FeedContent ref={feedRef} className={clsx({ loading: isLoadingNew }, 'no-shimmer')}>\n {isLoadingNew\n ? loadingPlaceholders\n : transformedActivitiesData.map((activity) => (\n <ActivityItem\n key={activity.activityId}\n activity={activity}\n onCheckChange={handleCommentChecked}\n onDelete={deleteComment}\n onUpdate={async (value, files, _refs) =>\n await updateComment(activity, value, files)\n }\n projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={handleRefClick}\n createdAts={entities.map((e) => e.createdAt)}\n onFileExpand={handleFileExpand}\n showOrigin={entities.length > 1}\n filter={currentTab}\n editProps={{\n projectName,\n entities: entities,\n entityType,\n }}\n isHighlighted={highlightedActivities.includes(activity.activityId)}\n readOnly={readOnly}\n statuses={statuses}\n />\n ))}\n {/* message when no versions published */}\n {transformedActivitiesData.length === 1 && currentTab === 'versions' && !isLoadingNew && (\n <EmptyPlaceholder message=\"No versions published yet\" icon=\"layers\" />\n )}\n {hasNextPage && loadNextPage && (\n <InView\n root={feedRef.current}\n onChange={(inView) => inView && loadNextPage()}\n rootMargin={'400px 0px 0px 0px'}\n >\n <Styled.LoadMore style={{ height: 0 }} onClick={() => loadNextPage()}>\n {isLoadingNextPage ? 'Loading more...' : 'Click to load more'}\n </Styled.LoadMore>\n </InView>\n )}\n </Styled.FeedContent>\n {!hideCommentInput && (\n <CommentInput\n initValue={null}\n onSubmit={submitComment}\n isOpen={editingId === FEED_NEW_COMMENT}\n onClose={() => setEditingId(null)}\n onOpen={() => setEditingId(FEED_NEW_COMMENT)}\n disabled={isMultiProjects}\n isLoading={isLoadingNew || !entities.length || isSaving}\n />\n )}\n </Styled.FeedContainer>\n </>\n )\n}\n"],"names":["index","entityType","jsxs","Styled.FeedContainer","Styled.Warning","jsx","Styled.FeedContent","Styled.LoadMore"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Feed.es.js","sources":["../../../../../src/containers/Feed/Feed.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react'\nimport ActivityItem from './components/ActivityItem'\nimport CommentInput from './components/CommentInput/CommentInput'\nimport * as Styled from './Feed.styled'\nimport useCommentMutations, { Activity } from './hooks/useCommentMutations'\nimport useTransformActivities from './hooks/useTransformActivities'\nimport { InView } from 'react-intersection-observer'\nimport useSaveScrollPos from './hooks/useSaveScrollPos'\nimport useScrollOnInputOpen from './hooks/useScrollOnInputOpen'\nimport { getLoadingPlaceholders } from './feedHelpers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport useScrollToHighlighted from './hooks/useScrollToHighlighted'\nimport { isFilePreviewable } from './components/FileUploadPreview/FileUploadPreview'\nimport EmptyPlaceholder from '@shared/components/EmptyPlaceholder'\nimport { useFeedContext, FEED_NEW_COMMENT } from './context/FeedContext'\nimport { Status } from '../ProjectTreeTable/types/project'\nimport { useDetailsPanelContext } from '@shared/context'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport mergeAnnotationAttachments from './helpers/mergeAnnotationAttachments'\n\n// number of activities to get\nexport const activitiesLast = 30\n\nexport type FeedProps = {\n isMultiProjects: boolean\n readOnly: boolean\n statuses: Status[]\n}\n\nexport const Feed = ({ isMultiProjects, readOnly, statuses = [] }: FeedProps) => {\n const {\n projectName,\n entities,\n entityType,\n editingId,\n projectInfo,\n setEditingId,\n userName,\n activitiesData,\n isLoadingNew,\n isLoadingNextPage,\n loadNextPage,\n hasNextPage,\n users,\n currentTab,\n } = useFeedContext()\n\n const {\n openSlideOut,\n highlightedActivities,\n setHighlightedActivities,\n onOpenImage,\n setFeedAnnotations,\n } = useDetailsPanelContext()\n\n // hide comment input for specific filters\n const hideCommentInput = ['versions'].includes(currentTab)\n\n const activitiesWithMergedAnnotations = useMemo(\n () => mergeAnnotationAttachments(activitiesData),\n [activitiesData],\n )\n\n useEffect(() => {\n if (!activitiesWithMergedAnnotations.length) return\n const annotations = activitiesWithMergedAnnotations\n .map((activity) => activity.activityData?.annotations)\n .filter(Boolean)\n .flat()\n\n setFeedAnnotations(annotations)\n }, [activitiesWithMergedAnnotations])\n\n // do any transformation on activities data\n // 1. status change activities, attach status data based on projectName\n // 2. reverse the order\n // 3. is this activity from the current user?\n const transformedActivitiesData = useTransformActivities(\n // @ts-ignore\n activitiesWithMergedAnnotations,\n users,\n projectInfo,\n entityType,\n userName,\n ) as any[]\n\n // REFS\n const feedRef = useRef(null)\n // const commentInputRef = useRef(null)\n\n // scroll by height of comment input when it opens or closes\n useScrollOnInputOpen({ feedRef, isInputOpen: editingId === FEED_NEW_COMMENT, height: 93 })\n\n // save scroll position of a feed\n useSaveScrollPos({\n entities,\n feedRef,\n filter: currentTab,\n disabled: !!highlightedActivities.length,\n isLoading: isLoadingNew,\n })\n\n // try and scroll to highlightedActivities activity\n useScrollToHighlighted({\n feedRef,\n highlighted: highlightedActivities,\n isLoading: isLoadingNew,\n loadNextPage,\n hasNextPage: !!loadNextPage,\n })\n\n // comment mutations here!\n const { submitComment, updateComment, deleteComment, isSaving } = useCommentMutations({\n projectName,\n entityType: entityType,\n entities,\n filter: currentTab,\n })\n\n // When a checkbox is clicked, update the body to add/remove \"x\" in [ ] markdown\n // Then update comment with new body\n const handleCommentChecked = (e: React.ChangeEvent<HTMLInputElement>, activity: Activity) => {\n const target = e?.target\n if (!target || !activity) return console.log('no target or activity')\n\n // the value that it's changing to\n const checked: boolean = target.checked\n const currentMarkdown: string = checked ? '[ ]' : '[x]'\n const newMarkdown: string = checked ? '[x]' : '[ ]'\n\n const { body } = activity\n\n // based on all li elements in the whole className 'comment-body' with className 'task-list-item'\n // find the index of the task that was checked\n const taskIndex: number = Array.from(\n target.closest('.comment-body')?.querySelectorAll('.task-list-item') || [],\n ).findIndex((li: Element) => li === target.closest('li'))\n\n let replaceIndex: number = taskIndex\n\n // count the number of current markdowns in the body\n const allMarkdowns: string[] = body.match(/\\[.\\]/g) || []\n\n allMarkdowns.forEach((markdown: string, index: number) => {\n // does it match the current markdown?\n if (markdown !== currentMarkdown && index < taskIndex) replaceIndex--\n })\n\n // now find the indexes of the current markdown to replace\n const indexesOfCurrentMarkdownInBody: number[] = []\n let index: number = -1\n while ((index = body.indexOf(currentMarkdown, index + 1)) > -1) {\n indexesOfCurrentMarkdownInBody.push(index)\n }\n\n const indexToReplaceInBody: number | undefined = indexesOfCurrentMarkdownInBody[replaceIndex]\n if (indexToReplaceInBody === undefined) return\n\n const endReplaceIndex: number = indexToReplaceInBody + currentMarkdown.length\n\n // replace the current markdown with the new markdown\n const newBody: string =\n body.slice(0, indexToReplaceInBody) + newMarkdown + body.slice(endReplaceIndex)\n\n if (!newBody) return\n\n updateComment(activity, newBody, activity.files)\n }\n\n const handleRefClick = (ref: {\n entityId: string\n entityType: DetailsPanelEntityType\n activityId: string\n }) => {\n const { entityId, entityType, activityId } = ref\n const supportedTypes = ['version', 'task', 'folder']\n\n if (!entityType || !supportedTypes.includes(entityType))\n return console.log('Entity type not supported yet')\n\n if (!entityId || !entityType || !projectName) return console.log('No entity id or type found')\n\n // open the slide out\n openSlideOut({ entityId, entityType, projectName })\n // set highlighted activity\n setHighlightedActivities([activityId])\n }\n\n const handleFileExpand = ({ index, activityId }: { index: number; activityId: string }) => {\n const previewableFiles = Object.values(transformedActivitiesData)\n .reverse()\n .filter((a) => a.activityType == 'comment')\n .map((a) => ({\n id: a.activityId,\n files: a.files.filter((file: any) => isFilePreviewable(file.mime, file.ext)),\n }))\n .filter((a) => a.files.length > 0)\n\n // open image callback\n onOpenImage?.({ files: previewableFiles, activityId, index, projectName })\n }\n\n const loadingPlaceholders = useMemo(() => getLoadingPlaceholders(10), [])\n\n let warningMessage\n\n // only viewing activities from one project\n if (isMultiProjects)\n warningMessage = `You are only viewing activities from one project: ${projectName}.`\n\n return (\n <>\n <Styled.FeedContainer className=\"feed\">\n {warningMessage && (\n <Styled.Warning>\n <Icon icon=\"info\" />\n {warningMessage}\n </Styled.Warning>\n )}\n <Styled.FeedContent ref={feedRef} className={clsx({ loading: isLoadingNew }, 'no-shimmer')}>\n {isLoadingNew\n ? loadingPlaceholders\n : transformedActivitiesData.map((activity) => (\n <ActivityItem\n key={activity.activityId}\n activity={activity}\n onCheckChange={handleCommentChecked}\n onDelete={deleteComment}\n onUpdate={async (value, files, _refs) =>\n await updateComment(activity, value, files)\n }\n projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={handleRefClick}\n createdAts={entities.map((e) => e.createdAt)}\n onFileExpand={handleFileExpand}\n showOrigin={entities.length > 1}\n filter={currentTab}\n editProps={{\n projectName,\n entities: entities,\n entityType,\n }}\n isHighlighted={highlightedActivities.includes(activity.activityId)}\n readOnly={readOnly}\n statuses={statuses}\n />\n ))}\n {/* message when no versions published */}\n {transformedActivitiesData.length === 1 && currentTab === 'versions' && !isLoadingNew && (\n <EmptyPlaceholder message=\"No versions published yet\" icon=\"layers\" />\n )}\n {hasNextPage && loadNextPage && (\n <InView\n root={feedRef.current}\n onChange={(inView) => inView && loadNextPage()}\n rootMargin={'400px 0px 0px 0px'}\n >\n <Styled.LoadMore style={{ height: 0 }} onClick={() => loadNextPage()}>\n {isLoadingNextPage ? 'Loading more...' : 'Click to load more'}\n </Styled.LoadMore>\n </InView>\n )}\n </Styled.FeedContent>\n {!hideCommentInput && (\n <CommentInput\n initValue={null}\n onSubmit={submitComment}\n isOpen={editingId === FEED_NEW_COMMENT}\n onClose={() => setEditingId(null)}\n onOpen={() => setEditingId(FEED_NEW_COMMENT)}\n disabled={isMultiProjects}\n isLoading={isLoadingNew || !entities.length || isSaving}\n />\n )}\n </Styled.FeedContainer>\n </>\n )\n}\n"],"names":["index","entityType","jsxs","Styled.FeedContainer","Styled.Warning","jsx","Styled.FeedContent","Styled.LoadMore"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBO,MAAM,iBAAiB;AAQjB,MAAA,OAAO,CAAC,EAAE,iBAAiB,UAAU,WAAW,SAAoB;AACzE,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,eAAe;AAEb,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,uBAAuB;AAG3B,QAAM,mBAAmB,CAAC,UAAU,EAAE,SAAS,UAAU;AAEzD,QAAM,kCAAkC;AAAA,IACtC,MAAM,2BAA2B,cAAc;AAAA,IAC/C,CAAC,cAAc;AAAA,EACjB;AAEA,YAAU,MAAM;AACV,QAAA,CAAC,gCAAgC,OAAQ;AAC7C,UAAM,cAAc,gCACjB,IAAI,CAAC,aAAa;;AAAA,4BAAS,iBAAT,mBAAuB;AAAA,KAAW,EACpD,OAAO,OAAO,EACd,KAAK;AAER,uBAAmB,WAAW;AAAA,EAAA,GAC7B,CAAC,+BAA+B,CAAC;AAMpC,QAAM,4BAA4B;AAAA;AAAA,IAEhC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGM,QAAA,UAAU,OAAO,IAAI;AAI3B,uBAAqB,EAAE,SAAS,aAAa,cAAc,kBAAkB,QAAQ,IAAI;AAGxE,mBAAA;AAAA,IACf;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,UAAU,CAAC,CAAC,sBAAsB;AAAA,IAClC,WAAW;AAAA,EAAA,CACZ;AAGsB,yBAAA;AAAA,IACrB;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,IACX;AAAA,IACA,aAAa,CAAC,CAAC;AAAA,EAAA,CAChB;AAGD,QAAM,EAAE,eAAe,eAAe,eAAe,SAAA,IAAa,oBAAoB;AAAA,IACpF;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EAAA,CACT;AAIK,QAAA,uBAAuB,CAAC,GAAwC,aAAuB;;AAC3F,UAAM,SAAS,uBAAG;AAClB,QAAI,CAAC,UAAU,CAAC,SAAiB,QAAA,QAAQ,IAAI,uBAAuB;AAGpE,UAAM,UAAmB,OAAO;AAC1B,UAAA,kBAA0B,UAAU,QAAQ;AAC5C,UAAA,cAAsB,UAAU,QAAQ;AAExC,UAAA,EAAE,SAAS;AAIjB,UAAM,YAAoB,MAAM;AAAA,QAC9B,YAAO,QAAQ,eAAe,MAA9B,mBAAiC,iBAAiB,uBAAsB,CAAA;AAAA,IAAC,EACzE,UAAU,CAAC,OAAgB,OAAO,OAAO,QAAQ,IAAI,CAAC;AAExD,QAAI,eAAuB;AAG3B,UAAM,eAAyB,KAAK,MAAM,QAAQ,KAAK,CAAC;AAE3C,iBAAA,QAAQ,CAAC,UAAkBA,WAAkB;AAEpD,UAAA,aAAa,mBAAmBA,SAAQ,UAAW;AAAA,IAAA,CACxD;AAGD,UAAM,iCAA2C,CAAC;AAClD,QAAI,QAAgB;AACpB,YAAQ,QAAQ,KAAK,QAAQ,iBAAiB,QAAQ,CAAC,KAAK,IAAI;AAC9D,qCAA+B,KAAK,KAAK;AAAA,IAAA;AAGrC,UAAA,uBAA2C,+BAA+B,YAAY;AAC5F,QAAI,yBAAyB,OAAW;AAElC,UAAA,kBAA0B,uBAAuB,gBAAgB;AAGjE,UAAA,UACJ,KAAK,MAAM,GAAG,oBAAoB,IAAI,cAAc,KAAK,MAAM,eAAe;AAEhF,QAAI,CAAC,QAAS;AAEA,kBAAA,UAAU,SAAS,SAAS,KAAK;AAAA,EACjD;AAEM,QAAA,iBAAiB,CAAC,QAIlB;AACJ,UAAM,EAAE,UAAU,YAAAC,aAAY,WAAe,IAAA;AAC7C,UAAM,iBAAiB,CAAC,WAAW,QAAQ,QAAQ;AAEnD,QAAI,CAACA,eAAc,CAAC,eAAe,SAASA,WAAU;AAC7C,aAAA,QAAQ,IAAI,+BAA+B;AAEhD,QAAA,CAAC,YAAY,CAACA,eAAc,CAAC,YAAa,QAAO,QAAQ,IAAI,4BAA4B;AAG7F,iBAAa,EAAE,UAAU,YAAAA,aAAY,aAAa;AAEzB,6BAAA,CAAC,UAAU,CAAC;AAAA,EACvC;AAEA,QAAM,mBAAmB,CAAC,EAAE,OAAO,iBAAwD;AACzF,UAAM,mBAAmB,OAAO,OAAO,yBAAyB,EAC7D,UACA,OAAO,CAAC,MAAM,EAAE,gBAAgB,SAAS,EACzC,IAAI,CAAC,OAAO;AAAA,MACX,IAAI,EAAE;AAAA,MACN,OAAO,EAAE,MAAM,OAAO,CAAC,SAAc,kBAAkB,KAAK,MAAM,KAAK,GAAG,CAAC;AAAA,IAAA,EAC3E,EACD,OAAO,CAAC,MAAM,EAAE,MAAM,SAAS,CAAC;AAGnC,+CAAc,EAAE,OAAO,kBAAkB,YAAY,OAAO;EAC9D;AAEA,QAAM,sBAAsB,QAAQ,MAAM,uBAAuB,EAAE,GAAG,CAAA,CAAE;AAEpE,MAAA;AAGA,MAAA;AACF,qBAAiB,qDAAqD,WAAW;AAEnF,6EAEI,UAACC,kCAAAA,KAAAC,eAAA,EAAqB,WAAU,QAC7B,UAAA;AAAA,IACC,kBAAAD,kCAAA,KAACE,SAAA,EACC,UAAA;AAAA,MAACC,kCAAAA,IAAA,MAAA,EAAK,MAAK,OAAO,CAAA;AAAA,MACjB;AAAA,IAAA,GACH;AAAA,IAEDH,kCAAAA,KAAAI,aAAA,EAAmB,KAAK,SAAS,WAAW,KAAK,EAAE,SAAS,aAAa,GAAG,YAAY,GACtF,UAAA;AAAA,MAAA,eACG,sBACA,0BAA0B,IAAI,CAAC,aAC7BD,kCAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC;AAAA,UACA,eAAe;AAAA,UACf,UAAU;AAAA,UACV,UAAU,OAAO,OAAO,OAAO,UAC7B,MAAM,cAAc,UAAU,OAAO,KAAK;AAAA,UAE5C;AAAA,UACA;AAAA,UACA;AAAA,UACA,kBAAkB;AAAA,UAClB,YAAY,SAAS,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,UAC3C,cAAc;AAAA,UACd,YAAY,SAAS,SAAS;AAAA,UAC9B,QAAQ;AAAA,UACR,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,eAAe,sBAAsB,SAAS,SAAS,UAAU;AAAA,UACjE;AAAA,UACA;AAAA,QAAA;AAAA,QAtBK,SAAS;AAAA,MAAA,CAwBjB;AAAA,MAEJ,0BAA0B,WAAW,KAAK,eAAe,cAAc,CAAC,gBACvEA,sCAAC,kBAAiB,EAAA,SAAQ,6BAA4B,MAAK,SAAS,CAAA;AAAA,MAErE,eAAe,gBACdA,kCAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAM,QAAQ;AAAA,UACd,UAAU,CAAC,WAAW,UAAU,aAAa;AAAA,UAC7C,YAAY;AAAA,UAEZ,UAACA,kCAAA,IAAAE,UAAA,EAAgB,OAAO,EAAE,QAAQ,EAAE,GAAG,SAAS,MAAM,aAAA,GACnD,UAAA,oBAAoB,oBAAoB,qBAC3C,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,GAEJ;AAAA,IACC,CAAC,oBACAF,kCAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,QACX,UAAU;AAAA,QACV,QAAQ,cAAc;AAAA,QACtB,SAAS,MAAM,aAAa,IAAI;AAAA,QAChC,QAAQ,MAAM,aAAa,gBAAgB;AAAA,QAC3C,UAAU;AAAA,QACV,WAAW,gBAAgB,CAAC,SAAS,UAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EACjD,EAAA,CAEJ,EACF,CAAA;AAEJ;"}
|
|
@@ -23,6 +23,15 @@ const confirmDelete = require("../../../../util/confirmDelete.cjs.js");
|
|
|
23
23
|
require("react-toastify");
|
|
24
24
|
require("../../../../util/pubsub.cjs.js");
|
|
25
25
|
const ActivityHeader = require("../ActivityHeader/ActivityHeader.cjs.js");
|
|
26
|
+
require("../../../../context/RemoteModulesContext.cjs.js");
|
|
27
|
+
const DetailsPanelContext = require("../../../../context/DetailsPanelContext.cjs.js");
|
|
28
|
+
require("../../../../context/ThumbnailUploaderContext.cjs.js");
|
|
29
|
+
require("../../../../context/SettingsPanelContext.cjs.js");
|
|
30
|
+
require("../../../../context/pip/PiPProvider.cjs.js");
|
|
31
|
+
require("react-dom");
|
|
32
|
+
require("../../../../context/pip/PiPWrapper.cjs.js");
|
|
33
|
+
require("../../../../context/AddonProjectContext.cjs.js");
|
|
34
|
+
require("../../../../context/AddonContext.cjs.js");
|
|
26
35
|
const ActivityComment = ({
|
|
27
36
|
activity = {},
|
|
28
37
|
onCheckChange,
|
|
@@ -56,6 +65,7 @@ const ActivityComment = ({
|
|
|
56
65
|
if (!authorName) authorName = (author == null ? void 0 : author.name) || "";
|
|
57
66
|
if (!authorFullName) authorFullName = (author == null ? void 0 : author.fullName) || authorName;
|
|
58
67
|
const { editingId, setEditingId } = FeedContext.useFeedContext();
|
|
68
|
+
const { onGoToFrame } = DetailsPanelContext.useDetailsPanelContext();
|
|
59
69
|
const handleEditComment = () => {
|
|
60
70
|
setEditingId(activityId);
|
|
61
71
|
};
|
|
@@ -110,6 +120,13 @@ const ActivityComment = ({
|
|
|
110
120
|
});
|
|
111
121
|
}
|
|
112
122
|
};
|
|
123
|
+
const onAnnotationClick = React.useCallback(
|
|
124
|
+
(file) => {
|
|
125
|
+
if (!file.annotation) return;
|
|
126
|
+
onGoToFrame == null ? void 0 : onGoToFrame(file.annotation.range[0] - 1);
|
|
127
|
+
},
|
|
128
|
+
[onGoToFrame]
|
|
129
|
+
);
|
|
113
130
|
return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(jsxRuntime.jsxRuntimeExports.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsxs(
|
|
114
131
|
ActivityComment_styled.Comment,
|
|
115
132
|
{
|
|
@@ -204,6 +221,7 @@ const ActivityComment = ({
|
|
|
204
221
|
projectName,
|
|
205
222
|
isDownloadable: true,
|
|
206
223
|
onExpand: onFileExpand,
|
|
224
|
+
onAnnotationClick,
|
|
207
225
|
onRemove: void 0
|
|
208
226
|
}
|
|
209
227
|
)
|
package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActivityComment.cjs.js","sources":["../../../../../../../src/containers/Feed/components/ActivityComment/ActivityComment.tsx"],"sourcesContent":["import clsx from 'clsx'\nimport { useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport emoji from 'remark-emoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkDirective from 'remark-directive'\nimport remarkDirectiveRehype from 'remark-directive-rehype'\n\nimport CommentInput from '../CommentInput/CommentInput'\nimport Reactions from '../ReactionContainer/Reactions'\nimport { Reaction } from '../ReactionContainer/types'\nimport useReferenceTooltip from '../../hooks/useReferenceTooltip'\nimport FilesGrid, { FilesGridProps } from '../FilesGrid/FilesGrid'\n\nimport { getTextRefs } from '../CommentInput/quillToMarkdown'\nimport * as Styled from './ActivityComment.styled'\nimport CommentWrapper from './CommentWrapper'\nimport { aTag, blockquoteTag, codeTag, inputTag } from './ActivityMarkdownComponents'\nimport { mapGraphQLReactions } from './mappers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport ActivityStatus from '../ActivityStatus/ActivityStatus'\nimport { useFeedContext } from '../../context/FeedContext'\nimport { confirmDelete } from '../../../../util'\nimport ActivityHeader, { ActivityHeaderProps } from '../ActivityHeader/ActivityHeader'\nimport type { Status } from '../../../ProjectTreeTable/types/project'\n\ntype Props = {\n activity: any\n onCheckChange?: Function\n onDelete?: (activityId: string, entityId: string, refs: any) => Promise<void>\n onUpdate?: Function\n projectInfo: any\n editProps?: {\n disabled: boolean\n isLoading: boolean\n }\n projectName: string\n entityType: string\n onReferenceClick?: ActivityHeaderProps['onReferenceClick']\n onFileExpand?: FilesGridProps['onExpand']\n showOrigin?: boolean\n isHighlighted?: boolean\n readOnly?: boolean\n statuses: Status[]\n}\n\nconst ActivityComment = ({\n activity = {},\n onCheckChange,\n onDelete,\n onUpdate,\n projectInfo,\n editProps,\n projectName,\n entityType,\n onReferenceClick,\n onFileExpand,\n showOrigin,\n isHighlighted,\n readOnly,\n statuses = [],\n}: Props) => {\n const { userName, createReaction, deleteReaction } = useFeedContext()\n\n let {\n body,\n authorName,\n authorFullName,\n createdAt,\n referenceType,\n entityId,\n activityId,\n author,\n isOwner,\n files = [],\n origin,\n } = activity\n if (!authorName) authorName = author?.name || ''\n if (!authorFullName) authorFullName = author?.fullName || authorName\n\n const { editingId, setEditingId } = useFeedContext()\n\n const handleEditComment = () => {\n setEditingId(activityId)\n }\n\n const handleEditCancel = () => {\n // close the edit comment\n setEditingId(null)\n }\n\n const handleSave = async (value: any, files: any) => {\n await onUpdate?.(value, files)\n setEditingId(null)\n }\n\n const isEditing = editingId === activityId\n\n const isRef = referenceType !== 'origin' || showOrigin\n\n const handleDelete = async () => {\n const refs = getTextRefs(body)\n\n // if the comment is a reference, (it's origin is not the entity)\n // we need to delete the reference from the origin as well\n // add it to the refs to delete\n if (isRef && origin) {\n refs.push({ id: origin.id, type: origin.type })\n }\n\n // note: body is used to match other refs to delete\n onDelete && (await onDelete(activityId, entityId, refs))\n }\n\n const deleteConfirmation = () => {\n confirmDelete({\n title: 'Delete comment',\n message: 'Are you sure you want to delete this comment?',\n accept: async () => {\n await handleDelete()\n },\n })\n }\n\n const [, setRefTooltip] = useReferenceTooltip()\n\n const mappedReactions = useMemo(\n () => mapGraphQLReactions(activity.reactions, userName),\n [[...(activity.reactions || [])]],\n )\n\n const reactionChangeHandler = (reaction: Reaction) => {\n if (reaction.isActive) {\n createReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n createReactionModel: {\n reaction: reaction.type,\n },\n })\n } else {\n deleteReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n reaction: reaction.type,\n })\n }\n }\n\n return (\n <>\n <Styled.Comment\n className={clsx('comment', { isOwner, isEditing, isHighlighted })}\n id={activityId}\n >\n <ActivityHeader\n name={authorName}\n fullName={authorFullName}\n date={createdAt}\n isRef={isRef}\n activity={activity}\n // projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={onReferenceClick}\n onReferenceTooltip={setRefTooltip}\n children={undefined}\n />\n <Styled.Body className={clsx('comment-body', { isEditing })}>\n {!readOnly && (\n <Styled.Tools className={'tools'}>\n {isOwner && onDelete && (\n <Styled.ToolButton\n icon=\"delete\"\n onClick={deleteConfirmation}\n tooltip=\"Delete comment\"\n />\n )}\n {isOwner && handleEditComment && (\n <Styled.ToolButton icon=\"edit_square\" onClick={handleEditComment} />\n )}\n </Styled.Tools>\n )}\n {isEditing ? (\n <CommentInput\n initValue={body}\n initFiles={files}\n isEditing\n onClose={handleEditCancel}\n onSubmit={handleSave}\n isOpen={true}\n {...editProps}\n />\n ) : (\n <>\n <CommentWrapper>\n <ReactMarkdown\n remarkPlugins={[remarkGfm, emoji, remarkDirective, remarkDirectiveRehype]}\n urlTransform={(url) => url}\n components={{\n // a links\n // @ts-ignore\n a: (props) =>\n // @ts-ignore\n aTag(props, {\n entityId,\n projectName,\n projectInfo,\n onReferenceClick,\n onReferenceTooltip: setRefTooltip,\n activityId,\n }),\n // checkbox inputs\n // @ts-ignore\n input: (props) => inputTag(props, { activity, onCheckChange }),\n // code syntax highlighting\n // eslint-disable-next-line\n // @ts-ignore\n code: (props) => codeTag(props),\n // @ts-ignore\n blockquote: (props) => blockquoteTag(props),\n // @ts-ignore\n tip: (props) => (\n <Styled.Tip>\n <Icon icon=\"info\" />\n {props.children}\n </Styled.Tip>\n ),\n // @ts-ignore\n status: (props) => {\n return (\n <ActivityStatus name={props.id} statuses={statuses}>\n {props.children}\n </ActivityStatus>\n )\n },\n }}\n >\n {body}\n </ReactMarkdown>\n </CommentWrapper>\n {/* file uploads */}\n {/* @ts-ignore */}\n <FilesGrid\n files={files}\n isCompact={files.length > 6}\n activityId={activityId}\n projectName={projectName}\n isDownloadable\n onExpand={onFileExpand}\n onRemove={undefined}\n />\n </>\n )}\n\n {!isEditing && (\n <div style={{ marginTop: '16px' }}>\n {mappedReactions && (\n <Reactions\n reactions={mappedReactions}\n changeHandler={reactionChangeHandler}\n readOnly={readOnly}\n />\n )}\n </div>\n )}\n </Styled.Body>\n </Styled.Comment>\n </>\n )\n}\n\nexport default ActivityComment\n"],"names":["useFeedContext","files","getTextRefs","confirmDelete","useMemo","mapGraphQLReactions","jsx","Fragment","jsxs","Styled.Comment","Styled.Body","Styled.Tools","Styled.ToolButton","CommentInput","aTag","inputTag","codeTag","blockquoteTag","Styled.Tip","Icon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActivityComment.cjs.js","sources":["../../../../../../../src/containers/Feed/components/ActivityComment/ActivityComment.tsx"],"sourcesContent":["import clsx from 'clsx'\nimport { useCallback, useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport emoji from 'remark-emoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkDirective from 'remark-directive'\nimport remarkDirectiveRehype from 'remark-directive-rehype'\n\nimport CommentInput from '../CommentInput/CommentInput'\nimport Reactions from '../ReactionContainer/Reactions'\nimport { Reaction } from '../ReactionContainer/types'\nimport useReferenceTooltip from '../../hooks/useReferenceTooltip'\nimport FilesGrid, { FilesGridProps } from '../FilesGrid/FilesGrid'\n\nimport { getTextRefs } from '../CommentInput/quillToMarkdown'\nimport * as Styled from './ActivityComment.styled'\nimport CommentWrapper from './CommentWrapper'\nimport { aTag, blockquoteTag, codeTag, inputTag } from './ActivityMarkdownComponents'\nimport { mapGraphQLReactions } from './mappers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport ActivityStatus from '../ActivityStatus/ActivityStatus'\nimport { useFeedContext } from '../../context/FeedContext'\nimport { confirmDelete } from '../../../../util'\nimport ActivityHeader, { ActivityHeaderProps } from '../ActivityHeader/ActivityHeader'\nimport type { Status } from '../../../ProjectTreeTable/types/project'\nimport { SavedAnnotationMetadata } from '../../index'\nimport { useDetailsPanelContext } from '@shared/context'\n\ntype Props = {\n activity: any\n onCheckChange?: Function\n onDelete?: (activityId: string, entityId: string, refs: any) => Promise<void>\n onUpdate?: Function\n projectInfo: any\n editProps?: {\n disabled: boolean\n isLoading: boolean\n }\n projectName: string\n entityType: string\n onReferenceClick?: ActivityHeaderProps['onReferenceClick']\n onFileExpand?: FilesGridProps['onExpand']\n showOrigin?: boolean\n isHighlighted?: boolean\n readOnly?: boolean\n statuses: Status[]\n}\n\nconst ActivityComment = ({\n activity = {},\n onCheckChange,\n onDelete,\n onUpdate,\n projectInfo,\n editProps,\n projectName,\n entityType,\n onReferenceClick,\n onFileExpand,\n showOrigin,\n isHighlighted,\n readOnly,\n statuses = [],\n}: Props) => {\n const { userName, createReaction, deleteReaction } = useFeedContext()\n\n let {\n body,\n authorName,\n authorFullName,\n createdAt,\n referenceType,\n entityId,\n activityId,\n author,\n isOwner,\n files = [],\n origin,\n } = activity\n if (!authorName) authorName = author?.name || ''\n if (!authorFullName) authorFullName = author?.fullName || authorName\n\n const { editingId, setEditingId } = useFeedContext()\n const { onGoToFrame } = useDetailsPanelContext()\n\n const handleEditComment = () => {\n setEditingId(activityId)\n }\n\n const handleEditCancel = () => {\n // close the edit comment\n setEditingId(null)\n }\n\n const handleSave = async (value: any, files: any) => {\n await onUpdate?.(value, files)\n setEditingId(null)\n }\n\n const isEditing = editingId === activityId\n\n const isRef = referenceType !== 'origin' || showOrigin\n\n const handleDelete = async () => {\n const refs = getTextRefs(body)\n\n // if the comment is a reference, (it's origin is not the entity)\n // we need to delete the reference from the origin as well\n // add it to the refs to delete\n if (isRef && origin) {\n refs.push({ id: origin.id, type: origin.type })\n }\n\n // note: body is used to match other refs to delete\n onDelete && (await onDelete(activityId, entityId, refs))\n }\n\n const deleteConfirmation = () => {\n confirmDelete({\n title: 'Delete comment',\n message: 'Are you sure you want to delete this comment?',\n accept: async () => {\n await handleDelete()\n },\n })\n }\n\n const [, setRefTooltip] = useReferenceTooltip()\n\n const mappedReactions = useMemo(\n () => mapGraphQLReactions(activity.reactions, userName),\n [[...(activity.reactions || [])]],\n )\n\n const reactionChangeHandler = (reaction: Reaction) => {\n if (reaction.isActive) {\n createReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n createReactionModel: {\n reaction: reaction.type,\n },\n })\n } else {\n deleteReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n reaction: reaction.type,\n })\n }\n }\n\n const onAnnotationClick = useCallback(\n (file: any) => {\n if (!file.annotation) return\n // annotation frame numbers are 1-based\n onGoToFrame?.((file.annotation as SavedAnnotationMetadata).range[0] - 1)\n },\n [onGoToFrame],\n )\n\n return (\n <>\n <Styled.Comment\n className={clsx('comment', { isOwner, isEditing, isHighlighted })}\n id={activityId}\n >\n <ActivityHeader\n name={authorName}\n fullName={authorFullName}\n date={createdAt}\n isRef={isRef}\n activity={activity}\n // projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={onReferenceClick}\n onReferenceTooltip={setRefTooltip}\n children={undefined}\n />\n <Styled.Body className={clsx('comment-body', { isEditing })}>\n {!readOnly && (\n <Styled.Tools className={'tools'}>\n {isOwner && onDelete && (\n <Styled.ToolButton\n icon=\"delete\"\n onClick={deleteConfirmation}\n tooltip=\"Delete comment\"\n />\n )}\n {isOwner && handleEditComment && (\n <Styled.ToolButton icon=\"edit_square\" onClick={handleEditComment} />\n )}\n </Styled.Tools>\n )}\n {isEditing ? (\n <CommentInput\n initValue={body}\n initFiles={files}\n isEditing\n onClose={handleEditCancel}\n onSubmit={handleSave}\n isOpen={true}\n {...editProps}\n />\n ) : (\n <>\n <CommentWrapper>\n <ReactMarkdown\n remarkPlugins={[remarkGfm, emoji, remarkDirective, remarkDirectiveRehype]}\n urlTransform={(url) => url}\n components={{\n // a links\n // @ts-ignore\n a: (props) =>\n // @ts-ignore\n aTag(props, {\n entityId,\n projectName,\n projectInfo,\n onReferenceClick,\n onReferenceTooltip: setRefTooltip,\n activityId,\n }),\n // checkbox inputs\n // @ts-ignore\n input: (props) => inputTag(props, { activity, onCheckChange }),\n // code syntax highlighting\n // eslint-disable-next-line\n // @ts-ignore\n code: (props) => codeTag(props),\n // @ts-ignore\n blockquote: (props) => blockquoteTag(props),\n // @ts-ignore\n tip: (props) => (\n <Styled.Tip>\n <Icon icon=\"info\" />\n {props.children}\n </Styled.Tip>\n ),\n // @ts-ignore\n status: (props) => {\n return (\n <ActivityStatus name={props.id} statuses={statuses}>\n {props.children}\n </ActivityStatus>\n )\n },\n }}\n >\n {body}\n </ReactMarkdown>\n </CommentWrapper>\n {/* file uploads */}\n {/* @ts-ignore */}\n <FilesGrid\n files={files}\n isCompact={files.length > 6}\n activityId={activityId}\n projectName={projectName}\n isDownloadable\n onExpand={onFileExpand}\n onAnnotationClick={onAnnotationClick}\n onRemove={undefined}\n />\n </>\n )}\n\n {!isEditing && (\n <div style={{ marginTop: '16px' }}>\n {mappedReactions && (\n <Reactions\n reactions={mappedReactions}\n changeHandler={reactionChangeHandler}\n readOnly={readOnly}\n />\n )}\n </div>\n )}\n </Styled.Body>\n </Styled.Comment>\n </>\n )\n}\n\nexport default ActivityComment\n"],"names":["useFeedContext","useDetailsPanelContext","files","getTextRefs","confirmDelete","useMemo","mapGraphQLReactions","useCallback","jsx","Fragment","jsxs","Styled.Comment","Styled.Body","Styled.Tools","Styled.ToolButton","CommentInput","aTag","inputTag","codeTag","blockquoteTag","Styled.Tip","Icon"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as jsxRuntimeExports } from "../../../../../../_virtual/jsx-runtime.es.js";
|
|
2
2
|
import clsx from "clsx";
|
|
3
|
-
import { useMemo } from "react";
|
|
3
|
+
import { useMemo, useCallback } from "react";
|
|
4
4
|
import ReactMarkdown from "react-markdown";
|
|
5
5
|
import emoji from "remark-emoji";
|
|
6
6
|
import remarkGfm from "remark-gfm";
|
|
@@ -22,6 +22,15 @@ import { confirmDelete } from "../../../../util/confirmDelete.es.js";
|
|
|
22
22
|
import "react-toastify";
|
|
23
23
|
import "../../../../util/pubsub.es.js";
|
|
24
24
|
import ActivityHeader from "../ActivityHeader/ActivityHeader.es.js";
|
|
25
|
+
import "../../../../context/RemoteModulesContext.es.js";
|
|
26
|
+
import { useDetailsPanelContext } from "../../../../context/DetailsPanelContext.es.js";
|
|
27
|
+
import "../../../../context/ThumbnailUploaderContext.es.js";
|
|
28
|
+
import "../../../../context/SettingsPanelContext.es.js";
|
|
29
|
+
import "../../../../context/pip/PiPProvider.es.js";
|
|
30
|
+
import "react-dom";
|
|
31
|
+
import "../../../../context/pip/PiPWrapper.es.js";
|
|
32
|
+
import "../../../../context/AddonProjectContext.es.js";
|
|
33
|
+
import "../../../../context/AddonContext.es.js";
|
|
25
34
|
const ActivityComment = ({
|
|
26
35
|
activity = {},
|
|
27
36
|
onCheckChange,
|
|
@@ -55,6 +64,7 @@ const ActivityComment = ({
|
|
|
55
64
|
if (!authorName) authorName = (author == null ? void 0 : author.name) || "";
|
|
56
65
|
if (!authorFullName) authorFullName = (author == null ? void 0 : author.fullName) || authorName;
|
|
57
66
|
const { editingId, setEditingId } = useFeedContext();
|
|
67
|
+
const { onGoToFrame } = useDetailsPanelContext();
|
|
58
68
|
const handleEditComment = () => {
|
|
59
69
|
setEditingId(activityId);
|
|
60
70
|
};
|
|
@@ -109,6 +119,13 @@ const ActivityComment = ({
|
|
|
109
119
|
});
|
|
110
120
|
}
|
|
111
121
|
};
|
|
122
|
+
const onAnnotationClick = useCallback(
|
|
123
|
+
(file) => {
|
|
124
|
+
if (!file.annotation) return;
|
|
125
|
+
onGoToFrame == null ? void 0 : onGoToFrame(file.annotation.range[0] - 1);
|
|
126
|
+
},
|
|
127
|
+
[onGoToFrame]
|
|
128
|
+
);
|
|
112
129
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
113
130
|
Comment,
|
|
114
131
|
{
|
|
@@ -203,6 +220,7 @@ const ActivityComment = ({
|
|
|
203
220
|
projectName,
|
|
204
221
|
isDownloadable: true,
|
|
205
222
|
onExpand: onFileExpand,
|
|
223
|
+
onAnnotationClick,
|
|
206
224
|
onRemove: void 0
|
|
207
225
|
}
|
|
208
226
|
)
|
package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActivityComment.es.js","sources":["../../../../../../../src/containers/Feed/components/ActivityComment/ActivityComment.tsx"],"sourcesContent":["import clsx from 'clsx'\nimport { useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport emoji from 'remark-emoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkDirective from 'remark-directive'\nimport remarkDirectiveRehype from 'remark-directive-rehype'\n\nimport CommentInput from '../CommentInput/CommentInput'\nimport Reactions from '../ReactionContainer/Reactions'\nimport { Reaction } from '../ReactionContainer/types'\nimport useReferenceTooltip from '../../hooks/useReferenceTooltip'\nimport FilesGrid, { FilesGridProps } from '../FilesGrid/FilesGrid'\n\nimport { getTextRefs } from '../CommentInput/quillToMarkdown'\nimport * as Styled from './ActivityComment.styled'\nimport CommentWrapper from './CommentWrapper'\nimport { aTag, blockquoteTag, codeTag, inputTag } from './ActivityMarkdownComponents'\nimport { mapGraphQLReactions } from './mappers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport ActivityStatus from '../ActivityStatus/ActivityStatus'\nimport { useFeedContext } from '../../context/FeedContext'\nimport { confirmDelete } from '../../../../util'\nimport ActivityHeader, { ActivityHeaderProps } from '../ActivityHeader/ActivityHeader'\nimport type { Status } from '../../../ProjectTreeTable/types/project'\n\ntype Props = {\n activity: any\n onCheckChange?: Function\n onDelete?: (activityId: string, entityId: string, refs: any) => Promise<void>\n onUpdate?: Function\n projectInfo: any\n editProps?: {\n disabled: boolean\n isLoading: boolean\n }\n projectName: string\n entityType: string\n onReferenceClick?: ActivityHeaderProps['onReferenceClick']\n onFileExpand?: FilesGridProps['onExpand']\n showOrigin?: boolean\n isHighlighted?: boolean\n readOnly?: boolean\n statuses: Status[]\n}\n\nconst ActivityComment = ({\n activity = {},\n onCheckChange,\n onDelete,\n onUpdate,\n projectInfo,\n editProps,\n projectName,\n entityType,\n onReferenceClick,\n onFileExpand,\n showOrigin,\n isHighlighted,\n readOnly,\n statuses = [],\n}: Props) => {\n const { userName, createReaction, deleteReaction } = useFeedContext()\n\n let {\n body,\n authorName,\n authorFullName,\n createdAt,\n referenceType,\n entityId,\n activityId,\n author,\n isOwner,\n files = [],\n origin,\n } = activity\n if (!authorName) authorName = author?.name || ''\n if (!authorFullName) authorFullName = author?.fullName || authorName\n\n const { editingId, setEditingId } = useFeedContext()\n\n const handleEditComment = () => {\n setEditingId(activityId)\n }\n\n const handleEditCancel = () => {\n // close the edit comment\n setEditingId(null)\n }\n\n const handleSave = async (value: any, files: any) => {\n await onUpdate?.(value, files)\n setEditingId(null)\n }\n\n const isEditing = editingId === activityId\n\n const isRef = referenceType !== 'origin' || showOrigin\n\n const handleDelete = async () => {\n const refs = getTextRefs(body)\n\n // if the comment is a reference, (it's origin is not the entity)\n // we need to delete the reference from the origin as well\n // add it to the refs to delete\n if (isRef && origin) {\n refs.push({ id: origin.id, type: origin.type })\n }\n\n // note: body is used to match other refs to delete\n onDelete && (await onDelete(activityId, entityId, refs))\n }\n\n const deleteConfirmation = () => {\n confirmDelete({\n title: 'Delete comment',\n message: 'Are you sure you want to delete this comment?',\n accept: async () => {\n await handleDelete()\n },\n })\n }\n\n const [, setRefTooltip] = useReferenceTooltip()\n\n const mappedReactions = useMemo(\n () => mapGraphQLReactions(activity.reactions, userName),\n [[...(activity.reactions || [])]],\n )\n\n const reactionChangeHandler = (reaction: Reaction) => {\n if (reaction.isActive) {\n createReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n createReactionModel: {\n reaction: reaction.type,\n },\n })\n } else {\n deleteReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n reaction: reaction.type,\n })\n }\n }\n\n return (\n <>\n <Styled.Comment\n className={clsx('comment', { isOwner, isEditing, isHighlighted })}\n id={activityId}\n >\n <ActivityHeader\n name={authorName}\n fullName={authorFullName}\n date={createdAt}\n isRef={isRef}\n activity={activity}\n // projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={onReferenceClick}\n onReferenceTooltip={setRefTooltip}\n children={undefined}\n />\n <Styled.Body className={clsx('comment-body', { isEditing })}>\n {!readOnly && (\n <Styled.Tools className={'tools'}>\n {isOwner && onDelete && (\n <Styled.ToolButton\n icon=\"delete\"\n onClick={deleteConfirmation}\n tooltip=\"Delete comment\"\n />\n )}\n {isOwner && handleEditComment && (\n <Styled.ToolButton icon=\"edit_square\" onClick={handleEditComment} />\n )}\n </Styled.Tools>\n )}\n {isEditing ? (\n <CommentInput\n initValue={body}\n initFiles={files}\n isEditing\n onClose={handleEditCancel}\n onSubmit={handleSave}\n isOpen={true}\n {...editProps}\n />\n ) : (\n <>\n <CommentWrapper>\n <ReactMarkdown\n remarkPlugins={[remarkGfm, emoji, remarkDirective, remarkDirectiveRehype]}\n urlTransform={(url) => url}\n components={{\n // a links\n // @ts-ignore\n a: (props) =>\n // @ts-ignore\n aTag(props, {\n entityId,\n projectName,\n projectInfo,\n onReferenceClick,\n onReferenceTooltip: setRefTooltip,\n activityId,\n }),\n // checkbox inputs\n // @ts-ignore\n input: (props) => inputTag(props, { activity, onCheckChange }),\n // code syntax highlighting\n // eslint-disable-next-line\n // @ts-ignore\n code: (props) => codeTag(props),\n // @ts-ignore\n blockquote: (props) => blockquoteTag(props),\n // @ts-ignore\n tip: (props) => (\n <Styled.Tip>\n <Icon icon=\"info\" />\n {props.children}\n </Styled.Tip>\n ),\n // @ts-ignore\n status: (props) => {\n return (\n <ActivityStatus name={props.id} statuses={statuses}>\n {props.children}\n </ActivityStatus>\n )\n },\n }}\n >\n {body}\n </ReactMarkdown>\n </CommentWrapper>\n {/* file uploads */}\n {/* @ts-ignore */}\n <FilesGrid\n files={files}\n isCompact={files.length > 6}\n activityId={activityId}\n projectName={projectName}\n isDownloadable\n onExpand={onFileExpand}\n onRemove={undefined}\n />\n </>\n )}\n\n {!isEditing && (\n <div style={{ marginTop: '16px' }}>\n {mappedReactions && (\n <Reactions\n reactions={mappedReactions}\n changeHandler={reactionChangeHandler}\n readOnly={readOnly}\n />\n )}\n </div>\n )}\n </Styled.Body>\n </Styled.Comment>\n </>\n )\n}\n\nexport default ActivityComment\n"],"names":["files","jsx","Fragment","jsxs","Styled.Comment","Styled.Body","Styled.Tools","Styled.ToolButton","Styled.Tip"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActivityComment.es.js","sources":["../../../../../../../src/containers/Feed/components/ActivityComment/ActivityComment.tsx"],"sourcesContent":["import clsx from 'clsx'\nimport { useCallback, useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport emoji from 'remark-emoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkDirective from 'remark-directive'\nimport remarkDirectiveRehype from 'remark-directive-rehype'\n\nimport CommentInput from '../CommentInput/CommentInput'\nimport Reactions from '../ReactionContainer/Reactions'\nimport { Reaction } from '../ReactionContainer/types'\nimport useReferenceTooltip from '../../hooks/useReferenceTooltip'\nimport FilesGrid, { FilesGridProps } from '../FilesGrid/FilesGrid'\n\nimport { getTextRefs } from '../CommentInput/quillToMarkdown'\nimport * as Styled from './ActivityComment.styled'\nimport CommentWrapper from './CommentWrapper'\nimport { aTag, blockquoteTag, codeTag, inputTag } from './ActivityMarkdownComponents'\nimport { mapGraphQLReactions } from './mappers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport ActivityStatus from '../ActivityStatus/ActivityStatus'\nimport { useFeedContext } from '../../context/FeedContext'\nimport { confirmDelete } from '../../../../util'\nimport ActivityHeader, { ActivityHeaderProps } from '../ActivityHeader/ActivityHeader'\nimport type { Status } from '../../../ProjectTreeTable/types/project'\nimport { SavedAnnotationMetadata } from '../../index'\nimport { useDetailsPanelContext } from '@shared/context'\n\ntype Props = {\n activity: any\n onCheckChange?: Function\n onDelete?: (activityId: string, entityId: string, refs: any) => Promise<void>\n onUpdate?: Function\n projectInfo: any\n editProps?: {\n disabled: boolean\n isLoading: boolean\n }\n projectName: string\n entityType: string\n onReferenceClick?: ActivityHeaderProps['onReferenceClick']\n onFileExpand?: FilesGridProps['onExpand']\n showOrigin?: boolean\n isHighlighted?: boolean\n readOnly?: boolean\n statuses: Status[]\n}\n\nconst ActivityComment = ({\n activity = {},\n onCheckChange,\n onDelete,\n onUpdate,\n projectInfo,\n editProps,\n projectName,\n entityType,\n onReferenceClick,\n onFileExpand,\n showOrigin,\n isHighlighted,\n readOnly,\n statuses = [],\n}: Props) => {\n const { userName, createReaction, deleteReaction } = useFeedContext()\n\n let {\n body,\n authorName,\n authorFullName,\n createdAt,\n referenceType,\n entityId,\n activityId,\n author,\n isOwner,\n files = [],\n origin,\n } = activity\n if (!authorName) authorName = author?.name || ''\n if (!authorFullName) authorFullName = author?.fullName || authorName\n\n const { editingId, setEditingId } = useFeedContext()\n const { onGoToFrame } = useDetailsPanelContext()\n\n const handleEditComment = () => {\n setEditingId(activityId)\n }\n\n const handleEditCancel = () => {\n // close the edit comment\n setEditingId(null)\n }\n\n const handleSave = async (value: any, files: any) => {\n await onUpdate?.(value, files)\n setEditingId(null)\n }\n\n const isEditing = editingId === activityId\n\n const isRef = referenceType !== 'origin' || showOrigin\n\n const handleDelete = async () => {\n const refs = getTextRefs(body)\n\n // if the comment is a reference, (it's origin is not the entity)\n // we need to delete the reference from the origin as well\n // add it to the refs to delete\n if (isRef && origin) {\n refs.push({ id: origin.id, type: origin.type })\n }\n\n // note: body is used to match other refs to delete\n onDelete && (await onDelete(activityId, entityId, refs))\n }\n\n const deleteConfirmation = () => {\n confirmDelete({\n title: 'Delete comment',\n message: 'Are you sure you want to delete this comment?',\n accept: async () => {\n await handleDelete()\n },\n })\n }\n\n const [, setRefTooltip] = useReferenceTooltip()\n\n const mappedReactions = useMemo(\n () => mapGraphQLReactions(activity.reactions, userName),\n [[...(activity.reactions || [])]],\n )\n\n const reactionChangeHandler = (reaction: Reaction) => {\n if (reaction.isActive) {\n createReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n createReactionModel: {\n reaction: reaction.type,\n },\n })\n } else {\n deleteReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n reaction: reaction.type,\n })\n }\n }\n\n const onAnnotationClick = useCallback(\n (file: any) => {\n if (!file.annotation) return\n // annotation frame numbers are 1-based\n onGoToFrame?.((file.annotation as SavedAnnotationMetadata).range[0] - 1)\n },\n [onGoToFrame],\n )\n\n return (\n <>\n <Styled.Comment\n className={clsx('comment', { isOwner, isEditing, isHighlighted })}\n id={activityId}\n >\n <ActivityHeader\n name={authorName}\n fullName={authorFullName}\n date={createdAt}\n isRef={isRef}\n activity={activity}\n // projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={onReferenceClick}\n onReferenceTooltip={setRefTooltip}\n children={undefined}\n />\n <Styled.Body className={clsx('comment-body', { isEditing })}>\n {!readOnly && (\n <Styled.Tools className={'tools'}>\n {isOwner && onDelete && (\n <Styled.ToolButton\n icon=\"delete\"\n onClick={deleteConfirmation}\n tooltip=\"Delete comment\"\n />\n )}\n {isOwner && handleEditComment && (\n <Styled.ToolButton icon=\"edit_square\" onClick={handleEditComment} />\n )}\n </Styled.Tools>\n )}\n {isEditing ? (\n <CommentInput\n initValue={body}\n initFiles={files}\n isEditing\n onClose={handleEditCancel}\n onSubmit={handleSave}\n isOpen={true}\n {...editProps}\n />\n ) : (\n <>\n <CommentWrapper>\n <ReactMarkdown\n remarkPlugins={[remarkGfm, emoji, remarkDirective, remarkDirectiveRehype]}\n urlTransform={(url) => url}\n components={{\n // a links\n // @ts-ignore\n a: (props) =>\n // @ts-ignore\n aTag(props, {\n entityId,\n projectName,\n projectInfo,\n onReferenceClick,\n onReferenceTooltip: setRefTooltip,\n activityId,\n }),\n // checkbox inputs\n // @ts-ignore\n input: (props) => inputTag(props, { activity, onCheckChange }),\n // code syntax highlighting\n // eslint-disable-next-line\n // @ts-ignore\n code: (props) => codeTag(props),\n // @ts-ignore\n blockquote: (props) => blockquoteTag(props),\n // @ts-ignore\n tip: (props) => (\n <Styled.Tip>\n <Icon icon=\"info\" />\n {props.children}\n </Styled.Tip>\n ),\n // @ts-ignore\n status: (props) => {\n return (\n <ActivityStatus name={props.id} statuses={statuses}>\n {props.children}\n </ActivityStatus>\n )\n },\n }}\n >\n {body}\n </ReactMarkdown>\n </CommentWrapper>\n {/* file uploads */}\n {/* @ts-ignore */}\n <FilesGrid\n files={files}\n isCompact={files.length > 6}\n activityId={activityId}\n projectName={projectName}\n isDownloadable\n onExpand={onFileExpand}\n onAnnotationClick={onAnnotationClick}\n onRemove={undefined}\n />\n </>\n )}\n\n {!isEditing && (\n <div style={{ marginTop: '16px' }}>\n {mappedReactions && (\n <Reactions\n reactions={mappedReactions}\n changeHandler={reactionChangeHandler}\n readOnly={readOnly}\n />\n )}\n </div>\n )}\n </Styled.Body>\n </Styled.Comment>\n </>\n )\n}\n\nexport default ActivityComment\n"],"names":["files","jsx","Fragment","jsxs","Styled.Comment","Styled.Body","Styled.Tools","Styled.ToolButton","Styled.Tip"],"mappings":"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"}
|
|
@@ -271,8 +271,8 @@ const CommentInput = ({
|
|
|
271
271
|
setFilesUploading((prev) => prev.filter((uploading) => uploading.name !== file.name));
|
|
272
272
|
return newFile;
|
|
273
273
|
};
|
|
274
|
-
const handleFileRemove = (id, name,
|
|
275
|
-
if (
|
|
274
|
+
const handleFileRemove = (id, name, isUnsavedAnnotation) => {
|
|
275
|
+
if (isUnsavedAnnotation) {
|
|
276
276
|
removeAnnotation == null ? void 0 : removeAnnotation(id);
|
|
277
277
|
} else {
|
|
278
278
|
setFiles((prev) => prev.filter((file) => file.id !== id));
|
|
@@ -313,15 +313,18 @@ const CommentInput = ({
|
|
|
313
313
|
try {
|
|
314
314
|
setIsSubmitting(true);
|
|
315
315
|
let annotationFiles = [];
|
|
316
|
+
let annotationMetadata = [];
|
|
316
317
|
if (annotations.length) {
|
|
317
|
-
|
|
318
|
+
const { files: files2, metadata } = await uploadAnnotations(annotations);
|
|
319
|
+
annotationFiles = files2;
|
|
320
|
+
annotationMetadata = metadata;
|
|
318
321
|
}
|
|
319
322
|
const [markdown] = quillToMarkdown.convertToMarkdown(editorValue);
|
|
320
323
|
const markdownParsed = helpers.parseImages(markdown);
|
|
321
324
|
const uploadedFiles = [...files, ...annotationFiles];
|
|
322
325
|
if ((markdownParsed || uploadedFiles.length) && onSubmit) {
|
|
323
326
|
try {
|
|
324
|
-
await onSubmit(markdownParsed, uploadedFiles);
|
|
327
|
+
await onSubmit(markdownParsed, uploadedFiles, { annotations: annotationMetadata });
|
|
325
328
|
setEditorValue("");
|
|
326
329
|
setFiles([]);
|
|
327
330
|
} catch (error) {
|