Skip to content

Commit 7d32fd0

Browse files
committed
now maybe
1 parent da7a73c commit 7d32fd0

2 files changed

Lines changed: 122 additions & 107 deletions

File tree

404.html

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
<!DOCTYPE html>
2-
<html lang="en">
3-
2+
<html>
43
<head>
5-
<meta charset="UTF-8">
6-
<title>Live2D Viewer - Loading...</title>
7-
<script type="text/javascript">
8-
sessionStorage.setItem('redirect', location.href);
9-
window.location.replace(document.baseURI);
10-
</script>
4+
<meta charset="utf-8">
5+
<title>Redirecting...</title>
6+
<script>
7+
// Get the path the user was trying to access.
8+
// The segmentCount determines how many parts of the path to ignore from the root.
9+
// For a project site like https://user.github.io/repo/, segmentCount should be 1.
10+
// For a user site like https://user.github.io/, segmentCount should be 0.
11+
const segmentCount = 1;
12+
const path = location.pathname.split('/').slice(segmentCount).join('/');
13+
14+
// Construct the new URL and redirect.
15+
// We pass the original path as the 'redirect' query parameter.
16+
location.replace(
17+
location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '') +
18+
'/?redirect=' + encodeURIComponent(path)
19+
);
20+
</script>
1121
</head>
12-
22+
<body>
23+
<p>If you are not redirected automatically, <a href="/">follow this link</a>.</p>
24+
</body>
1325
</html>

js/repoexplorer.js

