Browse Source

fix: improve handling of repo event not found

even if the repo event doesn't exist there may be many issues
and proposal that reference it so it makes sence to:
1. show the repo Menu with a count of proposals and issues
2. show the details within the address point
2. show the issues and proposals page with a warning

RepoPageWrapper stops overwriting all content with error
RepoHeader show warning
RepoDetails show basic details from address point and a warning
master
DanConwayDev 2 years ago
parent
commit
5d1aa91c08
No known key found for this signature in database
GPG Key ID: 68E15486D73F75E1
  1. 17
      src/lib/components/AlertWarning.svelte
  2. 292
      src/lib/components/repo/RepoDetails.svelte
  3. 6
      src/lib/components/repo/RepoHeader.svelte
  4. 1
      src/lib/stores/repos.ts
  5. 55
      src/lib/wrappers/RepoPageWrapper.svelte

17
src/lib/components/AlertWarning.svelte

@ -0,0 +1,17 @@
<div role="alert" class="m-auto max-w-xl">
<div role="alert" class="alert alert-warning bg-yellow-300 m-auto mt-6">
<!-- https://icon-sets.iconify.design/ph/warning-fill/ -->
<svg xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 shrink-0 stroke-current"
viewBox="0 0 256 256">
<path
fill="currentColor"
d="M236.8 188.09L149.35 36.22a24.76 24.76 0 0 0-42.7 0L19.2 188.09a23.51 23.51 0 0 0 0 23.72A24.35 24.35 0 0 0 40.55 224h174.9a24.35 24.35 0 0 0 21.33-12.19a23.51 23.51 0 0 0 .02-23.72M120 104a8 8 0 0 1 16 0v40a8 8 0 0 1-16 0Zm8 88a12 12 0 1 1 12-12a12 12 0 0 1-12 12"
/></svg
>
<div>
<slot />
</div>
</div>
</div>

