decentralized and customizable links page on top of atproto

Merge branch 'main' into oauth

Changed files
+62 -35
src
static
templates
+3
Makefile
··· 1 + .PHONY: debug 2 + debug: 3 + flask run --debug -h '0.0.0.0' -p 8080
+1
app.py
··· 1 + from src.main import app
+1
requirements.txt
··· 21 21 pycparser==2.23 22 22 pydantic==2.11.10 23 23 pydantic_core==2.33.2 24 + python-dotenv==1.1.1 24 25 sniffio==1.3.1 25 26 typing-inspection==0.4.2 26 27 typing_extensions==4.15.0
+18 -1
src/static/style.css
··· 77 77 } 78 78 79 79 link-item { 80 + background: currentColor; 80 81 display: block; 81 - background: currentColor; 82 + flex-grow: 1; 82 83 transition: transform 0.1s; 83 84 text-align: center; 84 85 padding: 0.5em; ··· 181 182 padding: 0.25em; 182 183 border: 1px solid var(--color-border-secondary); 183 184 border-radius: 2px; 185 + } 186 + 187 + link-editor-header { 188 + display: flex; 189 + flex-direction: row; 190 + gap: 0.25em; 191 + } 192 + 193 + link-editor-drag-handle { 194 + background: var(--color-background-secondary); 195 + display: flex; 196 + flex-grow: 0; 197 + padding: 2px; 198 + line-height: 100%; 199 + font-size: 1.5em; 200 + align-items: center; 184 201 } 185 202 186 203 link-editor-buttons {
+39 -34
src/templates/editor.html
··· 52 52 <noscript> 53 53 JavaScript is needed for a better experience configuring the links. 54 54 </noscript> 55 - <form action="/editor/links" method="post" @change="linksChanged = true" x-sort> 55 + <form action="/editor/links" method="post" @change="linksChanged = true"> 56 56 <input type="submit" value="save links" /> 57 57 58 - <template x-for="(link, index) in links"> 59 - <link-editor-item x-data="{ editing: !link.url }" x-sort:item="link.url"> 60 - <div x-show="!editing"> 61 - <link-item x-sort:handle class="static" :style="'color: ' + link.background"> 62 - <link-item-title x-text="link.title"></link-item-title> 63 - <link-item-detail x-show="link.detail" x-text="link.detail"></link-item-detail> 64 - </link-item> 65 - <link-editor-buttons> 66 - <button type="button" @click="editing = true">edit</button> 67 - <button type="button" @click="if (confirm('delete?')) links.splice(index, 1)">delete</button> 68 - </link-editor-buttons> 69 - </div> 70 - <div x-show="editing"> 71 - <label> 72 - <span>URL</span> 73 - <input type="text" name="link-url" x-model="link.url" required /> 74 - </label> 75 - <label> 76 - <span>Title</span> 77 - <input type="text" name="link-title" x-model="link.title" required /> 78 - </label> 79 - <label> 80 - <span>Subtitle</span> 81 - <input type="text" name="link-detail" x-model="link.detail" /> 82 - </label> 83 - <label> 84 - <span>Background color</span> 85 - <input type="color" name="link-background" x-model="link.background" required /> 86 - </label> 87 - <button type="button" @click="editing = false">ok</button> 88 - </div> 89 - </link-editor-item> 90 - </template> 58 + <div x-sort x-sort:config="{ handle: '[x-sort\\:handle]' }"> 59 + <template x-for="(link, index) in links"> 60 + <link-editor-item x-data="{ editing: !link.url }" x-sort:item="link.url"> 61 + <link-editor-header> 62 + <link-item class="static" :style="'color: ' + link.background"> 63 + <link-item-title x-text="link.title"></link-item-title> 64 + <link-item-detail x-show="link.detail" x-text="link.detail"></link-item-detail> 65 + </link-item> 66 + <link-editor-drag-handle x-sort:handle>⠿</link-editor-drag-handle> 67 + </link-editor-header> 68 + <div x-show="!editing"> 69 + <link-editor-buttons> 70 + <button type="button" @click="editing = true">edit</button> 71 + <button type="button" @click="if (confirm('delete?')) links.splice(index, 1)">delete</button> 72 + </link-editor-buttons> 73 + </div> 74 + <div x-show="editing"> 75 + <label> 76 + <span>URL</span> 77 + <input type="text" name="link-url" x-model="link.url" required /> 78 + </label> 79 + <label> 80 + <span>Title</span> 81 + <input type="text" name="link-title" x-model="link.title" required /> 82 + </label> 83 + <label> 84 + <span>Subtitle</span> 85 + <input type="text" name="link-detail" x-model="link.detail" /> 86 + </label> 87 + <label> 88 + <span>Background color</span> 89 + <input type="color" name="link-background" x-model="link.background" required /> 90 + </label> 91 + <button type="button" @click="editing = false">ok</button> 92 + </div> 93 + </link-editor-item> 94 + </template> 95 + </div> 91 96 92 97 <label style="display: block; margin-top: 1em;"> 93 98 <button type="button" @click="links.push({ background: '#fa0' })">add link</button>