mirror of
https://github.com/github/awesome-copilot.git
synced 2026-02-23 03:45:13 +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:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-01-28T22:56:09.687Z",
|
"generated": "2026-01-28T23:33:55.118Z",
|
||||||
"counts": {
|
"counts": {
|
||||||
"agents": 140,
|
"agents": 140,
|
||||||
"prompts": 134,
|
"prompts": 134,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Modal functionality for file viewing
|
* 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
|
// Modal state
|
||||||
let currentFilePath: string | null = null;
|
let currentFilePath: string | null = null;
|
||||||
@@ -56,6 +56,48 @@ export function setupModal(): void {
|
|||||||
|
|
||||||
// Setup install dropdown toggle
|
// Setup install dropdown toggle
|
||||||
setupInstallDropdown('install-dropdown');
|
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
|
* 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 modal = document.getElementById('file-modal');
|
||||||
const title = document.getElementById('modal-title');
|
const title = document.getElementById('modal-title');
|
||||||
const contentEl = document.getElementById('modal-content')?.querySelector('code');
|
const contentEl = document.getElementById('modal-content')?.querySelector('code');
|
||||||
@@ -105,6 +150,11 @@ export async function openFileModal(filePath: string, type: string): Promise<voi
|
|||||||
currentFilePath = filePath;
|
currentFilePath = filePath;
|
||||||
currentFileType = type;
|
currentFileType = type;
|
||||||
|
|
||||||
|
// Update URL for deep linking
|
||||||
|
if (updateUrl) {
|
||||||
|
updateHash(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
// Show modal with loading state
|
// Show modal with loading state
|
||||||
title.textContent = filePath.split('/').pop() || filePath;
|
title.textContent = filePath.split('/').pop() || filePath;
|
||||||
contentEl.textContent = 'Loading...';
|
contentEl.textContent = 'Loading...';
|
||||||
@@ -137,8 +187,9 @@ export async function openFileModal(filePath: string, type: string): Promise<voi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Close modal
|
* 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 modal = document.getElementById('file-modal');
|
||||||
const installDropdown = document.getElementById('install-dropdown');
|
const installDropdown = document.getElementById('install-dropdown');
|
||||||
|
|
||||||
@@ -149,6 +200,11 @@ export function closeModal(): void {
|
|||||||
installDropdown.classList.remove('open');
|
installDropdown.classList.remove('open');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update URL for deep linking
|
||||||
|
if (updateUrl) {
|
||||||
|
updateHash(null);
|
||||||
|
}
|
||||||
|
|
||||||
currentFilePath = null;
|
currentFilePath = null;
|
||||||
currentFileContent = null;
|
currentFileContent = null;
|
||||||
currentFileType = 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> {
|
export async function shareFile(filePath: string): Promise<boolean> {
|
||||||
const url = getGitHubUrl(filePath);
|
const deepLinkUrl = `${window.location.origin}${window.location.pathname}#file=${encodeURIComponent(filePath)}`;
|
||||||
return copyToClipboard(url);
|
return copyToClipboard(deepLinkUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user