Use Font Awesome 6 in file uploads
authorAlexander Ebert <ebert@woltlab.com>
Mon, 15 Aug 2022 17:20:02 +0000 (19:20 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 15 Aug 2022 17:20:02 +0000 (19:20 +0200)
ts/WoltLabSuite/Core/FileUtil.ts
ts/WoltLabSuite/Core/Media/Upload.ts
ts/WoltLabSuite/Core/Ui/File/Upload.ts
wcfsetup/install/files/js/WoltLabSuite/Core/FileUtil.js
wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/File/Upload.js
wcfsetup/install/files/lib/data/attachment/Attachment.class.php
wcfsetup/install/files/lib/util/FileUtil.class.php

index 686997c7440394181f37f27b7f88a947026ed2bc..df249642f5d2f664e15d5242cc500fd6c7816eae 100644 (file)
@@ -12,10 +12,10 @@ import * as StringUtil from "./StringUtil";
 const _fileExtensionIconMapping = new Map<string, string>(
   Object.entries({
     // archive
-    zip: "archive",
-    rar: "archive",
-    tar: "archive",
-    gz: "archive",
+    zip: "zipper",
+    rar: "zipper",
+    tar: "zipper",
+    gz: "zipper",
 
     // audio
     mp3: "audio",
@@ -59,7 +59,7 @@ const _fileExtensionIconMapping = new Map<string, string>(
     pptx: "powerpoint",
 
     // text
-    txt: "text",
+    txt: "lines",
 
     // word
     doc: "word",
index a9a95796b12cbec870847b4d09eef3b0500fbab2..30341baace6fea896ebe649fd4b6c048799fdea3 100644 (file)
@@ -180,7 +180,7 @@ class MediaUpload<TOptions extends MediaUploadOptions = MediaUploadOptions> exte
     return Core.extend(super._getParameters() as object, parameters as object) as ArbitraryObject;
   }
 
-  protected _replaceFileIcon(fileIcon: HTMLElement, media: Media, size: number): void {
+  protected _replaceFileIcon(fileIcon: FaIcon, media: Media, size: number): void {
     if (media.elementTag) {
       fileIcon.outerHTML = media.elementTag;
     } else if (media.tinyThumbnailType) {
@@ -192,13 +192,14 @@ class MediaUpload<TOptions extends MediaUploadOptions = MediaUploadOptions> exte
 
       DomUtil.replaceElement(fileIcon, img);
     } else {
-      fileIcon.classList.remove("fa-spinner");
-
       let fileIconName = FileUtil.getIconNameByFilename(media.filename);
       if (fileIconName) {
-        fileIconName = "-" + fileIconName;
+        fileIconName = `file-${fileIconName}`;
+      } else {
+        fileIconName = "file";
       }
-      fileIcon.classList.add(`fa-file${fileIconName}-o`);
+
+      fileIcon.setIcon(fileIconName, false);
     }
   }
 
@@ -220,7 +221,7 @@ class MediaUpload<TOptions extends MediaUploadOptions = MediaUploadOptions> exte
           file.querySelector(".columnMediaID")!.textContent = media.mediaID.toString();
 
           // update icon
-          this._replaceFileIcon(file.querySelector(".fa-spinner") as HTMLSpanElement, media, 48);
+          this._replaceFileIcon(file.querySelector("fa-icon")!, media, 48);
         } else {
           let error: MediaUploadError = data.returnValues.errors[internalFileId];
           if (!error) {
@@ -230,17 +231,20 @@ class MediaUpload<TOptions extends MediaUploadOptions = MediaUploadOptions> exte
             };
           }
 
-          const fileIcon = file.querySelector(".fa-spinner") as HTMLSpanElement;
-          fileIcon.classList.remove("fa-spinner");
-          fileIcon.classList.add("fa-remove", "pointer", "jsTooltip");
-          fileIcon.title = Language.get("wcf.global.button.delete");
-          fileIcon.addEventListener("click", (event) => {
-            const target = event.currentTarget as HTMLSpanElement;
-            target.closest(".mediaFile")!.remove();
+          const deleteButton = document.createElement("button");
+          deleteButton.classList.add("jsTooltip");
+          deleteButton.title = Language.get("wcf.global.button.delete");
+          deleteButton.addEventListener("click", () => {
+            deleteButton.closest(".mediaFile")!.remove();
 
             EventHandler.fire("com.woltlab.wcf.media.upload", "removedErroneousUploadRow");
           });
 
+          const fileIcon = file.querySelector("fa-icon")!;
+          fileIcon.setIcon("xmark", true);
+          fileIcon.insertAdjacentElement("beforebegin", deleteButton);
+          deleteButton.append(fileIcon);
+
           file.classList.add("uploadFailed");
 
           const p = file.querySelectorAll(".columnFilename .box48 > div > p")[1] as HTMLElement;
@@ -258,7 +262,7 @@ class MediaUpload<TOptions extends MediaUploadOptions = MediaUploadOptions> exte
         DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaInformation")!, "PROGRESS")!.remove();
 
         if (media) {
-          const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail")!, "SPAN")!;
+          const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail")!, "FA-ICON")!;
           this._replaceFileIcon(fileIcon, media, 144);
 
           file.classList.add("jsClipboardObject", "mediaFile", "jsObjectActionObject");
@@ -277,11 +281,10 @@ class MediaUpload<TOptions extends MediaUploadOptions = MediaUploadOptions> exte
             };
           }
 
-          const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail")!, "SPAN")!;
-          fileIcon.classList.remove("fa-spinner");
-          fileIcon.classList.add("fa-remove", "pointer");
+          const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail")!, "FA-ICON")!;
+          fileIcon.setIcon("xmark", true);
 
-          file.classList.add("uploadFailed", "jsTooltip");
+          file.classList.add("uploadFailed", "pointer", "jsTooltip");
           file.title = Language.get("wcf.global.button.delete");
           file.addEventListener("click", () => file.remove());
 
index eb55f1babbc0ddc6b654b91f675c68b80fa23534..09540f68d6f94a64e2eef0d306e28f71770cabb0 100644 (file)
@@ -85,8 +85,9 @@ class FileUpload extends Upload<FileUploadOptions> implements FileUploadHandler
 
     const progress = element.querySelector("progress") as HTMLProgressElement;
 
-    const icon = document.createElement("span");
-    icon.className = "icon icon64 fa-spinner";
+    const icon = document.createElement("fa-icon");
+    icon.size = 64;
+    icon.setIcon("spinner", false);
 
     const fileName = element.textContent;
     element.textContent = "";
@@ -122,9 +123,8 @@ class FileUpload extends Upload<FileUploadOptions> implements FileUploadHandler
       const small = fileElement.querySelector("small") as HTMLElement;
       small.innerHTML = "";
 
-      const icon = fileElement.querySelector(".icon") as HTMLElement;
-      icon.classList.remove("fa-spinner");
-      icon.classList.add("fa-ban");
+      const icon = fileElement.querySelector("fa-icon")!;
+      icon.setIcon("ban", true);
 
       const innerError = document.createElement("span");
       innerError.className = "innerError";
@@ -174,7 +174,7 @@ class FileUpload extends Upload<FileUploadOptions> implements FileUploadHandler
         } else {
           fileElement.dataset.uniqueFileId = fileData.uniqueFileId;
           fileElement.querySelector("small")!.textContent = fileData.filesize.toString();
-          const icon = fileElement.querySelector(".icon") as HTMLElement;
+          const icon = fileElement.querySelector("fa-icon")!;
 
           if (fileData.image !== null) {
             const a = document.createElement("a");
@@ -188,8 +188,7 @@ class FileUpload extends Upload<FileUploadOptions> implements FileUploadHandler
             a.appendChild(image);
             icon.replaceWith(a);
           } else {
-            icon.classList.remove("fa-spinner");
-            icon.classList.add(`fa-${fileData.icon}`);
+            icon.setIcon(fileData.icon, fileData.icon === "paperclip");
           }
         }
       } else if (data.error[index] !== undefined) {
@@ -200,9 +199,8 @@ class FileUpload extends Upload<FileUploadOptions> implements FileUploadHandler
         const small = fileElement.querySelector("small") as HTMLElement;
         small.innerHTML = "";
 
-        const icon = fileElement.querySelector(".icon") as HTMLElement;
-        icon.classList.remove("fa-spinner");
-        icon.classList.add("fa-ban");
+        const icon = fileElement.querySelector("fa-icon")!;
+        icon.setIcon("ban", true);
 
         let innerError = fileElement.querySelector(".innerError") as HTMLElement;
         if (innerError === null) {
index 2b4a77c184a177810041ee45d4c489938802d8e6..a8c8ac4c73b584dab6c6cb686bbdb01cd9494d27 100644 (file)
@@ -13,10 +13,10 @@ define(["require", "exports", "tslib", "./StringUtil"], function (require, expor
     StringUtil = tslib_1.__importStar(StringUtil);
     const _fileExtensionIconMapping = new Map(Object.entries({
         // archive
-        zip: "archive",
-        rar: "archive",
-        tar: "archive",
-        gz: "archive",
+        zip: "zipper",
+        rar: "zipper",
+        tar: "zipper",
+        gz: "zipper",
         // audio
         mp3: "audio",
         ogg: "audio",
@@ -52,7 +52,7 @@ define(["require", "exports", "tslib", "./StringUtil"], function (require, expor
         ppt: "powerpoint",
         pptx: "powerpoint",
         // text
-        txt: "text",
+        txt: "lines",
         // word
         doc: "word",
         docx: "word",
index 12881c4708f8d5b0878820da7481aa67dff6044b..65e796117bef3d3a1dfe585c6bfb2c9a3d7cb0e8 100644 (file)
@@ -156,12 +156,14 @@ define(["require", "exports", "tslib", "../Upload", "../Core", "../Dom/Util", ".
                 DomUtil.replaceElement(fileIcon, img);
             }
             else {
-                fileIcon.classList.remove("fa-spinner");
                 let fileIconName = FileUtil.getIconNameByFilename(media.filename);
                 if (fileIconName) {
-                    fileIconName = "-" + fileIconName;
+                    fileIconName = `file-${fileIconName}`;
                 }
-                fileIcon.classList.add(`fa-file${fileIconName}-o`);
+                else {
+                    fileIconName = "file";
+                }
+                fileIcon.setIcon(fileIconName, false);
             }
         }
         _success(uploadId, data) {
@@ -179,7 +181,7 @@ define(["require", "exports", "tslib", "../Upload", "../Core", "../Dom/Util", ".
                         });
                         file.querySelector(".columnMediaID").textContent = media.mediaID.toString();
                         // update icon
-                        this._replaceFileIcon(file.querySelector(".fa-spinner"), media, 48);
+                        this._replaceFileIcon(file.querySelector("fa-icon"), media, 48);
                     }
                     else {
                         let error = data.returnValues.errors[internalFileId];
@@ -189,15 +191,17 @@ define(["require", "exports", "tslib", "../Upload", "../Core", "../Dom/Util", ".
                                 filename: file.dataset.filename,
                             };
                         }
-                        const fileIcon = file.querySelector(".fa-spinner");
-                        fileIcon.classList.remove("fa-spinner");
-                        fileIcon.classList.add("fa-remove", "pointer", "jsTooltip");
-                        fileIcon.title = Language.get("wcf.global.button.delete");
-                        fileIcon.addEventListener("click", (event) => {
-                            const target = event.currentTarget;
-                            target.closest(".mediaFile").remove();
+                        const deleteButton = document.createElement("button");
+                        deleteButton.classList.add("jsTooltip");
+                        deleteButton.title = Language.get("wcf.global.button.delete");
+                        deleteButton.addEventListener("click", () => {
+                            deleteButton.closest(".mediaFile").remove();
                             EventHandler.fire("com.woltlab.wcf.media.upload", "removedErroneousUploadRow");
                         });
+                        const fileIcon = file.querySelector("fa-icon");
+                        fileIcon.setIcon("xmark", true);
+                        fileIcon.insertAdjacentElement("beforebegin", deleteButton);
+                        deleteButton.append(fileIcon);
                         file.classList.add("uploadFailed");
                         const p = file.querySelectorAll(".columnFilename .box48 > div > p")[1];
                         DomUtil.innerError(p, Language.get(`wcf.media.upload.error.${error.errorType}`, {
@@ -209,7 +213,7 @@ define(["require", "exports", "tslib", "../Upload", "../Core", "../Dom/Util", ".
                 else {
                     DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaInformation"), "PROGRESS").remove();
                     if (media) {
-                        const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail"), "SPAN");
+                        const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail"), "FA-ICON");
                         this._replaceFileIcon(fileIcon, media, 144);
                         file.classList.add("jsClipboardObject", "mediaFile", "jsObjectActionObject");
                         file.dataset.objectId = media.mediaID.toString();
@@ -226,10 +230,9 @@ define(["require", "exports", "tslib", "../Upload", "../Core", "../Dom/Util", ".
                                 filename: file.dataset.filename,
                             };
                         }
-                        const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail"), "SPAN");
-                        fileIcon.classList.remove("fa-spinner");
-                        fileIcon.classList.add("fa-remove", "pointer");
-                        file.classList.add("uploadFailed", "jsTooltip");
+                        const fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, "mediaThumbnail"), "FA-ICON");
+                        fileIcon.setIcon("xmark", true);
+                        file.classList.add("uploadFailed", "pointer", "jsTooltip");
                         file.title = Language.get("wcf.global.button.delete");
                         file.addEventListener("click", () => file.remove());
                         const title = DomTraverse.childByClass(DomTraverse.childByClass(file, "mediaInformation"), "mediaTitle");
index 130bb35581dd8158cd11ad506b0d6526deedd191..34871c0ea337b61493bdba67460e178ef8c95f1f 100644 (file)
@@ -41,8 +41,9 @@ define(["require", "exports", "tslib", "../../Core", "./Delete", "../../Dom/Util
             const element = super._createFileElement(file);
             element.classList.add("box64", "uploadedFile");
             const progress = element.querySelector("progress");
-            const icon = document.createElement("span");
-            icon.className = "icon icon64 fa-spinner";
+            const icon = document.createElement("fa-icon");
+            icon.size = 64;
+            icon.setIcon("spinner", false);
             const fileName = element.textContent;
             element.textContent = "";
             element.append(icon);
@@ -67,9 +68,8 @@ define(["require", "exports", "tslib", "../../Core", "./Delete", "../../Dom/Util
                 fileElement.classList.add("uploadFailed");
                 const small = fileElement.querySelector("small");
                 small.innerHTML = "";
-                const icon = fileElement.querySelector(".icon");
-                icon.classList.remove("fa-spinner");
-                icon.classList.add("fa-ban");
+                const icon = fileElement.querySelector("fa-icon");
+                icon.setIcon("ban", true);
                 const innerError = document.createElement("span");
                 innerError.className = "innerError";
                 innerError.textContent = Language.get("wcf.upload.error.uploadFailed");
@@ -110,7 +110,7 @@ define(["require", "exports", "tslib", "../../Core", "./Delete", "../../Dom/Util
                     else {
                         fileElement.dataset.uniqueFileId = fileData.uniqueFileId;
                         fileElement.querySelector("small").textContent = fileData.filesize.toString();
-                        const icon = fileElement.querySelector(".icon");
+                        const icon = fileElement.querySelector("fa-icon");
                         if (fileData.image !== null) {
                             const a = document.createElement("a");
                             a.classList.add("jsImageViewer");
@@ -124,8 +124,7 @@ define(["require", "exports", "tslib", "../../Core", "./Delete", "../../Dom/Util
                             icon.replaceWith(a);
                         }
                         else {
-                            icon.classList.remove("fa-spinner");
-                            icon.classList.add(`fa-${fileData.icon}`);
+                            icon.setIcon(fileData.icon, fileData.icon === "paperclip");
                         }
                     }
                 }
@@ -134,9 +133,8 @@ define(["require", "exports", "tslib", "../../Core", "./Delete", "../../Dom/Util
                     fileElement.classList.add("uploadFailed");
                     const small = fileElement.querySelector("small");
                     small.innerHTML = "";
-                    const icon = fileElement.querySelector(".icon");
-                    icon.classList.remove("fa-spinner");
-                    icon.classList.add("fa-ban");
+                    const icon = fileElement.querySelector("fa-icon");
+                    icon.setIcon("ban", true);
                     let innerError = fileElement.querySelector(".innerError");
                     if (innerError === null) {
                         innerError = document.createElement("span");
index 6d8559bf1ee4844829e8b674d879e9bff023823f..53f28ff310fc06104cda34643787c9fbd8761eb9 100644 (file)
@@ -322,7 +322,7 @@ class Attachment extends DatabaseObject implements ILinkableObject, IRouteContro
     public function getIconName()
     {
         if ($iconName = FileUtil::getIconNameByFilename($this->filename)) {
-            return 'file-' . $iconName . '-o';
+            return 'file-' . $iconName;
         }
 
         return 'paperclip';
index 8331a7c98a02e40be1d1c829c9a0601a2c30c8a4..d68cf3a6ed4de4499f957638483e891e5993266d 100644 (file)
@@ -616,10 +616,10 @@ final class FileUtil
     {
         static $mapping = [
             // archive
-            'zip' => 'archive',
-            'rar' => 'archive',
-            'tar' => 'archive',
-            'gz' => 'archive',
+            'zip' => 'zipper',
+            'rar' => 'zipper',
+            'tar' => 'zipper',
+            'gz' => 'zipper',
             // audio
             'mp3' => 'audio',
             'ogg' => 'audio',
@@ -655,7 +655,7 @@ final class FileUtil
             'ppt' => 'powerpoint',
             'pptx' => 'powerpoint',
             // text
-            'txt' => 'text',
+            'txt' => 'lines',
             // word
             'doc' => 'word',
             'docx' => 'word',