arama özelliği eklendi
This commit is contained in:
@@ -4,6 +4,11 @@
|
||||
import { cleanFileName, extractTitleAndYear } from "../utils/filename.js";
|
||||
import { refreshMovieCount } from "../stores/movieStore.js";
|
||||
import { refreshTvShowCount } from "../stores/tvStore.js";
|
||||
import {
|
||||
activeSearchTerm,
|
||||
setSearchScope,
|
||||
clearSearch
|
||||
} from "../stores/searchStore.js";
|
||||
const HIDDEN_ROOT_REGEX = /^\d{10,}$/;
|
||||
const FOLDER_ICON_PATH = "/folder.svg";
|
||||
const MAX_TRAIL_SEGMENTS = 3;
|
||||
@@ -13,6 +18,7 @@
|
||||
let visibleFolders = [];
|
||||
let visibleFiles = [];
|
||||
let visibleEntries = [];
|
||||
let renderedEntries = [];
|
||||
let allDirectories = [];
|
||||
let breadcrumbs = [];
|
||||
let currentFileScope = [];
|
||||
@@ -21,6 +27,8 @@
|
||||
let draggingItem = null;
|
||||
let dragOverItem = null;
|
||||
let lastDragPath = "";
|
||||
let searchTerm = "";
|
||||
let hasSearch = false;
|
||||
|
||||
const normalizePath = (value) => {
|
||||
if (!value) return "";
|
||||
@@ -33,6 +41,22 @@
|
||||
/safari/i.test(navigator.userAgent || "") &&
|
||||
!/chrome|crios|android/i.test(navigator.userAgent || "");
|
||||
|
||||
function filterEntriesBySearch(entries, term) {
|
||||
const query = term.trim().toLowerCase();
|
||||
if (!query) return entries;
|
||||
return entries.filter((entry) => {
|
||||
const labels = [
|
||||
entry.displayName,
|
||||
entry.displayPath,
|
||||
entry.name
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ")
|
||||
.toLowerCase();
|
||||
return labels.includes(query);
|
||||
});
|
||||
}
|
||||
|
||||
const shouldHideRootSegment = (segment) =>
|
||||
segment && (HIDDEN_ROOT_REGEX.test(segment) || segment === "downloads");
|
||||
|
||||
@@ -157,6 +181,10 @@
|
||||
customOrder.set(key, filteredOrder);
|
||||
}
|
||||
|
||||
$: searchTerm = $activeSearchTerm;
|
||||
$: hasSearch = searchTerm.trim().length > 0;
|
||||
$: renderedEntries = filterEntriesBySearch(visibleEntries, searchTerm);
|
||||
|
||||
function computeBreadcrumbs(path) {
|
||||
const segments = path ? path.split("/").filter(Boolean) : [];
|
||||
const crumbs = [{ label: "Home", path: "" }];
|
||||
@@ -320,11 +348,10 @@
|
||||
}
|
||||
let selectedItems = new Set();
|
||||
let allSelected = false;
|
||||
function syncSelectionState() {
|
||||
const keys = visibleEntries.map((entry) => entry.name).filter(Boolean);
|
||||
$: {
|
||||
const keys = renderedEntries.map((entry) => entry.name).filter(Boolean);
|
||||
allSelected = keys.length > 0 && keys.every((key) => selectedItems.has(key));
|
||||
}
|
||||
$: syncSelectionState();
|
||||
let pendingPlayTarget = null;
|
||||
let activeMenu = null; // Aktif menü öğesi
|
||||
let menuPosition = { top: 0, left: 0 }; // Menü pozisyonu
|
||||
@@ -485,7 +512,7 @@
|
||||
if (allSelected) {
|
||||
selectedItems = new Set();
|
||||
} else {
|
||||
const keys = visibleEntries.map((entry) => entry.name).filter(Boolean);
|
||||
const keys = renderedEntries.map((entry) => entry.name).filter(Boolean);
|
||||
selectedItems = new Set(keys);
|
||||
}
|
||||
}
|
||||
@@ -624,12 +651,19 @@
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const hadSearch = searchTerm.trim().length > 0;
|
||||
const nextSearchTerm = hadSearch ? "" : searchTerm;
|
||||
currentPath = normalized;
|
||||
currentOriginalPath = normalizedOriginal;
|
||||
if (hadSearch) {
|
||||
clearSearch("files");
|
||||
}
|
||||
selectedItems = new Set();
|
||||
activeMenu = null;
|
||||
if (isCreatingFolder) cancelCreateFolder();
|
||||
updateUrlPath(normalized, normalizedOriginal, { replace });
|
||||
updateVisibleState(files, normalized);
|
||||
renderedEntries = filterEntriesBySearch(visibleEntries, nextSearchTerm);
|
||||
}
|
||||
|
||||
function handleEntryClick(entry) {
|
||||
@@ -1288,6 +1322,7 @@
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
setSearchScope("files");
|
||||
await loadFiles(); // önce dosyaları getir
|
||||
const token = localStorage.getItem("token");
|
||||
const wsUrl = `${API.replace("http", "ws")}?token=${token}`;
|
||||
@@ -1565,10 +1600,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
{#if visibleEntries.length > 0 && selectedItems.size > 0}
|
||||
{#if renderedEntries.length > 0 && selectedItems.size > 0}
|
||||
<span class="selection-count">{selectedItems.size} öğe seçildi</span>
|
||||
{/if}
|
||||
{#if visibleEntries.length > 0 && selectedItems.size > 0}
|
||||
{#if renderedEntries.length > 0 && selectedItems.size > 0}
|
||||
<button
|
||||
class="select-all-btn"
|
||||
type="button"
|
||||
@@ -1603,10 +1638,16 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{#if visibleEntries.length === 0 && !isCreatingFolder}
|
||||
{#if renderedEntries.length === 0 && !isCreatingFolder}
|
||||
<div class="empty">
|
||||
<div style="font-size:42px"><i class="fa-solid fa-folder-open"></i></div>
|
||||
<div style="font-weight:700">No media found</div>
|
||||
<div style="font-weight:700">
|
||||
{#if hasSearch}
|
||||
Aramanla eşleşen öğe bulunamadı
|
||||
{:else}
|
||||
No media found
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
@@ -1633,7 +1674,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#each visibleEntries as entry (entry.name)}
|
||||
{#each renderedEntries as entry (entry.name)}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user