A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
80
fork

Configure Feed

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

collapse searchbox when not in use

+102 -12
+51 -8
pkg/appview/static/css/style.css
··· 153 153 color: var(--primary); 154 154 } 155 155 156 - .nav-search { 157 - flex: 1; 158 - max-width: 400px; 159 - margin: 0 2rem; 156 + /* Expandable search */ 157 + .nav-search-wrapper { 158 + position: relative; 159 + display: flex; 160 + align-items: center; 161 + } 162 + 163 + .search-toggle-btn { 164 + display: inline-flex; 165 + align-items: center; 166 + justify-content: center; 167 + background: transparent; 168 + border: none; 169 + color: var(--navbar-fg); 170 + cursor: pointer; 171 + padding: 0.5rem; 172 + border-radius: 4px; 173 + } 174 + 175 + .search-toggle-btn:hover { 176 + background: var(--secondary); 160 177 } 161 178 162 - .nav-search input { 179 + .search-toggle-btn .search-icon { 180 + width: 1.25rem; 181 + height: 1.25rem; 182 + } 183 + 184 + .nav-search-form { 185 + position: absolute; 186 + right: 100%; 187 + width: 0; 188 + opacity: 0; 189 + overflow: hidden; 190 + transition: width 0.3s ease, opacity 0.3s ease; 191 + margin-right: 0.5rem; 192 + } 193 + 194 + .nav-search-wrapper.expanded .nav-search-form { 195 + width: 250px; 196 + opacity: 1; 197 + } 198 + 199 + .nav-search-form input { 163 200 width: 100%; 164 201 padding: 0.5rem 1rem; 165 202 border: none; 166 203 border-radius: 4px; 167 204 font-size: 0.95rem; 205 + background: var(--bg); 206 + color: var(--fg); 207 + } 208 + 209 + .nav-search-form input:focus { 210 + outline: 2px solid var(--primary); 211 + outline-offset: -2px; 168 212 } 169 213 170 214 .nav-links { ··· 2078 2122 gap: 1rem; 2079 2123 } 2080 2124 2081 - .nav-search { 2082 - max-width: 100%; 2083 - margin: 0; 2125 + .nav-search-wrapper.expanded .nav-search-form { 2126 + width: 200px; 2084 2127 } 2085 2128 2086 2129 .push-details {
+44
pkg/appview/static/js/app.js
··· 35 35 themeBtn.setAttribute('aria-label', currentTheme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'); 36 36 } 37 37 38 + // Expandable search 39 + function toggleSearch() { 40 + const wrapper = document.querySelector('.nav-search-wrapper'); 41 + const input = document.getElementById('nav-search-input'); 42 + 43 + if (!wrapper || !input) return; 44 + 45 + wrapper.classList.toggle('expanded'); 46 + 47 + if (wrapper.classList.contains('expanded')) { 48 + input.focus(); 49 + } 50 + } 51 + 52 + function closeSearch() { 53 + const wrapper = document.querySelector('.nav-search-wrapper'); 54 + if (wrapper) { 55 + wrapper.classList.remove('expanded'); 56 + } 57 + } 58 + 59 + // Close search on Escape key and click outside 60 + document.addEventListener('DOMContentLoaded', () => { 61 + const wrapper = document.querySelector('.nav-search-wrapper'); 62 + const input = document.getElementById('nav-search-input'); 63 + 64 + if (!wrapper || !input) return; 65 + 66 + // Close on Escape key 67 + document.addEventListener('keydown', (e) => { 68 + if (e.key === 'Escape' && wrapper.classList.contains('expanded')) { 69 + closeSearch(); 70 + } 71 + }); 72 + 73 + // Close on click outside 74 + document.addEventListener('click', (e) => { 75 + if (wrapper.classList.contains('expanded') && 76 + !wrapper.contains(e.target)) { 77 + closeSearch(); 78 + } 79 + }); 80 + }); 81 + 38 82 // Copy to clipboard 39 83 function copyToClipboard(text) { 40 84 navigator.clipboard.writeText(text).then(() => {
+6 -3
pkg/appview/templates/components/nav-search.html
··· 1 1 {{ define "nav-search" }} 2 - <div class="nav-search"> 3 - <form action="/search" method="get"> 4 - <input type="text" name="q" placeholder="Search images..." value="{{ .Query }}" /> 2 + <div class="nav-search-wrapper"> 3 + <button id="search-toggle" onclick="toggleSearch()" class="btn-link search-toggle-btn" aria-label="Search"> 4 + <i data-lucide="search" class="search-icon"></i> 5 + </button> 6 + <form action="/search" method="get" class="nav-search-form"> 7 + <input type="text" id="nav-search-input" name="q" placeholder="Search images..." value="{{ .Query }}" /> 5 8 </form> 6 9 </div> 7 10 {{ end }}
+1 -1
pkg/appview/templates/components/nav.html
··· 1 1 {{ define "nav" }} 2 2 <nav class="navbar"> 3 3 {{ template "nav-brand" }} 4 - {{ template "nav-search" . }} 5 4 <div class="nav-links"> 5 + {{ template "nav-search" . }} 6 6 {{ template "nav-theme-toggle" }} 7 7 {{ template "nav-user" . }} 8 8 </div>