mirror of
https://github.com/github/awesome-copilot.git
synced 2026-02-20 02:15:12 +00:00
feat: add deep linking support for file modal
- Update URL hash when opening/closing modal (#file=path) - Handle browser back/forward navigation - Open modal on page load if hash is present - Share button now copies deep link URL instead of GitHub URL
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Modal functionality for file viewing
|
||||
*/
|
||||
|
||||
import { fetchFileContent, getVSCodeInstallUrl, copyToClipboard, showToast, downloadFile, shareFile } from './utils';
|
||||
import { fetchFileContent, getVSCodeInstallUrl, copyToClipboard, showToast, downloadFile, shareFile, getResourceType } from './utils';
|
||||
|
||||
// Modal state
|
||||
let currentFilePath: string | null = null;
|
||||
@@ -56,6 +56,48 @@ export function setupModal(): void {
|
||||
|
||||
// Setup install dropdown toggle
|
||||
setupInstallDropdown('install-dropdown');
|
||||
|
||||
// Handle browser back/forward navigation
|
||||
window.addEventListener('hashchange', handleHashChange);
|
||||
|
||||
// Check for deep link on initial load
|
||||
handleHashChange();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle hash changes for deep linking
|
||||
*/
|
||||
function handleHashChange(): void {
|
||||
const hash = window.location.hash;
|
||||
|
||||
if (hash && hash.startsWith('#file=')) {
|
||||
const filePath = decodeURIComponent(hash.slice(6));
|
||||
if (filePath && filePath !== currentFilePath) {
|
||||
const type = getResourceType(filePath);
|
||||
openFileModal(filePath, type, false); // Don't update hash since we're responding to it
|
||||
}
|
||||
} else if (!hash || hash === '#') {
|
||||
// No hash or empty hash - close modal if open
|
||||
if (currentFilePath) {
|
||||
closeModal(false); // Don't update hash since we're responding to it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update URL hash for deep linking
|
||||
*/
|
||||
function updateHash(filePath: string | null): void {
|
||||
if (filePath) {
|
||||
const newHash = `#file=${encodeURIComponent(filePath)}`;
|
||||
if (window.location.hash !== newHash) {
|
||||
history.pushState(null, '', newHash);
|
||||
}
|
||||
} else {
|
||||
if (window.location.hash) {
|
||||
history.pushState(null, '', window.location.pathname + window.location.search);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,8 +132,11 @@ export function setupInstallDropdown(containerId: string): void {
|
||||
|
||||
/**
|
||||
* Open file viewer modal
|
||||
* @param filePath - Path to the file
|
||||
* @param type - Resource type (agent, prompt, instruction, etc.)
|
||||
* @param updateUrl - Whether to update the URL hash (default: true)
|
||||
*/
|
||||
export async function openFileModal(filePath: string, type: string): Promise<void> {
|
||||
export async function openFileModal(filePath: string, type: string, updateUrl = true): Promise<void> {
|
||||
const modal = document.getElementById('file-modal');
|
||||
const title = document.getElementById('modal-title');
|
||||
const contentEl = document.getElementById('modal-content')?.querySelector('code');
|
||||
@@ -105,6 +150,11 @@ export async function openFileModal(filePath: string, type: string): Promise<voi
|
||||
currentFilePath = filePath;
|
||||
currentFileType = type;
|
||||
|
||||
// Update URL for deep linking
|
||||
if (updateUrl) {
|
||||
updateHash(filePath);
|
||||
}
|
||||
|
||||
// Show modal with loading state
|
||||
title.textContent = filePath.split('/').pop() || filePath;
|
||||
contentEl.textContent = 'Loading...';
|
||||
@@ -137,8 +187,9 @@ export async function openFileModal(filePath: string, type: string): Promise<voi
|
||||
|
||||
/**
|
||||
* Close modal
|
||||
* @param updateUrl - Whether to update the URL hash (default: true)
|
||||
*/
|
||||
export function closeModal(): void {
|
||||
export function closeModal(updateUrl = true): void {
|
||||
const modal = document.getElementById('file-modal');
|
||||
const installDropdown = document.getElementById('install-dropdown');
|
||||
|
||||
@@ -149,6 +200,11 @@ export function closeModal(): void {
|
||||
installDropdown.classList.remove('open');
|
||||
}
|
||||
|
||||
// Update URL for deep linking
|
||||
if (updateUrl) {
|
||||
updateHash(null);
|
||||
}
|
||||
|
||||
currentFilePath = null;
|
||||
currentFileContent = null;
|
||||
currentFileType = null;
|
||||
|
||||
@@ -144,11 +144,11 @@ export async function downloadFile(filePath: string): Promise<boolean> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Share/copy link to clipboard
|
||||
* Share/copy link to clipboard (deep link to current page with file hash)
|
||||
*/
|
||||
export async function shareFile(filePath: string): Promise<boolean> {
|
||||
const url = getGitHubUrl(filePath);
|
||||
return copyToClipboard(url);
|
||||
const deepLinkUrl = `${window.location.origin}${window.location.pathname}#file=${encodeURIComponent(filePath)}`;
|
||||
return copyToClipboard(deepLinkUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user