RenderFileName.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import React, { useEffect, useState } from 'react';
  2. import { updateFilePublicMagicMetadata } from 'services/fileService';
  3. import { EnteFile } from 'types/file';
  4. import {
  5. changeFileName,
  6. splitFilenameAndExtension,
  7. updateExistingFilePubMetadata,
  8. } from 'utils/file';
  9. import { FlexWrapper } from 'components/Container';
  10. import { logError } from 'utils/sentry';
  11. import { FILE_TYPE } from 'constants/file';
  12. import InfoItem from './InfoItem';
  13. import { makeHumanReadableStorage } from 'utils/billing';
  14. import Box from '@mui/material/Box';
  15. import { FileNameEditDialog } from './FileNameEditDialog';
  16. import VideocamOutlined from '@mui/icons-material/VideocamOutlined';
  17. import PhotoOutlined from '@mui/icons-material/PhotoOutlined';
  18. const getFileTitle = (filename, extension) => {
  19. if (extension) {
  20. return filename + '.' + extension;
  21. } else {
  22. return filename;
  23. }
  24. };
  25. const getCaption = (file: EnteFile, parsedExifData) => {
  26. const megaPixels = parsedExifData?.['megaPixels'];
  27. const resolution = parsedExifData?.['resolution'];
  28. const fileSize = file.info?.fileSize;
  29. const captionParts = [];
  30. if (megaPixels) {
  31. captionParts.push(megaPixels);
  32. }
  33. if (resolution) {
  34. captionParts.push(resolution);
  35. }
  36. if (fileSize) {
  37. captionParts.push(makeHumanReadableStorage(fileSize));
  38. }
  39. return (
  40. <FlexWrapper gap={1}>
  41. {captionParts.map((caption) => (
  42. <Box key={caption}> {caption}</Box>
  43. ))}
  44. </FlexWrapper>
  45. );
  46. };
  47. export function RenderFileName({
  48. parsedExifData,
  49. shouldDisableEdits,
  50. file,
  51. scheduleUpdate,
  52. }: {
  53. parsedExifData: Record<string, any>;
  54. shouldDisableEdits: boolean;
  55. file: EnteFile;
  56. scheduleUpdate: () => void;
  57. }) {
  58. const [isInEditMode, setIsInEditMode] = useState(false);
  59. const openEditMode = () => setIsInEditMode(true);
  60. const closeEditMode = () => setIsInEditMode(false);
  61. const [filename, setFilename] = useState<string>();
  62. const [extension, setExtension] = useState<string>();
  63. useEffect(() => {
  64. const [filename, extension] = splitFilenameAndExtension(
  65. file.metadata.title
  66. );
  67. setFilename(filename);
  68. setExtension(extension);
  69. }, []);
  70. const saveEdits = async (newFilename: string) => {
  71. try {
  72. if (file) {
  73. if (filename === newFilename) {
  74. closeEditMode();
  75. return;
  76. }
  77. setFilename(newFilename);
  78. const newTitle = getFileTitle(newFilename, extension);
  79. let updatedFile = await changeFileName(file, newTitle);
  80. updatedFile = (
  81. await updateFilePublicMagicMetadata([updatedFile])
  82. )[0];
  83. updateExistingFilePubMetadata(file, updatedFile);
  84. scheduleUpdate();
  85. }
  86. } catch (e) {
  87. logError(e, 'failed to update file name');
  88. throw e;
  89. }
  90. };
  91. return (
  92. <>
  93. <InfoItem
  94. icon={
  95. file.metadata.fileType === FILE_TYPE.VIDEO ? (
  96. <VideocamOutlined />
  97. ) : (
  98. <PhotoOutlined />
  99. )
  100. }
  101. title={getFileTitle(filename, extension)}
  102. caption={getCaption(file, parsedExifData)}
  103. openEditor={openEditMode}
  104. hideEditOption={shouldDisableEdits || isInEditMode}
  105. />
  106. <FileNameEditDialog
  107. isInEditMode={isInEditMode}
  108. closeEditMode={closeEditMode}
  109. filename={filename}
  110. extension={extension}
  111. saveEdits={saveEdits}
  112. />
  113. </>
  114. );
  115. }