Correctly list projects pending permission.
This commit is contained in:
parent
969539d3f6
commit
59096b4555
1 changed files with 124 additions and 21 deletions
137
index.html
137
index.html
|
|
@ -541,20 +541,59 @@
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.recent-project-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
.recent-project-btn {
|
.recent-project-btn {
|
||||||
width: 100%;
|
flex-grow: 1;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 0.75em;
|
padding: 0.75em;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
border: .1rem solid var(--shade);
|
border: .1rem solid var(--shade);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recent-project-btn:hover {
|
.recent-project-btn:hover {
|
||||||
border-color: var(--fg);
|
border-color: var(--fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.recent-project-btn.unavailable {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-project-btn.unavailable:hover {
|
||||||
|
border-color: var(--shade);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-project-warning {
|
||||||
|
color: #f80;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-project-btn {
|
||||||
|
padding: 0.5em;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
min-width: auto;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--shade);
|
||||||
|
border: .1rem solid var(--shade);
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-project-btn:hover {
|
||||||
|
color: var(--fg);
|
||||||
|
border-color: var(--fg);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
background-color: #782828;
|
background-color: #782828;
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
|
|
@ -936,6 +975,17 @@ chmod 755 kbtd
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function removeFileHandle(path) {
|
||||||
|
const db = await dbPromise;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const tx = db.transaction(STORE_NAME, 'readwrite');
|
||||||
|
const store = tx.objectStore(STORE_NAME);
|
||||||
|
const request = store.delete(path);
|
||||||
|
request.onsuccess = () => resolve();
|
||||||
|
request.onerror = () => reject(request.error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function getAllStoredProjects() {
|
async function getAllStoredProjects() {
|
||||||
const db = await dbPromise;
|
const db = await dbPromise;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -947,6 +997,23 @@ chmod 755 kbtd
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function validateFileHandle(handle) {
|
||||||
|
try {
|
||||||
|
const perm = await handle.queryPermission({ mode: 'readwrite' });
|
||||||
|
if (perm === 'granted') {
|
||||||
|
await handle.getFile();
|
||||||
|
return 'valid';
|
||||||
|
}
|
||||||
|
return 'needs-permission';
|
||||||
|
} catch (err) {
|
||||||
|
console.log('File handle validation failed:', err);
|
||||||
|
if (err.name === 'NotFoundError') {
|
||||||
|
return 'not-found';
|
||||||
|
}
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function parseMarkdown(text) {
|
function parseMarkdown(text) {
|
||||||
const lines = text.split('\n');
|
const lines = text.split('\n');
|
||||||
const sections = [];
|
const sections = [];
|
||||||
|
|
@ -1305,7 +1372,7 @@ chmod 755 kbtd
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error loading file:', err);
|
console.error('Error loading file:', err);
|
||||||
alert('Error loading file. See console.');
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1808,7 +1875,13 @@ chmod 755 kbtd
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const handle = await getFileHandle(projectName);
|
const handle = await getFileHandle(projectName);
|
||||||
if (handle) {
|
if (!handle) {
|
||||||
|
$('#landing-error').textContent =
|
||||||
|
`Could not find stored file handle for: ${projectName}`;
|
||||||
|
$('#landing-error').style.display = 'block';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
state.fileHandle = handle;
|
state.fileHandle = handle;
|
||||||
const perm = await handle.queryPermission({ mode: 'readwrite' });
|
const perm = await handle.queryPermission({ mode: 'readwrite' });
|
||||||
if (perm === 'granted') {
|
if (perm === 'granted') {
|
||||||
|
|
@ -1817,36 +1890,61 @@ chmod 755 kbtd
|
||||||
} else {
|
} else {
|
||||||
showScreen('permission-screen');
|
showScreen('permission-screen');
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$('#landing-error').textContent =
|
|
||||||
`Could not find stored file handle for: ${projectName}`;
|
|
||||||
$('#landing-error').style.display = 'block';
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error('Error loading project:', err);
|
||||||
$('#landing-error').textContent =
|
$('#landing-error').textContent =
|
||||||
`Error loading project: ${projectName}`;
|
`This file is no longer accessible. Please select it again.`;
|
||||||
$('#landing-error').style.display = 'block';
|
$('#landing-error').style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function removeRecentProject(projectName) {
|
||||||
|
console.log('Removing recent project:', projectName);
|
||||||
|
await removeFileHandle(projectName);
|
||||||
|
await renderRecentProjects();
|
||||||
|
}
|
||||||
|
|
||||||
async function renderRecentProjects() {
|
async function renderRecentProjects() {
|
||||||
try {
|
try {
|
||||||
const projects = await getAllStoredProjects();
|
const projects = await getAllStoredProjects();
|
||||||
console.log('Recent projects:', projects);
|
console.log('Recent projects:', projects);
|
||||||
|
|
||||||
if (projects.length > 0) {
|
if (projects.length > 0) {
|
||||||
|
const projectsWithStatus = await Promise.all(
|
||||||
|
projects.map(async (projectName) => {
|
||||||
|
const handle = await getFileHandle(projectName);
|
||||||
|
const status = handle ? await validateFileHandle(handle) : 'not-found';
|
||||||
|
return { projectName, status };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const list = $('#recent-projects-list');
|
const list = $('#recent-projects-list');
|
||||||
list.replaceChildren(
|
list.replaceChildren(
|
||||||
...projects.map(projectName =>
|
...projectsWithStatus.map(({ projectName, status }) => {
|
||||||
h('li', {},
|
const isClickable = status === 'valid' || status === 'needs-permission';
|
||||||
|
const showWarning = status === 'not-found' || status === 'error';
|
||||||
|
|
||||||
|
return h('li', { className: 'recent-project-item' },
|
||||||
h('button', {
|
h('button', {
|
||||||
className: 'recent-project-btn',
|
className: `recent-project-btn ${isClickable ? '' : 'unavailable'}`,
|
||||||
textContent: projectName,
|
onclick: isClickable ? () => openRecentProject(projectName) : () => {
|
||||||
onclick: () => openRecentProject(projectName)
|
alert('This file is no longer accessible. Please select it again or remove it from the list.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showWarning ? h('span', {
|
||||||
|
className: 'recent-project-warning',
|
||||||
|
textContent: '⚠ '
|
||||||
|
}) : null,
|
||||||
|
h('span', { textContent: projectName })
|
||||||
|
),
|
||||||
|
h('button', {
|
||||||
|
className: 'remove-project-btn',
|
||||||
|
textContent: '×',
|
||||||
|
title: 'Remove from list',
|
||||||
|
onclick: () => removeRecentProject(projectName)
|
||||||
|
})
|
||||||
|
);
|
||||||
})
|
})
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
$('#recent-projects').style.display = 'block';
|
$('#recent-projects').style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1891,6 +1989,11 @@ chmod 755 kbtd
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
await renderRecentProjects();
|
||||||
|
showScreen('landing-screen');
|
||||||
|
$('#landing-error').textContent =
|
||||||
|
`Error loading file. Please select it again.`;
|
||||||
|
$('#landing-error').style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue