Compare commits

..

15 Commits

12 changed files with 177 additions and 75 deletions

View File

@ -1,4 +1,4 @@
const appName = "EZPPLauncher"; const appName = "EZPPLauncher";
const appVersion = "2.1.6"; const appVersion = "2.1.7";
module.exports = { appName, appVersion }; module.exports = { appName, appVersion };

View File

@ -16,17 +16,25 @@ const platforms = {
}; };
const crypto = require("crypto"); const crypto = require("crypto");
const defaultHWID = "recorderinthesandybridge";
/** /**
* Returns machine hardware id. * Returns machine hardware id.
* Returns `undefined` if cannot determine. * Returns `undefined` if cannot determine.
* @return {string?} * @return {Promise<string>}
*/ */
function getHwId() { function getHwId() {
const getter = platforms[process.platform]; return new Promise((resolve) => {
if (!getter) return; try {
const result = getter[1].exec(child_process.execSync(getter[0], options)); const getter = platforms[process.platform];
if (!result) return; if (getter) {
return crypto.createHash("md5").update(result[1]).digest("hex") || const result = getter[1].exec(child_process.execSync(getter[0], options));
undefined; if (result) resolve(crypto.createHash("md5").update(result[1]).digest("hex"));
}
resolve(crypto.createHash("md5").update(defaultHWID).digest("hex"));
} catch {
resolve(crypto.createHash("md5").update(defaultHWID).digest("hex"));
}
})
} }
exports.getHwId = getHwId; exports.getHwId = getHwId;

View File

