Browse Source

fdix build

Nostr-Signature: aa457cd97e3af5c7e7e6f8938d159f62de2eee27afcf9a9a415192a8b39cd038 573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc 1959bae547fefff3b3fd72e23071e989724ab71f2042bad9cb5a969133045119a068b529df17ded13db96b54372f662760df79a34f1b6072dcabf5d2f003000b
main
Silberengel 2 weeks ago
parent
commit
73f215c0c5
  1. 1
      nostr/commit-signatures.jsonl
  2. 6
      src/lib/components/PublicationIndexViewer.svelte
  3. 42
      src/routes/repos/[npub]/[repo]/components/DiscussionsTab.svelte
  4. 8
      src/routes/repos/[npub]/[repo]/components/FileBrowser.svelte
  5. 48
      src/routes/repos/[npub]/[repo]/components/IssuesTab.svelte
  6. 86
      src/routes/repos/[npub]/[repo]/components/PRsTab.svelte
  7. 70
      src/routes/repos/[npub]/[repo]/components/PatchesTab.svelte
  8. 26
      src/routes/repos/[npub]/[repo]/components/StatusTabLayout.svelte

1
nostr/commit-signatures.jsonl

@ -91,3 +91,4 @@ @@ -91,3 +91,4 @@
{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1772011169,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","prevent zombie git processes"]],"content":"Signed commit: prevent zombie git processes","id":"fd370d2613105f16b0cfdd55b33f50c5b724ecef272109036a7cce5477da29bc","sig":"1d3cb4392f722b1b356247bde64691576d41fdb697e8dfe62d5e7ecd5ad8ea35757da2d56db310a2005e4b5528013aa1205256e37fc230f024d3b5a2e26735bf"}
{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1772087425,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","refactoring 1"]],"content":"Signed commit: refactoring 1","id":"533e9f7acbdd4dc16dbe304245469d57d8d37f0c0cce53b60d99719e2acf4502","sig":"0fad2d7c44f086ceb06ce40ea8cea2d4d002ebe8caec7d78e83483348b1404cfb6256d8d3796ebd9ae6f7866a431ec4a1abe84e417d3e238b9b554b4a32481e4"}
{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1772090269,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","refactoring 2"]],"content":"Signed commit: refactoring 2","id":"9375bfe35e0574bc722cad243c22fdf374dcc9016f91f358ff9ddf1d0a03bb50","sig":"10fbbcbc7cab48dfd2340f0c9eceafe558d893789e4838cbe26493e5c339f7a1f015d1cc4af8bfa51d57e9a9da94bb1bb44841305d5ce7cf92db9938985d0459"}
{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1772104036,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","fix build"]],"content":"Signed commit: fix build","id":"830b91f4efe7d208128a008d44fd3b4352c09af0a83b40ea1fab769f9c8563cf","sig":"49a9772580d5ba1b9b9800bdb53f0f4b55661f6062f9968b18cbbd4983d7a042b477281769488d44b4f43c7bdf627d621d83c16659d3d8d226fb32fe0a450756"}

6
src/lib/components/PublicationIndexViewer.svelte

@ -196,6 +196,12 @@ @@ -196,6 +196,12 @@
<div
class="item"
onclick={() => onItemClick?.(item)}
onkeydown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
onItemClick?.(item);
}
}}
role="button"
tabindex="0"
>

42
src/routes/repos/[npub]/[repo]/components/DiscussionsTab.svelte

@ -3,7 +3,17 @@ @@ -3,7 +3,17 @@
import TabLayout from './TabLayout.svelte';
import DiscussionRenderer, { type Discussion } from '$lib/components/DiscussionRenderer.svelte';
import CommentRenderer from '$lib/components/CommentRenderer.svelte';
import type { Comment } from '$lib/components/CommentRenderer.svelte';
// Define Comment type locally to match CommentRenderer's export
type Comment = {
id: string;
content: string;
author: string;
createdAt: number;
kind: number;
pubkey: string;
replies?: Comment[];
};
import EventCopyButton from '$lib/components/EventCopyButton.svelte';
import { DiscussionsService } from '$lib/services/nostr/discussions-service.js';
import { NostrClient } from '$lib/services/nostr/nostr-client.js';
@ -59,10 +69,10 @@ @@ -59,10 +69,10 @@
try {
const userRelays = userPubkey ? await getUserRelays(userPubkey, nostrClient) : null;
const allDefaultRelays = [...DEFAULT_NOSTR_RELAYS, ...DEFAULT_NOSTR_SEARCH_RELAYS];
const combinedRelays = combineRelays(
DEFAULT_NOSTR_RELAYS,
DEFAULT_NOSTR_SEARCH_RELAYS,
userRelays?.outbox || []
userRelays?.outbox || [],
allDefaultRelays
);
const { nip19 } = await import('nostr-tools');
@ -89,8 +99,8 @@ @@ -89,8 +99,8 @@
content: entry.content,
author: entry.author,
createdAt: entry.createdAt,
kind: entry.kind,
pubkey: entry.pubkey,
kind: entry.kind ?? KIND.THREAD,
pubkey: entry.pubkey ?? '',
comments: entry.comments
}));
@ -207,10 +217,10 @@ @@ -207,10 +217,10 @@
const signedEvent = await signEventWithNIP07(threadEventTemplate);
const userRelays = await getUserRelays(userPubkeyHex, nostrClient);
const allDefaultRelays = [...DEFAULT_NOSTR_RELAYS, ...DEFAULT_NOSTR_SEARCH_RELAYS];
const combinedRelays = combineRelays(
DEFAULT_NOSTR_RELAYS,
DEFAULT_NOSTR_SEARCH_RELAYS,
userRelays?.outbox || []
userRelays?.outbox || [],
allDefaultRelays
);
const publishClient = new NostrClient(combinedRelays);
@ -258,10 +268,10 @@ @@ -258,10 +268,10 @@
const signedEvent = await signEventWithNIP07(commentEventTemplate);
const userRelays = await getUserRelays(userPubkeyHex, nostrClient);
const allDefaultRelays = [...DEFAULT_NOSTR_RELAYS, ...DEFAULT_NOSTR_SEARCH_RELAYS];
const combinedRelays = combineRelays(
DEFAULT_NOSTR_RELAYS,
DEFAULT_NOSTR_SEARCH_RELAYS,
userRelays?.outbox || []
userRelays?.outbox || [],
allDefaultRelays
);
const publishClient = new NostrClient(combinedRelays);
@ -405,8 +415,10 @@ @@ -405,8 +415,10 @@
>
<div
class="modal"
role="document"
role="dialog"
onclick={(e) => e.stopPropagation()}
onkeydown={(e) => e.stopPropagation()}
tabindex="-1"
>
<h3>Create Discussion Thread</h3>
<label>
@ -444,8 +456,10 @@ @@ -444,8 +456,10 @@
>
<div
class="modal"
role="document"
role="dialog"
onclick={(e) => e.stopPropagation()}
onkeydown={(e) => e.stopPropagation()}
tabindex="-1"
>
<h3>{replyingToComment ? 'Reply to Comment' : 'Reply to Thread'}</h3>
<label>

