mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 21:46:49 +00:00
7c6a17c020
The rollbacks this branch added were snapshot-shaped: capture the whole collection before the write, restore it on any failure. That is wrong in two ways at once. It undoes work the server already accepted when a later step is the one that fails, and it throws away whatever a collaborator's socket event applied while the requests were in flight. The day-plan reorder is the clearest case: five awaits, and a failing day-note write reverted transport positions the server had already stored. It now records only the fields it is about to overwrite, per booking, and drops each one as its request lands - so a note failure reaches the catch with nothing to undo, and a booking that arrived mid-write survives. The notification toggle had the same shape underneath: the rollback was made surgical but the request still shipped the whole matrix built from the pre-toggle render, so two overlapping toggles overwrote each other anyway. It sends the one cell that changed. The test pinned the disagreement as correct; it asserts the payload now. Photo reorder awaits allSettled rather than all, so the UI is not snapped back while the remaining writes are still landing - a partial run really does leave the server holding part of the new order, and only a total refusal justifies restoring the old one. Both the desktop editor and the mobile sheet, which was still swallowing every rejection. Also: the geolocation start guard is a run generation now, because a start issued after a stop re-sets a plain flag while the first run is still parked in the iOS permission prompt; a category rename reports once for the batch and rethrows, so the settings dialog stops closing as if it had worked; and a 404'd import job stops telling the user their file was invalid when it had simply expired. The clipboard fallback for plain-HTTP installs was pasted into three files by this branch. It is one helper now, and the two copy buttons in the members modal that still called navigator.clipboard unguarded use it too. Same for the fourth local-date helper written next to the three that already import the existing one.
36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
/**
|
|
* Copying a link to the clipboard.
|
|
*
|
|
* `navigator.clipboard` is gated on a secure context, so on a plain-HTTP
|
|
* self-host — which is how a good part of TREK is deployed — it is simply
|
|
* undefined and reading `.writeText` off it throws. Every copy button has to
|
|
* carry the deprecated textarea + execCommand path as a fallback, so it lives
|
|
* here once instead of in each of them.
|
|
*/
|
|
export async function copyText(text: string): Promise<boolean> {
|
|
try {
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
await navigator.clipboard.writeText(text)
|
|
return true
|
|
}
|
|
const ta = document.createElement('textarea')
|
|
ta.value = text
|
|
ta.style.position = 'fixed'
|
|
ta.style.left = '-9999px'
|
|
document.body.appendChild(ta)
|
|
try {
|
|
ta.focus()
|
|
ta.select()
|
|
document.execCommand('copy')
|
|
} finally {
|
|
document.body.removeChild(ta)
|
|
}
|
|
// execCommand reports false for a refused copy in some browsers and true in
|
|
// others that did nothing, so it is not worth reading: a true here means
|
|
// nothing objected, not that the clipboard definitely changed.
|
|
return true
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|