Browse Source
stop automatic grouping of repo events by identifer and earliest unique commit into a single collection. allow selection of different repos that have an identifier collision by prioritising pubkey:identifier over identifer show repos grouped by namemaster
57 changed files with 1142 additions and 693 deletions
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
import type { RepoDIdentiferCollection } from '$lib/components/repo/type' |
||||
import { writable, type Writable } from 'svelte/store' |
||||
import { ensureRepo, eventToRepoEvent } from './repos' |
||||
import { base_relays, ndk } from './ndk' |
||||
import { repo_kind } from '$lib/kinds' |
||||
import { NDKEvent, NDKRelaySet } from '@nostr-dev-kit/ndk' |
||||
|
||||
export const repos_identifer: { |
||||
[d: string]: Writable<RepoDIdentiferCollection> |
||||
} = {} |
||||
|
||||
export const ensureIdentifierRepoCollection = ( |
||||
identifier: string |
||||
): Writable<RepoDIdentiferCollection> => { |
||||
if (!Object.keys(repos_identifer).includes(identifier)) { |
||||
repos_identifer[identifier] = writable({ |
||||
d: '', |
||||
events: [], |
||||
loading: true, |
||||
}) |
||||
const sub = ndk.subscribe( |
||||
{ kinds: [repo_kind], '#d': [identifier] }, |
||||
{ closeOnEose: true }, |
||||
NDKRelaySet.fromRelayUrls(base_relays, ndk) |
||||
) |
||||
sub.on('event', (event: NDKEvent) => { |
||||
const repo_event = eventToRepoEvent(event) |
||||
if (repo_event && repo_event.identifier === identifier) { |
||||
ensureRepo(event).subscribe((repo_event) => { |
||||
repos_identifer[identifier].update((collection) => { |
||||
let events = collection.events |
||||
let exists = false |
||||
events.map((e) => { |
||||
if (e.author === repo_event.author) { |
||||
exists = true |
||||
return repo_event |
||||
} else return e |
||||
}) |
||||
if (!exists) events = [...events, repo_event] |
||||
return { |
||||
...collection, |
||||
events, |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
}) |
||||
sub.on('eose', () => { |
||||
repos_identifer[identifier].update((collection) => ({ |
||||
...collection, |
||||
loading: false, |
||||
})) |
||||
}) |
||||
} |
||||
return repos_identifer[identifier] |
||||
} |
||||
@ -0,0 +1,78 @@
@@ -0,0 +1,78 @@
|
||||
import type { SelectedPubkeyRepoCollections } from '$lib/components/repo/type' |
||||
import { get, writable, type Unsubscriber, type Writable } from 'svelte/store' |
||||
import { ensureRepoCollection, eventToRepoEvent } from './repos' |
||||
import { base_relays, ndk } from './ndk' |
||||
import { repo_kind } from '$lib/kinds' |
||||
import { NDKEvent, NDKRelaySet } from '@nostr-dev-kit/ndk' |
||||
import { extractAReference } from '$lib/components/repo/utils' |
||||
|
||||
export const selected_npub_repo_collections: Writable<SelectedPubkeyRepoCollections> = |
||||
writable({ |
||||
pubkey: '', |
||||
collections: [], |
||||
}) |
||||
|
||||
const unsubscribers: Unsubscriber[] = [] |
||||
|
||||
export const ensureSelectedPubkeyRepoCollection = ( |
||||
pubkey: string |
||||
): Writable<SelectedPubkeyRepoCollections> => { |
||||
const collections = get(selected_npub_repo_collections) |
||||
if (collections.pubkey === pubkey) return selected_npub_repo_collections |
||||
// TODO call unsubscribers
|
||||
selected_npub_repo_collections.set({ |
||||
pubkey, |
||||
collections: [], |
||||
}) |
||||
|
||||
const sub = ndk.subscribe( |
||||
{ kinds: [repo_kind], authors: [pubkey] }, |
||||
{ closeOnEose: true }, |
||||
NDKRelaySet.fromRelayUrls(base_relays, ndk) |
||||
) |
||||
const identifiers: string[] = [] |
||||
sub.on('event', (event: NDKEvent) => { |
||||
const repo_event = eventToRepoEvent(event) |
||||
if ( |
||||
repo_event && |
||||
repo_event.author === pubkey && |
||||
!identifiers.includes(repo_event.identifier) |
||||
) |
||||
identifiers.push(repo_event.identifier) |
||||
}) |
||||
sub.on('eose', () => { |
||||
identifiers.forEach((identifier) => { |
||||
unsubscribers.push( |
||||
ensureRepoCollection(`${repo_kind}:${pubkey}:${identifier}`).subscribe( |
||||
(c) => { |
||||
if (!c.maintainers.includes(pubkey)) return |
||||
|
||||
selected_npub_repo_collections.update((selected_collections) => { |
||||
if (selected_collections.pubkey !== pubkey) |
||||
return { ...selected_collections } |
||||
let collection_in_selected_collections = false |
||||
const collections = selected_collections.collections.map( |
||||
(old_c) => { |
||||
const ref = extractAReference(old_c.selected_a) |
||||
if (ref && ref.identifier === identifier) { |
||||
collection_in_selected_collections = true |
||||
return { |
||||
...c, |
||||
} |
||||
} |
||||
return { ...old_c } |
||||
} |
||||
) |
||||
if (!collection_in_selected_collections) collections.push(c) |
||||
return { |
||||
...selected_collections, |
||||
collections, |
||||
} |
||||
}) |
||||
} |
||||
) |
||||
) |
||||
}) |
||||
}) |
||||
return selected_npub_repo_collections |
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
import type { RepoRecentCollection } from '$lib/components/repo/type' |
||||
import { writable, type Writable } from 'svelte/store' |
||||
import { ensureRepo, eventToRepoEvent } from './repos' |
||||
import { base_relays, ndk } from './ndk' |
||||
import { repo_kind } from '$lib/kinds' |
||||
import { NDKEvent, NDKRelaySet } from '@nostr-dev-kit/ndk' |
||||
|
||||
export const recent_repos: Writable<RepoRecentCollection> = writable({ |
||||
events: [], |
||||
loading: true, |
||||
}) |
||||
|
||||
let started = false |
||||
|
||||
export const ensureRecentRepos = (): Writable<RepoRecentCollection> => { |
||||
if (started) return recent_repos |
||||
started = true |
||||
const sub = ndk.subscribe( |
||||
{ kinds: [repo_kind] }, |
||||
{ closeOnEose: true }, |
||||
NDKRelaySet.fromRelayUrls(base_relays, ndk) |
||||
) |
||||
sub.on('event', (event: NDKEvent) => { |
||||
const repo_event = eventToRepoEvent(event) |
||||
if (repo_event) { |
||||
ensureRepo(event).subscribe((repo_event) => { |
||||
recent_repos.update((collection) => { |
||||
let events = collection.events |
||||
let exists = false |
||||
events.map((e) => { |
||||
if ( |
||||
e.author === repo_event.author && |
||||
e.identifier === repo_event.identifier |
||||
) { |
||||
exists = true |
||||
return repo_event |
||||
} else return e |
||||
}) |
||||
if (!exists) events = [...events, repo_event] |
||||
return { |
||||
...collection, |
||||
events, |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
}) |
||||
sub.on('eose', () => { |
||||
recent_repos.update((collection) => ({ |
||||
...collection, |
||||
loading: false, |
||||
})) |
||||
}) |
||||
return recent_repos |
||||
} |
||||
@ -1,16 +1,17 @@
@@ -1,16 +1,17 @@
|
||||
<script lang="ts"> |
||||
import ReposSummaryList from '$lib/components/ReposSummaryList.svelte' |
||||
import { |
||||
ensureRecentReposEvents, |
||||
recent_repo_summaries, |
||||
recent_repo_summaries_loading, |
||||
} from '$lib/stores/repos' |
||||
import { summary_defaults } from '$lib/components/repo/type' |
||||
import { ensureRecentRepos, recent_repos } from '$lib/stores/ReposRecent' |
||||
import { repoEventToSummary } from '$lib/stores/repos' |
||||
|
||||
ensureRecentReposEvents() |
||||
ensureRecentRepos() |
||||
</script> |
||||
|
||||
<ReposSummaryList |
||||
title="Latest Repositories" |
||||
repos={$recent_repo_summaries} |
||||
loading={$recent_repo_summaries_loading} |
||||
repos={$recent_repos.events.map( |
||||
(c) => repoEventToSummary(c) || { ...summary_defaults } |
||||
)} |
||||
group_by="name" |
||||
loading={$recent_repos.loading} |
||||
/> |
||||
|
||||
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
<script lang="ts"> |
||||
import { nip19 } from 'nostr-tools' |
||||
import Container from '$lib/components/Container.svelte' |
||||
import { goto } from '$app/navigation' |
||||
import { issue_kind, patch_kind, repo_kind } from '$lib/kinds' |
||||
import { base_relays, ndk } from '$lib/stores/ndk' |
||||
import { NDKEvent, NDKRelaySet } from '@nostr-dev-kit/ndk' |
||||
import { aToNaddr } from '$lib/components/repo/utils' |
||||
import { ensureIssueFull } from '$lib/stores/Issue' |
||||
import { ensureProposalFull } from '$lib/stores/Proposal' |
||||
|
||||
export let data: { nostr_ref: string } |
||||
|
||||
let error = false |
||||
let error_msg = |
||||
'reference in URL is not a repository, proposal, issue or npub reference' |
||||
let waited = false |
||||
|
||||
const showError = (msg?: string) => { |
||||
if (msg) error_msg = msg |
||||
error = true |
||||
waited = true |
||||
} |
||||
|
||||
let lookupEvent = (id: string) => { |
||||
let sub = ndk.subscribe( |
||||
{ |
||||
ids: [id], |
||||
limit: 100, |
||||
}, |
||||
{ |
||||
closeOnEose: false, |
||||
}, |
||||
NDKRelaySet.fromRelayUrls(base_relays, ndk) |
||||
) |
||||
|
||||
sub.on('event', (event: NDKEvent) => { |
||||
try { |
||||
if (event.id == id) { |
||||
let a = event.tagValue('a') |
||||
if (!a) { |
||||
showError( |
||||
'found event but it contains an invalid "a" tag reference' |
||||
) |
||||
} else { |
||||
if (event.kind === issue_kind) { |
||||
ensureIssueFull(a, id) |
||||
goto(`/r/${aToNaddr(a)}/issues/${nip19.noteEncode(id)}`) |
||||
} else if (event.kind === patch_kind) { |
||||
ensureProposalFull(a, id) |
||||
goto(`/r/${aToNaddr(a)}/proposals/${nip19.noteEncode(id)}`) |
||||
} else { |
||||
showError() |
||||
} |
||||
} |
||||
} |
||||
} catch {} |
||||
}) |
||||
|
||||
sub.on('eose', () => { |
||||
showError('cannot find event') |
||||
}) |
||||
} |
||||
|
||||
$: { |
||||
try { |
||||
let decoded = nip19.decode(data.nostr_ref) |
||||
if (decoded.type === 'npub' || decoded.type === 'nprofile') |
||||
goto(`/p/${data.nostr_ref}`) |
||||
else if (decoded.type === 'naddr' && decoded.data.kind === repo_kind) { |
||||
goto(`/r/${data.nostr_ref}`) |
||||
} else if (decoded.type === 'nrelay' || decoded.type === 'nsec') { |
||||
showError() |
||||
} else if (typeof decoded.data === 'string') { |
||||
lookupEvent(decoded.data) |
||||
} else if ( |
||||
(decoded.type === 'nevent' || decoded.type === 'note') && |
||||
// doesnt have a confirmed kind of something other than issue or patch |
||||
!( |
||||
decoded.data.kind && |
||||
[patch_kind, issue_kind].includes(decoded.data.kind) |
||||
) |
||||
) { |
||||
lookupEvent(decoded.data.id) |
||||
} else { |
||||
showError() |
||||
} |
||||
} catch { |
||||
try { |
||||
nip19.noteEncode(data.nostr_ref) // will throw if invalid event id |
||||
lookupEvent(data.nostr_ref) |
||||
} catch { |
||||
showError() |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
{#if error && waited} |
||||
<Container> |
||||
<div |
||||
role="alert" |
||||
class="wrap alert alert-error m-auto mt-6 w-full max-w-lg" |
||||
> |
||||
<svg |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
class="h-6 w-6 shrink-0 stroke-current" |
||||
fill="none" |
||||
viewBox="0 0 24 24" |
||||
><path |
||||
stroke-linecap="round" |
||||
stroke-linejoin="round" |
||||
stroke-width="2" |
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" |
||||
/></svg |
||||
> |
||||
<span>Error! {error_msg}: {data.nostr_ref}</span> |
||||
</div> |
||||
</Container> |
||||
{:else} |
||||
<Container>loading...</Container> |
||||
{/if} |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params }: { params: { nostr_ref: string } }) => { |
||||
return { |
||||
nostr_ref: params.nostr_ref, |
||||
} |
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
export const load = ({ params }: { params: { repo_naddr: string } }) => { |
||||
return { |
||||
repo_naddr: params.repo_naddr, |
||||
} |
||||
} |
||||
|
||||
export const ssr = false |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params }: { params: { repo_naddr: string } }) => { |
||||
return { |
||||
repo_naddr: params.repo_naddr, |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
export const load = ({ |
||||
params, |
||||
}: { |
||||
params: { issue_nip19: string; repo_naddr: string } |
||||
}) => { |
||||
return { |
||||
repo_naddr: decodeURIComponent(params.repo_naddr), |
||||
issue_nip19: params.issue_nip19, |
||||
} |
||||
} |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params }: { params: { repo_naddr: string } }) => { |
||||
return { |
||||
repo_naddr: params.repo_naddr, |
||||
} |
||||
} |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params }: { params: { repo_naddr: string } }) => { |
||||
return { |
||||
repo_naddr: params.repo_naddr, |
||||
} |
||||
} |
||||
@ -0,0 +1,107 @@
@@ -0,0 +1,107 @@
|
||||
<script lang="ts"> |
||||
import { |
||||
ensureProposalFull, |
||||
selected_proposal_full, |
||||
selected_proposal_replies, |
||||
} from '$lib/stores/Proposal' |
||||
import Thread from '$lib/wrappers/Thread.svelte' |
||||
import Container from '$lib/components/Container.svelte' |
||||
import ProposalHeader from '$lib/components/proposals/ProposalHeader.svelte' |
||||
import ProposalDetails from '$lib/components/proposals/ProposalDetails.svelte' |
||||
import RepoPageWrapper from '$lib/wrappers/RepoPageWrapper.svelte' |
||||
import { naddrToRepoA, neventOrNoteToHexId } from '$lib/components/repo/utils' |
||||
|
||||
export let data: { |
||||
repo_naddr: string |
||||
proposal_nip19: string |
||||
} |
||||
|
||||
let repo_naddr = data.repo_naddr |
||||
let a = '' |
||||
$: { |
||||
const a_result = naddrToRepoA(repo_naddr) |
||||
if (a_result) a = a_result |
||||
} |
||||
|
||||
let proposal_nip19 = data.proposal_nip19 |
||||
let proposal_id = '' |
||||
let invalid_proposal_ref = false |
||||
$: { |
||||
const proposal_nip19_result = neventOrNoteToHexId(proposal_nip19) |
||||
|
||||
if (proposal_nip19_result) { |
||||
proposal_id = proposal_nip19_result |
||||
invalid_proposal_ref = false |
||||
ensureProposalFull(a, proposal_id) |
||||
} else { |
||||
invalid_proposal_ref = true |
||||
} |
||||
} |
||||
|
||||
let repo_error = false |
||||
let proposal_error = false |
||||
$: { |
||||
proposal_error = |
||||
!$selected_proposal_full.summary.loading && |
||||
$selected_proposal_full.summary.created_at === 0 |
||||
} |
||||
|
||||
let waited_5_secs = false |
||||
setTimeout(() => { |
||||
waited_5_secs = true |
||||
}, 5000) |
||||
</script> |
||||
|
||||
<RepoPageWrapper {repo_naddr} with_side_bar={false} selected_tab="proposals"> |
||||
{#if invalid_proposal_ref || (waited_5_secs && proposal_error)} |
||||
<Container> |
||||
<div role="alert" class="alert alert-error m-auto mt-6 w-full max-w-xs"> |
||||
<svg |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
class="h-6 w-6 shrink-0 stroke-current" |
||||
fill="none" |
||||
viewBox="0 0 24 24" |
||||
><path |
||||
stroke-linecap="round" |
||||
stroke-linejoin="round" |
||||
stroke-width="2" |
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" |
||||
/></svg |
||||
> |
||||
{#if invalid_proposal_ref}<span |
||||
>Error! invalid Issue reference: {proposal_id} '{proposal_nip19}'</span |
||||
> |
||||
{:else} |
||||
<span |
||||
>Error! cannot find Issue {repo_error ? 'or repo ' : ''}event</span |
||||
> |
||||
{/if} |
||||
</div> |
||||
</Container> |
||||
{:else} |
||||
<ProposalHeader {...$selected_proposal_full.summary} /> |
||||
<Container> |
||||
<div class="mx-auto max-w-6xl lg:flex"> |
||||
<div class="md:mr-2 lg:w-2/3"> |
||||
<div class="max-w-4xl"> |
||||
{#if $selected_proposal_full.proposal_event} |
||||
<Thread |
||||
type="proposal" |
||||
event={$selected_proposal_full.proposal_event} |
||||
replies={$selected_proposal_replies} |
||||
/> |
||||
{/if} |
||||
</div> |
||||
</div> |
||||
<div class="prose ml-2 hidden w-1/3 lg:flex"> |
||||
<ProposalDetails |
||||
type="proposal" |
||||
summary={$selected_proposal_full.summary} |
||||
labels={$selected_proposal_full.labels} |
||||
loading={$selected_proposal_full.loading} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</Container> |
||||
{/if} |
||||
</RepoPageWrapper> |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
export const load = ({ |
||||
params, |
||||
}: { |
||||
params: { proposal_nip19: string; repo_naddr: string } |
||||
}) => { |
||||
return { |
||||
repo_naddr: decodeURIComponent(params.repo_naddr), |
||||
proposal_nip19: params.proposal_nip19, |
||||
} |
||||
} |
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
export const load = ({ params }: { params: { repo_id: string } }) => { |
||||
return { |
||||
repo_id: decodeURIComponent(params.repo_id), |
||||
} |
||||
} |
||||
|
||||
export const ssr = false |
||||
@ -1,10 +0,0 @@
@@ -1,10 +0,0 @@
|
||||
export const load = ({ |
||||
params, |
||||
}: { |
||||
params: { issue_id: string; repo_id: string } |
||||
}) => { |
||||
return { |
||||
repo_id: decodeURIComponent(params.repo_id), |
||||
issue_id: params.issue_id, |
||||
} |
||||
} |
||||
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
export const load = ({ params }: { params: { repo_id: string } }) => { |
||||
return { |
||||
repo_id: decodeURIComponent(params.repo_id), |
||||
} |
||||
} |
||||
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
export const load = ({ params }: { params: { repo_id: string } }) => { |
||||
return { |
||||
repo_id: decodeURIComponent(params.repo_id), |
||||
} |
||||
} |
||||
@ -1,122 +0,0 @@
@@ -1,122 +0,0 @@
|
||||
<script lang="ts"> |
||||
import { |
||||
ensureSelectedRepoCollection, |
||||
selected_repo_collection, |
||||
selected_repo_event, |
||||
} from '$lib/stores/repo' |
||||
import { |
||||
ensureProposalFull, |
||||
selected_proposal_full, |
||||
selected_proposal_replies, |
||||
} from '$lib/stores/Proposal' |
||||
import ProposalHeader from '$lib/components/proposals/ProposalHeader.svelte' |
||||
import Thread from '$lib/wrappers/Thread.svelte' |
||||
import ProposalDetails from '$lib/components/proposals/ProposalDetails.svelte' |
||||
import Container from '$lib/components/Container.svelte' |
||||
import RepoPageWrapper from '$lib/wrappers/RepoPageWrapper.svelte' |
||||
|
||||
export let data: { |
||||
repo_id: string |
||||
proposal_id: string |
||||
} |
||||
|
||||
let repo_id = data.repo_id |
||||
let proposal_id = data.proposal_id |
||||
|
||||
ensureSelectedRepoCollection(repo_id) |
||||
ensureProposalFull(repo_id, proposal_id) |
||||
|
||||
let repo_error = false |
||||
let proposal_error = false |
||||
$: { |
||||
repo_error = |
||||
!$selected_repo_collection.loading && |
||||
$selected_repo_event.name.length === 0 |
||||
proposal_error = |
||||
!$selected_proposal_full.summary.loading && |
||||
$selected_proposal_full.summary.created_at === 0 |
||||
} |
||||
</script> |
||||
|
||||
<RepoPageWrapper |
||||
identifier={repo_id} |
||||
with_side_bar={false} |
||||
selected_tab="proposals" |
||||
> |
||||
{#if proposal_error} |
||||
<Container> |
||||
<div role="alert" class="alert alert-error m-auto mt-6 w-full max-w-xs"> |
||||
<svg |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
class="h-6 w-6 shrink-0 stroke-current" |
||||
fill="none" |
||||
viewBox="0 0 24 24" |
||||
><path |
||||
stroke-linecap="round" |
||||
stroke-linejoin="round" |
||||
stroke-width="2" |
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" |
||||
/></svg |
||||
> |
||||
<span |
||||
>Error! cannot find Proposal {repo_error ? 'or repo ' : ''}event</span |
||||
> |
||||
</div> |
||||
</Container> |
||||
{:else} |
||||
<ProposalHeader {...$selected_proposal_full.summary} /> |
||||
<Container> |
||||
<div class="mx-auto max-w-6xl lg:flex"> |
||||
<div class="lg:w-2/3 xl:mr-2"> |
||||
<div class="max-w-4xl"> |
||||
{#if $selected_proposal_full.proposal_event} |
||||
<Thread |
||||
type="proposal" |
||||
event={$selected_proposal_full.proposal_event} |
||||
replies={$selected_proposal_replies} |
||||
/> |
||||
{/if} |
||||
</div> |
||||
</div> |
||||
<div class="prose ml-2 hidden w-1/3 lg:block"> |
||||
<div role="alert" class="alert mt-3"> |
||||
<div class="text-center"> |
||||
<div> |
||||
<svg |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
fill="none" |
||||
viewBox="0 0 24 24" |
||||
class="inline h-6 w-6 shrink-0 stroke-info" |
||||
><path |
||||
stroke-linecap="round" |
||||
stroke-linejoin="round" |
||||
stroke-width="2" |
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" |
||||
></path></svg |
||||
> |
||||
<h3 class="prose mx-1 inline text-sm font-bold"> |
||||
view in local git repository |
||||
</h3> |
||||
</div> |
||||
|
||||
<p class="mx-0 mb-1 mt-2 text-xs"> |
||||
<a href="/ngit">install ngit</a>, run |
||||
<span class="rounded bg-neutral p-1 font-mono" |
||||
><span class="py-3">ngit list</span></span |
||||
> from the local repository and select the proposal title |
||||
</p> |
||||
</div> |
||||
</div> |
||||
<div class="block"> |
||||
<ProposalDetails |
||||
type="proposal" |
||||
summary={$selected_proposal_full.summary} |
||||
labels={$selected_proposal_full.labels} |
||||
loading={$selected_proposal_full.loading} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</Container> |
||||
{/if} |
||||
</RepoPageWrapper> |
||||
@ -1,10 +0,0 @@
@@ -1,10 +0,0 @@
|
||||
export const load = ({ |
||||
params, |
||||
}: { |
||||
params: { proposal_id: string; repo_id: string } |
||||
}) => { |
||||
return { |
||||
repo_id: decodeURIComponent(params.repo_id), |
||||
proposal_id: params.proposal_id, |
||||
} |
||||
} |
||||
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
export const load = ({ params }: { params: { repo_id: string } }) => { |
||||
return { |
||||
repo_id: decodeURIComponent(params.repo_id), |
||||
} |
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
<script lang="ts"> |
||||
import Container from '$lib/components/Container.svelte' |
||||
import ReposSummaryList from '$lib/components/ReposSummaryList.svelte' |
||||
import { ensureIdentifierRepoCollection } from '$lib/stores/ReposIdentifier' |
||||
import { repoEventToSummary } from '$lib/stores/repos' |
||||
|
||||
export let data: { repo_identifier: string } |
||||
|
||||
let collection = ensureIdentifierRepoCollection(data.repo_identifier || '') |
||||
</script> |
||||
|
||||
<Container> |
||||
<div class="m-5"> |
||||
<ReposSummaryList |
||||
title={`repositories for '${data.repo_identifier}'`} |
||||
repos={$collection.events.map(repoEventToSummary)} |
||||
loading={$collection.loading} |
||||
/> |
||||
</div> |
||||
</Container> |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
export const load = ({ params }: { params: { repo_identifier: string } }) => { |
||||
return { |
||||
repo_identifier: params.repo_identifier, |
||||
} |
||||
} |
||||
|
||||
export const ssr = false |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
import { redirect } from '@sveltejs/kit' |
||||
|
||||
export const load = ({ params }: { params: { event_id: string } }) => { |
||||
throw redirect(301, `/e/${params.event_id}`) |
||||
} |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
import { redirect } from '@sveltejs/kit' |
||||
|
||||
export const load = ({ params }: { params: { repo_identifier: string } }) => { |
||||
throw redirect(301, `/repo/${params.repo_identifier}`) |
||||
} |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
import { redirect } from '@sveltejs/kit' |
||||
|
||||
export const load = ({ params }: { params: { event_id: string } }) => { |
||||
throw redirect(301, `/e/${params.event_id}`) |
||||
} |
||||
Loading…
Reference in new issue