292
src/lib/components/repo/RepoDetails.svelte

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import UserHeader from '$lib/components/users/UserHeader.svelte' import UserHeader from '$lib/components/users/UserHeader.svelte'
import AlertWarning from '../AlertWarning.svelte'
import { icons_misc } from '../icons' import { icons_misc } from '../icons'
import { event_defaults } from './type' import { event_defaults } from './type'
@ -28,134 +29,140 @@
let naddr_copied = false let naddr_copied = false
let git_url_copied: false | string = false let git_url_copied: false | string = false
let maintainer_copied: false | string = false let maintainer_copied: false | string = false
$: event_not_found = !loading && created_at == 0
</script> </script>
<div class="prose w-full max-w-md"> <div class="prose w-full max-w-md">
{#if name == identifier} {#if event_not_found}
{#if loading} <h4>identifier</h4>
<div class="skeleton my-3 h-5 w-20"></div> <p class="my-2 break-words text-sm">{identifier}</p>
<div class="skeleton my-2 h-4"></div>
<div class="skeleton my-2 mb-3 h-4 w-2/3"></div>
{:else if !name || name.length == 0}
<h4>name / identifier</h4>
<div>none</div>
{:else}
<h4>name / identifier</h4>
<p class="my-2 break-words text-sm">{name}</p>
{/if}
{:else} {:else}
{#if loading} {#if name == identifier}
<div class="skeleton my-3 h-5 w-20"></div> {#if loading}
<div class="skeleton my-2 h-4"></div> <div class="skeleton my-3 h-5 w-20"></div>
<div class="skeleton my-2 mb-3 h-4 w-2/3"></div> <div class="skeleton my-2 h-4"></div>
{:else if !name || name.length == 0} <div class="skeleton my-2 mb-3 h-4 w-2/3"></div>
<h4>name</h4> {:else if !name || name.length == 0}
<div>none</div> <h4>name / identifier</h4>
<div>none</div>
{:else}
<h4>name / identifier</h4>
<p class="my-2 break-words text-sm">{name}</p>
{/if}
{:else} {:else}
<h4>name</h4> {#if loading}
<p class="my-2 break-words text-sm">{name}</p> <div class="skeleton my-3 h-5 w-20"></div>
<div class="skeleton my-2 h-4"></div>
<div class="skeleton my-2 mb-3 h-4 w-2/3"></div>
{:else if !name || name.length == 0}
<h4>name</h4>
<div>none</div>
{:else}
<h4>name</h4>
<p class="my-2 break-words text-sm">{name}</p>
{/if}
{#if loading}
<div class="skeleton my-3 h-5 w-20"></div>
<div class="skeleton my-2 h-4"></div>
<div class="skeleton my-2 mb-3 h-4 w-2/3"></div>
{:else if !identifier || identifier.length == 0}
<h4>identifier</h4>
<div>none</div>
{:else}
<h4>identifier</h4>
<p class="my-2 break-words text-sm">{identifier}</p>
{/if}
{/if} {/if}
{#if loading} {#if loading}
<div class="skeleton my-3 h-5 w-20"></div> <div class="skeleton my-3 h-5 w-20"></div>
<div class="skeleton my-2 h-4"></div> <div class="skeleton my-2 h-4"></div>
<div class="skeleton my-2 mb-3 h-4 w-2/3"></div> <div class="skeleton my-2 mb-3 h-4 w-2/3"></div>
{:else if !identifier || identifier.length == 0} {:else if !short_descrption || description.length == 0}
<h4>identifier</h4> <h4>description</h4>
<div>none</div> <div>none</div>
{:else} {:else}
<h4>identifier</h4> <h4>description</h4>
<p class="my-2 break-words text-sm">{identifier}</p> <p class="my-2 break-words text-sm">{short_descrption}</p>
{/if}
{/if}
{#if loading}
<div class="skeleton my-3 h-5 w-20"></div>
<div class="skeleton my-2 h-4"></div>
<div class="skeleton my-2 mb-3 h-4 w-2/3"></div>
{:else if !short_descrption || description.length == 0}
<h4>description</h4>
<div>none</div>
{:else}
<h4>description</h4>
<p class="my-2 break-words text-sm">{short_descrption}</p>
{/if}
<div>
{#if loading}
<div class="badge skeleton w-20"></div>
<div class="badge skeleton w-20"></div>
{:else}
{#each tags as tag}
<div class="badge badge-secondary mr-2">{tag}</div>
{/each}
{/if} {/if}
</div> <div>
<div> {#if loading}
{#if loading} <div class="badge skeleton w-20"></div>
<div class="skeleton my-3 h-5 w-20"></div> <div class="badge skeleton w-20"></div>
<div class="badge skeleton my-2 block w-60"></div> {:else}
{:else if clone.length == 0} {#each tags as tag}
<div /> <div class="badge badge-secondary mr-2">{tag}</div>
{:else} {/each}
<h4> {/if}
clone {#if git_url_copied}<span class="text-sm text-success opacity-50"> </div>
(copied to clipboard)</span <div>
>{/if} {#if loading}
</h4> <div class="skeleton my-3 h-5 w-20"></div>
{#each clone as git_url} <div class="badge skeleton my-2 block w-60"></div>
<!-- eslint-disable-next-line svelte/valid-compile --> {:else if clone.length == 0}
<!-- svelte-ignore a11y-click-events-have-key-events --> <div />
<div {:else}
on:click={async () => { <h4>
try { clone {#if git_url_copied}<span class="text-sm text-success opacity-50">
await navigator.clipboard.writeText(git_url) (copied to clipboard)</span
git_url_copied = git_url >{/if}
setTimeout(() => { </h4>
git_url_copied = false {#each clone as git_url}
}, 2000) <!-- eslint-disable-next-line svelte/valid-compile -->
} catch {} <!-- svelte-ignore a11y-click-events-have-key-events -->
}} <div
class="group my-2 mt-3 cursor-pointer break-words text-xs" on:click={async () => {
class:text-success={git_url_copied === git_url} try {
class:opacity-50={git_url_copied === git_url} await navigator.clipboard.writeText(git_url)
> git_url_copied = git_url
{git_url} setTimeout(() => {
<svg git_url_copied = false
xmlns="http://www.w3.org/2000/svg" }, 2000)
viewBox="0 0 16 16" } catch {}
class="ml-1 inline h-4 w-4 flex-none fill-base-content opacity-50" }}
class:group-hover:opacity-100={git_url_copied !== git_url} class="group my-2 mt-3 cursor-pointer break-words text-xs"
class:fill-base-content={git_url_copied !== git_url} class:text-success={git_url_copied === git_url}
class:fill-success={git_url_copied === git_url} class:opacity-50={git_url_copied === git_url}
class:opacity-100={git_url_copied === git_url}
> >
{#each icons_misc.copy as d} {git_url}
<path {d} /> <svg
{/each} xmlns="http://www.w3.org/2000/svg"
</svg> viewBox="0 0 16 16"
</div> class="ml-1 inline h-4 w-4 flex-none fill-base-content opacity-50"
{/each} class:group-hover:opacity-100={git_url_copied !== git_url}
{/if} class:fill-base-content={git_url_copied !== git_url}
</div> class:fill-success={git_url_copied === git_url}
<div> class:opacity-100={git_url_copied === git_url}
{#if loading} >
<div class="skeleton my-3 h-5 w-20"></div> {#each icons_misc.copy as d}
<div class="badge skeleton my-2 block w-60"></div> <path {d} />
<div class="badge skeleton my-2 block w-40"></div> {/each}
{:else if web.length == 0} </svg>
<h4>websites</h4> </div>
<div>none</div> {/each}
{:else} {/if}
<h4>websites</h4> </div>
{#each web as site} <div>
<a {#if loading}
href={site} <div class="skeleton my-3 h-5 w-20"></div>
target="_blank" <div class="badge skeleton my-2 block w-60"></div>
class="link link-primary my-2 break-words text-sm" <div class="badge skeleton my-2 block w-40"></div>
> {:else if web.length == 0}
{site} <h4>websites</h4>
</a> <div>none</div>
{/each} {:else}
{/if} <h4>websites</h4>
</div> {#each web as site}
<a
href={site}
target="_blank"
class="link link-primary my-2 break-words text-sm"
>
{site}
</a>
{/each}
{/if}
</div>
{/if}
<div> <div>
{#if loading} {#if loading}
@ -166,7 +173,7 @@
<div /> <div />
{:else} {:else}
<h4> <h4>
maintainers {#if maintainer_copied}<span {#if event_not_found}author{:else}maintainers{/if} {#if maintainer_copied}<span
class="text-sm text-success opacity-50" class="text-sm text-success opacity-50"
> >
(copied to clipboard)</span (copied to clipboard)</span
@ -179,32 +186,35 @@
{/each} {/each}
{/if} {/if}
</div> </div>
<div>
{#if !event_not_found}
<div>
{#if loading}
<div class="skeleton my-3 h-5 w-20"></div>
<div class="badge skeleton my-2 block w-60"></div>
<div class="badge skeleton my-2 block w-40"></div>
{:else if relays.length == 0}
<h4>relays</h4>
<div>none</div>
{:else}
<h4>relays</h4>
{#each relays as relay}
<div class="badge badge-secondary badge-sm my-2 block">{relay}</div>
{/each}
{/if}
</div>
{#if loading} {#if loading}
<div class="skeleton my-3 h-5 w-20"></div> <div class="skeleton my-3 h-5 w-20"></div>
<div class="badge skeleton my-2 block w-60"></div> <div class="skeleton my-2 h-4"></div>
<div class="badge skeleton my-2 block w-40"></div> <div class="skeleton my-2 mb-3 h-4 w-2/3"></div>
{:else if relays.length == 0} {:else if !unique_commit || unique_commit.length == 0}
<h4>relays</h4> <h4>earliest unique commit</h4>
<div>none</div> <p class="my-2 break-words text-xs">not specified</p>
{:else} {:else}
<h4>relays</h4> <h4>earliest unique commit</h4>
{#each relays as relay} <p class="my-2 break-words text-xs">{unique_commit}</p>
<div class="badge badge-secondary badge-sm my-2 block">{relay}</div>
{/each}
{/if} {/if}
</div>
{#if loading}
<div class="skeleton my-3 h-5 w-20"></div>
<div class="skeleton my-2 h-4"></div>
<div class="skeleton my-2 mb-3 h-4 w-2/3"></div>
{:else if !unique_commit || unique_commit.length == 0}
<h4>earliest unique commit</h4>
<p class="my-2 break-words text-xs">not specified</p>
{:else}
<h4>earliest unique commit</h4>
<p class="my-2 break-words text-xs">{unique_commit}</p>
{/if} {/if}
{#if loading} {#if loading}
@ -247,4 +257,12 @@
<p class="my-2 break-words text-xs">{naddr}</p> <p class="my-2 break-words text-xs">{naddr}</p>
</div> </div>
{/if} {/if}
{#if event_not_found}
<div class="text-xs">
<AlertWarning>
<div class="font-semibold pb-1">missing repository details</div>
<div>cannot find referenced repository event</div>
</AlertWarning>
</div>
{/if}
</div> </div>

6
src/lib/components/repo/RepoHeader.svelte

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import RepoMenu from '$lib/wrappers/RepoMenu.svelte' import RepoMenu from '$lib/wrappers/RepoMenu.svelte'
import UserHeader from '$lib/components/users/UserHeader.svelte'
import Container from '../Container.svelte' import Container from '../Container.svelte'
import { event_defaults, type RepoPage } from './type' import { event_defaults, type RepoPage } from './type'
@ -45,6 +46,11 @@
class="strong btn btn-ghost mb-0 mt-0 break-words px-3 text-sm" class="strong btn btn-ghost mb-0 mt-0 break-words px-3 text-sm"
>{short_name}</a >{short_name}</a
> >
{#if created_at === 0 && name.length === 0}
<span class="text-xs text-warning">
cannot find referenced repository event by <UserHeader user={author} inline />
</span>
{/if}
{/if} {/if}
<RepoMenu {selected_tab} /> <RepoMenu {selected_tab} />
</Container> </Container>

1
src/lib/stores/repos.ts

@ -51,6 +51,7 @@ export const ensureRepo = (a: string | NDKEvent): Writable<RepoEvent> => {
identifier, identifier,
author: pubkey, author: pubkey,
naddr: aToNaddr(a_ref) || '', naddr: aToNaddr(a_ref) || '',
maintainers: [pubkey],
}) })
const sub = ndk.subscribe( const sub = ndk.subscribe(

55
src/lib/wrappers/RepoPageWrapper.svelte

@ -40,40 +40,37 @@
}, 5000) }, 5000)
</script> </script>
{#if invalid_naddr || (waited_5_secs && !$selected_repo_collection.loading && $selected_repo_event.name.length === 0)} <RepoHeader {...$selected_repo_event} {selected_tab} />
{#if invalid_naddr}
<Container> <Container>
<AlertError> <AlertError>
{#if invalid_naddr} <div>Error! invalid naddr in url:</div>
<div>Error! invalid naddr in url:</div> <div class="break-all">{repo_naddr}</div>
<div class="break-all">{repo_naddr}</div>
{:else}
<div>Error! cannot find repository event:</div>
<div class="break-all">{repo_naddr}</div>
{/if}
</AlertError> </AlertError>
</Container> </Container>
{:else} <Container>
<RepoHeader {...$selected_repo_event} {selected_tab} /> <slot />
{#if with_side_bar} </Container>
<Container> {/if}
<div class="mt-2 md:flex"> {#if with_side_bar}
<div class="md:mr-2 md:w-2/3"> <Container>
<slot /> <div class="mt-2 md:flex">
<div class="md:mr-2 md:w-2/3">
<slot />
</div>
<div
class:hidden={!show_details_on_mobile}
class=" rounded-lg border border-base-400 md:flex md:w-1/3 md:border-none"
>
<div class="border-b border-base-400 bg-base-300 px-6 py-3 md:hidden">
<h4 class="">Repository Details</h4>
</div> </div>
<div <div class="prose my-3 px-6 md:ml-2 md:px-0">
class:hidden={!show_details_on_mobile} <RepoDetails {a} />
class=" rounded-lg border border-base-400 md:flex md:w-1/3 md:border-none"
>
<div class="border-b border-base-400 bg-base-300 px-6 py-3 md:hidden">
<h4 class="">Repository Details</h4>
</div>
<div class="prose my-3 px-6 md:ml-2 md:px-0">
<RepoDetails {a} />
</div>
</div> </div>
</div> </div>
</Container> </div>
{:else} </Container>
<slot /> {:else}
{/if} <slot />
{/if} {/if}

Loading…
Cancel
Save