Browse Source

bug-fixes

master
Silberengel 4 weeks ago
parent
commit
aa64a9d413
  1. 24
      internal/nostr/wiki.go
  2. 301
      static/css/main.css
  3. 17
      templates/base.html
  4. 2
      templates/blog.html
  5. 4
      templates/components.html
  6. 36
      templates/contact.html
  7. 18
      templates/ebooks.html
  8. 34
      templates/landing.html

24
internal/nostr/wiki.go

@ -137,9 +137,17 @@ func (ws *WikiService) FetchWikiEvents(ctx context.Context, index *IndexEvent) ( @@ -137,9 +137,17 @@ func (ws *WikiService) FetchWikiEvents(ctx context.Context, index *IndexEvent) (
}
}
// Convert matched events to wiki events
// Convert matched events to wiki events, preserving order from index.Items
var wikiEvents []*WikiEvent
for key, event := range eventMap {
for _, item := range index.Items {
if item.Kind != ws.wikiKind {
continue
}
key := fmt.Sprintf("%d:%s:%s", item.Kind, item.Pubkey, item.DTag)
event, exists := eventMap[key]
if !exists {
continue
}
wiki, err := ParseWikiEvent(event, ws.wikiKind)
if err != nil {
logger.WithFields(map[string]interface{}{
@ -292,9 +300,17 @@ func (ws *WikiService) FetchIndexEvents(ctx context.Context, index *IndexEvent, @@ -292,9 +300,17 @@ func (ws *WikiService) FetchIndexEvents(ctx context.Context, index *IndexEvent,
}
}
// Convert to result slice
// Convert to result slice, preserving order from index.Items
events := make([]*nostr.Event, 0, len(eventMap))
for _, event := range eventMap {
for _, item := range index.Items {
if item.Kind != targetKind {
continue
}
key := fmt.Sprintf("%d:%s:%s", item.Kind, item.Pubkey, item.DTag)
event, exists := eventMap[key]
if !exists {
continue
}
events = append(events, event)
}

301
static/css/main.css

@ -45,19 +45,18 @@ body { @@ -45,19 +45,18 @@ body {
flex-direction: column;
margin: 0;
padding: 0;
padding-top: 80px; /* Space for fixed header */
}
/* Skip link for accessibility */
.skip-link {
position: fixed;
position: absolute;
top: -40px;
left: 0;
background: var(--accent-color);
color: var(--bg-primary);
padding: 8px;
text-decoration: none;
z-index: 1001; /* Above fixed header */
z-index: 1001;
}
.skip-link:focus {
@ -68,16 +67,10 @@ body { @@ -68,16 +67,10 @@ body {
header {
background-color: var(--bg-secondary);
border-bottom: 1px solid var(--border-color);
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
z-index: 1000;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin: 0;
padding: 0;
will-change: transform; /* Optimize for fixed positioning */
}
.navbar {
@ -130,6 +123,8 @@ header { @@ -130,6 +123,8 @@ header {
margin: 0;
padding: 0;
list-style: none;
display: flex;
align-items: center;
}
.nav-menu a {
@ -140,6 +135,7 @@ header { @@ -140,6 +135,7 @@ header {
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0;
line-height: 1.2;
}
.nav-menu a:hover {
@ -357,12 +353,12 @@ a:focus { @@ -357,12 +353,12 @@ a:focus {
display: inline-block;
padding: 0.75rem 1.5rem;
background: var(--accent-color);
color: var(--bg-primary);
color: #ffffff;
border: none;
border-radius: 4px;
cursor: pointer;
text-decoration: none;
font-weight: 500;
font-weight: 600;
transition: background 0.2s;
}
@ -384,6 +380,144 @@ a:focus { @@ -384,6 +380,144 @@ a:focus {
outline-offset: var(--focus-offset);
}
/* Landing Page Styles */
.landing-page {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.landing-page .hero {
text-align: center;
margin-bottom: 3rem;
padding: 2rem 0;
}
.landing-page .hero h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
}
.landing-page .hero .lead {
font-size: 1.25rem;
color: var(--text-secondary);
max-width: 600px;
margin: 0 auto;
}
.landing-page .feed-section {
margin: 2rem 0;
max-width: 100%;
}
.landing-page .feed-section .feed-container {
max-width: 100%;
margin: 0 auto;
}
.landing-page .features {
margin-top: 3rem;
}
.landing-page .features h2 {
text-align: center;
margin-bottom: 2rem;
font-size: 2rem;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.feature-card {
background: var(--bg-secondary);
padding: 2rem;
border-radius: 8px;
border: 1px solid var(--border-color);
display: flex;
flex-direction: column;
}
.feature-card h3 {
margin-bottom: 1rem;
font-size: 1.25rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.feature-card p {
margin-bottom: 1.5rem;
color: var(--text-secondary);
flex-grow: 1;
}
.feature-card ul {
list-style: none;
margin: 0;
padding: 0;
margin-bottom: 1.5rem;
}
.feature-card ul li {
margin-bottom: 0.5rem;
}
.feature-card ul li a {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--link-color);
text-decoration: none;
}
.feature-card ul li a:hover {
color: var(--link-hover);
text-decoration: underline;
}
/* Wiki Links Grid */
.feature-card .wiki-links {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-bottom: 1.5rem;
}
.feature-card .wiki-link {
display: inline-block;
padding: 0.5rem 1rem;
background: var(--bg-primary);
color: var(--text-primary);
text-decoration: none;
border-radius: 6px;
border: 1px solid var(--border-color);
font-size: 0.9rem;
transition: all 0.2s;
white-space: nowrap;
}
.feature-card .wiki-link:hover {
background: var(--accent-color);
color: #ffffff;
border-color: var(--accent-color);
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.feature-card .wiki-link:focus-visible {
outline: var(--focus-outline);
outline-offset: var(--focus-offset);
}
.feature-card .btn {
margin-top: auto;
align-self: flex-start;
}
/* Articles and Pages */
article {
background: var(--bg-secondary);
@ -818,6 +952,136 @@ textarea:focus-visible { @@ -818,6 +952,136 @@ textarea:focus-visible {
padding: 2rem;
}
.contact-links {
margin-bottom: 2rem;
padding: 1rem;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
}
.contact-links h2 {
margin-top: 0;
margin-bottom: 1rem;
font-size: 1.2rem;
color: var(--text-primary);
}
.contact-links ul {
list-style: none;
padding: 0;
margin: 0;
}
.contact-links li {
margin-bottom: 0.5rem;
}
.contact-links a {
color: var(--link-color);
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
transition: color 0.2s;
}
.contact-links a:hover {
color: var(--link-hover);
text-decoration: underline;
}
.contact-links a:focus-visible {
outline: var(--focus-outline);
outline-offset: var(--focus-offset);
border-radius: 2px;
}
.nostr-profile {
margin-bottom: 2rem;
padding: 1rem;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
}
.nostr-profile h2 {
margin-top: 0;
margin-bottom: 1rem;
font-size: 1.2rem;
color: var(--text-primary);
}
.nostr-profile-content {
display: flex;
gap: 1rem;
align-items: flex-start;
}
.nostr-profile-picture {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
border: 2px solid var(--border-color);
}
.nostr-profile-info {
flex: 1;
}
.nostr-profile-info h3 {
margin: 0 0 0.5rem 0;
font-size: 1.1rem;
color: var(--text-primary);
}
.nostr-profile-name {
margin: 0 0 0.5rem 0;
color: var(--text-secondary);
font-size: 0.9rem;
}
.nostr-profile-about {
margin: 0 0 0.5rem 0;
color: var(--text-primary);
white-space: pre-wrap;
line-height: 1.6;
}
.nostr-profile-website {
margin: 0.5rem 0 0 0;
}
.nostr-profile-website a {
color: var(--link-color);
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
transition: color 0.2s;
}
.nostr-profile-website a:hover {
color: var(--link-hover);
text-decoration: underline;
}
.nostr-profile-website a:focus-visible {
outline: var(--focus-outline);
outline-offset: var(--focus-offset);
border-radius: 2px;
}
.nostr-profile-nip05 {
margin: 0.5rem 0 0 0;
color: var(--text-secondary);
font-size: 0.9rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.contact-form {
margin-top: 2rem;
}
@ -896,7 +1160,7 @@ textarea:focus-visible { @@ -896,7 +1160,7 @@ textarea:focus-visible {
.btn-primary {
background: var(--accent-color);
color: var(--bg-primary);
color: #ffffff;
}
.btn-primary:hover {
@ -1034,7 +1298,9 @@ textarea:focus-visible { @@ -1034,7 +1298,9 @@ textarea:focus-visible {
/* Icon styles for Lucide icons */
.icon-inline {
display: inline-block;
display: inline-flex;
align-items: center;
justify-content: center;
width: 1em;
height: 1em;
vertical-align: middle;
@ -1042,6 +1308,12 @@ textarea:focus-visible { @@ -1042,6 +1308,12 @@ textarea:focus-visible {
flex-shrink: 0;
}
.nav-menu .icon-inline {
margin-right: 0;
width: 1.2em;
height: 1.2em;
}
/* User Badge Styles */
.user-badge {
display: inline-flex;
@ -1106,8 +1378,9 @@ p.icon-inline, h1.icon-inline, h2.icon-inline, h3.icon-inline, h4.icon-inline, h @@ -1106,8 +1378,9 @@ p.icon-inline, h1.icon-inline, h2.icon-inline, h3.icon-inline, h4.icon-inline, h
display: inline-flex;
}
/* Navigation links should be flex */
/* Navigation links should be flex with proper alignment */
.nav-menu a, .dropdown-menu a, .wiki-menu a {
align-items: center;
display: inline-flex;
align-items: center;
gap: 0.5rem;

17
templates/base.html

@ -48,18 +48,11 @@ @@ -48,18 +48,11 @@
<ul class="nav-menu">
<li><a href="/"><span class="icon-inline">{{icon "home"}}</span> Home</a></li>
<li><a href="/wiki"><span class="icon-inline">{{icon "book-open"}}</span> The Project</a></li>
<li class="dropdown">
<a href="/blog" class="dropdown-toggle"><span class="icon-inline">{{icon "file-text"}}</span> Blog</a>
<ul class="dropdown-menu">
{{range .BlogItems}}
<li><a href="/blog#{{.DTag}}"><span class="icon-inline">{{icon "file-text"}}</span> {{.Title}}</a></li>
{{end}}
</ul>
</li>
<li><a href="/articles"><span class="icon-inline">{{icon "file-text"}}</span> Articles</a></li>
<li><a href="/ebooks"><span class="icon-inline">{{icon "book"}}</span> E-Books</a></li>
<li><a href="/contact"><span class="icon-inline">{{icon "mail"}}</span> Contact</a></li>
<li><a href="/wiki"><span class="icon-inline">{{icon "book-open"}}</span> Project Wiki</a></li>
<li><a href="/blog"><span class="icon-inline">{{icon "file-text"}}</span> Project Blog</a></li>
<li><a href="/articles"><span class="icon-inline">{{icon "file-text"}}</span> TheForest Articles</a></li>
<li><a href="/ebooks"><span class="icon-inline">{{icon "book"}}</span> TheForest E-Books</a></li>
<li><a href="/contact"><span class="icon-inline">{{icon "mail"}}</span> Contact Us</a></li>
</ul>
</div>
</nav>

2
templates/blog.html

@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
{{end}}
<h1 class="blog-title">{{if .BlogIndexTitle}}{{.BlogIndexTitle}}{{else}}Blog{{end}}</h1>
{{if .BlogIndexAuthor}}
<p class="blog-byline">by {{.BlogIndexAuthor}}</p>
<p class="blog-byline">by {{template "user-badge-simple" (dict "Pubkey" .BlogIndexAuthor "Profiles" $.Profiles)}}</p>
{{end}}
{{if .BlogIndexSummary}}
<p class="blog-description">{{.BlogIndexSummary}}</p>

4
templates/components.html

@ -37,9 +37,9 @@ @@ -37,9 +37,9 @@
{{/* Wiki Sidebar Component - Reusable wiki navigation */}}
{{define "wiki-sidebar"}}
<aside class="wiki-sidebar" aria-label="The Project navigation">
<aside class="wiki-sidebar" aria-label="Project Wiki navigation">
<nav class="wiki-nav">
<h2><span class="icon-inline">{{icon "book-open"}}</span> The Project</h2>
<h2><span class="icon-inline">{{icon "book-open"}}</span> Project Wiki</h2>
<ul class="wiki-menu">
<li><a href="/wiki"{{if eq .CanonicalURL (printf "%s/wiki" .SiteURL)}} class="active"{{end}}><span class="icon-inline">{{icon "info"}}</span> Project Overview</a></li>
{{range .WikiPages}}

36
templates/contact.html

@ -2,16 +2,16 @@ @@ -2,16 +2,16 @@
<article class="contact-page">
<h1>Contact Us</h1>
<div class="contact-links" style="margin-bottom: 2rem; padding: 1rem; background: #f5f5f5; border-radius: 8px;">
<h2 style="margin-top: 0; font-size: 1.2rem;">Find us elsewhere:</h2>
<ul style="list-style: none; padding: 0; margin: 0;">
<li style="margin-bottom: 0.5rem;">
<a href="https://aitherboard.imwald.eu/repos/naddr1qvzqqqrhnypzplfq3m5v3u5r0q9f255fdeyz8nyac6lagssx8zy4wugxjs8ajf7pqq9xw6t5vd5hgctyv4kqde47kt?tab=about" target="_blank" rel="noopener noreferrer" style="color: #0066cc; text-decoration: none; display: inline-flex; align-items: center; gap: 0.5rem;">
<div class="contact-links">
<h2>Find us elsewhere:</h2>
<ul>
<li>
<a href="https://aitherboard.imwald.eu/repos/naddr1qvzqqqrhnypzplfq3m5v3u5r0q9f255fdeyz8nyac6lagssx8zy4wugxjs8ajf7pqq9xw6t5vd5hgctyv4kqde47kt?tab=about" target="_blank" rel="noopener noreferrer">
<span class="icon-inline">{{icon "package"}}</span> Aitherboard Repository
</a>
</li>
<li style="margin-bottom: 0.5rem;">
<a href="https://github.com/ShadowySupercode" target="_blank" rel="noopener noreferrer" style="color: #0066cc; text-decoration: none; display: inline-flex; align-items: center; gap: 0.5rem;">
<li>
<a href="https://github.com/ShadowySupercode" target="_blank" rel="noopener noreferrer">
<span class="icon-inline">{{icon "github"}}</span> GitHub: ShadowySupercode
</a>
</li>
@ -19,31 +19,31 @@ @@ -19,31 +19,31 @@
</div>
{{if .Profile}}
<div class="nostr-profile" style="margin-bottom: 2rem; padding: 1rem; background: #f9f9f9; border-radius: 8px; border: 1px solid #ddd;">
<h2 style="margin-top: 0; font-size: 1.2rem;">Nostr Profile</h2>
<div style="display: flex; gap: 1rem; align-items: flex-start;">
<div class="nostr-profile">
<h2>Nostr Profile</h2>
<div class="nostr-profile-content">
{{if .Profile.Picture}}
<img src="{{.Profile.Picture}}" alt="Profile picture" style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover;">
<img src="{{.Profile.Picture}}" alt="Profile picture" class="nostr-profile-picture">
{{end}}
<div style="flex: 1;">
<h3 style="margin: 0 0 0.5rem 0; font-size: 1.1rem;">
<div class="nostr-profile-info">
<h3>
{{if .Profile.DisplayName}}{{.Profile.DisplayName}}{{else if .Profile.Name}}{{.Profile.Name}}{{else}}Anonymous{{end}}
</h3>
{{if .Profile.Name}}
<p style="margin: 0 0 0.5rem 0; color: #666; font-size: 0.9rem;">@{{.Profile.Name}}</p>
<p class="nostr-profile-name">@{{.Profile.Name}}</p>
{{end}}
{{if .Profile.About}}
<p style="margin: 0 0 0.5rem 0; white-space: pre-wrap;">{{.Profile.About}}</p>
<p class="nostr-profile-about">{{.Profile.About}}</p>
{{end}}
{{if .Profile.Website}}
<p style="margin: 0.5rem 0 0 0;">
<a href="{{.Profile.Website}}" target="_blank" rel="noopener noreferrer" style="color: #0066cc; text-decoration: none; display: inline-flex; align-items: center; gap: 0.5rem;">
<p class="nostr-profile-website">
<a href="{{.Profile.Website}}" target="_blank" rel="noopener noreferrer">
<span class="icon-inline">{{icon "globe"}}</span> Website
</a>
</p>
{{end}}
{{if .Profile.NIP05}}
<p style="margin: 0.5rem 0 0 0; color: #666; font-size: 0.9rem; display: flex; align-items: center; gap: 0.5rem;">
<p class="nostr-profile-nip05">
<span class="icon-inline">{{icon "check-circle"}}</span> NIP-05: {{.Profile.NIP05}}
</p>
{{end}}

18
templates/ebooks.html

@ -11,9 +11,6 @@ @@ -11,9 +11,6 @@
<tr>
<th data-sort="title" class="sortable">Title <span class="sort-indicator"></span></th>
<th data-sort="author" class="sortable">Author <span class="sort-indicator"></span></th>
<th data-sort="type" class="sortable">Type <span class="sort-indicator"></span></th>
<th data-sort="created" class="sortable">Created <span class="sort-indicator"></span></th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@ -22,19 +19,15 @@ @@ -22,19 +19,15 @@
<td>
<strong>{{.Title}}</strong>
{{if .Summary}}<br><small class="text-muted">{{.Summary}}</small>{{end}}
<div style="margin-top: 0.75rem;">
<a href="https://alexandria.gitcitadel.eu/publication/naddr/{{.Naddr}}" target="_blank" rel="noopener noreferrer" class="btn btn-sm"><span class="icon-inline">{{icon "external-link"}}</span> View on Alexandria</a>
</div>
</td>
<td>{{template "user-badge-simple" (dict "Pubkey" .Author "Profiles" $.Profiles)}}</td>
<td>{{if .Type}}{{.Type}}{{else}}—{{end}}</td>
<td>
<time datetime="{{.TimeISO}}">{{.Time}}</time>
</td>
<td>
<a href="https://alexandria.gitcitadel.eu/publication/naddr/{{.Naddr}}" target="_blank" rel="noopener noreferrer" class="btn btn-sm"><span class="icon-inline">{{icon "external-link"}}</span> View</a>
</td>
</tr>
{{else}}
<tr>
<td colspan="5" class="text-center"><span class="icon-inline">{{icon "book-x"}}</span> No e-books found.</td>
<td colspan="2" class="text-center"><span class="icon-inline">{{icon "book-x"}}</span> No e-books found.</td>
</tr>
{{end}}
</tbody>
@ -76,9 +69,6 @@ @@ -76,9 +69,6 @@
if (column === 'title') {
aVal = aCell.querySelector('strong')?.textContent || '';
bVal = bCell.querySelector('strong')?.textContent || '';
} else if (column === 'created') {
aVal = aCell.querySelector('time')?.getAttribute('datetime') || '';
bVal = bCell.querySelector('time')?.getAttribute('datetime') || '';
} else {
aVal = aCell.textContent.trim();
bVal = bCell.textContent.trim();

34
templates/landing.html

@ -5,30 +5,48 @@ @@ -5,30 +5,48 @@
<p class="lead">Your gateway to decentralized knowledge and community-driven content.</p>
</section>
{{if .FeedItems}}
<section class="feed-section">
{{template "feed" .}}
</section>
{{end}}
<section class="features">
<h2>Explore Our Content</h2>
<div class="feature-grid">
<div class="feature-card">
<h3><span class="icon-inline">{{icon "book-open"}}</span> Wiki</h3>
<p>Browse our comprehensive wiki documentation.</p>
<ul>
<h3><span class="icon-inline">{{icon "book-open"}}</span> Project Wiki</h3>
<p>Browse our comprehensive wiki documentation and GitCitadel project information.</p>
<div class="wiki-links">
{{range .WikiPages}}
<li><a href="/wiki/{{.DTag}}"><span class="icon-inline">{{icon "file-text"}}</span> {{.Title}}</a></li>
<a href="/wiki/{{.DTag}}" class="wiki-link">{{.Title}}</a>
{{end}}
</ul>
</div>
</div>
<div class="feature-card">
<h3><span class="icon-inline">{{icon "file-text"}}</span> Blog</h3>
<p>Read the latest articles and updates.</p>
<h3><span class="icon-inline">{{icon "file-text"}}</span> Project Blog</h3>
<p>Read the latest articles and updates from the GitCitadel project blog.</p>
<a href="/blog" class="btn"><span class="icon-inline">{{icon "arrow-right"}}</span> View Blog</a>
</div>
<div class="feature-card">
<h3><span class="icon-inline">{{icon "file-text"}}</span> Articles</h3>
<p>Longform markdown articles from the Nostr network.</p>
<p>Longform markdown articles from the TheForest relay.</p>
<a href="/articles" class="btn"><span class="icon-inline">{{icon "arrow-right"}}</span> View Articles</a>
</div>
<div class="feature-card">
<h3><span class="icon-inline">{{icon "book"}}</span> E-Books</h3>
<p>Discover and download e-books from the decentralized #Alexandria library.</p>
<a href="/ebooks" class="btn"><span class="icon-inline">{{icon "arrow-right"}}</span> View E-Books</a>
</div>
<div class="feature-card">
<h3><span class="icon-inline">{{icon "mail"}}</span> Contact</h3>
<p>Have a question, suggestion, or want to report an issue? Get in touch with us.</p>
<a href="/contact" class="btn"><span class="icon-inline">{{icon "arrow-right"}}</span> Contact Us</a>
</div>
</div>
</section>
</article>

Loading…
Cancel
Save