Lines changed: 101 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ document.addEventListener('DOMContentLoaded', () => {
4242
repo: '',
4343
path: '',
4444
selectedFileItemElement: null,
45-
previewedFile: null,
45+
previewFile: null,
4646
};
4747

4848

@@ -55,7 +55,7 @@ document.addEventListener('DOMContentLoaded', () => {
5555
return;
5656
}
5757
setupEventListeners();
58-
handleInitialUrl();
58+
handleUrlAndLoad();
5959
}
6060

6161
// Set up all event listeners
@@ -68,83 +68,7 @@ document.addEventListener('DOMContentLoaded', () => {
6868
DOM.ownerInput.addEventListener('keypress', handleInputKeyPress);
6969
DOM.upDirectoryBtn.addEventListener('click', navigateUp);
7070
DOM.closePreviewBtn.addEventListener('click', closeFilePreview);
71-
window.addEventListener('popstate', handleInitialUrl); // New: Handle browser back/forward buttons
72-
}
73-
74-
75-
//==============================================================================
76-
// URL HANDLING
77-
//==============================================================================
78-
// Parses the URL on load and populates the file explorer state
79-
async function handleInitialUrl() {
80-
const redirectUrl = sessionStorage.getItem('redirect');
81-
if (redirectUrl) {
82-
sessionStorage.removeItem('redirect');
83-
history.replaceState(null, '', redirectUrl);
84-
}
85-
86-
// Proceed with the path from the URL bar
87-
const path = window.location.pathname;
88-
const params = new URLSearchParams(window.location.search);
89-
const previewFile = params.get('preview');
90-
91-
// This regex needs to account for potential repository names in the path on GitHub Pages
92-
const pathSegments = path.split('/').filter(Boolean);
93-
const feIndex = pathSegments.indexOf('fe');
94-
95-
if (feIndex > -1 && pathSegments.length >= feIndex + 3) {
96-
const owner = pathSegments[feIndex + 1];
97-
const repo = pathSegments[feIndex + 2];
98-
const filePath = pathSegments.slice(feIndex + 3).join('/');
99-
100-
DOM.ownerInput.value = owner;
101-
DOM.repoInput.value = repo;
102-
state.owner = owner;
103-
state.repo = repo;
104-
105-
// Open the explorer automatically if a repo is specified in the URL
106-
openExplorer();
107-
108-
await fetchAndDisplayContents(filePath || '', false);
109-
110-
if (previewFile) {
111-
// Find the file in the current listing and open its preview
112-
const fullItemPath = (filePath ? filePath + '/' : '') + previewFile;
113-
const fileItemElement = DOM.fileListingContainer.querySelector(`[data-path="${fullItemPath}"]`);
114-
if (fileItemElement) {
115-
const item = {
116-
path: fullItemPath,
117-
name: previewFile,
118-
type: 'file',
119-
};
120-
handleListItemClick(item);
121-
}
122-
}
123-
} else {
124-
updateStatus('Enter GitHub Owner and Repository to begin.');
125-
}
126-
}
127-
128-
// Updates the browser's URL to reflect the current state
129-
function updateUrl() {
130-
if (!state.owner || !state.repo) return;
131-
132-
let newPath = `/fe/${state.owner}/${state.repo}`;
133-
if (state.path) {
134-
newPath += `/${state.path}`;
135-
}
136-
137-
const params = new URLSearchParams();
138-
if (state.previewedFile) {
139-
params.set('preview', state.previewedFile.name);
140-
}
141-
142-
const queryString = params.toString();
143-
const finalUrl = queryString ? `${newPath}?${queryString}` : newPath;
144-
145-
if (window.location.pathname !== newPath || window.location.search !== (queryString ? `?${queryString}` : '')) {
146-
history.pushState({ path: state.path }, '', finalUrl);
147-
}
71+
window.addEventListener('popstate', handlePopState);
14872
}
14973

15074

@@ -222,6 +146,89 @@ document.addEventListener('DOMContentLoaded', () => {
222146
}
223147

224148

149+
//==============================================================================
150+
// URL HANDLING
151+
//==============================================================================
152+
// Updates the browser's URL to reflect the current state of the file explorer.
153+
function updateUrl(replaceState = false) {
154+
if (!state.owner || !state.repo) return;
155+
const basePath = window.location.pathname.substring(0, window.location.pathname.indexOf('/fe/'));
156+
let newPath = `${basePath}/fe/${state.owner}/${state.repo}`;
157+
if (state.path) {
158+
newPath += `/${state.path}`;
159+
}
160+
161+
const params = new URLSearchParams(window.location.search);
162+
if (state.previewFile) {
163+
params.set('preview', state.previewFile);
164+
} else {
165+
params.delete('preview');
166+
}
167+
168+
const queryString = params.toString();
169+
if (queryString) {
170+
newPath += `?${queryString}`;
171+
}
172+
173+
const currentUrl = window.location.pathname + window.location.search;
174+
if (currentUrl !== newPath) {
175+
const method = replaceState ? 'replaceState' : 'pushState';
176+
// Use an empty string for the title
177+
history[method]({}, '', newPath);
178+
}
179+
}
180+
181+
// Parses the URL on page load to initialize the explorer state.
182+
function handleUrlAndLoad() {
183+
// Handle the redirect from the 404.html page.
184+
const initialParams = new URLSearchParams(window.location.search);
185+
const redirectPath = initialParams.get('redirect');
186+
187+
if (redirectPath) {
188+
// Contain the path the user originally tried to access.
189+
history.replaceState(null, '', '/' + redirectPath);
190+
}
191+
192+
const path = window.location.pathname;
193+
const params = new URLSearchParams(window.location.search);
194+
const previewFile = params.get('preview');
195+
196+
const segments = path.split('/');
197+
// Find the 'fe' segment
198+
const feIndex = segments.findIndex(s => s.toLowerCase() === 'fe');
199+
200+
if (feIndex > -1 && segments.length >= feIndex + 3) {
201+
const owner = segments[feIndex + 1];
202+
const repo = segments[feIndex + 2];
203+
const filePath = segments.slice(feIndex + 3).join('/');
204+
205+
openExplorer();
206+
DOM.ownerInput.value = owner;
207+
DOM.repoInput.value = repo;
208+
state.owner = owner;
209+
state.repo = repo;
210+
211+
const onContentLoaded = (items) => {
212+
if (previewFile) {
213+
const fileToPreview = items.find(item => item.name === previewFile && item.type === 'file');
214+
if (fileToPreview) {
215+
handleListItemClick(fileToPreview);
216+
}
217+
}
218+
};
219+
fetchAndDisplayContents(filePath, onContentLoaded);
220+
} else {
221+
updateStatus('Enter GitHub Owner and Repository to begin.');
222+
}
223+
}
224+
225+
// Handles browser back/forward navigation.
226+
function handlePopState() {
227+
closeFilePreview();
228+
handleUrlAndLoad();
229+
}
230+
231+
225232
//==============================================================================
226233
// REPOSITORY LOADING & DATA FETCHING
227234
//==============================================================================
@@ -235,25 +242,24 @@ document.addEventListener('DOMContentLoaded', () => {
235242
}
236243
setPlaceholder(DOM.fileListingContainer, 'Loading content...');
237244
DOM.breadcrumbs.innerHTML = '';
238-
closeFilePreview(false); // Updated: Don't update URL yet
245+
closeFilePreview();
239246
fetchAndDisplayContents('');
240247
}
241248

242249
// Fetch and display contents for a given path
243-
async function fetchAndDisplayContents(path, shouldUpdateUrl = true) {
250+
async function fetchAndDisplayContents(path, onLoadCallback) {
244251
state.path = path;
245-
state.previewedFile = null;
246-
if (shouldUpdateUrl) {
247-
updateUrl();
248-
}
249-
252+
updateUrl();
250253
setPlaceholder(DOM.fileListingContainer, 'Loading items...');
251254
updateBreadcrumbs(path);
252255
DOM.upDirectoryBtn.style.display = path ? 'flex' : 'none';
253256

254257
try {
255258
const contents = await fetchGitHubContentsWithCache(path);
256259
renderItems(contents || []);
260+
if (onLoadCallback) {
261+
onLoadCallback(contents || []);
262+
}
257263
} catch (error) {
258264
console.error('[REPO EXPLORER] GitHub API Fetch error:', error);
259265
setPlaceholder(DOM.fileListingContainer, `Error: ${error.message}`, true);
@@ -425,16 +431,16 @@ document.addEventListener('DOMContentLoaded', () => {
425431

426432
// Display file preview for a given file item
427433
async function displayFilePreview(fileItem) {
428-
state.previewedFile = fileItem;
429-
updateUrl();
430-
431434
DOM.previewFileName.textContent = fileItem.name;
432435
setPlaceholder(DOM.previewContent, 'Loading preview...');
433436
DOM.previewActions.innerHTML = '';
434437
DOM.filePreviewContainer.style.display = 'flex';
435438
DOM.filePreviewContainer.classList.add('active');
436439
DOM.fileListingContainer.classList.add('preview-open');
437440

441+
state.previewFile = fileItem.name;
442+
updateUrl(true);
443+
438444
const jsDelivrUrl = `${JSDELIVR_CDN_BASE}/${state.owner}/${state.repo}/${fileItem.path}`;
439445
const extension = fileItem.name.split('.').pop().toLowerCase();
440446

@@ -521,26 +527,23 @@ document.addEventListener('DOMContentLoaded', () => {
521527
}
522528

523529
// Close the file preview panel
524-
function closeFilePreview(shouldUpdateUrl = true) {
530+
function closeFilePreview() {
531+
if (!DOM.filePreviewContainer.classList.contains('active')) return;
532+
525533
DOM.filePreviewContainer.classList.remove('active');
526534
DOM.fileListingContainer.classList.remove('preview-open');
527535
DOM.filePreviewContainer.style.display = 'none';
528536
DOM.previewContent.innerHTML = '';
529537
DOM.previewActions.innerHTML = '';
530538
DOM.previewFileName.textContent = '';
539+
540+
state.previewFile = null;
541+
updateUrl(true);
531542

532543
if (state.selectedFileItemElement) {
533544
state.selectedFileItemElement.classList.remove('selected');
534545
state.selectedFileItemElement = null;
535546
}
536-
537-
// Clear preview state and update URL
538-
if (state.previewedFile) {
539-
state.previewedFile = null;
540-
if (shouldUpdateUrl) {
541-
updateUrl();
542-
}
543-
}
544547
}
545548

546549
// Navigate up one directory level

0 commit comments

Comments
 (0)