@ -1,6 +1,12 @@
async function checkImageExists(url) { async function checkImageExists(url) {
try { try {
const response = await fetch(url, { method: "HEAD" }); const response = await fetch(url, {
method: "HEAD",
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
},
});
if (!response.ok) { if (!response.ok) {
return false; return false;
} }

View File

@ -152,7 +152,12 @@ function getUserConfig(osuPath) {
} }
async function getUpdateFiles(releaseStream) { async function getUpdateFiles(releaseStream) {
const releaseData = await fetch(checkUpdateURL + releaseStream); const releaseData = await fetch(checkUpdateURL + releaseStream, {
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
},
});
return releaseData.ok ? await releaseData.json() : undefined; return releaseData.ok ? await releaseData.json() : undefined;
} }
@ -244,6 +249,10 @@ async function getEZPPLauncherUpdateFiles(osuPath) {
const filesToDownload = []; const filesToDownload = [];
const updateFilesRequest = await fetch(ezppLauncherUpdateList, { const updateFilesRequest = await fetch(ezppLauncherUpdateList, {
method: "PATCH", method: "PATCH",
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
},
}); });
const updateFiles = await updateFilesRequest.json(); const updateFiles = await updateFilesRequest.json();
for (const updateFile of updateFiles) { for (const updateFile of updateFiles) {
@ -264,24 +273,44 @@ async function getEZPPLauncherUpdateFiles(osuPath) {
filesToDownload.push(updateFile); filesToDownload.push(updateFile);
} }
} }
return filesToDownload; return [filesToDownload, updateFiles];
} }
async function downloadEZPPLauncherUpdateFiles(osuPath, updateFiles) { async function downloadEZPPLauncherUpdateFiles(osuPath, updateFiles, allFiles) {
const eventEmitter = new EventEmitter(); const eventEmitter = new EventEmitter();
const startDownload = async () => { const startDownload = async () => {
//NOTE: delete files that are not in the updateFiles array //NOTE: delete files that are not in the updateFiles array
const foldersToPrune = updateFiles.map(file => path.dirname(path.join(osuPath, ...file.folder.split("/"), file.name))).filter((folder, index, self) => self.indexOf(folder) === index); const foldersToPrune = allFiles.map((file) =>
path.dirname(path.join(osuPath, ...file.folder.split("/"), file.name))
).filter((folder, index, self) => self.indexOf(folder) === index);
for (const pruneFolder of foldersToPrune) { for (const pruneFolder of foldersToPrune) {
//NOTE: check if the folder is not the osu root folder. //NOTE: check if the folder is not the osu root folder.
if (path.basename(pruneFolder) == "osu!") if (path.basename(pruneFolder) == "osu!") {
continue; continue;
for (const files of await fs.promises.readdir(pruneFolder)) { }
const filePath = path.join(pruneFolder, files); if (fs.existsSync(pruneFolder)) {
if (!updateFiles.some(file => path.join(osuPath, ...file.folder.split("/"), file.name) === filePath)) { for (const files of await fs.promises.readdir(pruneFolder)) {
const filePath = path.join(pruneFolder, files);
await fs.promises.rm(filePath, { recursive: true, force: true }); const validFolder = allFiles.find((file) =>
path.dirname(filePath).endsWith(file.folder)
);
if (!validFolder) {
if (
allFiles.find((file) => file.name == path.basename(filePath)) ===
undefined
) {
eventEmitter.emit("data", {
fileName: path.basename(filePath),
});
try {
await fs.promises.rm(filePath, {
recursive: true,
force: true,
});
} catch {}
}
}
} }
} }
} }

View File

@ -10,7 +10,12 @@ const releasesUrl =
module.exports = { module.exports = {
updateAvailable: async () => { updateAvailable: async () => {
try { try {
const latestRelease = await fetch(repoApiUrl); const latestRelease = await fetch(repoApiUrl, {
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
},
});
const json = await latestRelease.json(); const json = await latestRelease.json();
if (json.length <= 0) return false; if (json.length <= 0) return false;
return { return {

70
main.js
View File

@ -76,6 +76,12 @@ function startOsuStatus() {
try { try {
const currentUserInfo = await fetch( const currentUserInfo = await fetch(
`https://api.ez-pp.farm/get_player_info?name=${currentUser.username}&scope=info`, `https://api.ez-pp.farm/get_player_info?name=${currentUser.username}&scope=info`,
{
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
},
},
); );
const currentUserInfoJson = await currentUserInfo.json(); const currentUserInfoJson = await currentUserInfo.json();
if ( if (
@ -116,7 +122,14 @@ function startOsuStatus() {
const windowTitle = firstInstance.processTitle; const windowTitle = firstInstance.processTitle;
lastOsuStatus = windowTitle; lastOsuStatus = windowTitle;
const currentStatusRequest = await fetch( const currentStatusRequest = await fetch(
"https://api.ez-pp.farm/v1/get_player_status?name=" + currentUser.username, "https://api.ez-pp.farm/v1/get_player_status?name=" +
currentUser.username,
{
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
},
},
); );
const currentStatus = await currentStatusRequest.json(); const currentStatus = await currentStatusRequest.json();
@ -127,7 +140,14 @@ function startOsuStatus() {
const currentModeString = gamemodes[currentMode]; const currentModeString = gamemodes[currentMode];
const currentInfoRequest = await fetch( const currentInfoRequest = await fetch(
"https://api.ez-pp.farm/v1/get_player_info?name=" + currentUser.username + "&scope=all", "https://api.ez-pp.farm/v1/get_player_info?name=" +
currentUser.username + "&scope=all",
{
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
},
},
); );
const currentInfo = await currentInfoRequest.json(); const currentInfo = await currentInfoRequest.json();
let currentUsername = currentInfo.player.info.name; let currentUsername = currentInfo.player.info.name;
@ -228,7 +248,7 @@ function registerIPCPipes() {
ipcMain.handle("ezpplauncher:login", async (e, args) => { ipcMain.handle("ezpplauncher:login", async (e, args) => {
let hwid = ""; let hwid = "";
try { try {
hwid = getHwId(); hwid = await getHwId();
} catch (err) { } catch (err) {
logger.error(`Failed to get HWID.`, err); logger.error(`Failed to get HWID.`, err);
return { return {
@ -237,7 +257,7 @@ function registerIPCPipes() {
}; };
} }
const timeout = new AbortController(); const timeout = new AbortController();
const timeoutId = setTimeout(() => timeout.abort(), 8000); const timeoutId = setTimeout(() => timeout.abort(), 1000 * 10);
logger.log(`Logging in with user ${args.username}...`); logger.log(`Logging in with user ${args.username}...`);
try { try {
const fetchResult = await fetch("https://ez-pp.farm/login/check", { const fetchResult = await fetch("https://ez-pp.farm/login/check", {
@ -249,6 +269,8 @@ function registerIPCPipes() {
}), }),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
}, },
}); });
@ -268,7 +290,7 @@ function registerIPCPipes() {
return result; return result;
} }
logger.log( logger.log(
`Login failed for user ${username}.\nResponse:\n${await fetchResult `Login failed for user ${args.username}.\nResponse:\n${await fetchResult
.text()}`, .text()}`,
); );
return { return {
@ -293,7 +315,7 @@ function registerIPCPipes() {
}); });
ipcMain.handle("ezpplauncher:autologin", async (e) => { ipcMain.handle("ezpplauncher:autologin", async (e) => {
const hwid = getHwId(); const hwid = await getHwId();
const username = config.get("username"); const username = config.get("username");
const guest = config.get("guest"); const guest = config.get("guest");
if (guest) return { code: 200, message: "Login as guest", guest: true }; if (guest) return { code: 200, message: "Login as guest", guest: true };
@ -317,6 +339,8 @@ function registerIPCPipes() {
}), }),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
}, },
}); });
@ -384,7 +408,7 @@ function registerIPCPipes() {
} }
if (key == "logging") { if (key == "logging") {
logger.enabled = logging; logger.enabled = value;
} }
if (typeof value == "boolean") { if (typeof value == "boolean") {
@ -432,8 +456,9 @@ function registerIPCPipes() {
ipcMain.handle("ezpplauncher:checkUpdate", async (e) => { ipcMain.handle("ezpplauncher:checkUpdate", async (e) => {
const updateInfo = await updateAvailable(); const updateInfo = await updateAvailable();
if (updateInfo.update) if (updateInfo.update) {
mainWindow.webContents.send("ezpplauncher:update", updateInfo.release); mainWindow.webContents.send("ezpplauncher:update", updateInfo.release);
}
}); });
ipcMain.handle("ezpplauncher:exitAndUpdate", async (e) => { ipcMain.handle("ezpplauncher:exitAndUpdate", async (e) => {
@ -529,8 +554,9 @@ function registerIPCPipes() {
progress: Math.ceil(data.progress), progress: Math.ceil(data.progress),
}); });
mainWindow.webContents.send("ezpplauncher:launchstatus", { mainWindow.webContents.send("ezpplauncher:launchstatus", {
status: `Downloading ${data.fileName}(${formatBytes(data.loaded)}/${formatBytes(data.total) status: `Downloading ${data.fileName}(${formatBytes(data.loaded)}/${
})...`, formatBytes(data.total)
})...`,
}); });
}); });
await updateDownloader.startDownload(); await updateDownloader.startDownload();
@ -557,12 +583,15 @@ function registerIPCPipes() {
status: "Looking for patcher updates...", status: "Looking for patcher updates...",
}); });
await new Promise((res) => setTimeout(res, 1000)); await new Promise((res) => setTimeout(res, 1000));
const patchFiles = await getEZPPLauncherUpdateFiles(osuPath); const [patchFiles, allUpdateFiles] = await getEZPPLauncherUpdateFiles(
osuPath,
);
if (patchFiles.length > 0) { if (patchFiles.length > 0) {
logger.log("EZPPLauncher updates found."); logger.log("EZPPLauncher updates found.");
const patcherDownloader = await downloadEZPPLauncherUpdateFiles( const patcherDownloader = await downloadEZPPLauncherUpdateFiles(
osuPath, osuPath,
patchFiles, patchFiles,
allUpdateFiles,
); );
let errored = false; let errored = false;
patcherDownloader.eventEmitter.on("error", (data) => { patcherDownloader.eventEmitter.on("error", (data) => {
@ -583,8 +612,18 @@ function registerIPCPipes() {
progress: Math.ceil(data.progress), progress: Math.ceil(data.progress),
}); });
mainWindow.webContents.send("ezpplauncher:launchstatus", { mainWindow.webContents.send("ezpplauncher:launchstatus", {
status: `Downloading ${data.fileName}(${formatBytes(data.loaded) status: `Downloading ${data.fileName}(${
}/${formatBytes(data.total)})...`, formatBytes(data.loaded)
}/${formatBytes(data.total)})...`,
});
});
patcherDownloader.eventEmitter.on("delete", (data) => {
logger.log(`Deleting ${data.fileName}!`);
mainWindow.webContents.send("ezpplauncher:launchprogress", {
progress: -1,
});
mainWindow.webContents.send("ezpplauncher:launchstatus", {
status: `Deleting ${data.fileName}...`,
}); });
}); });
await patcherDownloader.startDownload(); await patcherDownloader.startDownload();
@ -664,7 +703,7 @@ function registerIPCPipes() {
if (fs.existsSync(updateFile)) { if (fs.existsSync(updateFile)) {
await fs.promises.rm(updateFile, { await fs.promises.rm(updateFile, {
force: true, force: true,
recursive: (await fs.promises.lstat(updateFile)).isDirectory, recursive: (await fs.promises.lstat(updateFile)).isDirectory(),
}); });
} }
} }
@ -718,7 +757,8 @@ function registerIPCPipes() {
const osuGameplayFile = path.join(osuPath, "osu!gameplay.dll"); const osuGameplayFile = path.join(osuPath, "osu!gameplay.dll");
if (isWritable(osuUIFile) && isWritable(osuGameplayFile)) { if (isWritable(osuUIFile) && isWritable(osuGameplayFile)) {
logger.log( logger.log(
`Cleanup complete, took ${((performance.now() - timeStart) / 1000).toFixed(3) `Cleanup complete, took ${
((performance.now() - timeStart) / 1000).toFixed(3)
} seconds.`, } seconds.`,
); );
clearInterval(cleanup); clearInterval(cleanup);

View File

@ -1,6 +1,6 @@
{ {
"name": "ezpplauncher-next", "name": "ezpplauncher-next",
"version": "2.1.6", "version": "2.1.7",
"description": "EZPPLauncher rewritten with Svelte.", "description": "EZPPLauncher rewritten with Svelte.",
"private": false, "private": false,
"license": "MIT", "license": "MIT",

View File

@ -69,6 +69,7 @@ export default {
resolve({ resolve({
browser: true, browser: true,
dedupe: ["svelte"], dedupe: ["svelte"],
exportConditions: ["svelte"],
}), }),
typescript({ typescript({
sourceMap: !production, sourceMap: !production,

View File

@ -1,20 +1,16 @@
<script lang="ts"> <script lang="ts">
import { import Avatar from "flowbite-svelte/Avatar.svelte";
Avatar, import Dropdown from "flowbite-svelte/Dropdown.svelte";
Dropdown, import DropdownItem from "flowbite-svelte/DropdownItem.svelte";
DropdownItem, import DropdownHeader from "flowbite-svelte/DropdownHeader.svelte";
DropdownHeader, import DropdownDivider from "flowbite-svelte/DropdownDivider.svelte";
DropdownDivider, import Button from "flowbite-svelte/Button.svelte";
Button, import Indicator from "flowbite-svelte/Indicator.svelte";
Indicator, import ArrowLeftSolid from "flowbite-svelte-icons/ArrowLeftSolid.svelte";
} from "flowbite-svelte"; import ArrowRightFromBracketSolid from "flowbite-svelte-icons/ArrowRightFromBracketSolid.svelte";
import { import ArrowRightToBracketSolid from "flowbite-svelte-icons/ArrowRightToBracketSolid.svelte";
ArrowLeftSolid, import HeartSolid from "flowbite-svelte-icons/HeartSolid.svelte";
ArrowRightFromBracketSolid, import UserSettingsSolid from "flowbite-svelte-icons/UserSettingsSolid.svelte";
ArrowRightToBracketSolid,
HeartSolid,
UserSettingsSolid,
} from "flowbite-svelte-icons";
import ezppLogo from "../public/favicon.png"; import ezppLogo from "../public/favicon.png";
import { import {
currentPage, currentPage,

View File

@ -1,11 +1,11 @@
<script lang="ts"> <script lang="ts">
import { Button } from "flowbite-svelte"; import Button from "flowbite-svelte/Button.svelte";
import Progressbar from "../lib/Progressbar.svelte"; import Progressbar from "../lib/Progressbar.svelte";
import { import {
launching, launching,
patch, patch,
launchStatus, launchStatus,
launchPercentage launchPercentage,
} from "./../storage/localStore"; } from "./../storage/localStore";
let progressbarFix = true; let progressbarFix = true;

View File

@ -1,10 +1,14 @@
<script lang="ts"> <script lang="ts">
import { Input, Button, Spinner, Checkbox } from "flowbite-svelte"; import Input from "flowbite-svelte/Input.svelte";
import Button from "flowbite-svelte/Button.svelte";
import Spinner from "flowbite-svelte/Spinner.svelte";
import Checkbox from "flowbite-svelte/Checkbox.svelte";
import { type User } from "../types/user"; import { type User } from "../types/user";
import { currentPage, currentUser, startup } from "../storage/localStore"; import { currentPage, currentUser, startup } from "../storage/localStore";
import toast from "svelte-french-toast"; import toast from "svelte-french-toast";
import { Page } from "../consts/pages"; import { Page } from "../consts/pages";
import { EyeSlashSolid, EyeSolid } from "flowbite-svelte-icons"; import EyeSolid from "flowbite-svelte-icons/EyeSolid.svelte";
import EyeSlashSolid from "flowbite-svelte-icons/EyeSlashSolid.svelte";
let loading = false; let loading = false;
let username = ""; let username = "";
@ -13,11 +17,20 @@
let showPassword = false; let showPassword = false;
const processLogin = async () => { const processLogin = async () => {
if (username.length <= 0 || password.length <= 0) {
toast.error(`Please provice a valid Username and Password!`, {
position: "bottom-center",
className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000,
});
return;
}
loading = true; loading = true;
const loginPromise = new Promise<void>((res, rej) => { const loginPromise = new Promise<string>((res, rej) => {
window.addEventListener( window.addEventListener(
"login-result", "login-result",
(e) => { async (e) => {
const customEvent = e as CustomEvent; const customEvent = e as CustomEvent;
const resultData = customEvent.detail; const resultData = customEvent.detail;
const wasSuccessful = "user" in resultData; const wasSuccessful = "user" in resultData;
@ -30,26 +43,26 @@
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 1500, duration: 1500,
}); */ }); */
rej(); rej(resultData.message);
loading = false; loading = false;
return; return;
} }
const userResult = resultData.user as User; const userResult = resultData.user as User;
currentUser.set(userResult); currentUser.set(userResult);
currentPage.set(Page.Launch); currentPage.set(Page.Launch);
res(); res("");
toast.success(`Welcome back, ${userResult.name}!`, { toast.success(`Welcome back, ${userResult.name}!`, {
position: "bottom-center", position: "bottom-center",
className: className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000 duration: 3000,
}); });
}, },
{ once: true } { once: true }
); );
window.dispatchEvent( window.dispatchEvent(
new CustomEvent("login-attempt", { new CustomEvent("login-attempt", {
detail: { username, password, saveCredentials } detail: { username, password, saveCredentials },
}) })
); );
}); });
@ -58,20 +71,20 @@
{ {
loading: "Logging in...", loading: "Logging in...",
success: "Successfully logged in!", success: "Successfully logged in!",
error: "Invalid Username or Password!" error: (e) => e,
}, },
{ {
position: "bottom-center", position: "bottom-center",
className: className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000 duration: 0,
} }
); );
}; };
const tryAutoLogin = async () => { const tryAutoLogin = async () => {
loading = true; loading = true;
const loginPromise = new Promise<void>((res, rej) => { const loginPromise = new Promise<string>((res, rej) => {
window.addEventListener( window.addEventListener(
"login-result", "login-result",
(e) => { (e) => {
@ -81,29 +94,29 @@
const wasSuccessful = "user" in resultData; const wasSuccessful = "user" in resultData;
if (isGuest) { if (isGuest) {
currentPage.set(Page.Launch); currentPage.set(Page.Launch);
res(); res("");
toast.success(`Logged in as Guest`, { toast.success(`Logged in as Guest`, {
position: "bottom-center", position: "bottom-center",
className: className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000 duration: 3000,
}); });
return; return;
} }
if (!wasSuccessful) { if (!wasSuccessful) {
loading = false; loading = false;
rej(); rej(resultData.message);
return; return;
} }
const userResult = resultData.user as User; const userResult = resultData.user as User;
currentUser.set(userResult); currentUser.set(userResult);
currentPage.set(Page.Launch); currentPage.set(Page.Launch);
res(); res("");
toast.success(`Welcome back, ${userResult.name}!`, { toast.success(`Welcome back, ${userResult.name}!`, {
position: "bottom-center", position: "bottom-center",
className: className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000 duration: 3000,
}); });
loading = false; loading = false;
}, },
@ -116,13 +129,13 @@
{ {
loading: "Logging in...", loading: "Logging in...",
success: "Successfully logged in!", success: "Successfully logged in!",
error: "Failed to login." error: (e) => e,
}, },
{ {
position: "bottom-center", position: "bottom-center",
className: className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000 duration: 0,
} }
); );
}; };
@ -134,7 +147,7 @@
position: "bottom-center", position: "bottom-center",
className: className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000 duration: 3000,
}); });
}; };

View File

@ -1,6 +1,10 @@
<script lang="ts"> <script lang="ts">
import { Button, ButtonGroup, Input, Toggle } from "flowbite-svelte"; import Button from "flowbite-svelte/Button.svelte";
import { FileSearchSolid, FolderSolid } from "flowbite-svelte-icons"; import ButtonGroup from "flowbite-svelte/ButtonGroup.svelte";
import Input from "flowbite-svelte/Input.svelte";
import Toggle from "flowbite-svelte/Toggle.svelte";
import FileSearchSolid from "flowbite-svelte-icons/FileSearchSolid.svelte";
import FolderSolid from "flowbite-svelte-icons/FolderSolid.svelte";
import { patch, presence, logging } from "./../storage/localStore"; import { patch, presence, logging } from "./../storage/localStore";
let folderPath: string = ""; let folderPath: string = "";