diff --git a/rspack.config.js b/rspack.config.js index 9bb41530b..4cf1ebf9a 100644 --- a/rspack.config.js +++ b/rspack.config.js @@ -89,9 +89,15 @@ module.exports = (env, options) => { ], type: 'javascript/auto', }, + { + test: /\.svg$/, + resourceQuery: /raw/, + type: 'asset/source', + }, // Asset files { test: /\.(png|svg|jpg|jpeg|ico|ttf|webp|eot|woff|webm|mp4|wav)(\?.*)?$/, + resourceQuery: { not: [/raw/] }, type: 'asset/resource', }, // Regular CSS/SCSS files diff --git a/src/cm/themes/noctisLilac.js b/src/cm/themes/noctisLilac.js index c8665b661..c32479274 100644 --- a/src/cm/themes/noctisLilac.js +++ b/src/cm/themes/noctisLilac.js @@ -11,7 +11,7 @@ export const config = { cursor: "#5c49e9", dropdownBackground: "#f2f1f8", dropdownBorder: "#e1def3", - activeLine: "#e1def3", + activeLine: "#e1def355", lineNumber: "#0c006b70", lineNumberActive: "#0c006b", matchingBracket: "#d5d1f2", diff --git a/src/dialogs/loader.js b/src/dialogs/loader.js index 0c69daf4f..133b982bd 100644 --- a/src/dialogs/loader.js +++ b/src/dialogs/loader.js @@ -2,11 +2,20 @@ import DOMPurify from "dompurify"; import Ref from "html-tag-js/ref"; import actionStack from "lib/actionStack"; import restoreTheme from "lib/restoreTheme"; +import tailSpinSvg from "res/tail-spin.svg?raw"; let loaderIsImmortal = false; let onCancelCallback = null; let $currentDialog = null; let $currentMask = null; +const titleLoaderId = "__title-loader"; +const tailSpinGradientId = "tail-spin-gradient"; +let tailSpinSvgId = 0; + +function createTailSpinSvg() { + const gradientId = `${tailSpinGradientId}-${tailSpinSvgId++}`; + return tailSpinSvg.split(tailSpinGradientId).join(gradientId); +} /** * @typedef {object} LoaderOptions @@ -51,7 +60,7 @@ function create(titleText, message = "", options = {}) { {titleText} - +
+ ); + + if (!$titleLoader.isConnected) { + app.append($titleLoader); + } + + return $titleLoader; +} + /** * Removes the loader from DOM permanently */ @@ -159,6 +180,7 @@ function showTitleLoader(immortal = false) { } setTimeout(() => { + createTitleLoader(); app.classList.remove("title-loading-hide"); app.classList.add("title-loading"); }, 0); diff --git a/src/dialogs/style.scss b/src/dialogs/style.scss index a91908105..2db23f2bb 100644 --- a/src/dialogs/style.scss +++ b/src/dialogs/style.scss @@ -1,5 +1,3 @@ -@use "../styles/mixins.scss"; - .prompt { position: fixed; left: 50%; @@ -285,8 +283,19 @@ align-items: center; .loader { - @include mixins.circular-loader(30px); + width: 30px; + height: 30px; + color: rgb(153, 153, 255); + color: var(--primary-color); + display: flex; + flex-shrink: 0; margin: 0 10px; + + svg { + width: 100%; + height: 100%; + display: block; + } } .message { diff --git a/src/lib/showFileInfo.js b/src/lib/showFileInfo.js index ebc5bd0b8..9b0650c3c 100644 --- a/src/lib/showFileInfo.js +++ b/src/lib/showFileInfo.js @@ -1,5 +1,6 @@ import fsOperation from "fileSystem"; import dialog from "dialogs/dialog"; +import loader from "dialogs/loader"; import { filesize } from "filesize"; import mustache from "mustache"; import helpers from "utils/helpers"; @@ -13,7 +14,7 @@ import settings from "./settings"; */ export default async function showFileInfo(url) { if (!url) url = editorManager.activeFile.uri; - app.classList.add("title-loading"); + loader.showTitleLoader(); try { const fs = fsOperation(url); const stats = await fs.stat(); @@ -65,5 +66,5 @@ export default async function showFileInfo(url) { helpers.error(err); } - app.classList.remove("title-loading"); + loader.removeTitleLoader(); } diff --git a/src/main.scss b/src/main.scss index 152cb77a4..7f985f59f 100644 --- a/src/main.scss +++ b/src/main.scss @@ -47,38 +47,48 @@ body { box-shadow: none !important; } + #__title-loader { + display: none; + } + &:not(.loading).title-loading { &.title-loading-hide { - &::after { - background-image: none; + #__title-loader { transform: translateX(-50%) translateY(-100%) scale3d(0.5, 0.5, 1); opacity: 0; animation: hide-loader 100ms ease-in 1; } } - &::after { - content: ""; - background-color: #3333ff; - background-color: var(--primary-color); + #__title-loader { + align-items: center; + background-color: #ffffff; + background-color: var(--popup-background-color); border-radius: 50%; + color: #9999ff; + color: var(--popup-text-color); + display: flex; + justify-content: center; position: fixed; height: 40px; width: 40px; top: 6px; left: 50%; transform: translateX(-50%); - background-image: url(res/tail-spin.svg); - background-repeat: no-repeat; - background-position: center; - background-size: 30px; box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2); box-shadow: 0 0 4px 0 var(--box-shadow-color); border: solid 1px transparent; border: solid 1px var(--popup-border-color); animation: appear 100ms ease-out 1; box-sizing: border-box; + pointer-events: none; z-index: 999; + + svg { + width: 30px; + height: 30px; + display: block; + } } } diff --git a/src/res/tail-spin.svg b/src/res/tail-spin.svg index a12f0f4b9..b72bb6088 100644 --- a/src/res/tail-spin.svg +++ b/src/res/tail-spin.svg @@ -1,15 +1,15 @@ - + - - - - + + + + - + - + @@ -127,6 +122,7 @@ export async function apply(id, init) { updateActiveTerminals("theme", theme.preferredTerminalTheme); } } + localStorage.__primary_color = theme.primaryColor; document.body.setAttribute("theme-type", theme.type); $style.textContent = theme.css; @@ -144,19 +140,6 @@ export async function apply(id, init) { }, 1000); firstTime = false; } - - try { - let fs = fsOperation(loaderFile); - const svg = await fs.readFile("utf8"); - - fs = fsOperation(img); - if (!(await fs.exists())) { - await fsOperation(DATA_STORAGE).createFile(svgName); - } - await fs.writeFile(svg.replace(/#fff/g, theme.primaryColor)); - } catch (error) { - window.log("error", error); - } } /** diff --git a/webpack.config.js b/webpack.config.js index a87528b11..8767eaa8f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -30,18 +30,24 @@ module.exports = (env, options) => { test: /\.(hbs|md)$/, use: ['raw-loader'], }, - { - test: /\.m.(sa|sc|c)ss$/, - use: [ - 'raw-loader', - 'postcss-loader', - 'sass-loader', - ], - }, - { - test: /\.(png|svg|jpg|jpeg|ico|ttf|webp|eot|woff|webm|mp4|webp|wav)(\?.*)?$/, - type: "asset/resource", - }, + { + test: /\.m.(sa|sc|c)ss$/, + use: [ + 'raw-loader', + 'postcss-loader', + 'sass-loader', + ], + }, + { + test: /\.svg$/, + resourceQuery: /raw/, + type: 'asset/source', + }, + { + test: /\.(png|svg|jpg|jpeg|ico|ttf|webp|eot|woff|webm|mp4|webp|wav)(\?.*)?$/, + resourceQuery: { not: [/raw/] }, + type: "asset/resource", + }, { test: /(?