diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons.d.ts b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons.d.ts new file mode 100644 index 00000000000..8e196020402 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons.d.ts @@ -0,0 +1,8 @@ +// Support importing SVG files as strings + +declare module '*.svg' { + + const content: string; + + export default content; +} \ No newline at end of file diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/LICENSE.md b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/LICENSE.md new file mode 100644 index 00000000000..518ad472680 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/LICENSE.md @@ -0,0 +1,7 @@ +The mimetype icons originate from the Elementary icon theme: + +Link: https://github.com/elementary/icons +Author: Members of the Elementary OS team (https://github.com/orgs/elementary/people) +License: GPLv3 (https://choosealicense.com/licenses/gpl-3.0/) + +https://github.com/linuxmint/mint-l-icons/tree/master/src/mimetypes \ No newline at end of file diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/application-json.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/application-json.svg new file mode 100644 index 00000000000..2cb871fa372 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/application-json.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/application-pdf.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/application-pdf.svg new file mode 100644 index 00000000000..c6a0a6caa68 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/application-pdf.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/audio-x-generic.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/audio-x-generic.svg new file mode 100644 index 00000000000..81cde3317a3 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/audio-x-generic.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/image-loading.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/image-loading.svg new file mode 100644 index 00000000000..3d587eb2f71 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/image-loading.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/image-x-generic.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/image-x-generic.svg new file mode 100644 index 00000000000..5bed5a1f4dc --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/image-x-generic.svg @@ -0,0 +1,247 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/model.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/model.svg new file mode 100644 index 00000000000..5d5a22d2a4b --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/model.svg @@ -0,0 +1,38 @@ + + + + + + + image/svg+xml + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/package-x-generic.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/package-x-generic.svg new file mode 100644 index 00000000000..26146f7c1f6 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/package-x-generic.svg @@ -0,0 +1,167 @@ + + + + + + image/svg+xml + + + + + + elementary Icon Template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-html.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-html.svg new file mode 100644 index 00000000000..11d468de20c --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-html.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-x-generic.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-x-generic.svg new file mode 100644 index 00000000000..c866c5c01e5 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-x-generic.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-x-makefile.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-x-makefile.svg new file mode 100644 index 00000000000..0c049bbf450 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/text-x-makefile.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/video-x-generic.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/video-x-generic.svg new file mode 100644 index 00000000000..c1888ad11d4 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/video-x-generic.svg @@ -0,0 +1,120 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-document.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-document.svg new file mode 100644 index 00000000000..2924227d253 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-document.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-presentation.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-presentation.svg new file mode 100644 index 00000000000..cf448d97b26 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-presentation.svg @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-spreadsheet.svg b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-spreadsheet.svg new file mode 100644 index 00000000000..dcc998d3740 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Attachments/MimetypeIcons/x-office-spreadsheet.svg @@ -0,0 +1,46 @@ + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/specifyweb/frontend/js_src/lib/components/Attachments/attachments.ts b/specifyweb/frontend/js_src/lib/components/Attachments/attachments.ts index 17220ed6e45..88f3e34d038 100644 --- a/specifyweb/frontend/js_src/lib/components/Attachments/attachments.ts +++ b/specifyweb/frontend/js_src/lib/components/Attachments/attachments.ts @@ -10,9 +10,22 @@ import type { SpecifyResource } from '../DataModel/legacyTypes'; import { tables } from '../DataModel/tables'; import type { Attachment } from '../DataModel/types'; import { load } from '../InitialContext'; -import { getIcon, unknownIcon } from '../InitialContext/icons'; import { getPref } from '../InitialContext/remotePrefs'; import { formatUrl } from '../Router/queryString'; +// Import SVG icons, but better than in Icons.tsx +import applicationJsonIcon from './MimetypeIcons/application-json.svg'; +import applicationPdfIcon from './MimetypeIcons/application-pdf.svg'; +import audioXGenericIcon from './MimetypeIcons/audio-x-generic.svg'; +import imageXGenericIcon from './MimetypeIcons/image-x-generic.svg'; +import modelIcon from './MimetypeIcons/model.svg'; +import packageXgeneric from './MimetypeIcons/package-x-generic.svg'; +import textHtmlIcon from './MimetypeIcons/text-html.svg'; +import textXGenericIcon from './MimetypeIcons/text-x-generic.svg'; +import textXMakefileIcon from './MimetypeIcons/text-x-makefile.svg'; +import videoXGenericIcon from './MimetypeIcons/video-x-generic.svg'; +import xOfficeDocumentIcon from './MimetypeIcons/x-office-document.svg'; +import xOfficePresentationIcon from './MimetypeIcons/x-office-presentation.svg'; +import xOfficeSpreadsheetIcon from './MimetypeIcons/x-office-spreadsheet.svg'; type AttachmentSettings = { readonly collection: string; @@ -48,31 +61,34 @@ function iconForMimeType(mimeType: string): { readonly alt: string; readonly src: string; } { - if (mimeType === 'text/plain') - return { alt: 'text', src: getIcon('text') ?? unknownIcon }; - if (mimeType === 'text/html') - return { alt: 'html', src: getIcon('html') ?? unknownIcon }; - - const parts = mimeType.split('/'); - const type = parts[0]; - const subtype = parts[1]; - - if (['audio', 'video', 'image', 'text'].includes(type)) - return { alt: type, src: getIcon(type) ?? unknownIcon }; - - if (type === 'application') { - const iconName = { - pdf: 'pdf', - 'vnd.ms-excel': 'MSExcel', - 'vnd.ms-word': 'MSWord', - 'vnd.ms-powerpoint': 'MSPowerPoint', - }[subtype]; - - if (typeof iconName === 'string') - return { alt: iconName, src: getIcon(iconName) ?? unknownIcon }; - } + const iconMap: Record = { + 'application/json': { alt: 'json', src: applicationJsonIcon }, + 'application/pdf': { alt: 'pdf', src: applicationPdfIcon }, + 'audio/x-generic': { alt: 'audio', src: audioXGenericIcon }, + 'image/x-generic': { alt: 'image', src: imageXGenericIcon }, + 'model': { alt: 'model', src: modelIcon }, + 'text/html': { alt: 'html', src: textHtmlIcon }, + 'text/xml': { alt: 'html', src: textHtmlIcon }, + 'text/plain': { alt: 'text', src: textXGenericIcon }, + 'text/x-makefile': { alt: 'makefile', src: textXMakefileIcon }, + 'application/x-yaml': { alt: 'yaml', src: textXMakefileIcon }, + 'video/x-generic': { alt: 'video', src: videoXGenericIcon }, + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': { alt: 'MSWord', src: xOfficeDocumentIcon }, + 'application/vnd.openxmlformats-officedocument.presentationml.presentation': { alt: 'MSPowerPoint', src: xOfficePresentationIcon }, + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': { alt: 'MSExcel', src: xOfficeSpreadsheetIcon }, + 'application/zip': { alt: 'zip', src: packageXgeneric }, + }; - return { alt: commonText.unknown(), src: getIcon('unknown') ?? unknownIcon }; + return ( + iconMap[mimeType] + ?? (mimeType.startsWith('video/') ? { alt: 'video', src: videoXGenericIcon } : null) + ?? (mimeType.startsWith('audio/') ? { alt: 'audio', src: audioXGenericIcon } : null) + ?? (mimeType.startsWith('image/') ? { alt: 'image', src: imageXGenericIcon } : null) + ?? (mimeType.endsWith('presentation') || mimeType.includes('powerpoint') ? { alt: 'presentation', src: xOfficePresentationIcon } : null) + ?? (mimeType.includes('wordprocessing') || mimeType.endsWith('word') ? { alt: 'document', src: xOfficeDocumentIcon } : null) + ?? (mimeType == null ? { alt: 'image', src: textXGenericIcon } : null) + ?? { alt: commonText.unknown(), src: textXGenericIcon } + ); } export const fetchAssetToken = async ( @@ -108,7 +124,7 @@ export async function fetchThumbnail( : iconForMimeType(mimeType); // Display an icon for resources that don't have a custom thumbnail - if (typeof thumbnail === 'object' && thumbnail?.src !== unknownIcon) + if (typeof thumbnail === 'object') return { ...thumbnail, width: scale, diff --git a/specifyweb/frontend/js_src/lib/components/Preferences/UserDefinitions.tsx b/specifyweb/frontend/js_src/lib/components/Preferences/UserDefinitions.tsx index 044bbd9fc25..78e891d0dff 100644 --- a/specifyweb/frontend/js_src/lib/components/Preferences/UserDefinitions.tsx +++ b/specifyweb/frontend/js_src/lib/components/Preferences/UserDefinitions.tsx @@ -65,9 +65,10 @@ const isDarkMode = ({ }: PreferencesVisibilityContext): boolean => isDarkMode || isRedirecting; // Navigator may not be defined in some environments, like non-browser environments -const altKeyName = typeof navigator !== 'undefined' && navigator?.userAgent?.includes('Mac') - ? 'Option' - : 'Alt'; +const altKeyName = + typeof navigator !== 'undefined' && navigator?.userAgent?.includes('Mac') + ? 'Option' + : 'Alt'; /** * Have to be careful as preferences may be used before schema is loaded diff --git a/specifyweb/frontend/js_src/lib/components/RouterCommands/SwitchCollection.tsx b/specifyweb/frontend/js_src/lib/components/RouterCommands/SwitchCollection.tsx index aeb54a2407e..ef201ec09d8 100644 --- a/specifyweb/frontend/js_src/lib/components/RouterCommands/SwitchCollection.tsx +++ b/specifyweb/frontend/js_src/lib/components/RouterCommands/SwitchCollection.tsx @@ -42,8 +42,8 @@ export function SwitchCollectionCommand(): null { body: collectionId!.toString(), errorMode: 'dismissible', }) - .then(clearAllCache) - .then(() => globalThis.location.replace(nextUrl)), + .then(clearAllCache) + .then(() => globalThis.location.replace(nextUrl)), [collectionId, nextUrl] ), true