8
src/routes/repos/[npub]/[repo]/components/FileBrowser.svelte

@ -38,7 +38,15 @@ @@ -38,7 +38,15 @@
{#each files as file}
<div
class="file-item {file.type}"
role="button"
tabindex="0"
onclick={() => file.type === 'directory' ? onDirectoryClick(file.path) : onFileClick(file)}
onkeydown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
file.type === 'directory' ? onDirectoryClick(file.path) : onFileClick(file);
}
}}
>
<span class="icon">
{#if file.type === 'directory'}

48
src/routes/repos/[npub]/[repo]/components/IssuesTab.svelte

@ -46,29 +46,17 @@ @@ -46,29 +46,17 @@
const selectedId = $derived(selectedIssue);
</script>
<StatusTabLayout
{items}
{selectedId}
{loading}
{error}
{onSelect}
statusGroups={[
{ label: 'Open', value: 'open' },
{ label: 'Closed', value: 'closed' },
{ label: 'Resolved', value: 'resolved' }
]}
>
{#snippet itemRenderer({ item })}
<div class="issue-item-content">
<div class="issue-subject">{item.subject}</div>
<div class="issue-meta">
<span class="issue-id">#{item.id.slice(0, 7)}</span>
<span class="issue-date">{new Date(item.created_at * 1000).toLocaleDateString()}</span>
</div>
{#snippet itemRenderer({ item })}
<div class="issue-item-content">
<div class="issue-subject">{item.subject}</div>
<div class="issue-meta">
<span class="issue-id">#{item.id.slice(0, 7)}</span>
<span class="issue-date">{new Date(item.created_at * 1000).toLocaleDateString()}</span>
</div>
{/snippet}
</div>
{/snippet}
{#snippet detailRenderer({ item })}
{#snippet detailRenderer({ item })}
<div class="issue-detail">
<div class="issue-detail-header">
<h2>{item.subject}</h2>
@ -103,8 +91,22 @@ @@ -103,8 +91,22 @@
</div>
{/if}
</div>
{/snippet}
</StatusTabLayout>
{/snippet}
<StatusTabLayout
{items}
{selectedId}
{loading}
{error}
{onSelect}
statusGroups={[
{ label: 'Open', value: 'open' },
{ label: 'Closed', value: 'closed' },
{ label: 'Resolved', value: 'resolved' }
]}
{itemRenderer}
{detailRenderer}
/>
<style>
.issue-item-content {

86
src/routes/repos/[npub]/[repo]/components/PRsTab.svelte

@ -42,6 +42,47 @@ @@ -42,6 +42,47 @@
const selectedId = $derived(selectedPR);
</script>
{#snippet itemRenderer({ item })}
<div class="pr-item-content">
<div class="pr-subject">{item.subject}</div>
<div class="pr-meta">
<span class="pr-id">#{item.id.slice(0, 7)}</span>
{#if item.commitId}
<span class="pr-commit">Commit: {item.commitId.slice(0, 7)}</span>
{/if}
<span class="pr-date">{new Date(item.created_at * 1000).toLocaleDateString()}</span>
</div>
</div>
{/snippet}
{#snippet detailRenderer({ item })}
<div class="pr-detail">
<div class="pr-detail-header">
<h2>{item.subject}</h2>
<div class="pr-actions">
<select
value={item.status}
onchange={(e) => onStatusUpdate(item.id, (e.target as HTMLSelectElement).value)}
>
<option value="open">Open</option>
<option value="closed">Closed</option>
<option value="merged">Merged</option>
</select>
</div>
</div>
<div class="pr-content">
{@html item.content || 'No content'}
</div>
{#if item.commitId}
<div class="pr-commit-info">
<strong>Commit:</strong> {item.commitId}
</div>
{/if}
</div>
{/snippet}
<StatusTabLayout
{items}
{selectedId}
@ -53,48 +94,9 @@ @@ -53,48 +94,9 @@
{ label: 'Closed', value: 'closed' },
{ label: 'Merged', value: 'merged' }
]}
>
{#snippet itemRenderer({ item })}
<div class="pr-item-content">
<div class="pr-subject">{item.subject}</div>
<div class="pr-meta">
<span class="pr-id">#{item.id.slice(0, 7)}</span>
{#if item.commitId}
<span class="pr-commit">Commit: {item.commitId.slice(0, 7)}</span>
{/if}
<span class="pr-date">{new Date(item.created_at * 1000).toLocaleDateString()}</span>
</div>
</div>
{/snippet}
{#snippet detailRenderer({ item })}
<div class="pr-detail">
<div class="pr-detail-header">
<h2>{item.subject}</h2>
<div class="pr-actions">
<select
value={item.status}
onchange={(e) => onStatusUpdate(item.id, (e.target as HTMLSelectElement).value)}
>
<option value="open">Open</option>
<option value="closed">Closed</option>
<option value="merged">Merged</option>
</select>
</div>
</div>
<div class="pr-content">
{@html item.content || 'No content'}
</div>
{#if item.commitId}
<div class="pr-commit-info">
<strong>Commit:</strong> {item.commitId}
</div>
{/if}
</div>
{/snippet}
</StatusTabLayout>
{itemRenderer}
{detailRenderer}
/>
<style>
.pr-item-content {

70
src/routes/repos/[npub]/[repo]/components/PatchesTab.svelte

@ -43,6 +43,39 @@ @@ -43,6 +43,39 @@
const selectedId = $derived(selectedPatch);
</script>
{#snippet itemRenderer({ item })}
<div class="patch-item-content">
<div class="patch-subject">{item.subject}</div>
<div class="patch-meta">
<span class="patch-id">#{item.id.slice(0, 7)}</span>
<span class="patch-date">{new Date(item.created_at * 1000).toLocaleDateString()}</span>
</div>
</div>
{/snippet}
{#snippet detailRenderer({ item })}
<div class="patch-detail">
<div class="patch-detail-header">
<h2>{item.subject}</h2>
<div class="patch-actions">
{#if item.status === 'open'}
<button
onclick={() => onApply(item.id)}
disabled={applying[item.id]}
class="apply-button"
>
{applying[item.id] ? 'Applying...' : 'Apply Patch'}
</button>
{/if}
</div>
</div>
<div class="patch-content">
<pre><code>{item.content}</code></pre>
</div>
</div>
{/snippet}
<StatusTabLayout
{items}
{selectedId}
@ -54,40 +87,9 @@ @@ -54,40 +87,9 @@
{ label: 'Applied', value: 'applied' },
{ label: 'Rejected', value: 'rejected' }
]}
>
{#snippet itemRenderer({ item })}
<div class="patch-item-content">
<div class="patch-subject">{item.subject}</div>
<div class="patch-meta">
<span class="patch-id">#{item.id.slice(0, 7)}</span>
<span class="patch-date">{new Date(item.created_at * 1000).toLocaleDateString()}</span>
</div>
</div>
{/snippet}
{#snippet detailRenderer({ item })}
<div class="patch-detail">
<div class="patch-detail-header">
<h2>{item.subject}</h2>
<div class="patch-actions">
{#if item.status === 'open'}
<button
onclick={() => onApply(item.id)}
disabled={applying[item.id]}
class="apply-button"
>
{applying[item.id] ? 'Applying...' : 'Apply Patch'}
</button>
{/if}
</div>
</div>
<div class="patch-content">
<pre><code>{item.content}</code></pre>
</div>
</div>
{/snippet}
</StatusTabLayout>
{itemRenderer}
{detailRenderer}
/>
<style>
.patch-item-content {

26
src/routes/repos/[npub]/[repo]/components/StatusTabLayout.svelte

@ -18,6 +18,8 @@ @@ -18,6 +18,8 @@
error?: string | null;
onSelect?: (id: string) => void;
statusGroups?: Array<{ label: string; value: string }>;
itemRenderer?: import('svelte').Snippet<[{ item: { id: string; title: string; status: string; [key: string]: any } }]>;
detailRenderer?: import('svelte').Snippet<[{ item: { id: string; title: string; status: string; [key: string]: any } }]>;
}
let {
@ -29,7 +31,9 @@ @@ -29,7 +31,9 @@
statusGroups = [
{ label: 'Open', value: 'open' },
{ label: 'Closed', value: 'closed' }
]
],
itemRenderer,
detailRenderer
}: Props = $props();
let selectedItem = $derived(items.find(item => item.id === selectedId) || null);
@ -65,12 +69,22 @@ @@ -65,12 +69,22 @@
{#each grouped[value] as item}
<div
class="item {selectedId === item.id ? 'selected' : ''}"
role="button"
tabindex="0"
onclick={() => onSelect(item.id)}
onkeydown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
onSelect(item.id);
}
}}
>
<slot name="itemRenderer" {item}>
{#if itemRenderer}
{@render itemRenderer({ item })}
{:else}
<div class="item-title">{item.title}</div>
<div class="item-meta">#{item.id.slice(0, 7)}</div>
</slot>
{/if}
</div>
{/each}
</div>
@ -82,12 +96,14 @@ @@ -82,12 +96,14 @@
{#snippet rightPanel()}
{#if selectedItem}
<slot name="detailRenderer" item={selectedItem}>
{#if detailRenderer}
{@render detailRenderer({ item: selectedItem })}
{:else}
<div class="detail-view">
<h2>{selectedItem.title}</h2>
<pre>{JSON.stringify(selectedItem, null, 2)}</pre>
</div>
</slot>
{/if}
{/if}
{/snippet}
</TabLayout>

Loading…
Cancel
Save