@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.
Files changed (74) hide show
  1. package/dist/_virtual/index.cjs5.js +3 -5
  2. package/dist/_virtual/index.cjs5.js.map +1 -1
  3. package/dist/_virtual/index.cjs6.js +5 -3
  4. package/dist/_virtual/index.cjs6.js.map +1 -1
  5. package/dist/_virtual/index.es5.js +2 -5
  6. package/dist/_virtual/index.es5.js.map +1 -1
  7. package/dist/_virtual/index.es6.js +5 -2
  8. package/dist/_virtual/index.es6.js.map +1 -1
  9. package/dist/node_modules/rehype-prism-plus/dist/index.es.cjs.js +1 -1
  10. package/dist/node_modules/rehype-prism-plus/dist/index.es.es.js +1 -1
  11. package/dist/node_modules/remove-accents/index.cjs.js +1 -1
  12. package/dist/node_modules/remove-accents/index.es.js +1 -1
  13. package/dist/shared/src/containers/Feed/Feed.cjs.js +21 -2
  14. package/dist/shared/src/containers/Feed/Feed.cjs.js.map +1 -1
  15. package/dist/shared/src/containers/Feed/Feed.es.js +22 -3
  16. package/dist/shared/src/containers/Feed/Feed.es.js.map +1 -1
  17. package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.cjs.js +18 -0
  18. package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.cjs.js.map +1 -1
  19. package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.es.js +19 -1
  20. package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.es.js.map +1 -1
  21. package/dist/shared/src/containers/Feed/components/CommentInput/CommentInput.cjs.js +7 -4
  22. package/dist/shared/src/containers/Feed/components/CommentInput/CommentInput.cjs.js.map +1 -1
  23. package/dist/shared/src/containers/Feed/components/CommentInput/CommentInput.es.js +7 -4
  24. package/dist/shared/src/containers/Feed/components/CommentInput/CommentInput.es.js.map +1 -1
  25. package/dist/shared/src/containers/Feed/components/CommentInput/helpers.cjs.js.map +1 -1
  26. package/dist/shared/src/containers/Feed/components/CommentInput/helpers.es.js.map +1 -1
  27. package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.cjs.js +1 -1
  28. package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.cjs.js.map +1 -1
  29. package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.es.js +1 -1
  30. package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.es.js.map +1 -1
  31. package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.cjs.js +27 -15
  32. package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.cjs.js.map +1 -1
  33. package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.es.js +27 -15
  34. package/dist/shared/src/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.es.js.map +1 -1
  35. package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.cjs.js +40 -12
  36. package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.cjs.js.map +1 -1
  37. package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.es.js +41 -13
  38. package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.es.js.map +1 -1
  39. package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.styled.cjs.js +33 -19
  40. package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.styled.cjs.js.map +1 -1
  41. package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.styled.es.js +33 -19
  42. package/dist/shared/src/containers/Feed/components/FileUploadCard/FileUploadCard.styled.es.js.map +1 -1
  43. package/dist/shared/src/containers/Feed/components/FilesGrid/FilesGrid.cjs.js +14 -12
  44. package/dist/shared/src/containers/Feed/components/FilesGrid/FilesGrid.cjs.js.map +1 -1
  45. package/dist/shared/src/containers/Feed/components/FilesGrid/FilesGrid.es.js +14 -12
  46. package/dist/shared/src/containers/Feed/components/FilesGrid/FilesGrid.es.js.map +1 -1
  47. package/dist/shared/src/containers/Feed/components/Tooltips/EntityTooltip/EntityTooltip.cjs.js +8 -8
  48. package/dist/shared/src/containers/Feed/components/Tooltips/EntityTooltip/EntityTooltip.es.js +8 -8
  49. package/dist/shared/src/containers/Feed/helpers/mergeAnnotationAttachments.cjs.js +18 -0
  50. package/dist/shared/src/containers/Feed/helpers/mergeAnnotationAttachments.cjs.js.map +1 -0
  51. package/dist/shared/src/containers/Feed/helpers/mergeAnnotationAttachments.es.js +19 -0
  52. package/dist/shared/src/containers/Feed/helpers/mergeAnnotationAttachments.es.js.map +1 -0
  53. package/dist/shared/src/containers/Feed/hooks/useCommentMutations.cjs.js +12 -3
  54. package/dist/shared/src/containers/Feed/hooks/useCommentMutations.cjs.js.map +1 -1
  55. package/dist/shared/src/containers/Feed/hooks/useCommentMutations.es.js +12 -3
  56. package/dist/shared/src/containers/Feed/hooks/useCommentMutations.es.js.map +1 -1
  57. package/dist/shared/src/containers/Feed/hooks/useTransformActivities.cjs.js.map +1 -1
  58. package/dist/shared/src/containers/Feed/hooks/useTransformActivities.es.js.map +1 -1
  59. package/dist/shared/src/context/DetailsPanelContext.cjs.js +3 -0
  60. package/dist/shared/src/context/DetailsPanelContext.cjs.js.map +1 -1
  61. package/dist/shared/src/context/DetailsPanelContext.es.js +3 -0
  62. package/dist/shared/src/context/DetailsPanelContext.es.js.map +1 -1
  63. package/dist/types/containers/Feed/components/CommentInput/CommentInput.d.ts +1 -1
  64. package/dist/types/containers/Feed/components/CommentInput/helpers.d.ts +6 -1
  65. package/dist/types/containers/Feed/components/CommentInput/hooks/useAnnotationsSync.d.ts +1 -1
  66. package/dist/types/containers/Feed/components/CommentInput/hooks/useAnnotationsUpload.d.ts +5 -1
  67. package/dist/types/containers/Feed/components/FileUploadCard/FileUploadCard.d.ts +5 -2
  68. package/dist/types/containers/Feed/components/FileUploadCard/FileUploadCard.styled.d.ts +4 -0
  69. package/dist/types/containers/Feed/components/FilesGrid/FilesGrid.d.ts +1 -1
  70. package/dist/types/containers/Feed/helpers/mergeAnnotationAttachments.d.ts +2 -0
  71. package/dist/types/containers/Feed/hooks/useCommentMutations.d.ts +1 -1
  72. package/dist/types/containers/Feed/index.d.ts +6 -0
  73. package/dist/types/context/DetailsPanelContext.d.ts +4 -0
  74. package/package.json +1 -1
@@ -1,7 +1,5 @@
1
1
  "use strict";
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;
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
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- var removeAccents = { exports: {} };
4
- exports.__module = removeAccents;
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
- 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);
1
+ var removeAccents = { exports: {} };
5
2
  export {
6
- n as default
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
- var removeAccents = { exports: {} };
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
- removeAccents as __module
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.cjs5.js");
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.es5.js";
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.cjs6.js");
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.es6.js";
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 { openSlideOut, highlightedActivities, setHighlightedActivities, onOpenImage } = DetailsPanelContext.useDetailsPanelContext();
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
- activitiesData,
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 { useRef, useMemo } from "react";
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 { openSlideOut, highlightedActivities, setHighlightedActivities, onOpenImage } = useDetailsPanelContext();
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
- activitiesData,
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":"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"}
@@ -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
  )
@@ -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
  )
@@ -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, isAnnotation) => {
275
- if (isAnnotation) {
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
- annotationFiles = await uploadAnnotations(annotations);
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) {