diff --git a/electron-builder.json5 b/electron-builder.json5
index c545728..b92f88f 100644
--- a/electron-builder.json5
+++ b/electron-builder.json5
@@ -20,7 +20,7 @@
             },
             {
                 target: 'portable',
-            }
+            },
         ],
         icon: 'public/icons/win/icon.ico',
         // artifactName: '${productName}-Windows-${version}-Setup.${ext}',
@@ -32,8 +32,8 @@
         deleteAppDataOnUninstall: true,
     },
     mac: {
-          target: ['mas'],
-          artifactName: '${productName}-Mac-${version}-Installer.${ext}',
+        target: ['mas'],
+        artifactName: '${productName}-Mac-${version}-Installer.${ext}',
     },
     linux: {
         target: ['AppImage', 'flatpak', 'tar.gz'],
diff --git a/electron/main.ts b/electron/main.ts
index 1c9209c..1e2a34a 100644
--- a/electron/main.ts
+++ b/electron/main.ts
@@ -175,9 +175,7 @@ ipcMain.on('delete-blob', (_, data) => {
     const extension = data.extension.includes('mp4') ? 'm4a' : 'opus'
     fs.promises
         .rm(path.join(downloadPath, `${data.id}.${extension}`))
-        .catch((err) => {
-            console.log(err)
-        })
+        .catch()
         .finally(sendDirSize)
 })
 ipcMain.handle('get-blob', async (_, id) => {
@@ -201,3 +199,9 @@ ipcMain.handle('get-blob', async (_, id) => {
         }
     }
 })
+ipcMain.handle('get-folder-path', () => {
+    return downloadPath
+})
+ipcMain.handle('get-folder-content', async () => {
+    return await fs.promises.readdir(downloadPath)
+})
diff --git a/forge.config.js b/forge.config.js
deleted file mode 100644
index 955c4fd..0000000
--- a/forge.config.js
+++ /dev/null
@@ -1,30 +0,0 @@
-module.exports = {
-    packagerConfig: {
-        asar: true,
-    },
-    rebuildConfig: {},
-    makers: [
-        {
-            name: '@electron-forge/maker-squirrel',
-            config: {},
-        },
-        {
-            name: '@electron-forge/maker-zip',
-            platforms: ['darwin'],
-        },
-        {
-            name: '@electron-forge/maker-deb',
-            config: {},
-        },
-        {
-            name: '@electron-forge/maker-rpm',
-            config: {},
-        },
-    ],
-    plugins: [
-        {
-            name: '@electron-forge/plugin-auto-unpack-natives',
-            config: {},
-        },
-    ],
-}
diff --git a/index.html b/index.html
deleted file mode 100644
index 77c5194..0000000
--- a/index.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!doctype html>
-<html>
-    <head>
-        <script type="module">
-            import RefreshRuntime from '/@react-refresh'
-            RefreshRuntime.injectIntoGlobalHook(window)
-            window.$RefreshReg$ = () => {}
-            window.$RefreshSig$ = () => (type) => type
-            window.__vite_plugin_react_preamble_installed__ = true
-        </script>
-
-        <script type="module" src="/@vite/client"></script>
-
-        <meta charset="utf-8" />
-        <!--
-  Customize this policy to fit your own app's needs. For more guidance, please refer to the docs:
-      https://cordova.apache.org/docs/en/latest/
-  Some notes:
-    * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
-    * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
-      * Enable inline JS: add 'unsafe-inline' to default-src
-  -->
-        <meta
-            http-equiv="Content-Security-Policy"
-            content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: content:"
-        />
-        <meta
-            name="viewport"
-            content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover"
-        />
-
-        <meta name="theme-color" content="#212121" />
-        <meta name="format-detection" content="telephone=no" />
-        <meta name="msapplication-tap-highlight" content="no" />
-        <title>Kiku</title>
-
-        <meta name="apple-mobile-web-app-capable" content="yes" />
-        <meta
-            name="apple-mobile-web-app-status-bar-style"
-            content="black-translucent"
-        />
-        <link rel="apple-touch-icon" href="icons/apple-touch-icon.png" />
-        <link rel="icon" href="icons/favicon.png" />
-
-        <!-- built styles file will be auto injected -->
-    </head>
-    <body>
-        <div id="app"></div>
-
-        <script type="module" src="./js/app.js"></script>
-    </body>
-</html>
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index f2a8708..ccd85a7 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -1,17 +1,17 @@
 {
-  "Search-here": "Search here",
-  "Search": "Search",
-  "Now-Playing": "Now Playing",
-  "Search-Result": "Search Result",
-  "Setting": "Setting",
-  "Videos": "Videos",
-  "views": "views",
-  "Channel": "Channel",
-  "Playlists": "Playlists",
-  "Load-More": "Load More",
-  "Playlist": "Playlist",
-  "Search-Results": "Search Results",
-  "URL": "URL:",
-  "Global-UI": "Global UI",
-  "setting": "setting"
+    "Search-here": "Search here",
+    "Search": "Search",
+    "Now-Playing": "Now Playing",
+    "Search-Result": "Search Result",
+    "Setting": "Setting",
+    "Videos": "Videos",
+    "views": "views",
+    "Channel": "Channel",
+    "Playlists": "Playlists",
+    "Load-More": "Load More",
+    "Playlist": "Playlist",
+    "Search-Results": "Search Results",
+    "URL": "URL:",
+    "Global-UI": "Global UI",
+    "setting": "setting"
 }
diff --git a/public/locales/en/common_old.json b/public/locales/en/common_old.json
index d964bce..aa31794 100644
--- a/public/locales/en/common_old.json
+++ b/public/locales/en/common_old.json
@@ -1,6 +1,6 @@
 {
-  "url": "url",
-  "details": {
-    "Relevant-Videos": "details.Relevant Videos"
-  }
+    "url": "url",
+    "details": {
+        "Relevant-Videos": "details.Relevant Videos"
+    }
 }
diff --git a/public/locales/en/now-playing.json b/public/locales/en/now-playing.json
index bc1fe04..482ab5d 100644
--- a/public/locales/en/now-playing.json
+++ b/public/locales/en/now-playing.json
@@ -1,4 +1,4 @@
 {
-  "Nothing-is-playing": "Nothing is playing",
-  "Add-something-to-playlist-to-play": "Add something to playlist to play"
+    "Nothing-is-playing": "Nothing is playing",
+    "Add-something-to-playlist-to-play": "Add something to playlist to play"
 }
diff --git a/public/locales/en/playlist.json b/public/locales/en/playlist.json
index 18daee5..ab9972e 100644
--- a/public/locales/en/playlist.json
+++ b/public/locales/en/playlist.json
@@ -1,19 +1,22 @@
 {
-  "Save-to-drive": "Save to drive",
-  "Remove-from-playlist": "Remove from playlist",
-  "Retry": "Retry",
-  "Are-you-sure-to-clear-the-playlist": "Are you sure to clear the playlist",
-  "Clear-playlist": "Clear playlist",
-  "Please-input-name-of-the-new-playlist": "Please input name of the new playlist",
-  "Playlist-Added": "Playlist Added",
-  "This-is-the-last-playlist": "This is the last playlist",
-  "Are-you-sure-to-remove-the-playlist?": "Are you sure to remove the playlist?",
-  "Please-input-the-new-name-for-playlist": "Please input the new name for playlist",
-  "Name-cannot-be-empty": "Name cannot be empty",
-  "New-Playlist": "New Playlist",
-  "Clear-Error-items": "Clear Error items",
-  "Clear-played-items": "Clear played items",
-  "Shuffle-unplayed-items": "Shuffle unplayed items",
-  "Remove-playlist": "Remove playlist",
-  "Rename-playlist": "Rename playlist"
+    "Save-to-drive": "Save to drive",
+    "Remove-from-playlist": "Remove from playlist",
+    "Retry": "Retry",
+    "Please-input-name-of-the-new-playlist": "Please input name of the new playlist",
+    "Playlist-Added": "Playlist Added",
+    "This-is-the-last-playlist": "This is the last playlist",
+    "Are-you-sure-to-remove-the-playlist?": "Are you sure to remove the playlist?",
+    "Please-input-the-new-name-for-playlist": "Please input the new name for playlist",
+    "Name-cannot-be-empty": "Name cannot be empty",
+    "New-Playlist": "New Playlist",
+    "Remove-playlist": "Remove playlist",
+    "Rename-playlist": "Rename playlist",
+    "Randomize-items": "Randomize items",
+    "Shuffle-unplayed-items": "Shuffle unplayed items",
+    "Shuffle-all-items": "Shuffle all items",
+    "Are-you-sure-to-clear-the-playlist": "Are you sure to clear the playlist",
+    "Clear-playlist": "Clear playlist",
+    "Remove-Items": "Remove Items",
+    "Clear-Error-items": "Clear Error items",
+    "Clear-played-items": "Clear played items"
 }
diff --git a/public/locales/en/playlist_old.json b/public/locales/en/playlist_old.json
index 7547a82..bfaf58f 100644
--- a/public/locales/en/playlist_old.json
+++ b/public/locales/en/playlist_old.json
@@ -1,3 +1,3 @@
 {
-  "Download-to-drive": "Download to drive"
+    "Download-to-drive": "Download to drive"
 }
diff --git a/public/locales/en/search-result.json b/public/locales/en/search-result.json
index 5992a04..683ab18 100644
--- a/public/locales/en/search-result.json
+++ b/public/locales/en/search-result.json
@@ -1,15 +1,15 @@
 {
-  "Details": "Details",
-  "Replace-Playlist-Prompt": "This will clear the current playlist. Are you sure to proceed?",
-  "Replace-current-playlist": "Replace current playlist",
-  "Browse-playlist": "Browse playlist",
-  "Add-all-to-playlist": "Add all to playlist",
-  "Already-on-playlist": "Already on playlist",
-  "Add-to-playlist": "Add to playlist",
-  "Add-to-next-song": "Add to next song",
-  "Copy-Link": "Copy Link",
-  "Open-link": "Open link",
-  "No-search-results": "No search results",
-  "Search-something-on-the-search-bar": "Search something on the search bar",
-  "Search-Results": "Search Results"
+    "Details": "Details",
+    "Replace-Playlist-Prompt": "This will clear the current playlist. Are you sure to proceed?",
+    "Replace-current-playlist": "Replace current playlist",
+    "Browse-playlist": "Browse playlist",
+    "Add-all-to-playlist": "Add all to playlist",
+    "Already-on-playlist": "Already on playlist",
+    "Add-to-playlist": "Add to playlist",
+    "Add-to-next-song": "Add to next song",
+    "Copy-Link": "Copy Link",
+    "Open-link": "Open link",
+    "No-search-results": "No search results",
+    "Search-something-on-the-search-bar": "Search something on the search bar",
+    "Search-Results": "Search Results"
 }
diff --git a/public/locales/en/search-result_old.json b/public/locales/en/search-result_old.json
index a2becfa..3e60d90 100644
--- a/public/locales/en/search-result_old.json
+++ b/public/locales/en/search-result_old.json
@@ -1,8 +1,8 @@
 {
-  "Duration": "Duration",
-  "Published-at": "Published at",
-  "Views": "Views",
-  "Likes": "Likes",
-  "Description": "Description",
-  "Relevant-Videos": "Relevant Videos"
+    "Duration": "Duration",
+    "Published-at": "Published at",
+    "Views": "Views",
+    "Likes": "Likes",
+    "Description": "Description",
+    "Relevant-Videos": "Relevant Videos"
 }
diff --git a/public/locales/en/setting.json b/public/locales/en/setting.json
index 9291bf8..7dc8853 100644
--- a/public/locales/en/setting.json
+++ b/public/locales/en/setting.json
@@ -1,21 +1,23 @@
 {
-  "Source": "Source",
-  "Youtube-Language": "Youtube Language",
-  "Youtube-Region": "Youtube Region",
-  "View-Invidious-Instances": "View Invidious Instances",
-  "View-Piped-Instances": "View Piped Instances",
-  "Reset-to-default": "Reset to default",
-  "Storage-size-must-be-a-positive-number": "Storage size must be a positive number",
-  "Store-audio-files-on-disk": "Store audio files on disk",
-  "Maximum-audio-files-storage": "Maximum audio files storage",
-  "Language": "Language",
-  "Theme": "Theme",
-  "Light": "Light",
-  "Dark": "Dark",
-  "Seek-Time": "Seek Time",
-  "Choose-Layout": "Choose Layout",
-  "Show-Timeline-in-wavesurfer": "Show Timeline in wavesurfer",
-  "Instance-Configuration": "Instance Configuration",
-  "UI-Preference": "UI Preference",
-  "Storage-Setting": "Storage Setting"
+    "Source": "Source",
+    "Youtube-Language": "Youtube Language",
+    "Youtube-Region": "Youtube Region",
+    "View-Invidious-Instances": "View Invidious Instances",
+    "View-Piped-Instances": "View Piped Instances",
+    "Reset-to-default": "Reset to default",
+    "Storage-size-must-be-a-positive-number": "Storage size must be a positive number",
+    "Store-audio-files-on-disk": "Store audio files on disk",
+    "Maximum-audio-files-storage": "Maximum audio files storage",
+    "Show-stored-files": "Show stored files",
+    "Manage-stored-files": "Manage stored files",
+    "Language": "Language",
+    "Theme": "Theme",
+    "Light": "Light",
+    "Dark": "Dark",
+    "Seek-Time": "Seek Time",
+    "Choose-Layout": "Choose Layout",
+    "Show-Timeline-in-wavesurfer": "Show Timeline in wavesurfer",
+    "Instance-Configuration": "Instance Configuration",
+    "UI-Preference": "UI Preference",
+    "Storage-Setting": "Storage Setting"
 }
diff --git a/public/locales/en/setting_old.json b/public/locales/en/setting_old.json
index 8b10cac..704a02e 100644
--- a/public/locales/en/setting_old.json
+++ b/public/locales/en/setting_old.json
@@ -1,6 +1,6 @@
 {
-  "Youtube-Country": "Youtube Country",
-  "Enable-Blob-Storage": "Enable Blob Storage",
-  "Maximum-Blob-Storage": "Maximum Blob Storage",
-  "Blob-Size-must-be-a-positive-number": "Blob Size must be a positive number"
+    "Youtube-Country": "Youtube Country",
+    "Enable-Blob-Storage": "Enable Blob Storage",
+    "Maximum-Blob-Storage": "Maximum Blob Storage",
+    "Blob-Size-must-be-a-positive-number": "Blob Size must be a positive number"
 }
diff --git a/public/locales/en/storage.json b/public/locales/en/storage.json
new file mode 100644
index 0000000..9781a90
--- /dev/null
+++ b/public/locales/en/storage.json
@@ -0,0 +1,22 @@
+{
+    "This-will-remove-all-files-in-the-download-folder-Are-you-sure-to-proceed?": "This will remove all files in the download folder Are you sure to proceed?",
+    "Removed-files-without-entries": "Removed files without entries",
+    "Removed-entries-without-files": "Removed entries without files",
+    "Removed-selected-files": "Removed selected files",
+    "Added-{{count}}-items-to-playlist_one": "Added {{count}} items to playlist",
+    "Added-{{count}}-items-to-playlist_other": "Added {{count}} items to playlist",
+    "Unknown": "Unknown",
+    "Storage-management": "Storage management",
+    "items-selected": "items selected",
+    "Add-entries-to-current-playlist": "Add entries to current playlist",
+    "Remove-selected-entries": "Remove selected entries",
+    "Audio-files": "Audio files",
+    "Remove-non-existent-entries": "Remove non existent entries",
+    "Remove-unhandled-entries": "Remove unhandled entries",
+    "Remove-all-files": "Remove all files",
+    "Title": "Title",
+    "Video-Id": "Video Id",
+    "Created-on": "Created on",
+    "Last-access": "Last access",
+    "File-exist": "File exist"
+}
diff --git a/public/locales/en/video-detail.json b/public/locales/en/video-detail.json
index a2becfa..2ccea9c 100644
--- a/public/locales/en/video-detail.json
+++ b/public/locales/en/video-detail.json
@@ -1,8 +1,9 @@
 {
-  "Duration": "Duration",
-  "Published-at": "Published at",
-  "Views": "Views",
-  "Likes": "Likes",
-  "Description": "Description",
-  "Relevant-Videos": "Relevant Videos"
+    "Copied-Link": "Copied Link",
+    "Duration": "Duration",
+    "Published-at": "Published at",
+    "Views": "Views",
+    "Likes": "Likes",
+    "Description": "Description",
+    "Relevant-Videos": "Relevant Videos"
 }
diff --git a/public/locales/zh-TW/common.json b/public/locales/zh-TW/common.json
index 8e54ae7..5802b84 100644
--- a/public/locales/zh-TW/common.json
+++ b/public/locales/zh-TW/common.json
@@ -1,17 +1,17 @@
 {
-  "Search-here": "在此搜尋",
-  "Search": "搜尋",
-  "Now-Playing": "現正播放",
-  "Search-Result": "搜尋結果",
-  "Setting": "設定",
-  "Videos": "影片",
-  "views": "觀看次數",
-  "Channel": "頻道",
-  "Playlists": "播放清單",
-  "Load-More": "載入更多",
-  "Playlist": "播放清單",
-  "Search-Results": "",
-  "URL": "鏈結:",
-  "Global-UI": "介面",
-  "setting": "設定"
+    "Search-here": "在此搜尋",
+    "Search": "搜尋",
+    "Now-Playing": "現正播放",
+    "Search-Result": "搜尋結果",
+    "Setting": "設定",
+    "Videos": "影片",
+    "views": "觀看次數",
+    "Channel": "頻道",
+    "Playlists": "播放清單",
+    "Load-More": "載入更多",
+    "Playlist": "播放清單",
+    "Search-Results": "",
+    "URL": "鏈結:",
+    "Global-UI": "介面",
+    "setting": "設定"
 }
diff --git a/public/locales/zh-TW/now-playing.json b/public/locales/zh-TW/now-playing.json
index f5b5b73..a57edd0 100644
--- a/public/locales/zh-TW/now-playing.json
+++ b/public/locales/zh-TW/now-playing.json
@@ -1,4 +1,4 @@
 {
-  "Nothing-is-playing": "尚未有播放項目",
-  "Add-something-to-playlist-to-play": "請在搜尋中添加播放項目"
+    "Nothing-is-playing": "尚未有播放項目",
+    "Add-something-to-playlist-to-play": "請在搜尋中添加播放項目"
 }
diff --git a/public/locales/zh-TW/playlist.json b/public/locales/zh-TW/playlist.json
index c1cbbd2..b35c96b 100644
--- a/public/locales/zh-TW/playlist.json
+++ b/public/locales/zh-TW/playlist.json
@@ -1,19 +1,22 @@
 {
-  "Save-to-drive": "儲存",
-  "Remove-from-playlist": "從播放清單移除",
-  "Retry": "重試",
-  "Are-you-sure-to-clear-the-playlist": "你確定要清空播放清單嗎?",
-  "Clear-playlist": "清空播放清單",
-  "Please-input-name-of-the-new-playlist": "",
-  "Playlist-Added": "",
-  "This-is-the-last-playlist": "",
-  "Are-you-sure-to-remove-the-playlist?": "",
-  "Please-input-the-new-name-for-playlist": "",
-  "Name-cannot-be-empty": "",
-  "New-Playlist": "",
-  "Clear-Error-items": "移除錯誤項目",
-  "Clear-played-items": "移除已播放項目",
-  "Shuffle-unplayed-items": "隨機打亂未播放項目",
-  "Remove-playlist": "",
-  "Rename-playlist": ""
+    "Save-to-drive": "儲存",
+    "Remove-from-playlist": "從播放清單移除",
+    "Retry": "重試",
+    "Please-input-name-of-the-new-playlist": "請輸入新播放清單的名字",
+    "Playlist-Added": "已新增播放清單",
+    "This-is-the-last-playlist": "這是最後一條播放清單",
+    "Are-you-sure-to-remove-the-playlist?": "你確定要移除播放清單嗎",
+    "Please-input-the-new-name-for-playlist": "請輸入播放清單的新名字",
+    "Name-cannot-be-empty": "名字不能為空白",
+    "New-Playlist": "新增播放清單",
+    "Remove-playlist": "移除播放清單",
+    "Rename-playlist": "重新命名播放清單",
+    "Randomize-items": "隨機打亂",
+    "Shuffle-unplayed-items": "隨機打亂未播放項目",
+    "Shuffle-all-items": "隨機打亂所有項目",
+    "Are-you-sure-to-clear-the-playlist": "你確定要清空播放清單嗎?",
+    "Clear-playlist": "清空播放清單",
+    "Remove-Items": "移除項目",
+    "Clear-Error-items": "移除錯誤項目",
+    "Clear-played-items": "移除已播放項目"
 }
diff --git a/public/locales/zh-TW/search-result.json b/public/locales/zh-TW/search-result.json
index 5322d34..631c7e9 100644
--- a/public/locales/zh-TW/search-result.json
+++ b/public/locales/zh-TW/search-result.json
@@ -1,15 +1,15 @@
 {
-  "Details": "影片詳情",
-  "Replace-Playlist-Prompt": "這會清空現時的播放清單。你確定要取代現時播放清單嗎?",
-  "Replace-current-playlist": "取代現時播放清單",
-  "Browse-playlist": "瀏覽清單",
-  "Add-all-to-playlist": "添加所有項目至播放清單",
-  "Already-on-playlist": "已經在播放清單",
-  "Add-to-playlist": "加到播放清單",
-  "Add-to-next-song": "加至下一首",
-  "Copy-Link": "複製鏈結",
-  "Open-link": "開啟鏈結",
-  "No-search-results": "尚未有搜尋結果",
-  "Search-something-on-the-search-bar": "請使用上方的搜尋欄",
-  "Search-Results": "搜尋結果:"
+    "Details": "影片詳情",
+    "Replace-Playlist-Prompt": "這會清空現時的播放清單。你確定要取代現時播放清單嗎?",
+    "Replace-current-playlist": "取代現時播放清單",
+    "Browse-playlist": "瀏覽清單",
+    "Add-all-to-playlist": "添加所有項目至播放清單",
+    "Already-on-playlist": "已經在播放清單",
+    "Add-to-playlist": "加到播放清單",
+    "Add-to-next-song": "加至下一首",
+    "Copy-Link": "複製鏈結",
+    "Open-link": "開啟鏈結",
+    "No-search-results": "尚未有搜尋結果",
+    "Search-something-on-the-search-bar": "請使用上方的搜尋欄",
+    "Search-Results": "搜尋結果:"
 }
diff --git a/public/locales/zh-TW/setting.json b/public/locales/zh-TW/setting.json
index 1f9baeb..6254df1 100644
--- a/public/locales/zh-TW/setting.json
+++ b/public/locales/zh-TW/setting.json
@@ -1,21 +1,23 @@
 {
-  "Source": "來源",
-  "Youtube-Language": "Youtube 語言",
-  "Youtube-Region": "Youtube 地區",
-  "View-Invidious-Instances": "顯示 Invidious 站台",
-  "View-Piped-Instances": "顯示 Piped 站台",
-  "Reset-to-default": "重設至預設",
-  "Storage-size-must-be-a-positive-number": "儲存空間必須是正數",
-  "Store-audio-files-on-disk": "在裝置上儲存音訊檔",
-  "Maximum-audio-files-storage": "最大音訊檔佔用空間",
-  "Language": "語言",
-  "Theme": "主題",
-  "Light": "亮色",
-  "Dark": "暗色",
-  "Seek-Time": "轉跳時間",
-  "Choose-Layout": "選擇版面",
-  "Show-Timeline-in-wavesurfer": "在wavesurfer 中顯示時間列",
-  "Instance-Configuration": "站台設定",
-  "UI-Preference": "介面偏好",
-  "Storage-Setting": "儲存設定"
+    "Source": "來源",
+    "Youtube-Language": "Youtube 語言",
+    "Youtube-Region": "Youtube 地區",
+    "View-Invidious-Instances": "顯示 Invidious 站台",
+    "View-Piped-Instances": "顯示 Piped 站台",
+    "Reset-to-default": "重設至預設",
+    "Storage-size-must-be-a-positive-number": "儲存空間必須是正數",
+    "Store-audio-files-on-disk": "在裝置上儲存音訊檔",
+    "Maximum-audio-files-storage": "最大音訊檔佔用空間",
+    "Show-stored-files": "顯示已儲存的檔案",
+    "Manage-stored-files": "管理已儲存的檔案",
+    "Language": "語言",
+    "Theme": "主題",
+    "Light": "亮色",
+    "Dark": "暗色",
+    "Seek-Time": "轉跳時間",
+    "Choose-Layout": "選擇版面",
+    "Show-Timeline-in-wavesurfer": "在wavesurfer 中顯示時間列",
+    "Instance-Configuration": "站台設定",
+    "UI-Preference": "介面偏好",
+    "Storage-Setting": "儲存設定"
 }
diff --git a/public/locales/zh-TW/setting_old.json b/public/locales/zh-TW/setting_old.json
index a370308..c68c9aa 100644
--- a/public/locales/zh-TW/setting_old.json
+++ b/public/locales/zh-TW/setting_old.json
@@ -1,6 +1,6 @@
 {
-  "Youtube-Country": "",
-  "Enable-Blob-Storage": "啟用儲存音訊檔",
-  "Maximum-Blob-Storage": "最大音訊儲存量",
-  "Blob-Size-must-be-a-positive-number": ""
+    "Youtube-Country": "",
+    "Enable-Blob-Storage": "啟用儲存音訊檔",
+    "Maximum-Blob-Storage": "最大音訊儲存量",
+    "Blob-Size-must-be-a-positive-number": ""
 }
diff --git a/public/locales/zh-TW/storage.json b/public/locales/zh-TW/storage.json
new file mode 100644
index 0000000..d80df38
--- /dev/null
+++ b/public/locales/zh-TW/storage.json
@@ -0,0 +1,21 @@
+{
+    "This-will-remove-all-files-in-the-download-folder-Are-you-sure-to-proceed?": "你確定要移除所有在下載資料夾中的檔案嗎?",
+    "Removed-files-without-entries": "已移除所有未在記錄中的檔案",
+    "Removed-entries-without-files": "已移除所有沒有檔案的記錄",
+    "Removed-selected-files": "已移除選取的項目",
+    "Added-{{count}}-items-to-playlist_other": "已新增{{count}}個項目到播放列表",
+    "Unknown": "未知",
+    "Storage-management": "管理已儲存的資料",
+    "items-selected": "個已選擇的項目",
+    "Add-entries-to-current-playlist": "新增已選取的項目到播放清單",
+    "Remove-selected-entries": "移除已選取的項目",
+    "Audio-files": "音訊檔案",
+    "Remove-non-existent-entries": "移除所有沒有檔案的記錄",
+    "Remove-unhandled-entries": "移除所有未在記錄中的檔案",
+    "Remove-all-files": "移除所有項目",
+    "Title": "標題",
+    "Video-Id": "影片編號",
+    "Created-on": "建立時間",
+    "Last-access": "最後存取時間",
+    "File-exist": "檔案是否存在"
+}
diff --git a/public/locales/zh-TW/video-detail.json b/public/locales/zh-TW/video-detail.json
index ed8ce1a..c4a3946 100644
--- a/public/locales/zh-TW/video-detail.json
+++ b/public/locales/zh-TW/video-detail.json
@@ -1,8 +1,9 @@
 {
-  "Duration": "影片長度",
-  "Published-at": "上載日期",
-  "Views": "觀看次數",
-  "Likes": "喜歡次數",
-  "Description": "介紹",
-  "Relevant-Videos": "相關影片"
+    "Copied-Link": "已複制鏈結",
+    "Duration": "影片長度",
+    "Published-at": "上載日期",
+    "Views": "觀看次數",
+    "Likes": "喜歡次數",
+    "Description": "介紹",
+    "Relevant-Videos": "相關影片"
 }
diff --git a/src/components/AudioWatcher.tsx b/src/components/AudioWatcher.tsx
index 57f799f..f183cd4 100644
--- a/src/components/AudioWatcher.tsx
+++ b/src/components/AudioWatcher.tsx
@@ -70,6 +70,8 @@ export default function AudioWatcher(): ReactElement {
             playingItem != undefined &&
             playingItem?.id != playerState.currentPlaying?.id
         ) {
+            audio.current.pause()
+            audio.current.currentTime = 0
             dispatch(setSong(playingItem))
             const newAudio = new Audio()
             newAudio.src = URL.createObjectURL(getBlobByID(playingItem.id))
diff --git a/src/components/ChannelResultCard.tsx b/src/components/ChannelResultCard.tsx
index 9b0395a..6a96c7b 100644
--- a/src/components/ChannelResultCard.tsx
+++ b/src/components/ChannelResultCard.tsx
@@ -28,7 +28,7 @@ export default function ChannelResultCard(props: ChannelResultCardProps) {
                     {/* Overlays */}
                     <a
                         className="absolute w-full h-full hidden group-hover:flex bg-black/60 backdrop-blur-sm flex-wrap justify-center items-center"
-                        href={`channel/${props.data.authorId}`}
+                        href={`/channel/${props.data.authorId}`}
                     >
                         <Icon
                             className="text-lg lg:text-2xl xl:text-4xl w-full"
@@ -46,7 +46,7 @@ export default function ChannelResultCard(props: ChannelResultCardProps) {
                 </div>
                 {/* ChannelTitle Title Here */}
                 <Link
-                    href={`channel/${props.data.authorId}`}
+                    href={`/channel/${props.data.authorId}`}
                     className="mt-2  line-clamp-2 underline"
                 >
                     {props.data.author}
diff --git a/src/components/MainNav.tsx b/src/components/MainNav.tsx
index f658fd8..5311488 100644
--- a/src/components/MainNav.tsx
+++ b/src/components/MainNav.tsx
@@ -10,9 +10,7 @@ import {
 } from 'framework7-react'
 
 import { handleSuggest } from '../js/suggestions'
-import { handleSearchVideo } from '../js/search'
 import { useDispatch, useSelector } from 'react-redux'
-import { newSearch, selectSearch } from '@/store/searchReducers'
 import { Store, useCustomContext } from '@/store/reactContext'
 import Innertube from 'youtubei.js/agnostic'
 import { selectConfig } from '@/store/globalConfig'
@@ -44,8 +42,6 @@ const MainNav = (props: MainNavProps) => {
     const onPageBeforeRemove = () => {
         autocompleteSearch.current.destroy()
     }
-    const search = useSelector(selectSearch)
-    const { setContinuation } = useCustomContext(Store)
     const dispatch = useDispatch()
     const { t } = useTranslation(['common'])
 
@@ -91,18 +87,25 @@ const MainNav = (props: MainNavProps) => {
         // Try to scan for url on input
         try {
             const url = new URL(searchTerm) // Will jump to catch if fail
+            f7.preloader.showIn('#page-router')
             let id: string | null
             let playlistId: string | null
+            let channelId: string | null
             // Extract parameters and path from url to get video id
             if (url.hostname === 'youtu.be') {
                 id = url.pathname.replaceAll('/', '')
                 playlistId = null
+                channelId = null
             } else {
                 id = url.searchParams.get('v')
                 playlistId = url.searchParams.get('list')
+                channelId = url.pathname.includes('channel/')
+                    ? url.pathname.replace(/^\/channel\//, '')
+                    : null
             }
+            console.log(id)
             // Skip if fail to get video id
-            if (id === null && playlistId === null) {
+            if (id === null && playlistId === null && channelId === null) {
                 throw new Error('')
             }
             // Browse playlist if playlist is found
@@ -111,7 +114,17 @@ const MainNav = (props: MainNavProps) => {
                 f7.views
                     .get('#page-router')
                     .router.navigate(`playlist/${playlistId}`)
+                return
             }
+            // Browse channel if channel id is found
+            if (channelId !== null) {
+                fullfilled = true
+                f7.views
+                    .get('#page-router')
+                    .router.navigate(`channel/${channelId}`)
+                return
+            }
+
             // Fetch basic information on given video id
             const res = await getPlayitem(
                 id as string,
diff --git a/src/components/Toast.ts b/src/components/Toast.ts
index 0f1ebd3..e2b404f 100644
--- a/src/components/Toast.ts
+++ b/src/components/Toast.ts
@@ -5,14 +5,15 @@ const presentToast = (type: ToastType, message: string) => {
         type === 'info'
             ? '<i class="f7-icons">info_circle</i>'
             : type === 'error'
-              ? '<i class="f7-icons">exclamationmark_circle</i>'
+              ? '<i class="f7-icons">exclamationmark_circle_fill</i>'
               : type === 'success'
                 ? '<i class="f7-icons">checkmark_alt_circle</i>'
                 : ''
     const newToast = f7.toast.create({
         icon: icon,
         text: message,
-        position: 'center',
+        horizontalPosition: 'center',
+        position: 'bottom',
         closeTimeout: 2000,
     })
     newToast.open()
diff --git a/src/components/VideoResultCard.tsx b/src/components/VideoResultCard.tsx
index e1642f2..8f3da65 100644
--- a/src/components/VideoResultCard.tsx
+++ b/src/components/VideoResultCard.tsx
@@ -1,7 +1,7 @@
 import { Icon, Link } from 'framework7-react'
 import React, { useState } from 'react'
 import { VideoResult, Playitem } from '@/typescript/interfaces'
-import { formatViewNumber, convertSecond } from '../utils/format'
+import { convertSecond, compactNumber } from '../utils/format'
 import { useDispatch, useSelector } from 'react-redux'
 import {
     addToNextSong,
@@ -157,7 +157,7 @@ export default function VideoResultCard(props: VideoResultCardProps) {
                     </Link>
                     {props.data.viewCount !== undefined && (
                         <p>
-                            {formatViewNumber(props.data.viewCount)}{' '}
+                            {compactNumber(props.data.viewCount)}{' '}
                             {t('common:views')}
                         </p>
                     )}
diff --git a/src/components/Worker.tsx b/src/components/Worker.tsx
index e60c5d2..8cd1dc2 100644
--- a/src/components/Worker.tsx
+++ b/src/components/Worker.tsx
@@ -24,11 +24,18 @@ import { Store } from '@/store/reactContext'
 import { selectPlayer } from '@/store/playerReducers'
 import { selectConfig } from '@/store/globalConfig'
 import Innertube from 'youtubei.js/agnostic'
-import presentToast from './Toast'
 import { getNextSong } from '@/utils/songControl'
 import { base64ToBlob, blobToBase64 } from '@/utils/base64'
-import { deleteBlob, saveBlob, selectLocalBlobs } from '@/store/blobStorage'
-import {savePlaylist, selectLocalPlaylist} from '@/store/localPlaylistReducers'
+import {
+    deleteBlob,
+    saveBlob,
+    selectLocalBlobs,
+    updateAccess,
+} from '@/store/blobStorage'
+import {
+    savePlaylist,
+    selectLocalPlaylist,
+} from '@/store/localPlaylistReducers'
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const { ipcRenderer } = require('electron')
 
@@ -45,6 +52,8 @@ export default function Worker(): ReactElement {
     const dispatch = useDispatch()
     // Spawn different instance of local forage for corresponding purpose
     const localBlobsRef = useRef(localBlobs)
+    // Will be updated when config is changed, used for ipcRenderer to keep the function updated with config
+    const configRef = useRef(config)
     // Get variables from react context
     const {
         dispatchAudioBlob,
@@ -61,7 +70,6 @@ export default function Worker(): ReactElement {
     const [queue, setQueue] = useState<Playitem[]>([])
     const [workerState, setWorkerState] = useState<string>('idle')
 
-
     // Helper function of adding abort controller to react context
     const handleAddAbortController = (
         id: string,
@@ -83,59 +91,65 @@ export default function Worker(): ReactElement {
             innertube?.current,
             axiosController
         )
-        // Pass parameters to fetch stream, including an abort controller to stop downloading if the item is removed
-        .then((blob: Blob | Error) => {
-            // Check if the result is an error
-            if (blob instanceof Error) {
-                throw new Error(blob as unknown as string)
-            } else {
-                // Dispatch the audio blob to react context
-                dispatchAudioBlob({
-                    type: 'ADD_BLOB',
-                    payload: { id: nextJob.id, blob: blob },
-                })
-                if (config.storage.enalbeBlobStorage) {
-                    // Store to local disk if enabled
-                    blobToBase64(blob).then((base64) => {
-                        // Send data as base64 to ipcMain
-                        ipcRenderer.send('create-blob', {
-                            id: nextJob.id,
-                            blob: base64,
-                            extension: blob.type,
-                        })
-                        const timeNow = new Date().getTime()
-                        // Make a record of the blob for deletion later
-                        dispatch(
-                            saveBlob({
+            // Pass parameters to fetch stream, including an abort controller to stop downloading if the item is removed
+            .then((blob: Blob | Error) => {
+                // Check if the result is an error
+                if (blob instanceof Error) {
+                    throw new Error(blob as unknown as string)
+                } else {
+                    // Dispatch the audio blob to react context
+                    dispatchAudioBlob({
+                        type: 'ADD_BLOB',
+                        payload: { id: nextJob.id, blob: blob },
+                    })
+                    if (configRef.current.storage.enalbeBlobStorage) {
+                        // Store to local disk if enabled
+                        blobToBase64(blob).then((base64) => {
+                            // Send data as base64 to ipcMain
+                            ipcRenderer.send('create-blob', {
                                 id: nextJob.id,
-                                title: nextJob.title,
+                                blob: base64,
                                 extension: blob.type,
-                                created: timeNow,
-                                lastAccess: timeNow,
                             })
-                        )
-                    })
+                            const timeNow = new Date().getTime()
+                            // Make a record of the blob for deletion later
+                            if (
+                                localBlobs.find(
+                                    (blob) => blob.id === nextJob.id
+                                ) === undefined
+                            ) {
+                                dispatch(
+                                    saveBlob({
+                                        id: nextJob.id,
+                                        title: nextJob.title,
+                                        extension: blob.type,
+                                        created: timeNow,
+                                        lastAccess: timeNow,
+                                    })
+                                )
+                            }
+                        })
+                    }
+                    setWorkerState('idle')
+                    dispatch(
+                        setItemDownloadStatus({
+                            id: nextJob.id,
+                            status: 'downloaded',
+                        })
+                    )
                 }
+            })
+            .catch((err: Error) => {
                 setWorkerState('idle')
+                console.log(err)
+                // Show toast
                 dispatch(
                     setItemDownloadStatus({
                         id: nextJob.id,
-                        status: 'downloaded',
+                        status: 'error',
                     })
                 )
-            }
-        })
-        .catch((err: Error) => {
-            setWorkerState('idle')
-            console.log(err)
-            // Show toast
-            dispatch(
-                setItemDownloadStatus({
-                    id: nextJob.id,
-                    status: 'error',
-                })
-            )
-        })
+            })
     }
 
     // Get the next job from playlist
@@ -178,18 +192,23 @@ export default function Worker(): ReactElement {
     }
 
     const generateQueue = () => {
+        // Helper function for generating new queue for worker
         let newQueue: Playitem[] = []
-        const currentPlayingIndex = playlist.findIndex(item => item.status === 'playing')
+        const currentPlayingIndex = playlist.findIndex(
+            (item) => item.status === 'playing'
+        )
         if (currentPlayingIndex === -1) {
-            newQueue = playlist.filter(item => item.downloadStatus !== 'downloaded')
+            newQueue = playlist.filter(
+                (item) => item.downloadStatus !== 'downloaded'
+            )
         } else {
-            for (let i = currentPlayingIndex + 1; i < playlist.length; i++){
-                if (playlist[i].downloadStatus !== 'downloaded'){
+            for (let i = currentPlayingIndex + 1; i < playlist.length; i++) {
+                if (playlist[i].downloadStatus !== 'downloaded') {
                     newQueue.push(playlist[i])
                 }
             }
-            for (let i = 0; i < currentPlayingIndex; i++){
-                if (playlist[i].downloadStatus !== 'downloaded'){
+            for (let i = 0; i < currentPlayingIndex; i++) {
+                if (playlist[i].downloadStatus !== 'downloaded') {
                     newQueue.push(playlist[i])
                 }
             }
@@ -198,7 +217,8 @@ export default function Worker(): ReactElement {
     }
 
     const queueChanged = (newQueue: Playitem[]) => {
-        if (newQueue.length !== queue.length){
+        // Helper function for checking if the queue has changed, only checking the id of every item
+        if (newQueue.length !== queue.length) {
             return true
         } else {
             return !newQueue.every((item, index) => item.id === queue[index].id)
@@ -206,23 +226,26 @@ export default function Worker(): ReactElement {
     }
 
     useEffect(() => {
+        // Watch for playlist
         const newQueue = generateQueue()
-        if (queueChanged(newQueue)){
-            setQueue(newQueue)
+        if (queueChanged(newQueue)) {
+            setQueue(newQueue) // Only trigger the worker when there is a change in queue
         }
     }, [playlist])
 
     useEffect(() => {
         // console.log(workerState)
         // Only work when the status is idle and next job exists
-        if (workerState !== 'idle' || queue.length === 0){
-            return 
+        if (workerState !== 'idle' || queue.length === 0) {
+            return
         }
-        setWorkerState('working');
+        setWorkerState('working')
         const nextJob = queue[0]
-        console.log(`[Worker] Start download video: ${nextJob.id} - ${nextJob.title}`)
+        console.log(
+            `[Worker] Start download video: ${nextJob.id} - ${nextJob.title}`
+        )
         // Create an abort controller for axios
-        const axiosController = new AbortController();
+        const axiosController = new AbortController()
         // Add the abort controller to react context
         handleAddAbortController(nextJob.id, axiosController)
         // Tell redux that the current job is downloading
@@ -237,41 +260,42 @@ export default function Worker(): ReactElement {
         ) // Try to find currently existing local blob first
         if (matchingLocalBlob !== undefined) {
             // If localBlob can be found, try to invoke a request to main process through ipcRenderer
-            ipcRenderer.invoke('get-blob', nextJob.id)
-            .then((res: {exist: boolean, data: undefined | string}) =>{ // ipcMain will return the data in base64 format
-                if (res.exist && res.data !== undefined){
-                    return base64ToBlob(res.data) // Convert back to blob if retrieved successfully
-                } else {
-                    throw new Error('Failed to fetch from local storage')
-                }
-            })
-            .then((blob: Blob) => {
-                // Add the blob the blob store afterwards
-                dispatchAudioBlob({
-                    type: 'ADD_BLOB',
-                    payload: {
-                        id: nextJob.id,
-                        blob: blob,
-                    },
+            ipcRenderer
+                .invoke('get-blob', nextJob.id)
+                .then((res: { exist: boolean; data: undefined | string }) => {
+                    // ipcMain will return the data in base64 format
+                    if (res.exist && res.data !== undefined) {
+                        return base64ToBlob(res.data) // Convert back to blob if retrieved successfully
+                    } else {
+                        throw new Error('Failed to fetch from local storage')
+                    }
                 })
-                dispatch(
-                    setItemDownloadStatus({
-                        id: nextJob.id,
-                        status: 'downloaded',
+                .then((blob: Blob) => {
+                    // Add the blob the blob store afterwards
+                    dispatchAudioBlob({
+                        type: 'ADD_BLOB',
+                        payload: {
+                            id: nextJob.id,
+                            blob: blob,
+                        },
                     })
-                )
-                setWorkerState('idle')
-            })
-            .catch(()=>{
-                fetchStream(nextJob, axiosController)
-            })
+                    dispatch(
+                        setItemDownloadStatus({
+                            id: nextJob.id,
+                            status: 'downloaded',
+                        })
+                    )
+                    dispatch(updateAccess(nextJob.id))
+                    setWorkerState('idle')
+                })
+                .catch(() => {
+                    fetchStream(nextJob, axiosController)
+                })
         } else {
             fetchStream(nextJob, axiosController)
         }
     }, [queue, workerState])
 
-
-
     // const getIsDownloading = () => {
     //     return playlist.some((item) => item.downloadStatus === 'downloading')
     // }
@@ -395,6 +419,7 @@ export default function Worker(): ReactElement {
                     } as LocalBlobEntry
                 )
                 dispatch(deleteBlob(targetBlob.id)) // Remove item from local blob entry
+                console.log('delete-blob', targetBlob)
                 ipcRenderer.send('delete-blob', {
                     id: targetBlob.id,
                     extension: targetBlob.extension,
@@ -405,34 +430,43 @@ export default function Worker(): ReactElement {
 
     // Load playlist on startup or changing
     useEffect(() => {
-        const currentPlaylist = localPlaylists.playlists.find(playlist => playlist.id === localPlaylists.currentPlaylistId) as LocalPlaylist
+        const currentPlaylist = localPlaylists.playlists.find(
+            (playlist) => playlist.id === localPlaylists.currentPlaylistId
+        ) as LocalPlaylist
         dispatch(loadPlaylist(currentPlaylist.data))
     }, [localPlaylists.currentPlaylistId])
 
     // Watch for current playlist, dispatch to save playlist if changed detected
     useEffect(() => {
         let changed = false
-        const newPlaylist: Playitem[] = playlist.map(item => {
+        const newPlaylist: Playitem[] = playlist.map((item) => {
             return {
                 ...item,
                 downloadStatus: 'pending',
-                status: 'added'
+                status: 'added',
             }
         })
-        const currentPlaylist = localPlaylists.playlists.find(item => item.id === localPlaylists.currentPlaylistId) as LocalPlaylist
+        const currentPlaylist = localPlaylists.playlists.find(
+            (item) => item.id === localPlaylists.currentPlaylistId
+        ) as LocalPlaylist
+        if (currentPlaylist.data.length != newPlaylist.length) {
+            changed = true
+        }
         newPlaylist.forEach((item, index) => {
-            const playlistItem = currentPlaylist.data[index];
-            if (playlistItem === undefined || item.id !== playlistItem.id){
+            const playlistItem = currentPlaylist.data[index]
+            if (playlistItem === undefined || item.id !== playlistItem.id) {
                 changed = true
             }
         })
-        if (changed){
+        if (changed) {
+            // console.log('changed')
             dispatch(savePlaylist(newPlaylist))
         }
     }, [playlist])
 
     useEffect(() => {
         localBlobsRef.current = localBlobs
-    }, [localBlobs, playlist])
+        configRef.current = config
+    }, [localBlobs, config])
     return <></>
 }
diff --git a/src/js/channel.ts b/src/js/channel.ts
index 11d66ad..bfb06b7 100644
--- a/src/js/channel.ts
+++ b/src/js/channel.ts
@@ -61,6 +61,10 @@ const channelInner = async (id: string, innertube: Innertube | null) => {
         const videoArr: (VideoResult | undefined)[] = videoRes.videos.map(
             (video) => {
                 const innerVideo = video as Video
+                const viewMatch = innerVideo.view_count.text
+                    ?.replaceAll(',', '')
+                    .match(/\d+/) as string[]
+                const viewNumber = viewMatch[0] as string
                 if (video.type === 'Video') {
                     return {
                         type: 'video',
@@ -71,11 +75,7 @@ const channelInner = async (id: string, innertube: Innertube | null) => {
                         videoThumbnails: extractInnertubeThumbnail(
                             innerVideo.thumbnails
                         ),
-                        viewCount: Number(
-                            innerVideo.view_count.text
-                                ?.replace(/ views$/, '')
-                                .replace(/,/g, '')
-                        ),
+                        viewCount: Number(viewNumber),
                         lengthSeconds: toSecond(
                             innerVideo.duration?.text as string
                         ),
diff --git a/src/js/search.ts b/src/js/search.ts
index bb00ffd..614d6fd 100644
--- a/src/js/search.ts
+++ b/src/js/search.ts
@@ -28,6 +28,7 @@ import {
     extractPipedPlaylist,
     extractPipedVideos,
 } from '@/utils/extractResults'
+import { extractNumber } from '@/utils/format'
 
 type InvidiousRes = InvidiousVideo | InvidiousPlaylist | InvidiousChannel
 type PipedRes = PipedVideo | PipedPlaylist | PipedChannel
@@ -111,10 +112,6 @@ async function searchInner(
             (item) => {
                 if (item.type === 'Video') {
                     const i = item as Video
-                    let views = Number(
-                        i.view_count.text?.replaceAll(',', '').match(/\d+/)[0]
-                    )
-                    views = isNaN(views) ? 0 : views
                     const newVideo: VideoResult = {
                         type: 'video',
                         title: i.title.text as string,
@@ -124,7 +121,7 @@ async function searchInner(
                         videoThumbnails: extractInnertubeThumbnail(
                             i.thumbnails
                         ),
-                        viewCount: views,
+                        viewCount: extractNumber(i.view_count.text as string),
                         lengthSeconds: i.duration.seconds,
                     }
                     // console.log(newVideo)
@@ -133,10 +130,6 @@ async function searchInner(
                     // console.log(item)
                     const i = item as Playlist
                     const author = i.author as Author
-                    let videoCount = Number(
-                        i.video_count.text?.replace(/ videos$/, '')
-                    )
-                    videoCount = isNaN(videoCount) ? 0 : videoCount
                     const newPlaylist: PlaylistResult = {
                         type: 'playlist',
                         title: i.title.text as string,
@@ -146,16 +139,11 @@ async function searchInner(
                         playlistThumbnails: extractInnertubeThumbnail(
                             i.thumbnails
                         ),
-                        vidCount: videoCount,
+                        vidCount: extractNumber(i.video_count.text as string),
                     }
                     return newPlaylist
                 } else if (item.type === 'Channel') {
                     const i = item as Channel
-                    let subCount = i.video_count.text?.replace(
-                        / subscribers$/,
-                        ''
-                    )
-                    subCount = subCount === undefined ? '0' : subCount
                     const newChannel: ChannelResult = {
                         type: 'channel',
                         author: i.author.name,
@@ -163,7 +151,9 @@ async function searchInner(
                         channelThumbnails: extractInnertubeThumbnail(
                             i.author.thumbnails
                         ),
-                        subCount: subCount,
+                        subCount: extractNumber(
+                            i.video_count.text as string
+                        ).toString(),
                     }
                     return newChannel
                 } else {
diff --git a/src/js/videoDetail.ts b/src/js/videoDetail.ts
index 87f5580..7aba22b 100644
--- a/src/js/videoDetail.ts
+++ b/src/js/videoDetail.ts
@@ -45,7 +45,6 @@ interface InvidiousDetails {
     hlsUrl?: string
     adaptiveFormats: {
         index: string
-        bitrate: string
         init: string
         url: string
         itag: string
@@ -55,6 +54,7 @@ interface InvidiousDetails {
         projectionType: number
         container: string
         encoding: string
+        bitrate: string
         qualityLabel?: string
         resolution?: string
     }[]
diff --git a/src/utils/format.ts b/src/utils/format.ts
index c24eb42..f52870d 100644
--- a/src/utils/format.ts
+++ b/src/utils/format.ts
@@ -1,3 +1,5 @@
+import { store } from '@/store/store'
+
 const formatViewNumber: (arg0: number) => string = (views) => {
     if (views > 1000000000) {
         return `${(views / 1000000000).toFixed(1)}B`
@@ -60,4 +62,23 @@ const stringToNumber: (arg0: string) => number = (string) => {
             return 0
     }
 }
-export { formatViewNumber, convertSecond, toSecond, stringToNumber }
+const compactNumber: (arg0: number) => string = (number) => {
+    const storeState = store.getState()
+    const lang = storeState.config.ui.lang
+    const formatNumber = new Intl.NumberFormat(lang, {
+        notation: 'compact',
+    })
+    return formatNumber.format(number)
+}
+const extractNumber: (arg0: string) => number = (string) => {
+    const match = string.replaceAll(',', '').match(/\d+/) as string[]
+    return Number(match[0])
+}
+export {
+    formatViewNumber,
+    convertSecond,
+    toSecond,
+    stringToNumber,
+    compactNumber,
+    extractNumber,
+}
diff --git a/src/utils/thumbnailExtract.tsx b/src/utils/thumbnailExtract.ts
similarity index 64%
rename from src/utils/thumbnailExtract.tsx
rename to src/utils/thumbnailExtract.ts
index 940ad45..90b9d62 100644
--- a/src/utils/thumbnailExtract.tsx
+++ b/src/utils/thumbnailExtract.ts
@@ -6,30 +6,42 @@ export const extractInnertubeThumbnail = (
 ) => {
     const maxresThumbnail: Thumbnail = {
         quality: 'maxres',
-        url: array[0].url,
+        url: fixChannelThumbnail(array[0].url),
         height: array[0].height,
         width: array[0].width,
     }
     const mediumThumbnail: Thumbnail = array[1]
         ? {
               quality: 'medium',
-              url: array[1].url,
+              url: fixChannelThumbnail(array[1].url),
               height: array[1].height,
               width: array[1].width,
           }
         : { ...maxresThumbnail, quality: 'medium' }
     return [maxresThumbnail, mediumThumbnail]
 }
+const fixChannelThumbnail = (string: string) => {
+    // Sometimes invidious and innertube will pass a thumbnail with a url starts with // instead of https://
+    return string.replace(/^\/\//, 'https://')
+}
 export const extractInvidiousChannelThumbnail = (
     array: { url: string; width: number; height: number }[]
 ) => {
     const thumbnails = array.sort((a, b) => b.width - a.width)
     return thumbnails.map((state, index) =>
         index === 0
-            ? { ...state, quality: 'maxres' }
+            ? {
+                  ...state,
+                  quality: 'maxres',
+                  url: fixChannelThumbnail(state.url),
+              }
             : index === 1
-              ? { ...state, quality: 'medium' }
-              : { ...state, quality: '' }
+              ? {
+                    ...state,
+                    quality: 'medium',
+                    url: fixChannelThumbnail(state.url),
+                }
+              : { ...state, quality: '', url: fixChannelThumbnail(state.url) }
     )
 }
 export const generatePipedThumbnail = (url: string) => {
diff --git a/src/views/DetailView.tsx b/src/views/DetailView.tsx
index e4da845..d6aef92 100644
--- a/src/views/DetailView.tsx
+++ b/src/views/DetailView.tsx
@@ -96,6 +96,7 @@ export default function DetailView(props: DetailViewProps): ReactElement {
                 break
             default:
         }
+        presentToast('success', t('video-detail:Copied-Link'))
     }
     const openLink = (type: string) => {
         const invidiousUrl = config.instance.preferType.find(
@@ -213,6 +214,10 @@ export default function DetailView(props: DetailViewProps): ReactElement {
                                             handleAddToPlaylist(false)
                                         }
                                     >
+                                        <Icon
+                                            f7="plus_rectangle_fill"
+                                            className="mr-2 text-[1.2rem]"
+                                        />
                                         {t('search-result:Add-to-playlist')}
                                     </Button>
                                     <Button
@@ -221,17 +226,29 @@ export default function DetailView(props: DetailViewProps): ReactElement {
                                             handleAddToPlaylist(true)
                                         }
                                     >
+                                        <Icon
+                                            f7="arrow_right_to_line"
+                                            className="mr-2 text-[1.2rem]"
+                                        />
                                         {t('search-result:Add-to-next-song')}
                                     </Button>
                                 </div>
                                 <div className="flex gap-8 w-full">
                                     <Button fill popoverOpen=".copy-popover">
+                                        <Icon
+                                            f7="doc_on_clipboard_fill"
+                                            className="mr-2 text-[1.2rem]"
+                                        />
                                         {t('search-result:Copy-Link')}
                                     </Button>
                                     <Button
                                         fill
                                         popoverOpen=".open-link-popover"
                                     >
+                                        <Icon
+                                            f7="link"
+                                            className="mr-2 text-[1.2rem]"
+                                        />
                                         {t('search-result:Open-link')}
                                     </Button>
                                 </div>
@@ -268,19 +285,33 @@ export default function DetailView(props: DetailViewProps): ReactElement {
                     >
                         <List>
                             <ListItem
-                                popoverClose
-                                title="Youtube"
+                                className="popover-close flex justify-start"
                                 onClick={() => copyLink('youtube')}
                                 link="#"
                                 noChevron={true}
-                            ></ListItem>
+                            >
+                                <div className="flex justify-start">
+                                    <Icon
+                                        f7="square_arrow_up_fill"
+                                        className="mr-2 text-[1.2rem]"
+                                    />
+                                    <p>Youtube</p>
+                                </div>
+                            </ListItem>
                             <ListItem
-                                popoverClose
-                                title="Invidious"
+                                className="popover-close"
                                 onClick={() => copyLink('invidious')}
                                 link="#"
                                 noChevron={true}
-                            ></ListItem>
+                            >
+                                <div className="flex justify-start">
+                                    <Icon
+                                        f7="smiley_fill"
+                                        className="mr-2 text-[1.2rem]"
+                                    />
+                                    <p>Invidious</p>
+                                </div>
+                            </ListItem>
                         </List>
                     </Popover>
                     <Popover
@@ -290,19 +321,33 @@ export default function DetailView(props: DetailViewProps): ReactElement {
                     >
                         <List>
                             <ListItem
-                                popoverClose
-                                title="Youtube"
+                                className="popover-close"
                                 onClick={() => openLink('youtube')}
                                 link="#"
                                 noChevron={true}
-                            ></ListItem>
+                            >
+                                <div className="flex justify-start">
+                                    <Icon
+                                        f7="square_arrow_up_fill"
+                                        className="mr-2 text-[1.2rem]"
+                                    />
+                                    <p>Youtube</p>
+                                </div>
+                            </ListItem>
                             <ListItem
-                                popoverClose
-                                title="Invidious"
+                                className="popover-close"
                                 onClick={() => openLink('invidious')}
                                 link="#"
                                 noChevron={true}
-                            ></ListItem>
+                            >
+                                <div className="flex justify-start">
+                                    <Icon
+                                        f7="smiley_fill"
+                                        className="mr-2 text-[1.2rem]"
+                                    />
+                                    <p>Invidious</p>
+                                </div>
+                            </ListItem>
                         </List>
                     </Popover>
                 </>
diff --git a/src/views/HomePage.tsx b/src/views/HomePage.tsx
index 18c976d..7839aca 100644
--- a/src/views/HomePage.tsx
+++ b/src/views/HomePage.tsx
@@ -1,5 +1,10 @@
 import MainNav from '@/components/MainNav'
-import React, { useState, type ReactElement, useEffect, BaseSyntheticEvent } from 'react'
+import React, {
+    useState,
+    type ReactElement,
+    useEffect,
+    BaseSyntheticEvent,
+} from 'react'
 import { Block, Tabs, Tab, View, Toolbar, f7 } from 'framework7-react'
 import ToolbarPlayer from '@/components/ToolbarPlayer'
 import NowPlaying from './NowPlaying'
@@ -29,8 +34,8 @@ export default function HomePage(props: HomePageProps): ReactElement {
             setTab('main')
         }
         f7.views.get('#page-router').on('routeChange', routerListener)
-        return () => f7.views.get('#page-router').off('routeChange', routerListener)
-
+        return () =>
+            f7.views.get('#page-router').off('routeChange', routerListener)
     }, [])
     return (
         <>
diff --git a/src/views/NowPlaying-modules/PlayingSlider.tsx b/src/views/NowPlaying-modules/PlayingSlider.tsx
new file mode 100644
index 0000000..f3eb603
--- /dev/null
+++ b/src/views/NowPlaying-modules/PlayingSlider.tsx
@@ -0,0 +1,31 @@
+import { convertSecond } from '@/utils/format'
+import { Range } from 'framework7-react'
+import React, { type ReactElement } from 'react'
+
+export interface PlayingSliderProps {
+    audio: HTMLAudioElement
+}
+
+export default function PlayingSlider(props: PlayingSliderProps): ReactElement {
+    const handleSliderChange = (duration: number) => {
+        props.audio.currentTime = duration
+    }
+    const formatLabel = (e: number) => {
+        return convertSecond(e)
+    }
+    return (
+        <>
+            <div className="px-10">
+                {!isNaN(props.audio.duration) && (
+                    <Range
+                        max={props.audio.duration}
+                        value={props.audio.currentTime}
+                        onRangeChanged={handleSliderChange}
+                        label={true}
+                        formatLabel={formatLabel}
+                    ></Range>
+                )}
+            </div>
+        </>
+    )
+}
diff --git a/src/views/NowPlaying.tsx b/src/views/NowPlaying.tsx
index 1e3bab7..4cd0f32 100644
--- a/src/views/NowPlaying.tsx
+++ b/src/views/NowPlaying.tsx
@@ -15,6 +15,7 @@ import Wavesurfer from '@/views/NowPlaying-modules/Wavesurfer'
 import NoPlaying from '@/views/NowPlaying-modules/NoPlaying'
 import { selectConfig } from '@/store/globalConfig'
 import { convertSecond } from '@/utils/format'
+import PlayingSlider from './NowPlaying-modules/PlayingSlider'
 
 export default function NowPlaying(): ReactElement {
     const playerState = useSelector(selectPlayer)
@@ -165,10 +166,14 @@ export default function NowPlaying(): ReactElement {
                                 {playerState.currentPlaying?.title}
                             </h5>
                         </div>
-                        <Wavesurfer
-                            media={audio.current}
-                            showTimeline={config.nowPlaying.showTimeline}
-                        />
+                        {audio.current.duration < 90 * 40 ? (
+                            <Wavesurfer
+                                media={audio.current}
+                                showTimeline={config.nowPlaying.showTimeline}
+                            />
+                        ) : (
+                            <PlayingSlider audio={audio.current} />
+                        )}
                         <a
                             className="text-lg flex mt-4 items-center justify-center cursor-pointer"
                             onClick={handleChangeTimestampStyle}
diff --git a/src/views/PlayList.tsx b/src/views/PlayList.tsx
index 7c7d43f..cb12d7d 100644
--- a/src/views/PlayList.tsx
+++ b/src/views/PlayList.tsx
@@ -5,7 +5,7 @@ import { useSelector, useDispatch } from 'react-redux'
 import { selectPlaylist, setItemPlaying, sort } from '@/store/playlistReducers'
 import { play, selectPlayer } from '@/store/playerReducers'
 import PlayItemInner from '@/components/PlayItemInner'
-import PlaylistControlBar from '@/components/PlaylistControlBar'
+import PlaylistControlBar from '@/views/Playlist-modules/PlaylistControlBar'
 import { useTranslation } from 'react-i18next'
 
 export interface PlayListProps {}
diff --git a/src/components/PlaylistControlBar.tsx b/src/views/Playlist-modules/PlaylistControlBar.tsx
similarity index 70%
rename from src/components/PlaylistControlBar.tsx
rename to src/views/Playlist-modules/PlaylistControlBar.tsx
index 7768354..2e0336b 100644
--- a/src/components/PlaylistControlBar.tsx
+++ b/src/views/Playlist-modules/PlaylistControlBar.tsx
@@ -1,12 +1,7 @@
 import React, { BaseSyntheticEvent, type ReactElement } from 'react'
 import { Button, Icon, List, ListItem, Popover, f7 } from 'framework7-react'
 import { useDispatch, useSelector } from 'react-redux'
-import {
-    clearErrorItems,
-    clearPlayedItems,
-    clearAllItems,
-    shuffleUnplayed,
-} from '@/store/playlistReducers'
+import { clearAllItems, shuffleUnplayed } from '@/store/playlistReducers'
 import { setSong, stop } from '@/store/playerReducers'
 import { useTranslation } from 'react-i18next'
 import {
@@ -17,7 +12,9 @@ import {
 } from '@/store/localPlaylistReducers'
 import { LocalPlaylist } from '@/typescript/interfaces'
 import { changeCurrentPlaylist } from '@/store/localPlaylistReducers'
-import presentToast from './Toast'
+import presentToast from '@/components/Toast'
+import RemoveButton from './RemoveButton'
+import RandomButton from './RandomButton'
 
 export interface PlaylistControlBarProps {}
 
@@ -26,17 +23,6 @@ export default function PlaylistControlBar(): ReactElement {
     const localPlaylist = useSelector(selectLocalPlaylist)
     const { t } = useTranslation(['playlist'])
 
-    const handleClearPlaylist = () => {
-        f7.dialog.confirm(
-            t('playlist:Are-you-sure-to-clear-the-playlist'),
-            t('playlist:Clear-playlist'),
-            () => {
-                dispatch(clearAllItems())
-                dispatch(setSong(undefined))
-                dispatch(stop())
-            }
-        )
-    }
     const getCurrentPlaylistName = () => {
         const currentPlaylist = localPlaylist.playlists.find(
             (item) => item.id === localPlaylist.currentPlaylistId
@@ -134,34 +120,8 @@ export default function PlaylistControlBar(): ReactElement {
                 </div>
             </div>
             <div className="flex h-full justify-around items-center py-2 m-0 flex-wrap gap-2">
-                <Button
-                    className="m-0"
-                    tooltip={t('playlist:Clear-Error-items')}
-                    onClick={() => dispatch(clearErrorItems())}
-                >
-                    <Icon className="text-[1.5rem]" f7="flag_slash_fill"></Icon>
-                </Button>
-                <Button
-                    className="m-0"
-                    tooltip={t('playlist:Clear-played-items')}
-                    onClick={() => dispatch(clearPlayedItems())}
-                >
-                    <Icon className="text-[1.5rem]" f7="flowchart_fill"></Icon>
-                </Button>
-                <Button
-                    className="m-0"
-                    tooltip={t('playlist:Shuffle-unplayed-items')}
-                    onClick={() => dispatch(shuffleUnplayed())}
-                >
-                    <Icon className="text-[1.5rem]" f7="shuffle"></Icon>
-                </Button>
-                <Button
-                    className="m-0"
-                    tooltip={t('playlist:Clear-playlist')}
-                    onClick={handleClearPlaylist}
-                >
-                    <Icon className="text-[1.5rem]" f7="trash"></Icon>
-                </Button>
+                <RandomButton />
+                <RemoveButton />
             </div>
             <Popover
                 className="playlist-popover"
@@ -169,13 +129,23 @@ export default function PlaylistControlBar(): ReactElement {
                 arrow={false}
             >
                 <List className="cursor-pointer">
-                    <ListItem onClick={handleRemovePlaylist} popoverClose>
-                        <Icon f7="minus" />
-                        <p>{t('playlist:Remove-playlist')}</p>
+                    <ListItem
+                        onClick={handleRemovePlaylist}
+                        className="popover-close"
+                    >
+                        <div className="flex justify-start">
+                            <Icon f7="minus" className="mr-4 text-[1.2rem]" />
+                            <p>{t('playlist:Remove-playlist')}</p>
+                        </div>
                     </ListItem>
-                    <ListItem onClick={handleRenamePlaylist} popoverClose>
-                        <Icon f7="pencil" />
-                        <p>{t('playlist:Rename-playlist')}</p>
+                    <ListItem
+                        onClick={handleRenamePlaylist}
+                        className="popover-close"
+                    >
+                        <div className="flex justify-start">
+                            <Icon f7="pencil" className="mr-4 text-[1.2rem]" />
+                            <p>{t('playlist:Rename-playlist')}</p>
+                        </div>
                     </ListItem>
                 </List>
             </Popover>
diff --git a/src/views/Playlist-modules/RandomButton.tsx b/src/views/Playlist-modules/RandomButton.tsx
new file mode 100644
index 0000000..d81b6b2
--- /dev/null
+++ b/src/views/Playlist-modules/RandomButton.tsx
@@ -0,0 +1,51 @@
+import { shuffleAll, shuffleUnplayed } from '@/store/playlistReducers'
+import { Button, Icon, List, ListItem, Popover, f7 } from 'framework7-react'
+import React, { type ReactElement } from 'react'
+import { useTranslation } from 'react-i18next'
+import { useDispatch } from 'react-redux'
+
+export interface RandomButtonProps {}
+
+export default function RandomButton(): ReactElement {
+    const { t } = useTranslation()
+    const dispatch = useDispatch()
+    return (
+        <>
+            <Button
+                popoverOpen=".random-popover"
+                tooltip={t('playlist:Randomize-items')}
+                className="m-0"
+            >
+                <Icon f7="shuffle" className="text-[1.2rem]"></Icon>
+            </Button>
+            <Popover className="random-popover" backdrop={false} arrow={false}>
+                <List className="cursor-pointer">
+                    <ListItem
+                        onClick={() => dispatch(shuffleUnplayed())}
+                        className="popover-close"
+                    >
+                        <div className="flex justify-start">
+                            <Icon
+                                f7="music_note_list"
+                                className="mr-4 text-[1.2rem]"
+                            />
+                            <p>{t('playlist:Shuffle-unplayed-items')}</p>
+                        </div>
+                    </ListItem>
+                    <ListItem
+                        onClick={() => dispatch(shuffleAll())}
+                        className="popover-close"
+                    >
+                        <div className="flex justify-start">
+                            <Icon
+                                f7="question_diamond"
+                                className="mr-4 text-[1.2rem]"
+                            />
+                            <p>{t('playlist:Shuffle-all-items')}</p>
+                        </div>
+                    </ListItem>
+                </List>
+            </Popover>
+        </>
+    )
+}
diff --git a/src/views/Playlist-modules/RemoveButton.tsx b/src/views/Playlist-modules/RemoveButton.tsx
new file mode 100644
index 0000000..d48693e
--- /dev/null
+++ b/src/views/Playlist-modules/RemoveButton.tsx
@@ -0,0 +1,76 @@
+import { setSong, stop } from '@/store/playerReducers'
+import {
+    clearAllItems,
+    clearErrorItems,
+    clearPlayedItems,
+} from '@/store/playlistReducers'
+import { Button, Icon, List, ListItem, Popover, f7 } from 'framework7-react'
+import React, { type ReactElement } from 'react'
+import { useTranslation } from 'react-i18next'
+import { useDispatch } from 'react-redux'
+
+export interface RemoveButtonProps {}
+
+export default function RemoveButton(): ReactElement {
+    const { t } = useTranslation()
+    const dispatch = useDispatch()
+    const handleClearPlaylist = () => {
+        f7.dialog.confirm(
+            t('playlist:Are-you-sure-to-clear-the-playlist'),
+            t('playlist:Clear-playlist'),
+            () => {
+                dispatch(clearAllItems())
+                dispatch(setSong(undefined))
+                dispatch(stop())
+            }
+        )
+    }
+    return (
+        <>
+            <Button
+                popoverOpen=".remove-popover"
+                tooltip={t('playlist:Remove-Items')}
+                className="m-0"
+            >
+                <Icon f7="trash" className="text-[1.5rem]"></Icon>
+            </Button>
+            <Popover className="remove-popover" backdrop={false} arrow={false}>
+                <List className="cursor-pointer">
+                    <ListItem
+                        onClick={() => dispatch(clearErrorItems())}
+                        className="popover-close"
+                    >
+                        <div className="flex justify-start">
+                            <Icon
+                                f7="flag_slash"
+                                className="mr-4 text-[1.2rem]"
+                            />
+                            <p>{t('playlist:Clear-Error-items')}</p>
+                        </div>
+                    </ListItem>
+                    <ListItem
+                        onClick={() => dispatch(clearPlayedItems())}
+                        className="popover-close"
+                    >
+                        <div className="flex justify-start">
+                            <Icon
+                                f7="flowchart_fill"
+                                className="mr-4 text-[1.2rem]"
+                            />
+                            <p>{t('playlist:Clear-played-items')}</p>
+                        </div>
+                    </ListItem>
+                    <ListItem
+                        onClick={handleClearPlaylist}
+                        className="popover-close"
+                    >
+                        <div className="flex justify-start">
+                            <Icon f7="xmark" className="mr-4 text-[1.2rem]" />
+                            <p>{t('playlist:Clear-playlist')}</p>
+                        </div>
+                    </ListItem>
+                </List>
+            </Popover>
+        </>
+    )
+}
diff --git a/src/views/Search-modules/NoResult.tsx b/src/views/Search-modules/NoResult.tsx
index 5242711..dc00275 100644
--- a/src/views/Search-modules/NoResult.tsx
+++ b/src/views/Search-modules/NoResult.tsx
@@ -1,7 +1,7 @@
 import { Icon } from 'framework7-react'
 import React, { type ReactElement } from 'react'
 import { useTranslation } from 'react-i18next'
-import {Page} from 'framework7-react'
+import { Page } from 'framework7-react'
 
 export interface NoResultProps {}
 
@@ -9,26 +9,28 @@ export default function NoResult(): ReactElement {
     const { t } = useTranslation(['search-result'])
     return (
         <Page className="h-page">
-        <section className="w-full h-full flex justify-center items-center">
-            <div className="w-full h-fit flex flex-wrap justify-center flex-row items-center gap-8 my-auto">
-                <div className="w-full">
-                    <Icon
-                        className="text-4xl lg:text-6xl w-full"
-                        f7="search_circle"
-                    />
+            <section className="w-full h-full flex justify-center items-center">
+                <div className="w-full h-fit flex flex-wrap justify-center flex-row items-center gap-8 my-auto">
+                    <div className="w-full">
+                        <Icon
+                            className="text-4xl lg:text-6xl w-full"
+                            f7="search_circle"
+                        />
+                    </div>
+                    <div className="w-full">
+                        <h1 className="text-3xl lg:text-5xl w-full text-center">
+                            {t('search-result:No-search-results')}
+                        </h1>
+                    </div>
+                    <div className="w-full">
+                        <h3 className="text-xl lg:text-3xl w-full text-center">
+                            {t(
+                                'search-result:Search-something-on-the-search-bar'
+                            )}
+                        </h3>
+                    </div>
                 </div>
-                <div className="w-full">
-                    <h1 className="text-3xl lg:text-5xl w-full text-center">
-                        {t('search-result:No-search-results')}
-                    </h1>
-                </div>
-                <div className="w-full">
-                    <h3 className="text-xl lg:text-3xl w-full text-center">
-                        {t('search-result:Search-something-on-the-search-bar')}
-                    </h3>
-                </div>
-            </div>
-        </section>
+            </section>
         </Page>
     )
 }
diff --git a/src/views/Setting-modules/InstanceSetting.tsx b/src/views/Setting-modules/InstanceSetting.tsx
index ce87d61..29db90e 100644
--- a/src/views/Setting-modules/InstanceSetting.tsx
+++ b/src/views/Setting-modules/InstanceSetting.tsx
@@ -12,7 +12,15 @@ import {
     updateInstancei18n,
 } from '@/store/globalConfig'
 import { Instance } from '@/typescript/interfaces'
-import { Block, List, ListItem, BlockTitle, f7, Button } from 'framework7-react'
+import {
+    Block,
+    List,
+    ListItem,
+    BlockTitle,
+    f7,
+    Button,
+    Icon,
+} from 'framework7-react'
 import { useTranslation } from 'react-i18next'
 import { Store, useCustomContext } from '@/store/reactContext'
 import Innertube from 'youtubei.js/agnostic'
@@ -32,7 +40,6 @@ export default function InstanceSetting(): ReactElement {
     )
     const {
         instanceList,
-        innertube,
     }: {
         instanceList: Instance[]
         innertube: React.RefObject<Innertube | null>
@@ -291,6 +298,10 @@ export default function InstanceSetting(): ReactElement {
                         shell.openExternal('https://api.invidious.io/')
                     }
                 >
+                    <Icon
+                        f7="arrow_up_right_square"
+                        className="mr-2 text-[1.2rem]"
+                    />
                     {t('setting:View-Invidious-Instances')}
                 </Button>
                 <Button
@@ -301,9 +312,17 @@ export default function InstanceSetting(): ReactElement {
                         )
                     }
                 >
+                    <Icon
+                        f7="arrow_up_right_square"
+                        className="mr-2 text-[1.2rem]"
+                    />
                     {t('setting:View-Piped-Instances')}
                 </Button>
                 <Button fill onClick={resetInstances}>
+                    <Icon
+                        f7="arrow_counterclockwise"
+                        className="mr-2 text-[1.2rem]"
+                    />
                     {t('setting:Reset-to-default')}
                 </Button>
             </Block>
diff --git a/src/views/Setting-modules/StorageManagement.tsx b/src/views/Setting-modules/StorageManagement.tsx
new file mode 100644
index 0000000..041e947
--- /dev/null
+++ b/src/views/Setting-modules/StorageManagement.tsx
@@ -0,0 +1,459 @@
+import presentToast from '@/components/Toast'
+import { getPlayitem } from '@/js/fetchInfo'
+import { deleteBlob, selectLocalBlobs } from '@/store/blobStorage'
+import { selectConfig } from '@/store/globalConfig'
+import { addToPlaylist, selectPlaylist } from '@/store/playlistReducers'
+import { Store, useCustomContext } from '@/store/reactContext'
+import { LocalBlobEntry } from '@/typescript/interfaces'
+import {
+    Block,
+    Button,
+    Card,
+    CardContent,
+    CardHeader,
+    Checkbox,
+    Icon,
+    Link,
+    NavRight,
+    Navbar,
+    Page,
+    f7,
+} from 'framework7-react'
+import React, { useState, type ReactElement, useEffect } from 'react'
+import { useTranslation } from 'react-i18next'
+import { useDispatch, useSelector } from 'react-redux'
+import Innertube from 'youtubei.js/agnostic'
+
+export interface StorageManagementProps {}
+interface ContentRecord extends LocalBlobEntry {
+    exist: boolean
+    selected: boolean
+}
+
+export default function StorageManagement(
+    props: StorageManagementProps
+): ReactElement {
+    const { t } = useTranslation(['storage'])
+    const config = useSelector(selectConfig)
+    const localBlobs = useSelector(selectLocalBlobs)
+    const playlist = useSelector(selectPlaylist)
+    const { innertube }: { innertube: React.RefObject<Innertube | null> } =
+        useCustomContext(Store)
+    const dispatch = useDispatch()
+    const [refresh, triggerRefresh] = useState(true)
+    const [fileList, setFileList] = useState<ContentRecord[]>([])
+    const [sortState, setSortState] = useState({
+        col: 'lastAccess',
+        order: 'dec',
+    })
+    /* eslint-disable-next-line @typescript-eslint/no-var-requires */
+    const { ipcRenderer } = require('electron')
+
+    const displayDate = (number: number) => {
+        const dateTimeFormat = new Intl.DateTimeFormat(config.ui.lang, {
+            dateStyle: 'short',
+            timeStyle: 'short',
+        })
+        const date = new Date(number)
+        return dateTimeFormat.format(date)
+    }
+    const handleTopCheckboxChange = () => {
+        if (fileList.every((file) => file.selected)) {
+            setFileList((prevState) =>
+                prevState.map((file) => {
+                    return { ...file, selected: false }
+                })
+            )
+        } else {
+            setFileList((prevState) =>
+                prevState.map((file) => {
+                    return {
+                        ...file,
+                        selected: true,
+                    }
+                })
+            )
+        }
+    }
+    const handleRemoveAll = () => {
+        f7.dialog.confirm(
+            t(
+                'storage:This-will-remove-all-files-in-the-download-folder-Are-you-sure-to-proceed?'
+            ),
+            () => {
+                fileList.forEach((file) => {
+                    ipcRenderer.send('delete-blob', file)
+                    dispatch(deleteBlob(file.id))
+                })
+            }
+        )
+    }
+    const handleRemoveUnhandled = () => {
+        fileList
+            .filter((file) => file.created === 0)
+            .forEach((file) => {
+                ipcRenderer.send('delete-blob', file)
+            })
+        triggerRefresh((prevState) => !prevState) // Trigger the useEffect as sending message over ipc channel will neither change the localBlob entries nor trigger a re-render
+        presentToast('success', t('storage:Removed-files-without-entries'))
+    }
+    const handleRemoveNonExist = () => {
+        fileList
+            .filter((file) => file.exist === false)
+            .forEach((file) => {
+                dispatch(deleteBlob(file.id))
+            })
+        presentToast('success', t('storage:Removed-entries-without-files'))
+    }
+    const handleRemoveSelected = () => {
+        fileList
+            .filter((file) => file.selected)
+            .forEach((file) => {
+                ipcRenderer.send('delete-blob', file)
+                dispatch(deleteBlob(file.id))
+            })
+        presentToast('success', t('storage:Removed-selected-files'))
+    }
+    const handleAddSelected = () => {
+        let count = 0
+        fileList
+            .filter((file) => file.selected)
+            .forEach((file) => {
+                if (!playlist.some((playitem) => playitem.id === file.id)) {
+                    // Do not add the item if already on playlist
+                    getPlayitem(
+                        file.id,
+                        config.instance.preferType,
+                        innertube.current
+                    )
+                        .then((item) => {
+                            if (item instanceof Error) {
+                                throw item
+                            }
+                            count++
+                            dispatch(addToPlaylist(item))
+                        })
+                        .catch((err) => presentToast('error', err))
+                        .finally(() => {
+                            presentToast(
+                                'success',
+                                t('storage:Added-{{count}}-items-to-playlist', {
+                                    count: count,
+                                })
+                            )
+                        })
+                }
+            })
+    }
+    useEffect(() => {
+        let folderContent: string[]
+        ipcRenderer.invoke('get-folder-content').then((list: string[]) => {
+            folderContent = list
+            const contentRecord: ContentRecord[] = localBlobs.map((record) => {
+                const fileExist = folderContent.some((content: string) => {
+                    const fileExtension = record.extension.includes('mp4')
+                        ? 'm4a'
+                        : 'opus'
+                    return content === `${record.id}.${fileExtension}`
+                })
+                return { ...record, exist: fileExist, selected: false }
+            }) // Search for existance of all localBlobs
+            folderContent.forEach((file) => {
+                const id = file.replace(/\..*$/, '')
+                const ext = file.replace(/^.*\./, '')
+                if (!contentRecord.some((item) => item.id === id)) {
+                    contentRecord.push({
+                        title: t('storage:Unknown'),
+                        id: id,
+                        extension: ext === 'm4a' ? 'mp4' : 'opus',
+                        created: 0,
+                        lastAccess: 0,
+                        exist: true,
+                        selected: false,
+                    })
+                }
+            })
+            setFileList(
+                contentRecord.sort((a, b) => b.lastAccess - a.lastAccess)
+            )
+        })
+    }, [localBlobs, refresh])
+
+    const sortBy = (type: string) => {
+        let sorted: ContentRecord[]
+        const newSortState = {
+            col: type,
+            order:
+                sortState.col === type && sortState.order === 'dec'
+                    ? 'acc'
+                    : 'dec',
+        }
+        switch (type) {
+            case 'title':
+                if (newSortState.order === 'acc') {
+                    sorted = [...fileList].sort((a, b) =>
+                        a.title.localeCompare(b.title)
+                    )
+                } else {
+                    sorted = [...fileList].sort((a, b) =>
+                        b.title.localeCompare(a.title)
+                    )
+                }
+                break
+            case 'id':
+                if (newSortState.order === 'acc') {
+                    sorted = [...fileList].sort((a, b) =>
+                        a.id.localeCompare(b.id)
+                    )
+                } else {
+                    sorted = [...fileList].sort((a, b) =>
+                        b.id.localeCompare(a.id)
+                    )
+                }
+                break
+            case 'create':
+                if (newSortState.order === 'acc') {
+                    sorted = [...fileList].sort((a, b) => a.created - b.created)
+                } else {
+                    sorted = [...fileList].sort((a, b) => b.created - a.created)
+                }
+                break
+            case 'lastAccess':
+                if (newSortState.order === 'acc') {
+                    sorted = [...fileList].sort(
+                        (a, b) => a.lastAccess - b.lastAccess
+                    )
+                } else {
+                    sorted = [...fileList].sort(
+                        (a, b) => b.lastAccess - a.lastAccess
+                    )
+                }
+                break
+            case 'exist':
+                if (newSortState.order === 'acc') {
+                    sorted = [...fileList].sort((a, b) =>
+                        a === b ? 0 : a ? -1 : 1
+                    )
+                } else {
+                    sorted = [...fileList].sort((a, b) =>
+                        a === b ? 0 : b ? -1 : 1
+                    )
+                }
+                break
+            default:
+                sorted = fileList
+        }
+        setFileList(sorted)
+        setSortState(newSortState)
+    }
+    const selectItem = (id: string) => {
+        setFileList((prevState) =>
+            prevState.map((file) =>
+                file.id === id ? { ...file, selected: !file.selected } : file
+            )
+        )
+    }
+    return (
+        <>
+            <Page>
+                <Navbar title={t('storage:Storage-management')}>
+                    <NavRight>
+                        <Link className="color-primary" popupClose>
+                            <Icon f7="xmark" />
+                        </Link>
+                    </NavRight>
+                </Navbar>
+                <Block>
+                    <Card className="data-table data-table-init">
+                        <CardHeader>
+                            {fileList.some((file) => file.selected) ? (
+                                // Top status bar when there are items selected
+                                <div className="data-table-header">
+                                    <div className="data-table-title">
+                                        {
+                                            fileList.filter(
+                                                (file) => file.selected
+                                            ).length
+                                        }{' '}
+                                        {t('storage:items-selected')}
+                                    </div>
+                                    <div className="data-table-actions">
+                                        <Button
+                                            fill
+                                            onClick={handleAddSelected}
+                                        >
+                                            {t(
+                                                'storage:Add-entries-to-current-playlist'
+                                            )}
+                                        </Button>
+                                        <Button
+                                            fill
+                                            onClick={handleRemoveSelected}
+                                        >
+                                            {t(
+                                                'storage:Remove-selected-entries'
+                                            )}
+                                        </Button>
+                                    </div>
+                                </div>
+                            ) : (
+                                // Top status bar when there are no item selected
+                                <div className="data-table-header">
+                                    <div className="data-table-title">
+                                        {t('storage:Audio-files')}
+                                    </div>
+                                    <div className="data-table-actions">
+                                        <Button
+                                            fill
+                                            onClick={handleRemoveNonExist}
+                                        >
+                                            {t(
+                                                'storage:Remove-non-existent-entries'
+                                            )}
+                                        </Button>
+                                        <Button
+                                            fill
+                                            onClick={handleRemoveUnhandled}
+                                        >
+                                            {t(
+                                                'storage:Remove-unhandled-entries'
+                                            )}
+                                        </Button>
+                                        <Button fill onClick={handleRemoveAll}>
+                                            {t('storage:Remove-all-files')}
+                                        </Button>
+                                    </div>
+                                </div>
+                            )}
+                        </CardHeader>
+                        <CardContent padding={false}>
+                            <table>
+                                <thead>
+                                    <tr>
+                                        <th className="checkbox-cell">
+                                            <Checkbox
+                                                checked={fileList.every(
+                                                    (file) => file.selected
+                                                )}
+                                                indeterminate={
+                                                    fileList.some(
+                                                        (file) => file.selected
+                                                    ) &&
+                                                    !fileList.every(
+                                                        (file) => file.selected
+                                                    )
+                                                }
+                                                onChange={
+                                                    handleTopCheckboxChange
+                                                }
+                                            />
+                                        </th>
+                                        <th
+                                            className={`label-cell sortable-cell ${
+                                                sortState.col === 'title' &&
+                                                'sortable-cell-active'
+                                            } ${
+                                                sortState.order === 'dec'
+                                                    ? 'sortable-asc'
+                                                    : 'sortable-desc'
+                                            }`}
+                                            onClick={() => sortBy('title')}
+                                        >
+                                            {t('storage:Title')}
+                                        </th>
+                                        <th
+                                            className={`label-cell sortable-cell large-only ${
+                                                sortState.col === 'id' &&
+                                                'sortable-cell-active'
+                                            } ${
+                                                sortState.order === 'dec'
+                                                    ? 'sortable-asc'
+                                                    : 'sortable-desc'
+                                            }`}
+                                            onClick={() => sortBy('id')}
+                                        >
+                                            {t('storage:Video-Id')}
+                                        </th>
+                                        <th
+                                            className={`label-cell sortable-cell ${
+                                                sortState.col === 'create' &&
+                                                'sortable-cell-active'
+                                            } ${
+                                                sortState.order === 'dec'
+                                                    ? 'sortable-asc'
+                                                    : 'sortable-desc'
+                                            }`}
+                                            onClick={() => sortBy('create')}
+                                        >
+                                            {t('storage:Created-on')}
+                                        </th>
+                                        <th
+                                            className={`label-cell sortable-cell ${
+                                                sortState.col ===
+                                                    'lastAccess' &&
+                                                'sortable-cell-active'
+                                            } ${
+                                                sortState.order === 'dec'
+                                                    ? 'sortable-asc'
+                                                    : 'sortable-desc'
+                                            }`}
+                                            onClick={() => sortBy('lastAccess')}
+                                        >
+                                            {t('storage:Last-access')}
+                                        </th>
+                                        <th
+                                            className={`label-cell sortable-cell ${
+                                                sortState.col === 'exist' &&
+                                                'sortable-cell-active'
+                                            } ${
+                                                sortState.order === 'dec'
+                                                    ? 'sortable-asc'
+                                                    : 'sortable-desc'
+                                            }`}
+                                            onClick={() => sortBy('exist')}
+                                        >
+                                            {t('storage:File-exist')}
+                                        </th>
+                                    </tr>
+                                </thead>
+                                <tbody>
+                                    {fileList.map((file) => (
+                                        <tr key={file.id}>
+                                            <td className="checkbox-cell">
+                                                <Checkbox
+                                                    checked={file.selected}
+                                                    onChange={() =>
+                                                        selectItem(file.id)
+                                                    }
+                                                />
+                                            </td>
+                                            <td className="label-cell">
+                                                {file.title}
+                                            </td>
+                                            <td className="label-cell large-only">
+                                                {file.id}
+                                            </td>
+                                            <td className="label-cell">
+                                                {displayDate(file.created)}
+                                            </td>
+                                            <td className="label-cell">
+                                                {displayDate(file.lastAccess)}
+                                            </td>
+                                            <td className="label-cell">
+                                                {file.exist ? (
+                                                    <Icon f7="checkmark" />
+                                                ) : (
+                                                    <Icon f7="xmark" />
+                                                )}
+                                            </td>
+                                        </tr>
+                                    ))}
+                                </tbody>
+                            </table>
+                        </CardContent>
+                    </Card>
+                </Block>
+            </Page>
+        </>
+    )
+}
diff --git a/src/views/Setting-modules/StorageSetting.tsx b/src/views/Setting-modules/StorageSetting.tsx
index c5723ff..f24d208 100644
--- a/src/views/Setting-modules/StorageSetting.tsx
+++ b/src/views/Setting-modules/StorageSetting.tsx
@@ -1,5 +1,5 @@
 import React, { BaseSyntheticEvent, type ReactElement } from 'react'
-import { List, ListItem } from 'framework7-react'
+import { Block, Button, Icon, List, ListItem, Popup } from 'framework7-react'
 import { useDispatch, useSelector } from 'react-redux'
 import {
     changeStorage,
@@ -8,6 +8,9 @@ import {
 } from '@/store/globalConfig'
 import { useTranslation } from 'react-i18next'
 import presentToast from '@/components/Toast'
+import StorageManagement from './StorageManagement'
+/* eslint-disable-next-line @typescript-eslint/no-var-requires */
+const { shell, ipcRenderer } = require('electron')
 
 export default function StorageSetting(): ReactElement {
     const config = useSelector(selectConfig)
@@ -25,6 +28,11 @@ export default function StorageSetting(): ReactElement {
             dispatch(changeStorage(e.target.value))
         }
     }
+    const handleOpenFolder = () => {
+        ipcRenderer.invoke('get-folder-path').then((path: string) => {
+            shell.openExternal(`file://${path}`)
+        })
+    }
     return (
         <>
             <List className="p-6">
@@ -47,6 +55,23 @@ export default function StorageSetting(): ReactElement {
                     </div>
                 </ListItem>
             </List>
+            <Block className="flex justify-center items-center gap-8">
+                <Button fill onClick={handleOpenFolder}>
+                    <Icon f7="folder_fill" className="mr-2 text-[1.2rem]" />
+                    {t('setting:Show-stored-files')}
+                </Button>
+                <Button fill popupOpen=".storage-management-popup">
+                    <Icon
+                        f7="square_stack_3d_down_right_fill"
+                        className="mr-2 text-[1.2rem]"
+                    />
+                    {t('setting:Manage-stored-files')}
+                </Button>
+            </Block>
+            <Block className="h-20"></Block>
+            <Popup className="storage-management-popup" tabletFullscreen={true}>
+                <StorageManagement />
+            </Popup>
         </>
     )
 }
diff --git a/tsconfig_old.json b/tsconfig_old.json
deleted file mode 100644
index 8815704..0000000
--- a/tsconfig_old.json
+++ /dev/null
@@ -1,111 +0,0 @@
-{
-    "compilerOptions": {
-        /* Visit https://aka.ms/tsconfig to read more about this file */
-
-        /* Projects */
-        // "incremental": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
-        // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
-        // "tsBuildInfoFile": "./.tsbuildinfo",              /* Specify the path to .tsbuildinfo incremental compilation file. */
-        // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */
-        // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */
-        // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */
-
-        /* Language and Environment */
-        "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
-        // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
-        "jsx": "react" /* Specify what JSX code is generated. */,
-        // "experimentalDecorators": true,                   /* Enable experimental support for legacy experimental decorators. */
-        // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
-        // "jsxFactory": "",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
-        // "jsxFragmentFactory": "",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
-        // "jsxImportSource": "",                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
-        // "reactNamespace": "",                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
-        // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */
-        // "useDefineForClassFields": true,                  /* Emit ECMAScript-standard-compliant class fields. */
-        // "moduleDetection": "auto",                        /* Control what method is used to detect module-format JS files. */
-
-        /* Modules */
-        "module": "commonjs" /* Specify what module code is generated. */,
-        // "rootDir": "./",                                  /* Specify the root folder within your source files. */
-        // "moduleResolution": "node10",                     /* Specify how TypeScript looks up a file from a given module specifier. */
-        // "baseUrl": "./",                                  /* Specify the base directory to resolve non-relative module names. */
-        "paths": {
-            "@/*": ["./src/*"]
-        } /* Specify a set of entries that re-map imports to additional lookup locations. */,
-        // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
-        // "typeRoots": [],                                  /* Specify multiple folders that act like './node_modules/@types'. */
-        // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */
-        // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */
-        // "moduleSuffixes": [],                             /* List of file name suffixes to search when resolving a module. */
-        // "allowImportingTsExtensions": true,               /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
-        // "resolvePackageJsonExports": true,                /* Use the package.json 'exports' field when resolving package imports. */
-        // "resolvePackageJsonImports": true,                /* Use the package.json 'imports' field when resolving imports. */
-        // "customConditions": [],                           /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
-        // "resolveJsonModule": true,                        /* Enable importing .json files. */
-        // "allowArbitraryExtensions": true,                 /* Enable importing files with any extension, provided a declaration file is present. */
-        // "noResolve": true,                                /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
-
-        /* JavaScript Support */
-        // "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
-        // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */
-        // "maxNodeModuleJsDepth": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
-        /* Emit */
-        // "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
-        // "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
-        // "emitDeclarationOnly": true,                      /* Only output d.ts files and not JavaScript files. */
-        // "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */
-        // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */
-        // "outFile": "./",                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
-        // "outDir": "./",                                   /* Specify an output folder for all emitted files. */
-        // "removeComments": true,                           /* Disable emitting comments. */
-        // "noEmit": true,                                   /* Disable emitting files from a compilation. */
-        // "importHelpers": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
-        // "importsNotUsedAsValues": "remove",               /* Specify emit/checking behavior for imports that are only used for types. */
-        // "downlevelIteration": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
-        // "sourceRoot": "",                                 /* Specify the root path for debuggers to find the reference source code. */
-        // "mapRoot": "",                                    /* Specify the location where debugger should locate map files instead of generated locations. */
-        // "inlineSources": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */
-        // "emitBOM": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
-        // "newLine": "crlf",                                /* Set the newline character for emitting files. */
-        // "stripInternal": true,                            /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
-        // "noEmitHelpers": true,                            /* Disable generating custom helper functions like '__extends' in compiled output. */
-        // "noEmitOnError": true,                            /* Disable emitting files if any type checking errors are reported. */
-        // "preserveConstEnums": true,                       /* Disable erasing 'const enum' declarations in generated code. */
-        // "declarationDir": "./",                           /* Specify the output directory for generated declaration files. */
-        // "preserveValueImports": true,                     /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
-        /* Interop Constraints */
-        // "isolatedModules": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */
-        // "verbatimModuleSyntax": true,                     /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
-        // "allowSyntheticDefaultImports": true,             /* Allow 'import x from y' when a module doesn't have a default export. */
-        "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
-        // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
-        "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
-
-        /* Type Checking */
-        "strict": true /* Enable all strict type-checking options. */,
-        // "noImplicitAny": true,                            /* Enable error reporting for expressions and declarations with an implied 'any' type. */
-        // "strictNullChecks": true,                         /* When type checking, take into account 'null' and 'undefined'. */
-        // "strictFunctionTypes": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
-        // "strictBindCallApply": true,                      /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
-        // "strictPropertyInitialization": true,             /* Check for class properties that are declared but not set in the constructor. */
-        // "noImplicitThis": true,                           /* Enable error reporting when 'this' is given the type 'any'. */
-        // "useUnknownInCatchVariables": true,               /* Default catch clause variables as 'unknown' instead of 'any'. */
-        // "alwaysStrict": true,                             /* Ensure 'use strict' is always emitted. */
-        // "noUnusedLocals": true,                           /* Enable error reporting when local variables aren't read. */
-        // "noUnusedParameters": true,                       /* Raise an error when a function parameter isn't read. */
-        // "exactOptionalPropertyTypes": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */
-        // "noImplicitReturns": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */
-        // "noFallthroughCasesInSwitch": true,               /* Enable error reporting for fallthrough cases in switch statements. */
-        // "noUncheckedIndexedAccess": true,                 /* Add 'undefined' to a type when accessed using an index. */
-        // "noImplicitOverride": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */
-        // "noPropertyAccessFromIndexSignature": true,       /* Enforces using indexed accessors for keys declared using an indexed type. */
-        // "allowUnusedLabels": true,                        /* Disable error reporting for unused labels. */
-        // "allowUnreachableCode": true,                     /* Disable error reporting for unreachable code. */
-
-        /* Completeness */
-        // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
-        "skipLibCheck": true /* Skip type checking all .d.ts files. */
-    }
-}