Ver código fonte

feat: sort adornments

Sv443 8 meses atrás
pai
commit
58c20fd511
1 arquivos alterados com 44 adições e 18 exclusões
  1. 44 18
      src/features/index.ts

+ 44 - 18
src/features/index.ts

@@ -23,36 +23,55 @@ interface SelectOption<TValue = number | string> {
   label: string;
 }
 
+type AdornmentFunc =
+  | ((...args: any[]) => Promise<string | undefined>)
+  | Promise<string | undefined>;
+
 //#region dependencies
 
+/** Decoration elements that can be added next to the label */
+const adornments = {
+  advanced: async () => getAdornHtml("bytm-advanced-mode-icon", t("advanced_mode"), "icon-advanced_mode"),
+  experimental: async () => getAdornHtml("bytm-experimental-icon", t("experimental_feature"), "icon-experimental"),
+  globe: async () => await resourceAsString("icon-globe_small") ?? "",
+  alert: async (title: string) => getAdornHtml("bytm-warning-icon", title, "icon-error", "role=\"alert\""),
+  reloadRequired: async () => getFeature("advancedMode") ? getAdornHtml("bytm-reload-icon", t("feature_requires_reload"), "icon-reload") : undefined,
+} satisfies Record<string, AdornmentFunc>;
+
+/** Order of adornment elements in the {@linkcode combineAdornments()} function */
+const adornmentOrder = new Map<AdornmentFunc, number>();
+adornmentOrder.set(adornments.alert, 0);
+adornmentOrder.set(adornments.experimental, 1);
+adornmentOrder.set(adornments.globe, 2);
+adornmentOrder.set(adornments.reloadRequired, 3);
+adornmentOrder.set(adornments.advanced, 4);
+
 /** Creates an HTML string for the given adornment properties */
 const getAdornHtml = async (className: string, title: string, resource: ResourceKey, extraParams?: string) =>
   `<span class="${className} bytm-adorn-icon" title="${title}" aria-label="${title}"${extraParams ? " " + extraParams : ""}>${await resourceAsString(resource) ?? ""}</span>`;
 
 /** Combines multiple async functions or promises that resolve with an adornment HTML string into a single string */
 const combineAdornments = (
-  adornments: Array<(
-    | (() => Promise<string | undefined>)
-    | Promise<string | undefined>
-  )>
-) =>
-  new Promise<string>(async (resolve) => {
+  adornments: Array<AdornmentFunc>
+) => new Promise<string>(
+  async (resolve) => {
+    const sortedAdornments = adornments.sort((a, b) => {
+      const aIndex = adornmentOrder.get(a) ? adornmentOrder.get(a)! : -1;
+      const bIndex = adornmentOrder.has(b) ? adornmentOrder.get(b)! : -1;
+      return aIndex - bIndex;
+    });
     const html = [] as string[];
-    for(const adornment of adornments) {
-      const val = typeof adornment === "function" ? await adornment() : await adornment;
+
+    for(const adornment of sortedAdornments) {
+      const val = typeof adornment === "function"
+        ? await adornment()
+        : await adornment;
       val && html.push(val);
     }
-    resolve(html.join(""));
-  });
 
-/** Decoration elements that can be added next to the label */
-const adornments = {
-  advanced: async () => getAdornHtml("bytm-advanced-mode-icon", t("advanced_mode"), "icon-advanced_mode"),
-  experimental: async () => getAdornHtml("bytm-experimental-icon", t("experimental_feature"), "icon-experimental"),
-  globe: async () => await resourceAsString("icon-globe_small") ?? "",
-  alert: async (title: string) => getAdornHtml("bytm-warning-icon", title, "icon-error", "role=\"alert\""),
-  reloadRequired: async () => getFeature("advancedMode") ? getAdornHtml("bytm-reload-icon", t("feature_requires_reload"), "icon-reload") : undefined,
-} satisfies Record<string, (...args: any[]) => Promise<string | undefined>>;
+    resolve(html.join(""));
+  }
+);
 
 /** Common options for config items of type "select" */
 const options = {
@@ -686,6 +705,13 @@ export const featInfo = {
       iconSrc: getResourceUrl(`img-logo${mode === "development" ? "_dev" : ""}`),
     }),
   },
+  showToastOnGenericError: {
+    type: "toggle",
+    category: "general",
+    default: true,
+    advanced: true,
+    textAdornment: () => combineAdornments([adornments.advanced, adornments.reloadRequired]),
+  },
   resetConfig: {
     type: "button",
     category: "general",