Changeset 8ea3d0d in Klonkt


Ignore:
Timestamp:
06/16/2026 07:35:21 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
04a6b15
Parents:
1578f5d
Message:

Defaults: new sites grid + moderate; Circle page graphical header

(A) New-site defaults aligned with Robin's preference: feed_view_default
'timeline'->'grid' and comments_moderation_mode 'trust'->'moderate'. Set in
column defaults (fresh installs), siteEditableFields + createSite INSERT,
and ensurePrimarySite. Other defaults were already correct (public/index/
audio/switcher/search/archive on, login-to-comment off).
(B) /circle header redesigned: centred, graphical "connected circles"
motif in accent colour + chips with the avatars/names of the synced circle
sites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@…>

Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/config/database.js

    r1578f5d r8ea3d0d  
    4444  ensureColumn('users', 'readonly', 'INTEGER DEFAULT 0');
    4545  // Site-level moderation toggle. 'trust' = auto-approve, 'moderate' = pending until reviewed.
    46   ensureColumn('sites', 'comments_moderation_mode', "TEXT DEFAULT 'trust'");
     46  ensureColumn('sites', 'comments_moderation_mode', "TEXT DEFAULT 'moderate'");
    4747  // Per-site Prutter toggle: when off, DM endpoints/UI are hidden for that site.
    4848  ensureColumn('sites', 'enable_prutter', 'INTEGER DEFAULT 1');
     
    6262  ensureColumn('sites', 'profile_bio',     'TEXT');     // short bio for header
    6363  ensureColumn('sites', 'profile_links',   'TEXT');     // JSON array [{platform, url}]
    64   ensureColumn('sites', 'feed_view_default', "TEXT DEFAULT 'timeline'"); // timeline | grid
     64  ensureColumn('sites', 'feed_view_default', "TEXT DEFAULT 'grid'"); // timeline | grid
    6565  ensureColumn('sites', 'feed_view_switch',  'INTEGER DEFAULT 1');       // show switcher
    6666  ensureColumn('sites', 'show_search',     'INTEGER DEFAULT 1');
  • src/routes/admin-sites.js

    r1578f5d r8ea3d0d  
    119119    enable_audio_player: 1,
    120120    enable_prutter: 1,
    121     feed_view_default: 'timeline',
     121    comments_moderation_mode: 'moderate',
     122    feed_view_default: 'grid',
    122123    feed_view_switch: 1,
    123124    show_search: 1,
     
    191192      id, slug, title, description, tagline, owner_id,
    192193      language, palette, accent, profile_photo,
    193       is_public, robots_index, require_login_to_comment, enable_audio_player
    194     ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
     194      is_public, robots_index, require_login_to_comment, enable_audio_player,
     195      feed_view_default, comments_moderation_mode
     196    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    195197  `).run(
    196198    siteId, slug,
     
    207209    f.require_login_to_comment ? 1 : 0,
    208210    (f.enable_audio_player !== undefined ? (f.enable_audio_player ? 1 : 0) : 1),
     211    f.feed_view_default === 'timeline' ? 'timeline' : 'grid',
     212    f.comments_moderation_mode === 'trust' ? 'trust' : 'moderate',
    209213  );
    210214
  • src/routes/circle.js

    r1578f5d r8ea3d0d  
    5858  });
    5959
    60   renderPage(req, res, 'pages/circle-feed', { pageTitle: 'Cirkel', bodyClass: 'on-cirkel', posts });
     60  // Sites in de cirkel (alleen succesvol gesyncte = proto-compatibel) — voor de
     61  // grafische header met avatars.
     62  const sites = db.prepare('SELECT name, url, avatar FROM remote_actors ORDER BY name')
     63    .all()
     64    .map((s) => ({
     65      name: s.name || 'Onbekend',
     66      url: safeUrl(s.url),
     67      avatar: safeUrl(s.avatar),
     68    }));
     69
     70  renderPage(req, res, 'pages/circle-feed', { pageTitle: 'Cirkel', bodyClass: 'on-cirkel', posts, sites });
    6171});
    6272
  • src/services/ensurePrimarySite.js

    r1578f5d r8ea3d0d  
    3939      id, slug, title, description, tagline, owner_id,
    4040      language, palette, accent, profile_photo,
    41       is_public, robots_index, require_login_to_comment, enable_audio_player
    42     ) VALUES (?, ?, ?, '', '', ?, 'nl', 'sage', '#c2410c', NULL, 1, 1, 0, 1)
     41      is_public, robots_index, require_login_to_comment, enable_audio_player,
     42      feed_view_default, comments_moderation_mode
     43    ) VALUES (?, ?, ?, '', '', ?, 'nl', 'sage', '#c2410c', NULL, 1, 1, 0, 1, 'grid', 'moderate')
    4344  `).run(siteId, slug, defaultTitle(), owner.id);
    4445
  • src/views/pages/circle-feed.ejs

    r1578f5d r8ea3d0d  
    1 <div class="container cirkel-head">
     1<div class="container cirkel-hero">
     2  <span class="cirkel-badge" aria-hidden="true">
     3    <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
     4      <line x1="32" y1="16" x2="17" y2="45"/>
     5      <line x1="32" y1="16" x2="47" y2="45"/>
     6      <line x1="17" y1="45" x2="47" y2="45"/>
     7      <circle cx="32" cy="16" r="8" fill="currentColor" fill-opacity=".16"/>
     8      <circle cx="17" cy="45" r="8" fill="currentColor" fill-opacity=".16"/>
     9      <circle cx="47" cy="45" r="8" fill="currentColor" fill-opacity=".16"/>
     10    </svg>
     11  </span>
    212  <h1>Cirkel</h1>
    313  <p class="cirkel-sub">Wat er speelt bij de andere sites in mijn cirkel.</p>
     14  <% if (typeof sites !== 'undefined' && sites && sites.length) { %>
     15    <div class="cirkel-members">
     16      <% sites.forEach(function(s){ %>
     17        <% if (s.url) { %><a class="cirkel-member" href="<%= s.url %>" target="_blank" rel="noopener" title="<%= s.name %>"><% } else { %><span class="cirkel-member" title="<%= s.name %>"><% } %>
     18          <span class="cirkel-avatar"<% if (s.avatar) { %> style="background-image:url('<%= s.avatar %>')"<% } %>><% if (!s.avatar) { %><%= (s.name || '?').charAt(0).toUpperCase() %><% } %></span>
     19          <span class="cirkel-member-name"><%= s.name %></span>
     20        <% if (s.url) { %></a><% } else { %></span><% } %>
     21      <% }); %>
     22    </div>
     23  <% } %>
    424</div>
    525
     
    3757
    3858<style>
    39 .cirkel-head { margin-top: 2rem; }
    40 .cirkel-head h1 { font-family: var(--font-display, serif); font-size: 2rem; margin: 0 0 .25rem; }
    41 .cirkel-sub { color: var(--ink-muted); margin: 0 0 1.5rem; }
    42 .cirkel-empty { color: var(--ink-muted); }
     59.cirkel-hero { text-align: center; max-width: 640px; margin: 2.5rem auto 2rem; }
     60.cirkel-badge { display: block; width: 60px; height: 60px; margin: 0 auto .6rem; color: var(--accent); }
     61.cirkel-badge svg { width: 100%; height: 100%; }
     62.cirkel-hero h1 { font-family: var(--font-display, serif); font-size: 2.4rem; margin: 0 0 .3rem; }
     63.cirkel-sub { color: var(--ink-muted); margin: 0 0 1.25rem; font-size: 1.02rem; }
     64.cirkel-members { display: flex; flex-wrap: wrap; gap: .55rem; justify-content: center; }
     65.cirkel-member { display: inline-flex; align-items: center; gap: .45rem;
     66  padding: .28rem .8rem .28rem .3rem; border: 1px solid var(--rule); border-radius: 999px;
     67  text-decoration: none; color: var(--ink); background: var(--paper-2);
     68  transition: border-color .15s, transform .15s; }
     69.cirkel-member:hover { border-color: var(--accent); transform: translateY(-1px); }
     70.cirkel-avatar { width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
     71  background-size: cover; background-position: center; background-color: var(--accent);
     72  color: #fff; display: inline-flex; align-items: center; justify-content: center;
     73  font-weight: 700; font-size: .82rem; }
     74.cirkel-member-name { font-size: .9rem; font-weight: 600; }
     75.cirkel-empty { color: var(--ink-muted); text-align: center; margin: 2rem auto; }
    4376.cirkel-empty a { color: var(--accent); }
    4477</style>
Note: See TracChangeset for help on using the changeset viewer.