Monorepo for Tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview/pages: allow customizing atom feed via checkboxes

uses a bit of js to modify the final link

Signed-off-by: oppiliappan <me@oppi.li>

authored by

oppiliappan and committed by tangled.org 73950bf6 cfbb567c

+118 -6
+1 -6
appview/pages/templates/layouts/repobase.html
··· 125 125 fork 126 126 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 127 127 </a> 128 - <a 129 - class="btn text-sm no-underline hover:no-underline flex items-center gap-2 group" 130 - href="/{{ .RepoInfo.FullName }}/feed.atom"> 131 - {{ i "rss" "size-4" }} 132 - <span class="md:hidden">atom</span> 133 - </a> 128 + {{ template "repo/fragments/feedDropdown" . }} 134 129 </div> 135 130 {{ end }}
+117
appview/pages/templates/repo/fragments/feedDropdown.html
··· 1 + {{ define "repo/fragments/feedDropdown" }} 2 + <button 3 + popovertarget="feed-dropdown" 4 + popovertargetaction="toggle" 5 + class="btn text-sm cursor-pointer list-none flex items-center gap-2"> 6 + {{ i "rss" "size-4" }} 7 + <span class="hidden md:inline">atom</span> 8 + </button> 9 + 10 + <div 11 + popover 12 + id="feed-dropdown" 13 + class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 14 + dark:text-white backdrop:bg-gray-400/50 dark:backdrop:bg-gray-800/50 15 + w-96 p-4 rounded drop-shadow overflow-visible"> 16 + 17 + <h3 class="text-sm font-semibold text-gray-900 dark:text-white mb-3"> 18 + Configure Feed 19 + </h3> 20 + 21 + <div class="space-y-2 mb-4"> 22 + <label class="flex items-center gap-2 cursor-pointer"> 23 + <input 24 + type="checkbox" 25 + id="feed-issues" 26 + class="feed-checkbox" 27 + data-type="issues" 28 + checked> 29 + <span class="text-sm">Issues</span> 30 + </label> 31 + 32 + <label class="flex items-center gap-2 cursor-pointer"> 33 + <input 34 + type="checkbox" 35 + id="feed-pulls" 36 + class="feed-checkbox" 37 + data-type="pulls" 38 + checked> 39 + <span class="text-sm">Pull Requests</span> 40 + </label> 41 + 42 + <label class="flex items-center gap-2 cursor-pointer"> 43 + <input 44 + type="checkbox" 45 + id="feed-commits" 46 + class="feed-checkbox" 47 + data-type="commits" 48 + checked> 49 + <span class="text-sm">Commits</span> 50 + </label> 51 + 52 + <label class="flex items-center gap-2 cursor-pointer"> 53 + <input 54 + type="checkbox" 55 + id="feed-tags" 56 + class="feed-checkbox" 57 + data-type="tags" 58 + checked> 59 + <span class="text-sm">Tags</span> 60 + </label> 61 + </div> 62 + 63 + <!-- generated url display --> 64 + <div> 65 + <label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1 normal-case"> 66 + Feed URL 67 + </label> 68 + <div class="flex items-stretch border border-gray-300 dark:border-gray-600 divide-x divide-gray-300 dark:divide-gray-600 rounded"> 69 + <input 70 + type="text" 71 + id="feed-url" 72 + readonly 73 + value="/{{ .RepoInfo.FullName }}/feed.atom" 74 + class="flex-1 px-3 py-2 text-sm text-gray-900 dark:text-gray-100 select-all cursor-pointer whitespace-nowrap overflow-x-auto font-mono bg-gray-200 dark:bg-gray-700 border-0 outline-none" 75 + onclick="this.select()"> 76 + <button 77 + id="feed-copy-btn" 78 + onclick="copyFeedUrl(this)" 79 + class="px-3 py-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200" 80 + title="Copy to clipboard"> 81 + {{ i "copy" "w-4 h-4" }} 82 + </button> 83 + </div> 84 + </div> 85 + 86 + <p class="text-xs text-gray-500 dark:text-gray-400 mt-3"> 87 + Select the types of activity you want to include in your feed. 88 + </p> 89 + </div> 90 + 91 + <script> 92 + (function() { 93 + const updateFeedUrl = () => { 94 + const popover = document.getElementById('feed-dropdown'); 95 + if (!popover) return; 96 + 97 + const allCheckboxes = popover.querySelectorAll('.feed-checkbox'); 98 + const selectedTypes = [...allCheckboxes].filter(cb => cb.checked).map(cb => cb.dataset.type); 99 + const baseUrl = '/{{ .RepoInfo.FullName }}/feed.atom'; 100 + const query = selectedTypes.length === allCheckboxes.length ? '' : `?include=${selectedTypes.join(',')}`; 101 + 102 + document.getElementById('feed-url').value = window.location.origin + baseUrl + query; 103 + }; 104 + 105 + window.copyFeedUrl = (button) => { 106 + navigator.clipboard.writeText(document.getElementById('feed-url').value).then(() => { 107 + const original = button.innerHTML; 108 + button.innerHTML = `{{ i "check" "w-4 h-4" }}`; 109 + setTimeout(() => button.innerHTML = original, 2000); 110 + }); 111 + }; 112 + 113 + document.querySelectorAll('.feed-checkbox').forEach(cb => cb.addEventListener('change', updateFeedUrl)); 114 + document.getElementById('feed-dropdown')?.addEventListener('toggle', e => e.newState === 'open' && updateFeedUrl()); 115 + })(); 116 + </script> 117 + {{ end }}