base.layout.tmpl

  1{{define "base"}}
  2<!doctype html>
  3<html lang="en">
  4  <head>
  5    <meta charset='utf-8'>
  6    <meta name="viewport" content="width=device-width, initial-scale=1" />
  7    <title>{{template "title" .}}</title>
  8    <meta name="keywords" content="git code forge repo repository" />
  9    {{template "meta" .}}
 10    <style>
 11      /* Critical CSS - inlined to prevent FOUC */
 12      :root {
 13        --line-height: 1.3rem;
 14        --grid-height: 0.65rem;
 15        --bg-color: #282a36;
 16        --text-color: #f8f8f2;
 17        --border: #6272a4;
 18        --link-color: #8be9fd;
 19        --hover: #ff79c6;
 20        --visited: #8be9fd;
 21        --white: #f2f2f2;
 22        --white-light: #f2f2f2;
 23        --white-dark: #e8e8e8;
 24        --grey: #414558;
 25        --grey-light: #6a708e;
 26        --code: #414558;
 27        --pre: #252525;
 28        --blockquote: #bd93f9;
 29        --blockquote-bg: #353548;
 30        --text-red: #ff5555;
 31        --text-green: #50fa7b;
 32      }
 33      html {
 34        background-color: var(--bg-color);
 35        color: var(--text-color);
 36        font-size: 16px;
 37        line-height: var(--line-height);
 38        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
 39        -webkit-text-size-adjust: 100%;
 40        -moz-tab-size: 4;
 41        tab-size: 4;
 42      }
 43      body {
 44        margin: 0 auto;
 45        max-width: 900px;
 46      }
 47      *, ::before, ::after { box-sizing: border-box; }
 48    </style>
 49    <link rel="stylesheet" href="{{.Repo.RootRelative}}{{.Repo.CSSFile}}">
 50  </head>
 51  <body hx-boost="true" hx-swap="innerHTML transition:true">
 52    <header>{{template "header" .}}</header>
 53    <main>{{template "content" .}}</main>
 54    <hr />
 55    <footer>{{template "footer" .}}</footer>
 56    <script>
 57    (function() {
 58      var MINUTE_MS = 60000;
 59      var HOUR_MS = 3600000;
 60      var DAY_MS = 86400000;
 61      var MONTH_MS = 30 * DAY_MS;
 62
 63      function updateTimes() {
 64        var elements = document.querySelectorAll('[data-time]');
 65        var now = new Date();
 66        var minDiffMs = Infinity;
 67
 68        elements.forEach(function(el) {
 69          var date = new Date(el.getAttribute('data-time'));
 70          var diffMs = now - date;
 71
 72          // Track the smallest difference for interval calculation
 73          if (diffMs < minDiffMs && diffMs >= 0) {
 74            minDiffMs = diffMs;
 75          }
 76
 77          var diffMins = Math.floor(diffMs / MINUTE_MS);
 78          var diffHours = Math.floor(diffMs / HOUR_MS);
 79          var diffDays = Math.floor(diffMs / DAY_MS);
 80
 81          var text;
 82          if (diffMins < 1) {
 83            text = 'just now';
 84          } else if (diffMins < 60) {
 85            text = diffMins + ' minute' + (diffMins === 1 ? '' : 's') + ' ago';
 86          } else if (diffHours < 24) {
 87            text = diffHours + ' hour' + (diffHours === 1 ? '' : 's') + ' ago';
 88          } else if (diffDays < 30) {
 89            text = diffDays + ' day' + (diffDays === 1 ? '' : 's') + ' ago';
 90          } else {
 91            // Keep default MMM dd format (already in element text)
 92            return;
 93          }
 94          el.textContent = text;
 95        });
 96
 97        return minDiffMs;
 98      }
 99
100      function scheduleUpdate() {
101        var minDiffMs = updateTimes();
102        var intervalMs;
103
104        // Determine interval based on smallest time difference
105        if (minDiffMs < HOUR_MS) {
106          // Smallest diff is in minutes - update every minute
107          intervalMs = MINUTE_MS;
108        } else if (minDiffMs < DAY_MS) {
109          // Smallest diff is in hours - update every hour
110          intervalMs = HOUR_MS;
111        } else if (minDiffMs < MONTH_MS) {
112          // Smallest diff is in days - update every day
113          intervalMs = DAY_MS;
114        } else {
115          // All timestamps are > 30 days, no updates needed
116          return;
117        }
118
119        setTimeout(scheduleUpdate, intervalMs);
120      }
121
122      scheduleUpdate();
123    })();
124    </script>
125    <script type="module"
126        src="https://cdn.jsdelivr.net/npm/[email protected]/dist/htmx.esm.min.js"
127        integrity="sha384-PcS7xfab7VmrX3d1pc3sw10FpukcW7k3kZT2sFgm1lti8gAT/ti9n9KEq/qRnfLT"
128        crossorigin="anonymous"></script>
129  </body>
130</html>
131{{end}}