feat(repo): hide write UI for users without push access

Fetch the viewer's push permission via GET /repos/{owner}/{repo} when
entering a repo and gate every write affordance behind it: edit and
image-upload buttons in StackedNote, new-fleeting-note and YouTube
buttons in FleetingNotes, and interactive checkboxes in TodoNotes
(rendered disabled when read-only). Anonymous viewers get the same
treatment because the permissions field is absent without auth, which
collapses to canPush = false.

Previously every write button was visible regardless of role, so
read-role collaborators and anonymous viewers could enter edit mode and
type before the save failed with 401/403.
This commit is contained in:
Julien Calixte
2026-05-29 15:24:12 +02:00
parent 455addf760
commit a09e541fa8
7 changed files with 115 additions and 10 deletions

View File

@@ -35,7 +35,8 @@ export const useCheckboxCommit = ({
initialContent,
initialSha,
containerSelector,
debounceMs = 1000
debounceMs = 1000,
enabled = true
}: {
user: string
repo: string
@@ -44,6 +45,7 @@ export const useCheckboxCommit = ({
initialSha: Ref<string> | string
containerSelector: string
debounceMs?: number
enabled?: Ref<boolean> | boolean
}) => {
const { updateFile } = useGitHubContent({ user, repo })
@@ -91,6 +93,8 @@ export const useCheckboxCommit = ({
const debouncedCommit = useDebounceFn(commitChanges, debounceMs)
const handleCheckboxChange = (event: Event) => {
if (!toValue(enabled)) return
const target = event.target as HTMLInputElement
if (target.tagName !== "INPUT" || target.type !== "checkbox") {
@@ -128,8 +132,16 @@ export const useCheckboxCommit = ({
const listenToCheckboxes = () => {
removeListeners()
const container = document.querySelector(containerSelector)
if (container) {
if (!container) return
if (toValue(enabled)) {
container.addEventListener("change", handleCheckboxChange)
} else {
container
.querySelectorAll<HTMLInputElement>('input[type="checkbox"]')
.forEach((checkbox) => {
checkbox.disabled = true
})
}
}