Просмотр исходного кода

update Attachment component and attributes

ryoji-s 3 лет назад
Родитель
Сommit
18a0a8e309

+ 71 - 14
packages/app/src/components/ReactMarkdownComponents/Attachment.tsx

@@ -1,24 +1,81 @@
-import React from 'react';
+import React, { useMemo, useCallback } from 'react';
 
-type AttachmentProps = {
-  className?: string,
-  url: string,
-  attachmentName: string,
-  attachmentId: string,
-}
+import { UserPicture } from '@growi/ui';
+import prettyBytes from 'pretty-bytes';
 
-export const Attachment = React.memo((props: AttachmentProps): JSX.Element => {
-  const { className, url, attachmentName } = props;
+import { useSWRxAttachments } from '~/stores/attachment';
+import { useCurrentPageId } from '~/stores/page';
+
+export const Attachment: React.FC<{
+  attachmentId: string
+}> = React.memo(({ attachmentId }) => {
+  const { data: pageId } = useCurrentPageId();
+  // TODO: We need to be able to get it from all pages if there are a lot of attachments.
+  const { data: dataAttachments, remove } = useSWRxAttachments(pageId, 1);
+
+  const attachment = useMemo(() => {
+    if (dataAttachments == null) {
+      return;
+    }
+
+    return dataAttachments.attachments.find(item => item._id === attachmentId);
+  }, [attachmentId, dataAttachments]);
+
+  const handleAttachmentDelete = useCallback(async() => {
+    if (attachment == null) {
+      return;
+    }
+
+    try {
+      await remove({ attachment_id: attachment._id });
+      // TODO: success notification
+    }
+    catch (err) {
+      // TODO: error handling
+    }
+  }, [attachment, remove]);
+
+  // TODO: update fo attachment is not found
+  // TODO: fix hydration failed error
+  if (attachment == null) {
+    return (
+      <div className='text-muted'>This attachment not found.</div>
+    );
+  }
 
   return (
-    <div className="card">
-      <h3 className="card-title m-0">Remark Attachment Component</h3>
+    <div className="card my-3" style={{ width: 'fit-content' }}>
       <div className="card-body">
-        <a className={className} href={url}>
-          {attachmentName}
-        </a>
+        <div className='row'>
+          {/* TODO: Design check */}
+          <div className='col-2'>
+            <i className='icon-doc' style={{ fontSize: '2.7rem' }}/>
+          </div>
+          <div className='col-10'>
+            <div>
+              <a href={attachment.downloadPathProxied}>{attachment.originalName}</a>
+              <span className='ml-2'>
+                <a className="attachment-download" href={attachment.downloadPathProxied}>
+                  <i className="icon-cloud-download" />
+                </a>
+              </span>
+              <span className='ml-2'>
+                <a className="text-danger attachment-delete" onClick={handleAttachmentDelete}>
+                  <i className="icon-trash" />
+                </a>
+              </span>
+            </div>
+            <div>
+              <UserPicture user={attachment.creator} size="sm"></UserPicture>
+              {/* TODO: check locale */}
+              <span className='ml-2 text-muted'>{new Date(attachment.createdAt).toLocaleString('ja-JP')}</span>
+              <span className='border-left ml-2 pl-2 text-muted'>{prettyBytes(attachment.fileSize)}</span>
+            </div>
+          </div>
+        </div>
       </div>
     </div>
+
   );
 });
 Attachment.displayName = 'Attachment';

+ 1 - 3
packages/app/src/services/renderer/remark-plugins/attachment.ts

@@ -2,7 +2,7 @@ import { Schema as SanitizeOption } from 'hast-util-sanitize';
 import { Plugin } from 'unified';
 import { visit } from 'unist-util-visit';
 
-const SUPPORTED_ATTRIBUTES = ['url', 'attachmentName', 'attachmentId'];
+const SUPPORTED_ATTRIBUTES = ['attachmentId'];
 
 const isAttachmentLink = (url: string) => {
   // https://regex101.com/r/9qZhiK/1
@@ -20,8 +20,6 @@ export const remarkPlugin: Plugin = () => {
           const data = node.data ?? (node.data = {});
           data.hName = 'attachment';
           data.hProperties = {
-            url: node.url,
-            attachmentName: node.children[0].value,
             attachmentId: pathName[2],
           };