marky

Lightweight bookmarking + plaintext archive
Log | Files | Refs | README | LICENSE

user.html (14520B)


      1 <!DOCTYPE html>
      2 <html lang="en">
      3   <head>
      4     <meta charset="utf-8" />
      5     <meta name="viewport" content="width=device-width, initial-scale=1" />
      6     <title>Marky</title>
      7     <link rel="stylesheet" href="/styles.css" />
      8     <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
      9     <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
     10     <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
     11     <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
     12     <script src="/vendor/vue.global.prod.js"></script>
     13     <script>if(!window.Vue){var s=document.createElement('script');s.src='https://unpkg.com/vue@3/dist/vue.global.prod.js';document.head.appendChild(s)}</script>
     14     <script src="/vendor/marked.min.js"></script>
     15     <script>if(!window.marked){var s=document.createElement('script');s.src='https://cdn.jsdelivr.net/npm/marked/marked.min.js';document.head.appendChild(s)}</script>
     16     <script src="/vendor/purify.min.js"></script>
     17     <script>if(!window.DOMPurify){var s=document.createElement('script');s.src='https://cdn.jsdelivr.net/npm/[email protected]/dist/purify.min.js';document.head.appendChild(s)}</script>
     18   </head>
     19   <body>
     20     <div id="app">
     21       {{HEADER}}
     22       <main class="container grid">
     23         <section v-if="view==='self'">
     24           <h2>Add Bookmark</h2>
     25           <form @submit.prevent="createBookmark">
     26             <label>URL <input v-model.trim="form.url" type="url" required placeholder="https://example.com" /></label>
     27             <label>Title (optional) <input v-model.trim="form.title" type="text" placeholder="Page title" /></label>
     28             <label>Description (optional) <textarea v-model.trim="form.description" rows="2" placeholder="Notes..."></textarea></label>
     29             <label>Referrer (optional) <input v-model.trim="form.referrer" type="url" placeholder="https://site-that-linked-here.example" /></label>
     30             <label class="inline"><input type="checkbox" v-model="form.public" /> Public</label>
     31             <button :disabled="busy">{{ busy ? 'Working…' : 'Save' }}</button>
     32             <p v-if="error" class="error">{{ error }}</p>
     33             <p v-if="message" class="ok">{{ message }}</p>
     34           </form>
     35         </section>
     36         <section v-if="view==='self'" id="bookmarks">
     37           <h2>
     38             Bookmarks
     39             <span class="small-links" v-if="me && me.username">
     40               <a :href="`/u:${me.username}.json`" title="Your JSON feed (includes private if logged in)">JSON</a>
     41               <span class="sep">|</span>
     42               <a :href="`/u:${me.username}.rss`" title="Your RSS feed (includes private if logged in)">RSS</a>
     43             </span>
     44           </h2>
     45           <form method="GET" :action="`/u:${me.username}#bookmarks`">
     46             <input name="q" type="search" placeholder="Search…" :value="pager && pager.query ? pager.query : ''" @search="submitOnClear" />
     47             <input type="hidden" name="vis" :value="pager && pager.vis ? pager.vis : 'all'" />
     48             <button>Search</button>
     49           </form>
     50           <p v-if="pager" class="muted results-summary">
     51             <span>
     52               Displaying {{ (pager.count||0) === 0 ? 0 : ((pager.page-1)*pager.size + 1) }}-{{ (pager.count||0) === 0 ? 0 : ((pager.page-1)*pager.size + results.length) }} of {{ pager.count || 0 }} bookmarks
     53             </span>
     54             <span class="results-filter" v-if="pager && pager.owner">
     55               <a :class="{ selected: (pager.vis||'all')==='all' }" :href="pager && pager.query ? `/u:${me.username}?page=1&size=${pager.size}&q=${pager.queryEncoded}&vis=all#bookmarks` : `/u:${me.username}?page=1&size=${pager.size}&vis=all#bookmarks`">All</a>
     56               <span class="sep">|</span>
     57               <a :class="{ selected: (pager.vis||'all')==='public' }" :href="pager && pager.query ? `/u:${me.username}?page=1&size=${pager.size}&q=${pager.queryEncoded}&vis=public#bookmarks` : `/u:${me.username}?page=1&size=${pager.size}&vis=public#bookmarks`">Public</a>
     58               <span class="sep">|</span>
     59               <a :class="{ selected: (pager.vis||'all')==='private' }" :href="pager && pager.query ? `/u:${me.username}?page=1&size=${pager.size}&q=${pager.queryEncoded}&vis=private#bookmarks` : `/u:${me.username}?page=1&size=${pager.size}&vis=private#bookmarks`">Private</a>
     60             </span>
     61           </p>
     62           <div class="results">
     63             <article v-for="b in results" :key="b.id" :class="['card', { private: !b.public }]">
     64               <h3><a :href="b.url" target="_blank" rel="noopener noreferrer">{{ b.title || b.url }}</a></h3>
     65               <p :class="['url', { truncate: b.urlTrunc }]" :title="b.url" @click="toggleURL(b)">{{ b.url }}</p>
     66               <p v-if="b.referrer" class="referrer">Referrer: <span class="ref-link"><a :href="b.referrer" target="_blank" rel="noopener noreferrer">{{ b.referrer }}</a></span></p>
     67               <div v-if="b.editing" class="edit-form">
     68                 <label>URL <input v-model.trim="b.editUrl" type="url" required /></label>
     69                 <label>Title <input v-model.trim="b.editTitle" type="text" required /></label>
     70                 <label>Description <textarea v-model.trim="b.editDescription" rows="2"></textarea></label>
     71                 <label>Referrer <input v-model.trim="b.editReferrer" type="url" placeholder="https://site-that-linked-here.example" /></label>
     72                 <label class="inline"><input type="checkbox" v-model="b.editPublic" /> Public</label>
     73                 <div class="actions">
     74                   <button @click="saveEdit(b)" :disabled="b.saving">{{ b.saving ? 'Saving…' : 'Save' }}</button>
     75                   <button @click="cancelEdit(b)">Cancel</button>
     76                 </div>
     77               </div>
     78               <p v-else-if="b.excerpt" class="excerpt" v-html="formatExcerpt(b.excerpt)"></p>
     79               <div v-if="!b.editing && !b.excerpt && b.description" class="desc" v-html="renderMarkdown(b.description)"></div>
     80               <p class="action-links">
     81                 <span class="meta">{{ formatDate(b.updated_at) }}</span>
     82                 <span class="sep">|</span>
     83                 <template v-if="b.has_archive">
     84                   <a :href="`/bookmarks/${b.id}/archive`" target="_blank" title="View archived text">Archive</a>
     85                   <span class="sep">|</span>
     86                 </template>
     87                 <a href="#" @click.prevent="startEdit(b)">Edit</a>
     88                 <span class="sep">|</span>
     89                 <a href="#" @click.prevent="confirmDelete(b)">Delete</a>
     90               </p>
     91             </article>
     92           </div>
     93           <div class="pager">
     94             <div v-if="pager && pager.total > 1" class="pages">
     95               <template v-if="pager.page > 1">
     96                 <a :href="pager && pager.query ? `/u:${me.username}?page=${pager.page-1}&size=${pager.size}&q=${pager.queryEncoded}&vis=${pager.vis||'all'}#bookmarks` : `/u:${me.username}?page=${pager.page-1}&size=${pager.size}&vis=${pager.vis||'all'}#bookmarks`">Prev</a>
     97               </template>
     98               <template v-else>
     99                 <span class="muted">Prev</span>
    100               </template>
    101               <span class="sep">|</span>
    102               <template v-for="item in pagerPages" :key="item.key">
    103                 <template v-if="item.type === 'page'">
    104                   <template v-if="item.n === pager.page">
    105                     <span class="muted">{{ item.n }}</span>
    106                   </template>
    107                   <template v-else>
    108                     <a :href="pager && pager.query ? `/u:${me.username}?page=${item.n}&size=${pager.size}&q=${pager.queryEncoded}&vis=${pager.vis||'all'}#bookmarks` : `/u:${me.username}?page=${item.n}&size=${pager.size}&vis=${pager.vis||'all'}#bookmarks`">{{ item.n }}</a>
    109                   </template>
    110                 </template>
    111                 <template v-else>
    112                   <span class="muted">…</span>
    113                 </template>
    114               </template>
    115               <span class="sep">|</span>
    116               <template v-if="pager.page < pager.total">
    117                 <a :href="pager && pager.query ? `/u:${me.username}?page=${pager.page+1}&size=${pager.size}&q=${pager.queryEncoded}&vis=${pager.vis||'all'}#bookmarks` : `/u:${me.username}?page=${pager.page+1}&size=${pager.size}&vis=${pager.vis||'all'}#bookmarks`">Next</a>
    118               </template>
    119               <template v-else>
    120                 <span class="muted">Next</span>
    121               </template>
    122             </div>
    123             <div class="sizes">
    124               <span>Page size:</span>
    125               <template v-if="pager && pager.size===20">
    126                 <span class="muted">20</span>
    127               </template>
    128               <template v-else>
    129                 <a :href="pager && pager.query ? `/u:${me.username}?page=1&size=20&q=${pager.queryEncoded}&vis=${pager.vis||'all'}#bookmarks` : `/u:${me.username}?page=1&size=20&vis=${pager.vis||'all'}#bookmarks`">20</a>
    130               </template>
    131               <span class="sep">|</span>
    132               <template v-if="pager && pager.size===50">
    133                 <span class="muted">50</span>
    134               </template>
    135               <template v-else>
    136                 <a :href="pager && pager.query ? `/u:${me.username}?page=1&size=50&q=${pager.queryEncoded}&vis=${pager.vis||'all'}#bookmarks` : `/u:${me.username}?page=1&size=50&vis=${pager.vis||'all'}#bookmarks`">50</a>
    137               </template>
    138               <span class="sep">|</span>
    139               <template v-if="pager && pager.size===100">
    140                 <span class="muted">100</span>
    141               </template>
    142               <template v-else>
    143                 <a :href="pager && pager.query ? `/u:${me.username}?page=1&size=100&q=${pager.queryEncoded}&vis=${pager.vis||'all'}#bookmarks` : `/u:${me.username}?page=1&size=100&vis=${pager.vis||'all'}#bookmarks`">100</a>
    144               </template>
    145             </div>
    146           </div>
    147         </section>
    148 
    149         <section v-if="view==='public'" class="span2">
    150           <h2>
    151             {{ viewUser }}
    152             <span class="small-links">
    153               <a :href="`/u:${viewUser}.json`" title="User JSON feed">JSON</a>
    154               <span class="sep">|</span>
    155               <a :href="`/u:${viewUser}.rss`" title="User RSS feed">RSS</a>
    156             </span>
    157           </h2>
    158           <p v-if="pager" class="muted results-summary">
    159             Displaying {{ (pager.count||0) === 0 ? 0 : ((pager.page-1)*pager.size + 1) }}-{{ (pager.count||0) === 0 ? 0 : ((pager.page-1)*pager.size + results.length) }} of {{ pager.count || 0 }} bookmarks
    160           </p>
    161           <div class="results">
    162             <article v-for="b in results" :key="b.id" class="card">
    163               <h3><a :href="b.url" target="_blank" rel="noopener noreferrer">{{ b.title || b.url }}</a></h3>
    164               <p :class="['url', { truncate: b.urlTrunc }]" :title="b.url" @click="toggleURL(b)">{{ b.url }}</p>
    165               <p v-if="b.referrer" class="referrer">Referrer: <span class="ref-link"><a :href="b.referrer" target="_blank" rel="noopener noreferrer">{{ b.referrer }}</a></span></p>
    166               <div v-if="b.description" class="desc" v-html="renderMarkdown(b.description)"></div>
    167               <p class="action-links">
    168                 <span class="meta">{{ formatDate(b.updated_at) }}</span>
    169                 <template v-if="b.has_archive">
    170                   <span class="sep">|</span>
    171                   <a :href="`/bookmarks/${b.id}/archive`" target="_blank">Archive</a>
    172                 </template>
    173               </p>
    174             </article>
    175           </div>
    176           <div class="pager">
    177             <div v-if="pager && pager.total > 1" class="pages">
    178               <template v-if="pager.page > 1">
    179                 <a :href="pager && pager.query ? `/u:${viewUser}?page=${pager.page-1}&size=${pager.size}&q=${pager.queryEncoded}` : `/u:${viewUser}?page=${pager.page-1}&size=${pager.size}`">Prev</a>
    180               </template>
    181               <template v-else>
    182                 <span class="muted">Prev</span>
    183               </template>
    184               <span class="sep">|</span>
    185               <template v-for="item in pagerPages" :key="item.key">
    186                 <template v-if="item.type === 'page'">
    187                   <template v-if="item.n === pager.page">
    188                     <span class="muted">{{ item.n }}</span>
    189                   </template>
    190                   <template v-else>
    191                     <a :href="pager && pager.query ? `/u:${viewUser}?page=${item.n}&size=${pager.size}&q=${pager.queryEncoded}` : `/u:${viewUser}?page=${item.n}&size=${pager.size}`">{{ item.n }}</a>
    192                   </template>
    193                 </template>
    194                 <template v-else>
    195                   <span class="muted">…</span>
    196                 </template>
    197               </template>
    198               <span class="sep">|</span>
    199               <template v-if="pager.page < pager.total">
    200                 <a :href="pager && pager.query ? `/u:${viewUser}?page=${pager.page+1}&size=${pager.size}&q=${pager.queryEncoded}` : `/u:${viewUser}?page=${pager.page+1}&size=${pager.size}`">Next</a>
    201               </template>
    202               <template v-else>
    203                 <span class="muted">Next</span>
    204               </template>
    205             </div>
    206             <div class="sizes">
    207               <span>Page size:</span>
    208               <template v-if="pager && pager.size===20">
    209                 <span class="muted">20</span>
    210               </template>
    211               <template v-else>
    212                 <a :href="pager && pager.query ? `/u:${viewUser}?page=1&size=20&q=${pager.queryEncoded}` : `/u:${viewUser}?page=1&size=20`">20</a>
    213               </template>
    214               <span class="sep">|</span>
    215               <template v-if="pager && pager.size===50">
    216                 <span class="muted">50</span>
    217               </template>
    218               <template v-else>
    219                 <a :href="pager && pager.query ? `/u:${viewUser}?page=1&size=50&q=${pager.queryEncoded}` : `/u:${viewUser}?page=1&size=50`">50</a>
    220               </template>
    221               <span class="sep">|</span>
    222               <template v-if="pager && pager.size===100">
    223                 <span class="muted">100</span>
    224               </template>
    225               <template v-else>
    226                 <a :href="pager && pager.query ? `/u:${viewUser}?page=1&size=100&q=${pager.queryEncoded}` : `/u:${viewUser}?page=1&size=100`">100</a>
    227               </template>
    228             </div>
    229           </div>
    230         </section>
    231       </main>
    232     </div>
    233     <script src="/app.js"></script>
    234   </body>
    235   </html>