refactor(files): konum senkronizasyonunu sağlamlaştır
URL tabanlı konum yönetimini tek bir fonksiyon altında toplayarak tarayıcı navigasyonu ve history API olaylarının tutarlı şekilde işlenmesini sağla. pushState ve replaceState metodlarını patch ederek özel locationchange olayı oluşturur ve bileşen yok edildiğinde patch işlemini geri alır.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { onMount, tick } from "svelte";
|
||||
import { onDestroy, onMount, tick } from "svelte";
|
||||
import MatchModal from "../components/MatchModal.svelte";
|
||||
import { API, apiFetch, moveEntry, renameFolder, copyEntry } from "../utils/api.js";
|
||||
import { cleanFileName, extractTitleAndYear } from "../utils/filename.js";
|
||||
@@ -452,6 +452,7 @@
|
||||
const VIEW_KEY = "filesViewMode";
|
||||
let viewMode = "grid";
|
||||
let initialPath = "";
|
||||
let unpatchHistory = null;
|
||||
if (typeof window !== "undefined") {
|
||||
const storedView = window.localStorage.getItem(VIEW_KEY);
|
||||
if (storedView === "grid" || storedView === "list") {
|
||||
@@ -491,14 +492,16 @@
|
||||
let clipboardItem = null;
|
||||
let clipboardOperation = null; // 'cut' veya 'copy'
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
const syncFromLocation = ({ replace = false } = {}) => {
|
||||
if (typeof window === "undefined") return;
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const pathParam = params.get("path");
|
||||
let nextPath = "";
|
||||
if (pathParam) {
|
||||
try {
|
||||
initialPath = normalizePath(decodeURIComponent(pathParam));
|
||||
nextPath = normalizePath(decodeURIComponent(pathParam));
|
||||
} catch (err) {
|
||||
initialPath = normalizePath(pathParam);
|
||||
nextPath = normalizePath(pathParam);
|
||||
}
|
||||
}
|
||||
const playParam = params.get("play");
|
||||
@@ -509,16 +512,49 @@
|
||||
pendingPlayTarget = playParam;
|
||||
}
|
||||
params.delete("play");
|
||||
}
|
||||
const search = params.toString();
|
||||
const newUrl = `${window.location.pathname}${search ? `?${search}` : ""}${window.location.hash}`;
|
||||
window.history.replaceState(
|
||||
{ path: initialPath, originalPath: null },
|
||||
{ path: nextPath, originalPath: null },
|
||||
"",
|
||||
newUrl,
|
||||
);
|
||||
}
|
||||
currentPath = normalizePath(initialPath);
|
||||
|
||||
const state = window.history.state || {};
|
||||
const nextOriginal =
|
||||
typeof state.originalPath === "string"
|
||||
? normalizePath(state.originalPath)
|
||||
: resolveOriginalPathForDisplay(nextPath);
|
||||
|
||||
if (
|
||||
normalizePath(currentPath) === nextPath &&
|
||||
normalizePath(currentOriginalPath) === nextOriginal
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hadSearch = searchTerm.trim().length > 0;
|
||||
const nextSearchTerm = hadSearch ? "" : searchTerm;
|
||||
currentPath = nextPath;
|
||||
currentOriginalPath = nextOriginal;
|
||||
if (hadSearch) {
|
||||
clearSearch("files");
|
||||
}
|
||||
selectedItems = new Set();
|
||||
activeMenu = null;
|
||||
if (isCreatingFolder) cancelCreateFolder();
|
||||
updateVisibleState(files, nextPath);
|
||||
renderedEntries = filterEntriesBySearch(visibleEntries, nextSearchTerm);
|
||||
if (replace) {
|
||||
updateUrlPath(nextPath, nextOriginal, { replace: true });
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
syncFromLocation({ replace: true });
|
||||
initialPath = currentPath;
|
||||
}
|
||||
// 🎬 Player kontrolleri
|
||||
let videoEl;
|
||||
let isPlaying = false;
|
||||
@@ -1694,34 +1730,37 @@
|
||||
}, 50);
|
||||
}
|
||||
});
|
||||
const handlePopState = (event) => {
|
||||
if (typeof window === "undefined") return;
|
||||
const statePath =
|
||||
event?.state && typeof event.state.path === "string"
|
||||
? event.state.path
|
||||
: null;
|
||||
const stateOriginal =
|
||||
event?.state && typeof event.state.originalPath === "string"
|
||||
? event.state.originalPath
|
||||
: null;
|
||||
if (statePath !== null) {
|
||||
currentPath = normalizePath(statePath);
|
||||
} else {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const paramPath = params.get("path");
|
||||
currentPath = normalizePath(paramPath || "");
|
||||
}
|
||||
if (stateOriginal !== null) {
|
||||
currentOriginalPath = normalizePath(stateOriginal);
|
||||
} else {
|
||||
currentOriginalPath = resolveOriginalPathForDisplay(
|
||||
currentPath,
|
||||
currentOriginalPath,
|
||||
);
|
||||
}
|
||||
selectedItems = new Set();
|
||||
activeMenu = null;
|
||||
const handlePopState = () => {
|
||||
syncFromLocation();
|
||||
};
|
||||
|
||||
const handleLocationChange = () => {
|
||||
syncFromLocation();
|
||||
};
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
const originalPushState = window.history.pushState;
|
||||
const originalReplaceState = window.history.replaceState;
|
||||
const triggerChange = () => {
|
||||
window.dispatchEvent(new Event("locationchange"));
|
||||
};
|
||||
window.history.pushState = function (...args) {
|
||||
originalPushState.apply(this, args);
|
||||
triggerChange();
|
||||
};
|
||||
window.history.replaceState = function (...args) {
|
||||
originalReplaceState.apply(this, args);
|
||||
triggerChange();
|
||||
};
|
||||
window.addEventListener("locationchange", handleLocationChange);
|
||||
window.addEventListener("popstate", handlePopState);
|
||||
unpatchHistory = () => {
|
||||
window.history.pushState = originalPushState;
|
||||
window.history.replaceState = originalReplaceState;
|
||||
window.removeEventListener("locationchange", handleLocationChange);
|
||||
window.removeEventListener("popstate", handlePopState);
|
||||
};
|
||||
}
|
||||
ws.onmessage = async (event) => {
|
||||
try {
|
||||
const msg = JSON.parse(event.data);
|
||||
@@ -1949,6 +1988,7 @@
|
||||
|
||||
window.removeEventListener("click", handleClickOutside);
|
||||
window.removeEventListener("popstate", handlePopState);
|
||||
if (unpatchHistory) unpatchHistory();
|
||||
|
||||
// Resize observer'ı temizle
|
||||
if (breadcrumbContainer) {
|
||||
|
||||
Reference in New Issue
Block a user