Monorepo for Tangled
tangled.org
1{{ define "title" }}Timeline · Tangled{{ end }}
2
3{{ define "extrameta" }}
4 <meta property="og:title" content="Timeline · Tangled" />
5 <meta property="og:type" content="object" />
6 <meta property="og:url" content="https://tangled.org" />
7 <meta property="og:description" content="The next-generation social coding platform" />
8{{ end }}
9
10{{ define "mainLayout" }}
11<div class="flex-grow flex flex-col">
12 <main class="flex-grow flex flex-col">{{ block "content" . }}{{ end }}</main>
13</div>
14{{ end }}
15
16{{ define "content" }}
17<div id="timeline-grid" class="flex flex-col md:grid md:grid-cols-8 md:items-start">
18
19 <div class="hidden md:flex md:col-span-2 md:flex-col md:gap-4 md:pt-4 md:px-4 md:sticky md:top-0 md:h-screen md:overflow-y-auto md:pb-4">
20 {{ template "timeline/fragments/notifications" . }}
21 {{ template "timeline/fragments/recents" . }}
22 </div>
23
24 <div class="order-2 md:order-none md:col-start-3 md:row-start-1 md:col-span-4">
25 {{ template "timeline/fragments/timeline" . }}
26 </div>
27
28 <div class="order-1 md:order-none flex flex-col gap-4 md:col-start-7 md:row-start-1 md:col-span-2 md:pt-4 md:px-4 md:sticky md:top-0 md:h-screen md:overflow-y-auto md:pb-4">
29 {{ if .ShowNewsletter }}
30 <div id="newsletter-col" class="order-first md:order-last">
31 {{ template "timeline/fragments/newsletterWidget" . }}
32 </div>
33 {{ end }}
34
35 {{ template "timeline/fragments/trending" . }}
36
37 <div class="hidden md:block">
38 {{ template "timeline/fragments/announcements" . }}
39 </div>
40
41 {{ if and .LoggedInUser .VouchSuggestions }}
42 <div class="hidden md:block">
43 {{ template "timeline/fragments/vouchSuggestions" . }}
44 </div>
45 {{ end }}
46 </div>
47</div>
48
49{{ if .ShowNewsletter }}
50<script>
51 (function() {
52 var DISMISS_KEY = 'newsletter-dismissed';
53 var newsletterCol = document.getElementById('newsletter-col');
54 if (!newsletterCol) return;
55
56 // hide removes the widget from the DOM without persisting anything.
57 // Used when this browser's localStorage says we already dismissed in a
58 // past session — the server has already told us .ShowNewsletter is true
59 // (no DB row), so we deliberately do NOT re-POST /newsletter/dismiss
60 // here: that would clobber a 'subscribed' row created from another
61 // device after this localStorage entry was set.
62 function hide() {
63 newsletterCol.remove();
64 }
65
66 // dismiss is the user-initiated path. Persists both locally and (for
67 // logged-in users) server-side so the widget stays hidden on all their
68 // devices.
69 function dismiss() {
70 hide();
71 try { localStorage.setItem(DISMISS_KEY, '1'); } catch (e) {}
72 fetch('/newsletter/dismiss', { method: 'POST', credentials: 'same-origin' })
73 .catch(function () { /* localStorage is the fallback */ });
74 }
75
76 try {
77 if (localStorage.getItem(DISMISS_KEY) === '1') {
78 hide();
79 return;
80 }
81 } catch (e) { /* storage disabled; keep widget visible */ }
82
83 newsletterCol.addEventListener('click', function(e) {
84 if (e.target.closest('[data-newsletter-dismiss]')) dismiss();
85 });
86 })();
87</script>
88{{ end }}
89{{ end }}