Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

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

Revert "*.html: format with prettier"

This reverts commits 1931b62baa4452616203ccbb356da72688bc4587 and 86d0b4060de074759eff40666b90be86c244ab23.

Signed-off-by: Winter <winter@winter.cafe>

Winter 1f681c12 acff01ec

+3974 -5227
+4 -2
appview/pages/templates/errors/404.html
··· 1 1 {{ define "title" }}404 &middot; tangled{{ end }} 2 2 3 3 {{ define "content" }} 4 - <h1>404 &mdash; nothing like that here!</h1> 5 - <p>It seems we couldn't find what you were looking for. Sorry about that!</p> 4 + <h1>404 &mdash; nothing like that here!</h1> 5 + <p> 6 + It seems we couldn't find what you were looking for. Sorry about that! 7 + </p> 6 8 {{ end }}
+2 -2
appview/pages/templates/errors/500.html
··· 1 1 {{ define "title" }}500 &middot; tangled{{ end }} 2 2 3 3 {{ define "content" }} 4 - <h1>500 &mdash; something broke!</h1> 5 - <p>We're working on getting service back up. Hang tight!</p> 4 + <h1>500 &mdash; something broke!</h1> 5 + <p>We're working on getting service back up. Hang tight!</p> 6 6 {{ end }}
+5 -4
appview/pages/templates/errors/503.html
··· 1 1 {{ define "title" }}503 &middot; tangled{{ end }} 2 2 3 3 {{ define "content" }} 4 - <h1>503 &mdash; unable to reach knot</h1> 5 - <p> 6 - We were unable to reach the knot hosting this repository. Try again later. 7 - </p> 4 + <h1>503 &mdash; unable to reach knot</h1> 5 + <p> 6 + We were unable to reach the knot hosting this repository. Try again 7 + later. 8 + </p> 8 9 {{ end }}
+20 -24
appview/pages/templates/favicon.html
··· 1 1 {{ define "favicon" }} 2 - <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"> 3 - <style> 2 + <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"> 3 + <style> 4 + .favicon-text { 5 + fill: #000000; 6 + stroke: none; 7 + } 8 + 9 + @media (prefers-color-scheme: dark) { 4 10 .favicon-text { 5 - fill: #000000; 11 + fill: #ffffff; 6 12 stroke: none; 7 13 } 14 + } 15 + </style> 8 16 9 - @media (prefers-color-scheme: dark) { 10 - .favicon-text { 11 - fill: #ffffff; 12 - stroke: none; 13 - } 14 - } 15 - </style> 16 - 17 - <g style="display:inline"> 18 - <path 19 - d="M0-2.117h62.177v25.135H0z" 20 - style="display:inline;fill:none;fill-opacity:1;stroke-width:.396875" 21 - transform="translate(11.01 6.9)" /> 22 - <path 23 - d="M3.64 22.787c-1.697 0-2.943-.45-3.74-1.35-.77-.9-1.156-2.094-1.156-3.585 0-.36.013-.72.038-1.08.052-.385.129-.873.232-1.464L.44 6.826h-5.089l.733-4.394h3.2c.822 0 1.439-.168 1.85-.502.437-.334.72-.938.848-1.812l.771-4.703h5.243L6.84 2.432h7.787l-.733 4.394H6.107L4.257 17.93l.77.27 6.015-4.742 2.775 3.161-2.313 2.005c-.822.694-1.568 1.31-2.236 1.85-.668.515-1.31.952-1.927 1.311a7.406 7.406 0 0 1-1.774.733c-.59.18-1.233.27-1.927.27z" 24 - aria-label="tangled.sh" 25 - class="favicon-text" 26 - style="font-size:16.2278px;font-family:'IBM Plex Mono';-inkscape-font-specification:'IBM Plex Mono, Normal';display:inline;fill-opacity:1" 27 - transform="translate(11.01 6.9)" /> 28 - </g> 29 - </svg> 17 + <g style="display:inline"> 18 + <path d="M0-2.117h62.177v25.135H0z" style="display:inline;fill:none;fill-opacity:1;stroke-width:.396875" transform="translate(11.01 6.9)"/> 19 + <path d="M3.64 22.787c-1.697 0-2.943-.45-3.74-1.35-.77-.9-1.156-2.094-1.156-3.585 0-.36.013-.72.038-1.08.052-.385.129-.873.232-1.464L.44 6.826h-5.089l.733-4.394h3.2c.822 0 1.439-.168 1.85-.502.437-.334.72-.938.848-1.812l.771-4.703h5.243L6.84 2.432h7.787l-.733 4.394H6.107L4.257 17.93l.77.27 6.015-4.742 2.775 3.161-2.313 2.005c-.822.694-1.568 1.31-2.236 1.85-.668.515-1.31.952-1.927 1.311a7.406 7.406 0 0 1-1.774.733c-.59.18-1.233.27-1.927.27z" 20 + aria-label="tangled.sh" 21 + class="favicon-text" 22 + style="font-size:16.2278px;font-family:'IBM Plex Mono';-inkscape-font-specification:'IBM Plex Mono, Normal';display:inline;fill-opacity:1" 23 + transform="translate(11.01 6.9)"/> 24 + </g> 25 + </svg> 30 26 {{ end }}
+5 -12
appview/pages/templates/knots/dashboard.html
··· 14 14 <div id="right-side" class="flex gap-2"> 15 15 {{ $style := "px-2 py-1 rounded flex items-center flex-shrink-0 gap-2" }} 16 16 {{ if .Registration.Registered }} 17 - <span 18 - class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 {{ $style }}"> 19 - {{ i "shield-check" "w-4 h-4" }} verified 20 - </span> 17 + <span class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 {{$style}}">{{ i "shield-check" "w-4 h-4" }} verified</span> 21 18 {{ template "knots/fragments/addMemberModal" .Registration }} 22 19 {{ else }} 23 - <span 24 - class="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 {{ $style }}"> 25 - {{ i "shield-off" "w-4 h-4" }} pending 26 - </span> 20 + <span class="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 {{$style}}">{{ i "shield-off" "w-4 h-4" }} pending</span> 27 21 {{ end }} 28 22 </div> 29 23 </div> ··· 25 31 </div> 26 32 27 33 {{ if .Members }} 28 - <section 29 - class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 34 + <section class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 30 35 <div class="flex flex-col gap-2"> 31 - {{ block "knotMember" . }}{{ end }} 36 + {{ block "knotMember" . }} {{ end }} 32 37 </div> 33 38 </section> 34 39 {{ end }} ··· 39 46 <div class="flex justify-between items-center"> 40 47 <div class="flex items-center gap-2"> 41 48 {{ template "user/fragments/picHandleLink" . }} 42 - <span class="ml-2 font-mono text-gray-500">{{ . }}</span> 49 + <span class="ml-2 font-mono text-gray-500">{{.}}</span> 43 50 </div> 44 51 </div> 45 52 <div class="ml-2 pl-2 pt-2 border-l border-gray-200 dark:border-gray-700">
+40 -39
appview/pages/templates/knots/fragments/addMemberModal.html
··· 3 3 class="btn gap-2 group" 4 4 title="Add member to this spindle" 5 5 popovertarget="add-member-{{ .Id }}" 6 - popovertargetaction="toggle"> 6 + popovertargetaction="toggle" 7 + > 7 8 {{ i "user-plus" "w-5 h-5" }} 8 - <span class="hidden md:inline">add member</span> 9 + <span class="hidden md:inline">add member</span> 9 10 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 10 11 </button> 11 12 ··· 14 13 id="add-member-{{ .Id }}" 15 14 popover 16 15 class="bg-white w-full md:w-96 dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 drop-shadow dark:text-white backdrop:bg-gray-400/50 dark:backdrop:bg-gray-800/50"> 17 - {{ block "addKnotMemberPopover" . }}{{ end }} 16 + {{ block "addKnotMemberPopover" . }} {{ end }} 18 17 </div> 19 18 {{ end }} 20 19 21 20 {{ define "addKnotMemberPopover" }} 22 - <form 23 - hx-put="/knots/{{ .Domain }}/member" 24 - hx-indicator="#spinner" 25 - hx-swap="none" 26 - class="flex flex-col gap-2"> 27 - <label for="member-did-{{ .Id }}" class="uppercase p-0">ADD MEMBER</label> 28 - <p class="text-sm text-gray-500 dark:text-gray-400"> 29 - Members can create repositories on this knot. 30 - </p> 31 - <input 32 - type="text" 33 - id="member-did-{{ .Id }}" 34 - name="subject" 35 - required 36 - placeholder="@foo.bsky.social" /> 37 - <div class="flex gap-2 pt-2"> 38 - <button 39 - type="button" 40 - popovertarget="add-member-{{ .Id }}" 41 - popovertargetaction="hide" 42 - class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"> 43 - {{ i "x" "size-4" }} cancel 44 - </button> 45 - <button type="submit" class="btn w-1/2 flex items-center"> 46 - <span class="inline-flex gap-2 items-center"> 47 - {{ i "user-plus" "size-4" }} add 48 - </span> 49 - <span id="spinner" class="group"> 50 - {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 51 - </span> 52 - </button> 53 - </div> 54 - <div 55 - id="add-member-error-{{ .Id }}" 56 - class="text-red-500 dark:text-red-400"></div> 57 - </form> 21 + <form 22 + hx-put="/knots/{{ .Domain }}/member" 23 + hx-indicator="#spinner" 24 + hx-swap="none" 25 + class="flex flex-col gap-2" 26 + > 27 + <label for="member-did-{{ .Id }}" class="uppercase p-0"> 28 + ADD MEMBER 29 + </label> 30 + <p class="text-sm text-gray-500 dark:text-gray-400">Members can create repositories on this knot.</p> 31 + <input 32 + type="text" 33 + id="member-did-{{ .Id }}" 34 + name="subject" 35 + required 36 + placeholder="@foo.bsky.social" 37 + /> 38 + <div class="flex gap-2 pt-2"> 39 + <button 40 + type="button" 41 + popovertarget="add-member-{{ .Id }}" 42 + popovertargetaction="hide" 43 + class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300" 44 + > 45 + {{ i "x" "size-4" }} cancel 46 + </button> 47 + <button type="submit" class="btn w-1/2 flex items-center"> 48 + <span class="inline-flex gap-2 items-center">{{ i "user-plus" "size-4" }} add</span> 49 + <span id="spinner" class="group"> 50 + {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 51 + </span> 52 + </button> 53 + </div> 54 + <div id="add-member-error-{{ .Id }}" class="text-red-500 dark:text-red-400"></div> 55 + </form> 58 56 {{ end }} 57 +
+10 -14
appview/pages/templates/knots/fragments/knotListing.html
··· 1 1 {{ define "knots/fragments/knotListing" }} 2 - <div 3 - id="knot-{{ .Id }}" 2 + <div 3 + id="knot-{{.Id}}" 4 4 hx-swap-oob="true" 5 5 class="flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-700"> 6 - {{ block "listLeftSide" . }}{{ end }} 7 - {{ block "listRightSide" . }}{{ end }} 6 + {{ block "listLeftSide" . }} {{ end }} 7 + {{ block "listRightSide" . }} {{ end }} 8 8 </div> 9 9 {{ end }} 10 10 ··· 28 28 <div id="right-side" class="flex gap-2"> 29 29 {{ $style := "px-2 py-1 rounded flex items-center flex-shrink-0 gap-2 text-sm" }} 30 30 {{ if .Registered }} 31 - <span 32 - class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 {{ $style }}"> 33 - {{ i "shield-check" "w-4 h-4" }} verified 34 - </span> 31 + <span class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 {{$style}}">{{ i "shield-check" "w-4 h-4" }} verified</span> 35 32 {{ template "knots/fragments/addMemberModal" . }} 36 33 {{ else }} 37 - <span 38 - class="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 {{ $style }}"> 39 - {{ i "shield-off" "w-4 h-4" }} pending 40 - </span> 41 - {{ block "initializeButton" . }}{{ end }} 34 + <span class="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 {{$style}}">{{ i "shield-off" "w-4 h-4" }} pending</span> 35 + {{ block "initializeButton" . }} {{ end }} 42 36 {{ end }} 43 37 </div> 44 38 {{ end }} ··· 41 47 <button 42 48 class="btn dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 flex gap-2 items-center group" 43 49 hx-post="/knots/{{ .Domain }}/init" 44 - hx-swap="none"> 50 + hx-swap="none" 51 + > 45 52 {{ i "square-play" "w-5 h-5" }} 46 53 <span class="hidden md:inline">initialize</span> 47 54 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 48 55 </button> 49 56 {{ end }} 57 +
+16 -20
appview/pages/templates/knots/fragments/knotListingFull.html
··· 1 1 {{ define "knots/fragments/knotListingFull" }} 2 - <section 3 - id="knot-listing-full" 4 - hx-swap-oob="true" 5 - class="rounded w-full flex flex-col gap-2"> 6 - <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300"> 7 - your knots 8 - </h2> 9 - <div 10 - class="flex flex-col rounded border border-gray-200 dark:border-gray-700 w-full"> 11 - {{ range $knot := .Registrations }} 12 - {{ template "knots/fragments/knotListing" . }} 13 - {{ else }} 14 - <div 15 - class="flex items-center justify-center p-2 border-b border-gray-200 dark:border-gray-700 text-gray-500"> 16 - no knots registered yet 17 - </div> 18 - {{ end }} 19 - </div> 20 - <div id="operation-error" class="text-red-500 dark:text-red-400"></div> 21 - </section> 2 + <section 3 + id="knot-listing-full" 4 + hx-swap-oob="true" 5 + class="rounded w-full flex flex-col gap-2"> 6 + <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300">your knots</h2> 7 + <div class="flex flex-col rounded border border-gray-200 dark:border-gray-700 w-full"> 8 + {{ range $knot := .Registrations }} 9 + {{ template "knots/fragments/knotListing" . }} 10 + {{ else }} 11 + <div class="flex items-center justify-center p-2 border-b border-gray-200 dark:border-gray-700 text-gray-500"> 12 + no knots registered yet 13 + </div> 14 + {{ end }} 15 + </div> 16 + <div id="operation-error" class="text-red-500 dark:text-red-400"></div> 17 + </section> 22 18 {{ end }}
+2 -6
appview/pages/templates/knots/fragments/secret.html
··· 3 3 id="secret" 4 4 hx-swap-oob="true" 5 5 class="bg-gray-50 dark:bg-gray-700 border border-black dark:border-gray-500 rounded px-6 py-2 w-full lg:w-3xl"> 6 - <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300"> 7 - generated secret 8 - </h2> 9 - <p class="pb-2"> 10 - Configure your knot to use this secret, and then hit initialize. 11 - </p> 6 + <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300">generated secret</h2> 7 + <p class="pb-2">Configure your knot to use this secret, and then hit initialize.</p> 12 8 <span class="font-mono overflow-x">{{ .Secret }}</span> 13 9 </div> 14 10 {{ end }}
+22 -27
appview/pages/templates/knots/index.html
··· 1 1 {{ define "title" }}knots{{ end }} 2 2 3 3 {{ define "content" }} 4 - <div class="px-6 py-4"> 5 - <h1 class="text-xl font-bold dark:text-white">Knots</h1> 6 - </div> 4 + <div class="px-6 py-4"> 5 + <h1 class="text-xl font-bold dark:text-white">Knots</h1> 6 + </div> 7 7 8 - <section 9 - class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 10 - <div class="flex flex-col gap-6"> 11 - {{ block "about" . }}{{ end }} 12 - {{ template "knots/fragments/knotListingFull" . }} 13 - {{ block "register" . }}{{ end }} 14 - </div> 15 - </section> 8 + <section class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 9 + <div class="flex flex-col gap-6"> 10 + {{ block "about" . }} {{ end }} 11 + {{ template "knots/fragments/knotListingFull" . }} 12 + {{ block "register" . }} {{ end }} 13 + </div> 14 + </section> 16 15 {{ end }} 17 16 18 17 {{ define "about" }} 19 18 <section class="rounded flex flex-col gap-2"> 20 19 <p class="dark:text-gray-300"> 21 - Knots are lightweight headless servers that enable users to host Git 22 - repositories with ease. Knots are designed for either single or 23 - multi-tenant use which is perfect for self-hosting on a Raspberry Pi at 24 - home, or larger “community” servers. When creating a repository, you can 25 - choose a knot to store it on. 26 - <a 27 - href="https://tangled.sh/@tangled.sh/core/blob/master/docs/knot-hosting.md"> 20 + Knots are lightweight headless servers that enable users to host Git repositories with ease. 21 + Knots are designed for either single or multi-tenant use which is perfect for self-hosting on a Raspberry Pi at home, or larger “community” servers. 22 + When creating a repository, you can choose a knot to store it on. 23 + <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/knot-hosting.md"> 28 24 Checkout the documentation if you're interested in self-hosting. 29 25 </a> 30 26 </p> ··· 29 33 30 34 {{ define "register" }} 31 35 <section class="rounded max-w-2xl flex flex-col gap-2"> 32 - <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300"> 33 - register a knot 34 - </h2> 35 - <p class="mb-2 dark:text-gray-300"> 36 - Enter the hostname of your knot to generate a key. 37 - </p> 36 + <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300">register a knot</h2> 37 + <p class="mb-2 dark:text-gray-300">Enter the hostname of your knot to generate a key.</p> 38 38 <form 39 39 hx-post="/knots/key" 40 40 class="space-y-4" 41 41 hx-indicator="#register-button" 42 - hx-swap="none"> 42 + hx-swap="none" 43 + > 43 44 <div class="flex gap-2"> 44 45 <input 45 46 type="text" ··· 44 51 name="domain" 45 52 placeholder="knot.example.com" 46 53 required 47 - class="flex-1 w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" /> 54 + class="flex-1 w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" 55 + > 48 56 <button 49 57 type="submit" 50 58 id="register-button" 51 - class="btn rounded flex items-center py-2 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 group"> 59 + class="btn rounded flex items-center py-2 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 group" 60 + > 52 61 <span class="inline-flex items-center gap-2"> 53 62 {{ i "plus" "w-4 h-4" }} 54 63 generate
+52 -56
appview/pages/templates/layouts/base.html
··· 1 1 {{ define "layouts/base" }} 2 - <!doctype html> 3 - <html lang="en" class="dark:bg-gray-900"> 4 - <head> 5 - <meta charset="UTF-8" /> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <meta name="htmx-config" content='{"includeIndicatorStyles": false}' /> 8 - <script src="/static/htmx.min.js"></script> 9 - <script src="/static/htmx-ext-ws.min.js"></script> 10 - <link 11 - rel="stylesheet" 12 - href="/static/tw.css?{{ cssContentHash }}" 13 - type="text/css" /> 14 - <title>{{ block "title" . }}{{ end }} · tangled</title> 15 - {{ block "extrameta" . }}{{ end }} 16 - </head> 17 - <body 18 - class="min-h-screen grid grid-cols-1 grid-rows-[min-content_auto_min-content] md:grid-cols-12 gap-4 bg-slate-100 dark:bg-gray-900 dark:text-white transition-colors duration-200"> 19 - {{ block "topbarLayout" . }} 20 - <header 21 - class="px-1 col-span-1 md:col-start-3 md:col-span-8" 22 - style="z-index: 20;"> 23 - {{ template "layouts/topbar" . }} 24 - </header> 25 - {{ end }} 2 + <!doctype html> 3 + <html lang="en" class="dark:bg-gray-900"> 4 + <head> 5 + <meta charset="UTF-8" /> 6 + <meta 7 + name="viewport" 8 + content="width=device-width, initial-scale=1.0" 9 + /> 10 + <meta name="htmx-config" content='{"includeIndicatorStyles": false}'> 11 + <script src="/static/htmx.min.js"></script> 12 + <script src="/static/htmx-ext-ws.min.js"></script> 13 + <link rel="stylesheet" href="/static/tw.css?{{ cssContentHash }}" type="text/css" /> 14 + <title>{{ block "title" . }}{{ end }} · tangled</title> 15 + {{ block "extrameta" . }}{{ end }} 16 + </head> 17 + <body class="min-h-screen grid grid-cols-1 grid-rows-[min-content_auto_min-content] md:grid-cols-12 gap-4 bg-slate-100 dark:bg-gray-900 dark:text-white transition-colors duration-200"> 18 + {{ block "topbarLayout" . }} 19 + <header class="px-1 col-span-1 md:col-start-3 md:col-span-8" style="z-index: 20;"> 20 + {{ template "layouts/topbar" . }} 21 + </header> 22 + {{ end }} 26 23 27 - {{ block "mainLayout" . }} 28 - <div 29 - class="px-1 col-span-1 md:col-start-3 md:col-span-8 flex flex-col gap-4"> 30 - {{ block "contentLayout" . }} 31 - <div class="col-span-1 md:col-span-2"> 32 - {{ block "contentLeft" . }}{{ end }} 33 - </div> 34 - <main class="col-span-1 md:col-span-8"> 35 - {{ block "content" . }}{{ end }} 36 - </main> 37 - <div class="col-span-1 md:col-span-2"> 38 - {{ block "contentRight" . }}{{ end }} 24 + {{ block "mainLayout" . }} 25 + <div class="px-1 col-span-1 md:col-start-3 md:col-span-8 flex flex-col gap-4"> 26 + {{ block "contentLayout" . }} 27 + <div class="col-span-1 md:col-span-2"> 28 + {{ block "contentLeft" . }} {{ end }} 29 + </div> 30 + <main class="col-span-1 md:col-span-8"> 31 + {{ block "content" . }}{{ end }} 32 + </main> 33 + <div class="col-span-1 md:col-span-2"> 34 + {{ block "contentRight" . }} {{ end }} 35 + </div> 36 + {{ end }} 37 + 38 + {{ block "contentAfterLayout" . }} 39 + <div class="col-span-1 md:col-span-2"> 40 + {{ block "contentAfterLeft" . }} {{ end }} 41 + </div> 42 + <main class="col-span-1 md:col-span-8"> 43 + {{ block "contentAfter" . }}{{ end }} 44 + </main> 45 + <div class="col-span-1 md:col-span-2"> 46 + {{ block "contentAfterRight" . }} {{ end }} 47 + </div> 48 + {{ end }} 39 49 </div> 40 50 {{ end }} 41 51 42 - {{ block "contentAfterLayout" . }} 43 - <div class="col-span-1 md:col-span-2"> 44 - {{ block "contentAfterLeft" . }}{{ end }} 45 - </div> 46 - <main class="col-span-1 md:col-span-8"> 47 - {{ block "contentAfter" . }}{{ end }} 48 - </main> 49 - <div class="col-span-1 md:col-span-2"> 50 - {{ block "contentAfterRight" . }}{{ end }} 51 - </div> 52 + {{ block "footerLayout" . }} 53 + <footer class="px-1 col-span-1 md:col-start-3 md:col-span-8 mt-12"> 54 + {{ template "layouts/footer" . }} 55 + </footer> 52 56 {{ end }} 53 - </div> 54 - {{ end }} 55 - 56 - {{ block "footerLayout" . }} 57 - <footer class="px-1 col-span-1 md:col-start-3 md:col-span-8 mt-12"> 58 - {{ template "layouts/footer" . }} 59 - </footer> 60 - {{ end }} 61 - </body> 62 - </html> 57 + </body> 58 + </html> 63 59 {{ end }}
+38 -84
appview/pages/templates/layouts/footer.html
··· 1 1 {{ define "layouts/footer" }} 2 - <div 3 - class="w-full p-4 md:p-8 bg-white dark:bg-gray-800 rounded-t drop-shadow-sm"> 4 - <div class="container mx-auto max-w-7xl px-4"> 5 - <div 6 - class="flex flex-col lg:flex-row justify-between items-start text-gray-600 dark:text-gray-400 text-sm gap-8"> 7 - <div class="mb-4 md:mb-0"> 8 - <a href="/" hx-boost="true" class="flex gap-2 font-semibold italic"> 9 - tangled 10 - <sub>alpha</sub> 11 - </a> 2 + <div class="w-full p-4 md:p-8 bg-white dark:bg-gray-800 rounded-t drop-shadow-sm"> 3 + <div class="container mx-auto max-w-7xl px-4"> 4 + <div class="flex flex-col lg:flex-row justify-between items-start text-gray-600 dark:text-gray-400 text-sm gap-8"> 5 + <div class="mb-4 md:mb-0"> 6 + <a href="/" hx-boost="true" class="flex gap-2 font-semibold italic"> 7 + tangled<sub>alpha</sub> 8 + </a> 9 + </div> 10 + 11 + {{ $headerStyle := "text-gray-900 dark:text-gray-200 font-bold text-xs uppercase tracking-wide mb-1" }} 12 + {{ $linkStyle := "text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 hover:underline inline-flex gap-1 items-center" }} 13 + {{ $iconStyle := "w-4 h-4 flex-shrink-0" }} 14 + <div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-4 sm:gap-6 md:gap-2 gap-6 flex-1"> 15 + <div class="flex flex-col gap-1"> 16 + <div class="{{ $headerStyle }}">legal</div> 17 + <a href="/terms" class="{{ $linkStyle }}">{{ i "file-text" $iconStyle }} terms of service</a> 18 + <a href="/privacy" class="{{ $linkStyle }}">{{ i "shield" $iconStyle }} privacy policy</a> 12 19 </div> 13 20 14 - {{ $headerStyle := "text-gray-900 dark:text-gray-200 font-bold text-xs uppercase tracking-wide mb-1" }} 15 - {{ $linkStyle := "text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 hover:underline inline-flex gap-1 items-center" }} 16 - {{ $iconStyle := "w-4 h-4 flex-shrink-0" }} 17 - <div 18 - class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-4 sm:gap-6 md:gap-2 gap-6 flex-1"> 19 - <div class="flex flex-col gap-1"> 20 - <div class="{{ $headerStyle }}">legal</div> 21 - <a href="/terms" class="{{ $linkStyle }}"> 22 - {{ i "file-text" $iconStyle }} terms of service 23 - </a> 24 - <a href="/privacy" class="{{ $linkStyle }}"> 25 - {{ i "shield" $iconStyle }} privacy policy 26 - </a> 27 - </div> 28 - 29 - <div class="flex flex-col gap-1"> 30 - <div class="{{ $headerStyle }}">resources</div> 31 - <a 32 - href="https://blog.tangled.sh" 33 - class="{{ $linkStyle }}" 34 - target="_blank" 35 - rel="noopener noreferrer"> 36 - {{ i "book-open" $iconStyle }} blog 37 - </a> 38 - <a 39 - href="https://tangled.sh/@tangled.sh/core/tree/master/docs" 40 - class="{{ $linkStyle }}"> 41 - {{ i "book" $iconStyle }} docs 42 - </a> 43 - <a 44 - href="https://tangled.sh/@tangled.sh/core" 45 - class="{{ $linkStyle }}"> 46 - {{ i "code" $iconStyle }} source 47 - </a> 48 - </div> 49 - 50 - <div class="flex flex-col gap-1"> 51 - <div class="{{ $headerStyle }}">social</div> 52 - <a 53 - href="https://chat.tangled.sh" 54 - class="{{ $linkStyle }}" 55 - target="_blank" 56 - rel="noopener noreferrer"> 57 - {{ i "message-circle" $iconStyle }} discord 58 - </a> 59 - <a 60 - href="https://web.libera.chat/#tangled" 61 - class="{{ $linkStyle }}" 62 - target="_blank" 63 - rel="noopener noreferrer"> 64 - {{ i "hash" $iconStyle }} irc 65 - </a> 66 - <a 67 - href="https://bsky.app/profile/tangled.sh" 68 - class="{{ $linkStyle }}" 69 - target="_blank" 70 - rel="noopener noreferrer"> 71 - {{ template "user/fragments/bluesky" $iconStyle }} bluesky 72 - </a> 73 - </div> 74 - 75 - <div class="flex flex-col gap-1"> 76 - <div class="{{ $headerStyle }}">contact</div> 77 - <a href="mailto:team@tangled.sh" class="{{ $linkStyle }}"> 78 - {{ i "mail" "w-4 h-4 flex-shrink-0" }} team@tangled.sh 79 - </a> 80 - <a href="mailto:security@tangled.sh" class="{{ $linkStyle }}"> 81 - {{ i "shield-check" "w-4 h-4 flex-shrink-0" }} security@tangled.sh 82 - </a> 83 - </div> 21 + <div class="flex flex-col gap-1"> 22 + <div class="{{ $headerStyle }}">resources</div> 23 + <a href="https://blog.tangled.sh" class="{{ $linkStyle }}" target="_blank" rel="noopener noreferrer">{{ i "book-open" $iconStyle }} blog</a> 24 + <a href="https://tangled.sh/@tangled.sh/core/tree/master/docs" class="{{ $linkStyle }}">{{ i "book" $iconStyle }} docs</a> 25 + <a href="https://tangled.sh/@tangled.sh/core" class="{{ $linkStyle }}">{{ i "code" $iconStyle }} source</a> 84 26 </div> 85 27 86 - <div class="text-center lg:text-right flex-shrink-0"> 87 - <div class="text-xs"> 88 - &copy; 2025 Tangled Labs Oy. All rights reserved. 89 - </div> 28 + <div class="flex flex-col gap-1"> 29 + <div class="{{ $headerStyle }}">social</div> 30 + <a href="https://chat.tangled.sh" class="{{ $linkStyle }}" target="_blank" rel="noopener noreferrer">{{ i "message-circle" $iconStyle }} discord</a> 31 + <a href="https://web.libera.chat/#tangled" class="{{ $linkStyle }}" target="_blank" rel="noopener noreferrer">{{ i "hash" $iconStyle }} irc</a> 32 + <a href="https://bsky.app/profile/tangled.sh" class="{{ $linkStyle }}" target="_blank" rel="noopener noreferrer">{{ template "user/fragments/bluesky" $iconStyle }} bluesky</a> 90 33 </div> 34 + 35 + <div class="flex flex-col gap-1"> 36 + <div class="{{ $headerStyle }}">contact</div> 37 + <a href="mailto:team@tangled.sh" class="{{ $linkStyle }}">{{ i "mail" "w-4 h-4 flex-shrink-0" }} team@tangled.sh</a> 38 + <a href="mailto:security@tangled.sh" class="{{ $linkStyle }}">{{ i "shield-check" "w-4 h-4 flex-shrink-0" }} security@tangled.sh</a> 39 + </div> 40 + </div> 41 + 42 + <div class="text-center lg:text-right flex-shrink-0"> 43 + <div class="text-xs">&copy; 2025 Tangled Labs Oy. All rights reserved.</div> 91 44 </div> 92 45 </div> 93 46 </div> 47 + </div> 94 48 {{ end }}
+61 -66
appview/pages/templates/layouts/topbar.html
··· 1 1 {{ define "layouts/topbar" }} 2 - <nav 3 - class="space-x-4 px-6 py-2 rounded bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm"> 4 - <div class="flex justify-between p-0 items-center"> 5 - <div id="left-items"> 6 - <a href="/" hx-boost="true" class="flex gap-2 font-bold italic"> 7 - tangled 8 - <sub>alpha</sub> 9 - </a> 10 - </div> 2 + <nav class="space-x-4 px-6 py-2 rounded bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm"> 3 + <div class="flex justify-between p-0 items-center"> 4 + <div id="left-items"> 5 + <a href="/" hx-boost="true" class="flex gap-2 font-bold italic"> 6 + tangled<sub>alpha</sub> 7 + </a> 8 + </div> 11 9 12 - <div id="right-items" class="flex items-center gap-2"> 13 - {{ with .LoggedInUser }} 14 - {{ block "newButton" . }}{{ end }} 15 - {{ block "dropDown" . }}{{ end }} 16 - {{ else }} 17 - <a href="/login">login</a> 18 - <span class="text-gray-500 dark:text-gray-400">or</span> 19 - <a 20 - href="/signup" 21 - class="btn-create py-0 hover:no-underline hover:text-white flex items-center gap-2"> 22 - join now 23 - {{ i "arrow-right" "size-4" }} 24 - </a> 25 - {{ end }} 26 - </div> 27 - </div> 28 - </nav> 10 + <div id="right-items" class="flex items-center gap-2"> 11 + {{ with .LoggedInUser }} 12 + {{ block "newButton" . }} {{ end }} 13 + {{ block "dropDown" . }} {{ end }} 14 + {{ else }} 15 + <a href="/login">login</a> 16 + <span class="text-gray-500 dark:text-gray-400">or</span> 17 + <a href="/signup" class="btn-create py-0 hover:no-underline hover:text-white flex items-center gap-2"> 18 + join now {{ i "arrow-right" "size-4" }} 19 + </a> 20 + {{ end }} 21 + </div> 22 + </div> 23 + </nav> 29 24 {{ end }} 30 25 31 26 {{ define "newButton" }} 32 - <details class="relative inline-block text-left nav-dropdown"> 33 - <summary 34 - class="btn-create py-0 cursor-pointer list-none flex items-center gap-2"> 27 + <details class="relative inline-block text-left nav-dropdown"> 28 + <summary class="btn-create py-0 cursor-pointer list-none flex items-center gap-2"> 35 29 {{ i "plus" "w-4 h-4" }} new 36 30 </summary> 37 - <div 38 - class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700"> 39 - <a href="/repo/new" class="flex items-center gap-2"> 40 - {{ i "book-plus" "w-4 h-4" }} 41 - new repository 42 - </a> 43 - <a href="/strings/new" class="flex items-center gap-2"> 44 - {{ i "line-squiggle" "w-4 h-4" }} 45 - new string 46 - </a> 31 + <div class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700"> 32 + <a href="/repo/new" class="flex items-center gap-2"> 33 + {{ i "book-plus" "w-4 h-4" }} 34 + new repository 35 + </a> 36 + <a href="/strings/new" class="flex items-center gap-2"> 37 + {{ i "line-squiggle" "w-4 h-4" }} 38 + new string 39 + </a> 47 40 </div> 48 - </details> 41 + </details> 49 42 {{ end }} 50 43 51 44 {{ define "dropDown" }} 52 - <details class="relative inline-block text-left nav-dropdown"> 53 - <summary class="cursor-pointer list-none flex items-center"> 54 - {{ $user := didOrHandle .Did .Handle }} 55 - {{ template "user/fragments/picHandle" $user }} 45 + <details class="relative inline-block text-left nav-dropdown"> 46 + <summary 47 + class="cursor-pointer list-none flex items-center" 48 + > 49 + {{ $user := didOrHandle .Did .Handle }} 50 + {{ template "user/fragments/picHandle" $user }} 56 51 </summary> 57 52 <div 58 - class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700"> 59 - <a href="/{{ $user }}">profile</a> 60 - <a href="/{{ $user }}?tab=repos">repositories</a> 61 - <a href="/strings/{{ $user }}">strings</a> 62 - <a href="/knots">knots</a> 63 - <a href="/spindles">spindles</a> 64 - <a href="/settings">settings</a> 65 - <a 66 - href="#" 67 - hx-post="/logout" 68 - hx-swap="none" 69 - class="text-red-400 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"> 70 - logout 71 - </a> 53 + class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700" 54 + > 55 + <a href="/{{ $user }}">profile</a> 56 + <a href="/{{ $user }}?tab=repos">repositories</a> 57 + <a href="/strings/{{ $user }}">strings</a> 58 + <a href="/knots">knots</a> 59 + <a href="/spindles">spindles</a> 60 + <a href="/settings">settings</a> 61 + <a href="#" 62 + hx-post="/logout" 63 + hx-swap="none" 64 + class="text-red-400 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"> 65 + logout 66 + </a> 72 67 </div> 73 - </details> 68 + </details> 74 69 75 - <script> 76 - document.addEventListener("click", function (event) { 77 - const dropdowns = document.querySelectorAll(".nav-dropdown"); 78 - dropdowns.forEach(function (dropdown) { 70 + <script> 71 + document.addEventListener('click', function(event) { 72 + const dropdowns = document.querySelectorAll('.nav-dropdown'); 73 + dropdowns.forEach(function(dropdown) { 79 74 if (!dropdown.contains(event.target)) { 80 - dropdown.removeAttribute("open"); 75 + dropdown.removeAttribute('open'); 81 76 } 82 - }); 83 77 }); 84 - </script> 78 + }); 79 + </script> 85 80 {{ end }}
+65 -155
appview/pages/templates/legal/privacy.html
··· 1 - {{ define "title" }}privacy policy{{ end }} 1 + {{ define "title" }} privacy policy {{ end }} 2 2 {{ define "content" }} 3 - <div class="max-w-4xl mx-auto px-4 py-8"> 3 + <div class="max-w-4xl mx-auto px-4 py-8"> 4 4 <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm p-8"> 5 - <div class="prose prose-gray dark:prose-invert max-w-none"> 5 + <div class="prose prose-gray dark:prose-invert max-w-none"> 6 6 <h1>Privacy Policy</h1> 7 7 8 - <p> 9 - <strong>Last updated:</strong> 10 - {{ now.Format "January 2, 2006" }} 11 - </p> 8 + <p><strong>Last updated:</strong> {{ now.Format "January 2, 2006" }}</p> 12 9 13 - <p> 14 - This Privacy Policy describes how Tangled ("we," "us," or "our") 15 - collects, uses, and shares your personal information when you use our 16 - platform and services (the "Service"). 17 - </p> 10 + <p>This Privacy Policy describes how Tangled ("we," "us," or "our") collects, uses, and shares your personal information when you use our platform and services (the "Service").</p> 18 11 19 12 <h2>1. Information We Collect</h2> 20 13 21 14 <h3>Account Information</h3> 22 15 <p>When you create an account, we collect:</p> 23 16 <ul> 24 - <li>Your chosen username</li> 25 - <li>Email address</li> 26 - <li>Profile information you choose to provide</li> 27 - <li>Authentication data</li> 17 + <li>Your chosen username</li> 18 + <li>Email address</li> 19 + <li>Profile information you choose to provide</li> 20 + <li>Authentication data</li> 28 21 </ul> 29 22 30 23 <h3>Content and Activity</h3> 31 24 <p>We store:</p> 32 25 <ul> 33 - <li>Code repositories and associated metadata</li> 34 - <li>Issues, pull requests, and comments</li> 35 - <li>Activity logs and usage patterns</li> 36 - <li>Public keys for authentication</li> 26 + <li>Code repositories and associated metadata</li> 27 + <li>Issues, pull requests, and comments</li> 28 + <li>Activity logs and usage patterns</li> 29 + <li>Public keys for authentication</li> 37 30 </ul> 38 31 39 32 <h2>2. Data Location and Hosting</h2> 40 - <div 41 - class="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4 my-6"> 42 - <h3 class="text-blue-800 dark:text-blue-200 font-semibold mb-2"> 43 - EU Data Hosting 44 - </h3> 45 - <p class="text-blue-700 dark:text-blue-300"> 46 - <strong> 47 - All Tangled service data is hosted within the European Union. 48 - </strong> 49 - Specifically: 50 - </p> 51 - <ul class="text-blue-700 dark:text-blue-300 mt-2"> 52 - <li> 53 - <strong>Personal Data Servers (PDS):</strong> 54 - Accounts hosted on Tangled PDS (*.tngl.sh) are located in Finland 55 - </li> 56 - <li> 57 - <strong>Application Data:</strong> 58 - All other service data is stored on EU-based servers 59 - </li> 60 - <li> 61 - <strong>Data Processing:</strong> 62 - All data processing occurs within EU jurisdiction 63 - </li> 64 - </ul> 33 + <div class="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4 my-6"> 34 + <h3 class="text-blue-800 dark:text-blue-200 font-semibold mb-2">EU Data Hosting</h3> 35 + <p class="text-blue-700 dark:text-blue-300"> 36 + <strong>All Tangled service data is hosted within the European Union.</strong> Specifically: 37 + </p> 38 + <ul class="text-blue-700 dark:text-blue-300 mt-2"> 39 + <li><strong>Personal Data Servers (PDS):</strong> Accounts hosted on Tangled PDS (*.tngl.sh) are located in Finland</li> 40 + <li><strong>Application Data:</strong> All other service data is stored on EU-based servers</li> 41 + <li><strong>Data Processing:</strong> All data processing occurs within EU jurisdiction</li> 42 + </ul> 65 43 </div> 66 44 67 - <div 68 - class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4 my-6"> 69 - <h3 class="text-yellow-800 dark:text-yellow-200 font-semibold mb-2"> 70 - External PDS Notice 71 - </h3> 72 - <p class="text-yellow-700 dark:text-yellow-300"> 73 - <strong>Important:</strong> 74 - If your account is hosted on Bluesky's PDS or other self-hosted 75 - Personal Data Servers (not *.tngl.sh), we do not control that data. 76 - The data protection, storage location, and privacy practices for 77 - such accounts are governed by the respective PDS provider's 78 - policies, not this Privacy Policy. We only control data processing 79 - within our own services and infrastructure. 80 - </p> 45 + <div class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4 my-6"> 46 + <h3 class="text-yellow-800 dark:text-yellow-200 font-semibold mb-2">External PDS Notice</h3> 47 + <p class="text-yellow-700 dark:text-yellow-300"> 48 + <strong>Important:</strong> If your account is hosted on Bluesky's PDS or other self-hosted Personal Data Servers (not *.tngl.sh), we do not control that data. The data protection, storage location, and privacy practices for such accounts are governed by the respective PDS provider's policies, not this Privacy Policy. We only control data processing within our own services and infrastructure. 49 + </p> 81 50 </div> 82 51 83 52 <h2>3. Third-Party Data Processors</h2> 84 - <p> 85 - We only share your data with the following third-party processors: 86 - </p> 53 + <p>We only share your data with the following third-party processors:</p> 87 54 88 55 <h3>Resend (Email Services)</h3> 89 56 <ul> 90 - <li> 91 - <strong>Purpose:</strong> 92 - Sending transactional emails (account verification, notifications) 93 - </li> 94 - <li> 95 - <strong>Data Shared:</strong> 96 - Email address and necessary message content 97 - </li> 98 - <li> 99 - <strong>Location:</strong> 100 - EU-compliant email delivery service 101 - </li> 57 + <li><strong>Purpose:</strong> Sending transactional emails (account verification, notifications)</li> 58 + <li><strong>Data Shared:</strong> Email address and necessary message content</li> 59 + <li><strong>Location:</strong> EU-compliant email delivery service</li> 102 60 </ul> 103 61 104 62 <h3>Cloudflare (Image Caching)</h3> 105 63 <ul> 106 - <li> 107 - <strong>Purpose:</strong> 108 - Caching and optimizing image delivery 109 - </li> 110 - <li> 111 - <strong>Data Shared:</strong> 112 - Public images and associated metadata for caching purposes 113 - </li> 114 - <li> 115 - <strong>Location:</strong> 116 - Global CDN with EU data protection compliance 117 - </li> 64 + <li><strong>Purpose:</strong> Caching and optimizing image delivery</li> 65 + <li><strong>Data Shared:</strong> Public images and associated metadata for caching purposes</li> 66 + <li><strong>Location:</strong> Global CDN with EU data protection compliance</li> 118 67 </ul> 119 68 120 69 <h2>4. How We Use Your Information</h2> 121 70 <p>We use your information to:</p> 122 71 <ul> 123 - <li>Provide and maintain the Service</li> 124 - <li>Process your transactions and requests</li> 125 - <li>Send you technical notices and support messages</li> 126 - <li>Improve and develop new features</li> 127 - <li>Ensure security and prevent fraud</li> 128 - <li>Comply with legal obligations</li> 72 + <li>Provide and maintain the Service</li> 73 + <li>Process your transactions and requests</li> 74 + <li>Send you technical notices and support messages</li> 75 + <li>Improve and develop new features</li> 76 + <li>Ensure security and prevent fraud</li> 77 + <li>Comply with legal obligations</li> 129 78 </ul> 130 79 131 80 <h2>5. Data Sharing and Disclosure</h2> 132 - <p> 133 - We do not sell, trade, or rent your personal information. We may share 134 - your information only in the following circumstances: 135 - </p> 81 + <p>We do not sell, trade, or rent your personal information. We may share your information only in the following circumstances:</p> 136 82 <ul> 137 - <li>With the third-party processors listed above</li> 138 - <li>When required by law or legal process</li> 139 - <li> 140 - To protect our rights, property, or safety, or that of our users 141 - </li> 142 - <li> 143 - In connection with a merger, acquisition, or sale of assets (with 144 - appropriate protections) 145 - </li> 83 + <li>With the third-party processors listed above</li> 84 + <li>When required by law or legal process</li> 85 + <li>To protect our rights, property, or safety, or that of our users</li> 86 + <li>In connection with a merger, acquisition, or sale of assets (with appropriate protections)</li> 146 87 </ul> 147 88 148 89 <h2>6. Data Security</h2> 149 - <p> 150 - We implement appropriate technical and organizational measures to 151 - protect your personal information against unauthorized access, 152 - alteration, disclosure, or destruction. However, no method of 153 - transmission over the Internet is 100% secure. 154 - </p> 90 + <p>We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, disclosure, or destruction. However, no method of transmission over the Internet is 100% secure.</p> 155 91 156 92 <h2>7. Data Retention</h2> 157 - <p> 158 - We retain your personal information for as long as necessary to 159 - provide the Service and fulfill the purposes outlined in this Privacy 160 - Policy, unless a longer retention period is required by law. 161 - </p> 93 + <p>We retain your personal information for as long as necessary to provide the Service and fulfill the purposes outlined in this Privacy Policy, unless a longer retention period is required by law.</p> 162 94 163 95 <h2>8. Your Rights</h2> 164 96 <p>Under applicable data protection laws, you have the right to:</p> 165 97 <ul> 166 - <li>Access your personal information</li> 167 - <li>Correct inaccurate information</li> 168 - <li>Request deletion of your information</li> 169 - <li>Object to processing of your information</li> 170 - <li>Data portability</li> 171 - <li>Withdraw consent (where applicable)</li> 98 + <li>Access your personal information</li> 99 + <li>Correct inaccurate information</li> 100 + <li>Request deletion of your information</li> 101 + <li>Object to processing of your information</li> 102 + <li>Data portability</li> 103 + <li>Withdraw consent (where applicable)</li> 172 104 </ul> 173 105 174 106 <h2>9. Cookies and Tracking</h2> 175 107 <p>We use cookies and similar technologies to:</p> 176 108 <ul> 177 - <li>Maintain your login session</li> 178 - <li>Remember your preferences</li> 179 - <li>Analyze usage patterns to improve the Service</li> 109 + <li>Maintain your login session</li> 110 + <li>Remember your preferences</li> 111 + <li>Analyze usage patterns to improve the Service</li> 180 112 </ul> 181 113 <p>You can control cookie settings through your browser preferences.</p> 182 114 183 115 <h2>10. Children's Privacy</h2> 184 - <p> 185 - The Service is not intended for children under 16 years of age. We do 186 - not knowingly collect personal information from children under 16. If 187 - we become aware that we have collected such information, we will take 188 - steps to delete it. 189 - </p> 116 + <p>The Service is not intended for children under 16 years of age. We do not knowingly collect personal information from children under 16. If we become aware that we have collected such information, we will take steps to delete it.</p> 190 117 191 118 <h2>11. International Data Transfers</h2> 192 - <p> 193 - While all our primary data processing occurs within the EU, some of 194 - our third-party processors may process data outside the EU. When this 195 - occurs, we ensure appropriate safeguards are in place, such as 196 - Standard Contractual Clauses or adequacy decisions. 197 - </p> 119 + <p>While all our primary data processing occurs within the EU, some of our third-party processors may process data outside the EU. When this occurs, we ensure appropriate safeguards are in place, such as Standard Contractual Clauses or adequacy decisions.</p> 198 120 199 121 <h2>12. Changes to This Privacy Policy</h2> 200 - <p> 201 - We may update this Privacy Policy from time to time. We will notify 202 - you of any changes by posting the new Privacy Policy on this page and 203 - updating the "Last updated" date. 204 - </p> 122 + <p>We may update this Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page and updating the "Last updated" date.</p> 205 123 206 124 <h2>13. Contact Information</h2> 207 - <p> 208 - If you have any questions about this Privacy Policy or wish to 209 - exercise your rights, please contact us through our platform or via 210 - email. 211 - </p> 125 + <p>If you have any questions about this Privacy Policy or wish to exercise your rights, please contact us through our platform or via email.</p> 212 126 213 - <div 214 - class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700 text-sm text-gray-600 dark:text-gray-400"> 215 - <p> 216 - This Privacy Policy complies with the EU General Data Protection 217 - Regulation (GDPR) and other applicable data protection laws. 218 - </p> 127 + <div class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700 text-sm text-gray-600 dark:text-gray-400"> 128 + <p>This Privacy Policy complies with the EU General Data Protection Regulation (GDPR) and other applicable data protection laws.</p> 219 129 </div> 220 - </div> 130 + </div> 221 131 </div> 222 - </div> 132 + </div> 223 133 {{ end }}
+32 -118
appview/pages/templates/legal/terms.html
··· 1 1 {{ define "title" }}terms of service{{ end }} 2 2 3 3 {{ define "content" }} 4 - <div class="max-w-4xl mx-auto px-4 py-8"> 4 + <div class="max-w-4xl mx-auto px-4 py-8"> 5 5 <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm p-8"> 6 - <div class="prose prose-gray dark:prose-invert max-w-none"> 6 + <div class="prose prose-gray dark:prose-invert max-w-none"> 7 7 <h1>Terms of Service</h1> 8 8 9 - <p> 10 - <strong>Last updated:</strong> 11 - {{ now.Format "January 2, 2006" }} 12 - </p> 9 + <p><strong>Last updated:</strong> {{ now.Format "January 2, 2006" }}</p> 13 10 14 - <p> 15 - Welcome to Tangled. These Terms of Service ("Terms") govern your 16 - access to and use of the Tangled platform and services (the "Service") 17 - operated by us ("Tangled," "we," "us," or "our"). 18 - </p> 11 + <p>Welcome to Tangled. These Terms of Service ("Terms") govern your access to and use of the Tangled platform and services (the "Service") operated by us ("Tangled," "we," "us," or "our").</p> 19 12 20 13 <h2>1. Acceptance of Terms</h2> 21 - <p> 22 - By accessing or using our Service, you agree to be bound by these 23 - Terms. If you disagree with any part of these terms, then you may not 24 - access the Service. 25 - </p> 14 + <p>By accessing or using our Service, you agree to be bound by these Terms. If you disagree with any part of these terms, then you may not access the Service.</p> 26 15 27 16 <h2>2. Account Registration</h2> 28 - <p> 29 - To use certain features of the Service, you must register for an 30 - account. You agree to provide accurate, current, and complete 31 - information during the registration process and to update such 32 - information to keep it accurate, current, and complete. 33 - </p> 17 + <p>To use certain features of the Service, you must register for an account. You agree to provide accurate, current, and complete information during the registration process and to update such information to keep it accurate, current, and complete.</p> 34 18 35 19 <h2>3. Account Termination</h2> 36 - <div 37 - class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 my-6"> 38 - <h3 class="text-red-800 dark:text-red-200 font-semibold mb-2"> 39 - Important Notice 40 - </h3> 41 - <p class="text-red-700 dark:text-red-300"> 42 - <strong> 43 - We reserve the right to terminate, suspend, or restrict access to 44 - your account at any time, for any reason, or for no reason at all, 45 - at our sole discretion. 46 - </strong> 47 - This includes, but is not limited to, termination for violation of 48 - these Terms, inappropriate conduct, spam, abuse, or any other 49 - behavior we deem harmful to the Service or other users. 50 - </p> 51 - <p class="text-red-700 dark:text-red-300 mt-2"> 52 - Account termination may result in the loss of access to your 53 - repositories, data, and other content associated with your account. 54 - We are not obligated to provide advance notice of termination, 55 - though we may do so in our discretion. 56 - </p> 20 + <div class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 my-6"> 21 + <h3 class="text-red-800 dark:text-red-200 font-semibold mb-2">Important Notice</h3> 22 + <p class="text-red-700 dark:text-red-300"> 23 + <strong>We reserve the right to terminate, suspend, or restrict access to your account at any time, for any reason, or for no reason at all, at our sole discretion.</strong> This includes, but is not limited to, termination for violation of these Terms, inappropriate conduct, spam, abuse, or any other behavior we deem harmful to the Service or other users. 24 + </p> 25 + <p class="text-red-700 dark:text-red-300 mt-2"> 26 + Account termination may result in the loss of access to your repositories, data, and other content associated with your account. We are not obligated to provide advance notice of termination, though we may do so in our discretion. 27 + </p> 57 28 </div> 58 29 59 30 <h2>4. Acceptable Use</h2> 60 31 <p>You agree not to use the Service to:</p> 61 32 <ul> 62 - <li>Violate any applicable laws or regulations</li> 63 - <li>Infringe upon the rights of others</li> 64 - <li> 65 - Upload, store, or share content that is illegal, harmful, 66 - threatening, abusive, harassing, defamatory, vulgar, obscene, or 67 - otherwise objectionable 68 - </li> 69 - <li>Engage in spam, phishing, or other deceptive practices</li> 70 - <li> 71 - Attempt to gain unauthorized access to the Service or other users' 72 - accounts 73 - </li> 74 - <li> 75 - Interfere with or disrupt the Service or servers connected to the 76 - Service 77 - </li> 33 + <li>Violate any applicable laws or regulations</li> 34 + <li>Infringe upon the rights of others</li> 35 + <li>Upload, store, or share content that is illegal, harmful, threatening, abusive, harassing, defamatory, vulgar, obscene, or otherwise objectionable</li> 36 + <li>Engage in spam, phishing, or other deceptive practices</li> 37 + <li>Attempt to gain unauthorized access to the Service or other users' accounts</li> 38 + <li>Interfere with or disrupt the Service or servers connected to the Service</li> 78 39 </ul> 79 40 80 41 <h2>5. Content and Intellectual Property</h2> 81 - <p> 82 - You retain ownership of the content you upload to the Service. By 83 - uploading content, you grant us a non-exclusive, worldwide, 84 - royalty-free license to use, reproduce, modify, and distribute your 85 - content as necessary to provide the Service. 86 - </p> 42 + <p>You retain ownership of the content you upload to the Service. By uploading content, you grant us a non-exclusive, worldwide, royalty-free license to use, reproduce, modify, and distribute your content as necessary to provide the Service.</p> 87 43 88 44 <h2>6. Privacy</h2> 89 - <p> 90 - Your privacy is important to us. Please review our 91 - <a 92 - href="/privacy" 93 - class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"> 94 - Privacy Policy 95 - </a> 96 - , which also governs your use of the Service. 97 - </p> 45 + <p>Your privacy is important to us. Please review our <a href="/privacy" class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300">Privacy Policy</a>, which also governs your use of the Service.</p> 98 46 99 47 <h2>7. Disclaimers</h2> 100 - <p> 101 - The Service is provided on an "AS IS" and "AS AVAILABLE" basis. We 102 - make no warranties, expressed or implied, and hereby disclaim and 103 - negate all other warranties including without limitation, implied 104 - warranties or conditions of merchantability, fitness for a particular 105 - purpose, or non-infringement of intellectual property or other 106 - violation of rights. 107 - </p> 48 + <p>The Service is provided on an "AS IS" and "AS AVAILABLE" basis. We make no warranties, expressed or implied, and hereby disclaim and negate all other warranties including without limitation, implied warranties or conditions of merchantability, fitness for a particular purpose, or non-infringement of intellectual property or other violation of rights.</p> 108 49 109 50 <h2>8. Limitation of Liability</h2> 110 - <p> 111 - In no event shall Tangled, nor its directors, employees, partners, 112 - agents, suppliers, or affiliates, be liable for any indirect, 113 - incidental, special, consequential, or punitive damages, including 114 - without limitation, loss of profits, data, use, goodwill, or other 115 - intangible losses, resulting from your use of the Service. 116 - </p> 51 + <p>In no event shall Tangled, nor its directors, employees, partners, agents, suppliers, or affiliates, be liable for any indirect, incidental, special, consequential, or punitive damages, including without limitation, loss of profits, data, use, goodwill, or other intangible losses, resulting from your use of the Service.</p> 117 52 118 53 <h2>9. Indemnification</h2> 119 - <p> 120 - You agree to defend, indemnify, and hold harmless Tangled and its 121 - affiliates, officers, directors, employees, and agents from and 122 - against any and all claims, damages, obligations, losses, liabilities, 123 - costs, or debt, and expenses (including attorney's fees). 124 - </p> 54 + <p>You agree to defend, indemnify, and hold harmless Tangled and its affiliates, officers, directors, employees, and agents from and against any and all claims, damages, obligations, losses, liabilities, costs, or debt, and expenses (including attorney's fees).</p> 125 55 126 56 <h2>10. Governing Law</h2> 127 - <p> 128 - These Terms shall be interpreted and governed by the laws of Finland, 129 - without regard to its conflict of law provisions. 130 - </p> 57 + <p>These Terms shall be interpreted and governed by the laws of Finland, without regard to its conflict of law provisions.</p> 131 58 132 59 <h2>11. Changes to Terms</h2> 133 - <p> 134 - We reserve the right to modify or replace these Terms at any time. If 135 - a revision is material, we will try to provide at least 30 days notice 136 - prior to any new terms taking effect. 137 - </p> 60 + <p>We reserve the right to modify or replace these Terms at any time. If a revision is material, we will try to provide at least 30 days notice prior to any new terms taking effect.</p> 138 61 139 62 <h2>12. Contact Information</h2> 140 - <p> 141 - If you have any questions about these Terms of Service, please contact 142 - us through our platform or via email. 143 - </p> 63 + <p>If you have any questions about these Terms of Service, please contact us through our platform or via email.</p> 144 64 145 - <div 146 - class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700 text-sm text-gray-600 dark:text-gray-400"> 147 - <p> 148 - These terms are effective as of the last updated date shown above 149 - and will remain in effect except with respect to any changes in 150 - their provisions in the future, which will be in effect immediately 151 - after being posted on this page. 152 - </p> 65 + <div class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700 text-sm text-gray-600 dark:text-gray-400"> 66 + <p>These terms are effective as of the last updated date shown above and will remain in effect except with respect to any changes in their provisions in the future, which will be in effect immediately after being posted on this page.</p> 153 67 </div> 154 - </div> 68 + </div> 155 69 </div> 156 - </div> 70 + </div> 157 71 {{ end }}
+70 -93
appview/pages/templates/repo/blob.html
··· 1 - {{ define "title" }} 2 - {{ .Path }} at {{ .Ref }} &middot; 3 - {{ .RepoInfo.FullName }} 4 - {{ end }} 1 + {{ define "title" }}{{ .Path }} at {{ .Ref }} &middot; {{ .RepoInfo.FullName }}{{ end }} 5 2 6 3 {{ define "extrameta" }} 7 - {{ template "repo/fragments/meta" . }} 4 + {{ template "repo/fragments/meta" . }} 8 5 9 - {{ $title := printf "%s at %s &middot; %s" .Path .Ref .RepoInfo.FullName }} 10 - {{ $url := printf "https://tangled.sh/%s/blob/%s/%s" .RepoInfo.FullName .Ref .Path }} 6 + {{ $title := printf "%s at %s &middot; %s" .Path .Ref .RepoInfo.FullName }} 7 + {{ $url := printf "https://tangled.sh/%s/blob/%s/%s" .RepoInfo.FullName .Ref .Path }} 11 8 12 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 9 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 10 + 13 11 {{ end }} 14 12 15 13 {{ define "repoContent" }} 16 - {{ $lines := split .Contents }} 17 - {{ $tot_lines := len $lines }} 18 - {{ $tot_chars := len (printf "%d" $tot_lines) }} 19 - {{ $code_number_style := "text-gray-400 dark:text-gray-500 left-0 bg-white dark:bg-gray-800 text-right mr-6 select-none inline-block w-12" }} 20 - {{ $linkstyle := "no-underline hover:underline" }} 21 - <div 22 - class="pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700"> 23 - <div class="flex flex-col md:flex-row md:justify-between gap-2"> 24 - <div 25 - id="breadcrumbs" 26 - class="overflow-x-auto whitespace-nowrap text-gray-400 dark:text-gray-500"> 27 - {{ range $idx, $value := .BreadCrumbs }} 28 - {{ if ne $idx (sub (len $.BreadCrumbs) 1) }} 29 - <a 30 - href="{{ index . 1 }}" 31 - class="text-bold text-gray-500 dark:text-gray-400 {{ $linkstyle }}"> 32 - {{ pathUnescape (index . 0) }} 33 - </a> 34 - / 35 - {{ else }} 36 - <span class="text-bold text-black dark:text-white"> 37 - {{ pathUnescape (index . 0) }} 38 - </span> 39 - {{ end }} 40 - {{ end }} 41 - </div> 42 - <div 43 - id="file-info" 44 - class="text-gray-500 dark:text-gray-400 text-xs md:text-sm flex flex-wrap items-center gap-1 md:gap-0"> 45 - <span> 46 - at 47 - <a href="/{{ .RepoInfo.FullName }}/tree/{{ .Ref }}">{{ .Ref }}</a> 48 - </span> 49 - <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 50 - <span>{{ .Lines }} lines</span> 51 - <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 52 - <span>{{ byteFmt .SizeHint }}</span> 53 - <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 54 - <a href="/{{ .RepoInfo.FullName }}/raw/{{ .Ref }}/{{ .Path }}"> 55 - view raw 56 - </a> 57 - {{ if .RenderToggle }} 58 - <span 59 - class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 60 - <a 61 - href="/{{ .RepoInfo.FullName }}/blob/{{ .Ref }}/{{ .Path }}?code={{ .ShowRendered }}" 62 - hx-boost="true"> 63 - view {{ if .ShowRendered }}code{{ else }}rendered{{ end }} 64 - </a> 65 - {{ end }} 66 - </div> 14 + {{ $lines := split .Contents }} 15 + {{ $tot_lines := len $lines }} 16 + {{ $tot_chars := len (printf "%d" $tot_lines) }} 17 + {{ $code_number_style := "text-gray-400 dark:text-gray-500 left-0 bg-white dark:bg-gray-800 text-right mr-6 select-none inline-block w-12" }} 18 + {{ $linkstyle := "no-underline hover:underline" }} 19 + <div class="pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700"> 20 + <div class="flex flex-col md:flex-row md:justify-between gap-2"> 21 + <div id="breadcrumbs" class="overflow-x-auto whitespace-nowrap text-gray-400 dark:text-gray-500"> 22 + {{ range $idx, $value := .BreadCrumbs }} 23 + {{ if ne $idx (sub (len $.BreadCrumbs) 1) }} 24 + <a 25 + href="{{ index . 1 }}" 26 + class="text-bold text-gray-500 dark:text-gray-400 {{ $linkstyle }}" 27 + >{{ pathUnescape (index . 0) }}</a 28 + > 29 + / 30 + {{ else }} 31 + <span class="text-bold text-black dark:text-white" 32 + >{{ pathUnescape (index . 0) }}</span 33 + > 34 + {{ end }} 35 + {{ end }} 36 + </div> 37 + <div id="file-info" class="text-gray-500 dark:text-gray-400 text-xs md:text-sm flex flex-wrap items-center gap-1 md:gap-0"> 38 + <span>at <a href="/{{ .RepoInfo.FullName }}/tree/{{ .Ref }}">{{ .Ref }}</a></span> 39 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 40 + <span>{{ .Lines }} lines</span> 41 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 42 + <span>{{ byteFmt .SizeHint }}</span> 43 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 44 + <a href="/{{ .RepoInfo.FullName }}/raw/{{ .Ref }}/{{ .Path }}">view raw</a> 45 + {{ if .RenderToggle }} 46 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 47 + <a 48 + href="/{{ .RepoInfo.FullName }}/blob/{{ .Ref }}/{{ .Path }}?code={{ .ShowRendered }}" 49 + hx-boost="true" 50 + >view {{ if .ShowRendered }}code{{ else }}rendered{{ end }}</a> 51 + {{ end }} 52 + </div> 53 + </div> 67 54 </div> 68 - </div> 69 - {{ if and .IsBinary .Unsupported }} 70 - <p class="text-center text-gray-400 dark:text-gray-500"> 71 - Previews are not supported for this file type. 72 - </p> 73 - {{ else if .IsBinary }} 74 - <div class="text-center"> 75 - {{ if .IsImage }} 76 - <img 77 - src="{{ .ContentSrc }}" 78 - alt="{{ .Path }}" 79 - class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded" /> 80 - {{ else if .IsVideo }} 81 - <video 82 - controls 83 - class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded"> 84 - <source src="{{ .ContentSrc }}" /> 85 - Your browser does not support the video tag. 86 - </video> 87 - {{ end }} 88 - </div> 89 - {{ else }} 55 + {{ if and .IsBinary .Unsupported }} 56 + <p class="text-center text-gray-400 dark:text-gray-500"> 57 + Previews are not supported for this file type. 58 + </p> 59 + {{ else if .IsBinary }} 60 + <div class="text-center"> 61 + {{ if .IsImage }} 62 + <img src="{{ .ContentSrc }}" 63 + alt="{{ .Path }}" 64 + class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded" /> 65 + {{ else if .IsVideo }} 66 + <video controls class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded"> 67 + <source src="{{ .ContentSrc }}"> 68 + Your browser does not support the video tag. 69 + </video> 70 + {{ end }} 71 + </div> 72 + {{ else }} 90 73 <div class="overflow-auto relative"> 91 - {{ if .ShowRendered }} 92 - <div id="blob-contents" class="prose dark:prose-invert"> 93 - {{ .RenderedContents }} 94 - </div> 95 - {{ else }} 96 - <div 97 - id="blob-contents" 98 - class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900"> 99 - {{ $.Contents | escapeHtml }} 100 - </div> 101 - {{ end }} 74 + {{ if .ShowRendered }} 75 + <div id="blob-contents" class="prose dark:prose-invert">{{ .RenderedContents }}</div> 76 + {{ else }} 77 + <div id="blob-contents" class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900">{{ $.Contents | escapeHtml }}</div> 78 + {{ end }} 102 79 </div> 103 - {{ end }} 80 + {{ end }} 104 81 {{ end }}
+83 -116
appview/pages/templates/repo/branches.html
··· 1 1 {{ define "title" }} 2 - branches &middot; 3 - {{ .RepoInfo.FullName }} 2 + branches &middot; {{ .RepoInfo.FullName }} 4 3 {{ end }} 5 4 6 5 {{ define "extrameta" }} 7 - {{ $title := printf "branches &middot; %s" .RepoInfo.FullName }} 8 - {{ $url := printf "https://tangled.sh/%s/branches" .RepoInfo.FullName }} 9 - 10 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 6 + {{ $title := printf "branches &middot; %s" .RepoInfo.FullName }} 7 + {{ $url := printf "https://tangled.sh/%s/branches" .RepoInfo.FullName }} 8 + 9 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 11 10 {{ end }} 12 11 13 12 {{ define "repoContent" }} 14 - <section id="branches-table" class="overflow-x-auto"> 15 - <h2 class="font-bold text-sm mb-4 uppercase dark:text-white">Branches</h2> 13 + <section id="branches-table" class="overflow-x-auto"> 14 + <h2 class="font-bold text-sm mb-4 uppercase dark:text-white"> 15 + Branches 16 + </h2> 16 17 17 - <!-- desktop view (hidden on small screens) --> 18 - <table class="w-full border-collapse hidden md:table"> 19 - <thead> 20 - <tr> 21 - <th 22 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold"> 23 - Name 24 - </th> 25 - <th 26 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold"> 27 - Commit 28 - </th> 29 - <th 30 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold"> 31 - Message 32 - </th> 33 - <th 34 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold"> 35 - Date 36 - </th> 37 - </tr> 38 - </thead> 39 - <tbody> 40 - {{ range $index, $branch := .Branches }} 41 - <tr 42 - class="{{ if ne $index (sub (len $.Branches) 1) }} 43 - border-b border-gray-200 dark:border-gray-700 44 - {{ end }}"> 45 - <td class="py-3 whitespace-nowrap"> 46 - <a 47 - href="/{{ $.RepoInfo.FullName }}/tree/{{ .Name | urlquery }}" 48 - class="no-underline hover:underline flex items-center gap-2"> 49 - <span class="dark:text-white"> 50 - {{ .Name }} 51 - </span> 52 - {{ if .IsDefault }} 53 - <span 54 - class=" 18 + <!-- desktop view (hidden on small screens) --> 19 + <table class="w-full border-collapse hidden md:table"> 20 + <thead> 21 + <tr> 22 + <th class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold">Name</th> 23 + <th class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold">Commit</th> 24 + <th class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold">Message</th> 25 + <th class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold">Date</th> 26 + </tr> 27 + </thead> 28 + <tbody> 29 + {{ range $index, $branch := .Branches }} 30 + <tr class="{{ if ne $index (sub (len $.Branches) 1) }}border-b border-gray-200 dark:border-gray-700{{ end }}"> 31 + <td class="py-3 whitespace-nowrap"> 32 + <a href="/{{ $.RepoInfo.FullName }}/tree/{{ .Name | urlquery }}" class="no-underline hover:underline flex items-center gap-2"> 33 + <span class="dark:text-white"> 34 + {{ .Name }} 35 + </span> 36 + {{ if .IsDefault }} 37 + <span class=" 55 38 text-sm rounded 56 39 bg-gray-100 dark:bg-gray-700 text-black dark:text-white 57 40 font-mono 58 41 px-2 mx-1/2 59 42 inline-flex items-center 60 43 "> 61 - default 62 - </span> 63 - {{ end }} 64 - </a> 65 - </td> 66 - <td class="py-3 whitespace-nowrap"> 67 - {{ if .Commit }} 68 - <a 69 - href="/{{ $.RepoInfo.FullName }}/commits/{{ .Name | urlquery }}" 70 - class="font-mono text-gray-700 dark:text-gray-300 no-underline hover:underline"> 71 - {{ slice .Commit.Hash.String 0 8 }} 72 - </a> 73 - {{ end }} 74 - </td> 75 - <td class="py-3 whitespace-nowrap"> 76 - {{ if .Commit }} 77 - {{ $messageParts := splitN .Commit.Message "\n\n" 2 }} 78 - <span class="text-gray-700 dark:text-gray-300"> 79 - {{ index $messageParts 0 }} 80 - </span> 81 - {{ end }} 82 - </td> 83 - <td class="py-3 whitespace-nowrap text-gray-500 dark:text-gray-400"> 84 - {{ if .Commit }} 85 - {{ template "repo/fragments/time" .Commit.Committer.When }} 86 - {{ end }} 87 - </td> 88 - </tr> 89 - {{ end }} 90 - </tbody> 91 - </table> 92 - 93 - <!-- mobile view (visible only on small screens) --> 94 - <div class="md:hidden"> 95 - {{ range $index, $branch := .Branches }} 96 - <div 97 - class="relative p-2 {{ if ne $index (sub (len $.Branches) 1) }} 98 - border-b border-gray-200 dark:border-gray-700 99 - {{ end }}"> 100 - <div class="flex items-center justify-between"> 101 - <a 102 - href="/{{ $.RepoInfo.FullName }}/tree/{{ .Name | urlquery }}" 103 - class="no-underline hover:underline flex items-center gap-2"> 104 - <span class="dark:text-white font-medium"> 105 - {{ .Name }} 44 + default 106 45 </span> 107 - {{ if .IsDefault }} 108 - <span 109 - class=" 46 + {{ end }} 47 + </a> 48 + </td> 49 + <td class="py-3 whitespace-nowrap"> 50 + {{ if .Commit }} 51 + <a href="/{{ $.RepoInfo.FullName }}/commits/{{ .Name | urlquery }}" class="font-mono text-gray-700 dark:text-gray-300 no-underline hover:underline">{{ slice .Commit.Hash.String 0 8 }}</a> 52 + {{ end }} 53 + </td> 54 + <td class="py-3 whitespace-nowrap"> 55 + {{ if .Commit }} 56 + {{ $messageParts := splitN .Commit.Message "\n\n" 2 }} 57 + <span class="text-gray-700 dark:text-gray-300">{{ index $messageParts 0 }}</span> 58 + {{ end }} 59 + </td> 60 + <td class="py-3 whitespace-nowrap text-gray-500 dark:text-gray-400"> 61 + {{ if .Commit }} 62 + {{ template "repo/fragments/time" .Commit.Committer.When }} 63 + {{ end }} 64 + </td> 65 + </tr> 66 + {{ end }} 67 + </tbody> 68 + </table> 69 + 70 + <!-- mobile view (visible only on small screens) --> 71 + <div class="md:hidden"> 72 + {{ range $index, $branch := .Branches }} 73 + <div class="relative p-2 {{ if ne $index (sub (len $.Branches) 1) }}border-b border-gray-200 dark:border-gray-700{{ end }}"> 74 + <div class="flex items-center justify-between"> 75 + <a href="/{{ $.RepoInfo.FullName }}/tree/{{ .Name | urlquery }}" class="no-underline hover:underline flex items-center gap-2"> 76 + <span class="dark:text-white font-medium"> 77 + {{ .Name }} 78 + </span> 79 + {{ if .IsDefault }} 80 + <span class=" 110 81 text-xs rounded 111 82 bg-gray-100 dark:bg-gray-700 text-black dark:text-white 112 83 font-mono 113 84 px-2 114 85 inline-flex items-center 115 86 "> 116 - default 117 - </span> 118 - {{ end }} 119 - </a> 120 - </div> 121 - 122 - {{ if .Commit }} 123 - <div 124 - class="text-xs text-gray-500 dark:text-gray-400 mt-1 flex items-center"> 125 - <span class="font-mono"> 126 - <a 127 - href="/{{ $.RepoInfo.FullName }}/commits/{{ .Name | urlquery }}" 128 - class="text-gray-500 dark:text-gray-400 no-underline hover:underline"> 129 - {{ slice .Commit.Hash.String 0 8 }} 130 - </a> 131 - </span> 132 - <div 133 - class="inline-block px-1 select-none after:content-['·']"></div> 134 - {{ template "repo/fragments/time" .Commit.Committer.When }} 135 - </div> 87 + default 88 + </span> 136 89 {{ end }} 137 - </div> 90 + </a> 91 + </div> 92 + 93 + {{ if .Commit }} 94 + <div class="text-xs text-gray-500 dark:text-gray-400 mt-1 flex items-center"> 95 + <span class="font-mono"> 96 + <a href="/{{ $.RepoInfo.FullName }}/commits/{{ .Name | urlquery }}" class="text-gray-500 dark:text-gray-400 no-underline hover:underline"> 97 + {{ slice .Commit.Hash.String 0 8 }} 98 + </a> 99 + </span> 100 + <div class="inline-block px-1 select-none after:content-['·']"></div> 101 + {{ template "repo/fragments/time" .Commit.Committer.When }} 102 + </div> 138 103 {{ end }} 139 104 </div> 140 - </section> 105 + {{ end }} 106 + </div> 107 + </section> 141 108 {{ end }}
+61 -94
appview/pages/templates/repo/commit.html
··· 1 - {{ define "title" }} 2 - commit {{ .Diff.Commit.This }} &middot; 3 - {{ .RepoInfo.FullName }} 4 - {{ end }} 1 + {{ define "title" }} commit {{ .Diff.Commit.This }} &middot; {{ .RepoInfo.FullName }} {{ end }} 5 2 6 3 {{ define "extrameta" }} 7 - {{ $title := printf "commit %s &middot; %s" .Diff.Commit.This .RepoInfo.FullName }} 8 - {{ $url := printf "https://tangled.sh/%s/commit/%s" .RepoInfo.FullName .Diff.Commit.This }} 4 + {{ $title := printf "commit %s &middot; %s" .Diff.Commit.This .RepoInfo.FullName }} 5 + {{ $url := printf "https://tangled.sh/%s/commit/%s" .RepoInfo.FullName .Diff.Commit.This }} 9 6 10 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 7 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 11 8 {{ end }} 9 + 12 10 13 11 {{ define "repoContent" }} 14 12 15 - {{ $repo := .RepoInfo.FullName }} 16 - {{ $commit := .Diff.Commit }} 13 + {{ $repo := .RepoInfo.FullName }} 14 + {{ $commit := .Diff.Commit }} 17 15 18 - 19 - <section class="commit dark:text-white"> 20 - <div id="commit-message"> 21 - {{ $messageParts := splitN $commit.Message "\n\n" 2 }} 22 - <div> 23 - <p class="pb-2">{{ index $messageParts 0 }}</p> 24 - {{ if gt (len $messageParts) 1 }} 25 - <p class="mt-1 cursor-text pb-2 text-sm"> 26 - {{ nl2br (index $messageParts 1) }} 27 - </p> 28 - {{ end }} 29 - </div> 16 + <section class="commit dark:text-white"> 17 + <div id="commit-message"> 18 + {{ $messageParts := splitN $commit.Message "\n\n" 2 }} 19 + <div> 20 + <p class="pb-2">{{ index $messageParts 0 }}</p> 21 + {{ if gt (len $messageParts) 1 }} 22 + <p class="mt-1 cursor-text pb-2 text-sm">{{ nl2br (index $messageParts 1) }}</p> 23 + {{ end }} 30 24 </div> 25 + </div> 31 26 32 - <div class="flex items-center space-x-2"> 27 + <div class="flex items-center space-x-2"> 33 28 <p class="text-sm text-gray-500 dark:text-gray-300"> 34 - {{ $didOrHandle := index $.EmailToDidOrHandle $commit.Author.Email }} 29 + {{ $didOrHandle := index $.EmailToDidOrHandle $commit.Author.Email }} 35 30 36 - {{ if $didOrHandle }} 37 - <a 38 - href="/{{ $didOrHandle }}" 39 - class="no-underline hover:underline text-gray-500 dark:text-gray-300"> 40 - {{ $didOrHandle }} 41 - </a> 42 - {{ else }} 43 - <a 44 - href="mailto:{{ $commit.Author.Email }}" 45 - class="no-underline hover:underline text-gray-500 dark:text-gray-300"> 46 - {{ $commit.Author.Name }} 47 - </a> 48 - {{ end }} 49 - <span class="px-1 select-none before:content-['\00B7']"></span> 50 - {{ template "repo/fragments/time" $commit.Author.When }} 51 - <span class="px-1 select-none before:content-['\00B7']"></span> 31 + {{ if $didOrHandle }} 32 + <a href="/{{ $didOrHandle }}" class="no-underline hover:underline text-gray-500 dark:text-gray-300">{{ $didOrHandle }}</a> 33 + {{ else }} 34 + <a href="mailto:{{ $commit.Author.Email }}" class="no-underline hover:underline text-gray-500 dark:text-gray-300">{{ $commit.Author.Name }}</a> 35 + {{ end }} 36 + <span class="px-1 select-none before:content-['\00B7']"></span> 37 + {{ template "repo/fragments/time" $commit.Author.When }} 38 + <span class="px-1 select-none before:content-['\00B7']"></span> 52 39 </p> 53 40 54 41 <p class="flex items-center text-sm text-gray-500 dark:text-gray-300"> 55 - <a 56 - href="/{{ $repo }}/commit/{{ $commit.This }}" 57 - class="no-underline hover:underline text-gray-500 dark:text-gray-300"> 58 - {{ slice $commit.This 0 8 }} 59 - </a> 60 - {{ if $commit.Parent }} 42 + <a href="/{{ $repo }}/commit/{{ $commit.This }}" class="no-underline hover:underline text-gray-500 dark:text-gray-300">{{ slice $commit.This 0 8 }}</a> 43 + {{ if $commit.Parent }} 61 44 {{ i "arrow-left" "w-3 h-3 mx-1" }} 62 - <a 63 - href="/{{ $repo }}/commit/{{ $commit.Parent }}" 64 - class="no-underline hover:underline text-gray-500 dark:text-gray-300"> 65 - {{ slice $commit.Parent 0 8 }} 66 - </a> 67 - {{ end }} 45 + <a href="/{{ $repo }}/commit/{{ $commit.Parent }}" class="no-underline hover:underline text-gray-500 dark:text-gray-300">{{ slice $commit.Parent 0 8 }}</a> 46 + {{ end }} 68 47 </p> 69 48 70 49 {{ if .VerifiedCommit.IsVerified $commit.This }} 71 - <div class="group relative inline-block text-sm"> 72 - <div 73 - class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 py-1 rounded cursor-pointer"> 74 - <div class="flex items-center gap-2"> 75 - {{ i "shield-check" "w-4 h-4" }} 76 - verified 77 - </div> 78 - </div> 79 - <div 80 - class="absolute z-[9999] hidden group-hover:block bg-white dark:bg-gray-900 text-sm text-black dark:text-white rounded-md shadow-md p-4 w-80 top-full mt-2"> 81 - <div class="mb-1"> 82 - This commit was signed with the committer's 83 - <span class="text-green-600 font-semibold">known signature</span> 84 - . 85 - </div> 86 - <div class="flex items-center gap-2 my-2"> 87 - {{ i "user" "w-4 h-4" }} 88 - {{ $committerDidOrHandle := index $.EmailToDidOrHandle $commit.Committer.Email }} 89 - <a href="/{{ $committerDidOrHandle }}"> 90 - {{ template "user/fragments/picHandleLink" $committerDidOrHandle }} 91 - </a> 92 - </div> 93 - <div class="my-1 pt-2 text-xs border-t"> 94 - <div class="text-gray-600 dark:text-gray-300"> 95 - SSH Key Fingerprint: 50 + <div class="group relative inline-block text-sm"> 51 + <div class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 py-1 rounded cursor-pointer"> 52 + <div class="flex items-center gap-2"> 53 + {{ i "shield-check" "w-4 h-4" }} 54 + verified 96 55 </div> 97 - <div class="break-all"> 98 - {{ .VerifiedCommit.Fingerprint $commit.This }} 99 - </div> 100 - </div> 101 56 </div> 102 - </div> 57 + <div class="absolute z-[9999] hidden group-hover:block bg-white dark:bg-gray-900 text-sm text-black dark:text-white rounded-md shadow-md p-4 w-80 top-full mt-2"> 58 + <div class="mb-1">This commit was signed with the committer's <span class="text-green-600 font-semibold">known signature</span>.</div> 59 + <div class="flex items-center gap-2 my-2"> 60 + {{ i "user" "w-4 h-4" }} 61 + {{ $committerDidOrHandle := index $.EmailToDidOrHandle $commit.Committer.Email }} 62 + <a href="/{{ $committerDidOrHandle }}">{{ template "user/fragments/picHandleLink" $committerDidOrHandle }}</a> 63 + </div> 64 + <div class="my-1 pt-2 text-xs border-t"> 65 + <div class="text-gray-600 dark:text-gray-300">SSH Key Fingerprint:</div> 66 + <div class="break-all">{{ .VerifiedCommit.Fingerprint $commit.This }}</div> 67 + </div> 68 + </div> 69 + </div> 103 70 {{ end }} 104 - 105 71 106 72 <div class="text-sm"> 107 73 {{ if $.Pipeline }} 108 74 {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" $.Pipeline "RepoInfo" $.RepoInfo) }} 109 75 {{ end }} 110 76 </div> 111 - </div> 112 - </section> 113 - {{ end }} 77 + </div> 78 + 79 + </section> 80 + {{end}} 114 81 115 82 {{ define "topbarLayout" }} 116 83 <header class="px-1 col-span-full" style="z-index: 20;"> ··· 92 125 {{ end }} 93 126 94 127 {{ block "contentAfterLayout" . }} 95 - <div class="flex-grow grid grid-cols-1 md:grid-cols-12 gap-4"> 96 - <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> 97 - {{ block "contentAfterLeft" . }}{{ end }} 98 - </div> 99 - <main class="col-span-1 md:col-span-10"> 100 - {{ block "contentAfter" . }}{{ end }} 101 - </main> 128 + <div class="flex-grow grid grid-cols-1 md:grid-cols-12 gap-4"> 129 + <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> 130 + {{ block "contentAfterLeft" . }} {{ end }} 102 131 </div> 132 + <main class="col-span-1 md:col-span-10"> 133 + {{ block "contentAfter" . }}{{ end }} 134 + </main> 135 + </div> 103 136 {{ end }} 104 137 </div> 105 138 {{ end }} ··· 112 145 113 146 {{ define "contentAfter" }} 114 147 {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff .DiffOpts) }} 115 - {{ end }} 148 + {{end}} 116 149 117 150 {{ define "contentAfterLeft" }} 118 151 <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> ··· 121 154 <div class="sticky top-0 flex-grow max-h-screen"> 122 155 {{ template "repo/fragments/diffChangedFiles" .Diff }} 123 156 </div> 124 - {{ end }} 157 + {{end}}
+10 -11
appview/pages/templates/repo/compare/compare.html
··· 1 1 {{ define "title" }} 2 - comparing {{ .Base }} and {{ .Head }} on 3 - {{ .RepoInfo.FullName }} 2 + comparing {{ .Base }} and {{ .Head }} on {{ .RepoInfo.FullName }} 4 3 {{ end }} 5 4 6 5 {{ define "repoContent" }} ··· 23 24 {{ end }} 24 25 25 26 {{ block "contentAfterLayout" . }} 26 - <div class="flex-grow grid grid-cols-1 md:grid-cols-12 gap-4"> 27 - <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> 28 - {{ block "contentAfterLeft" . }}{{ end }} 29 - </div> 30 - <main class="col-span-1 md:col-span-10"> 31 - {{ block "contentAfter" . }}{{ end }} 32 - </main> 27 + <div class="flex-grow grid grid-cols-1 md:grid-cols-12 gap-4"> 28 + <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> 29 + {{ block "contentAfterLeft" . }} {{ end }} 33 30 </div> 31 + <main class="col-span-1 md:col-span-10"> 32 + {{ block "contentAfter" . }}{{ end }} 33 + </main> 34 + </div> 34 35 {{ end }} 35 36 </div> 36 37 {{ end }} ··· 43 44 44 45 {{ define "contentAfter" }} 45 46 {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff .DiffOpts) }} 46 - {{ end }} 47 + {{end}} 47 48 48 49 {{ define "contentAfterLeft" }} 49 50 <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> ··· 52 53 <div class="sticky top-0 flex-grow max-h-screen"> 53 54 {{ template "repo/fragments/diffChangedFiles" .Diff }} 54 55 </div> 55 - {{ end }} 56 + {{end}}
+9 -16
appview/pages/templates/repo/compare/new.html
··· 1 1 {{ define "title" }} 2 - compare refs on 3 - {{ .RepoInfo.FullName }} 2 + compare refs on {{ .RepoInfo.FullName }} 4 3 {{ end }} 5 4 6 5 {{ define "repoContent" }} ··· 9 10 {{ define "repoAfter" }} 10 11 {{ $brs := take .Branches 5 }} 11 12 {{ if $brs }} 12 - <section 13 - class="p-6 mt-4 rounded-br rounded-bl bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm w-full mx-auto"> 13 + <section class="p-6 mt-4 rounded-br rounded-bl bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm w-full mx-auto"> 14 14 <div class="flex flex-col items-center"> 15 15 <p class="text-center text-black dark:text-white"> 16 - Recently updated branches in this repository: 16 + Recently updated branches in this repository: 17 17 </p> 18 - <div 19 - class="mt-4 grid grid-cols-1 divide-y divide-gray-200 dark:divide-gray-700 rounded border border-gray-200 dark:border-gray-700 w-full md:w-1/2"> 20 - {{ range $br := $brs }} 21 - <a 22 - href="/{{ $.RepoInfo.FullName }}/compare?head={{ $br.Name | urlquery }}" 23 - class="no-underline hover:no-underline"> 18 + <div class="mt-4 grid grid-cols-1 divide-y divide-gray-200 dark:divide-gray-700 rounded border border-gray-200 dark:border-gray-700 w-full md:w-1/2"> 19 + {{ range $br := $brs }} 20 + <a href="/{{ $.RepoInfo.FullName }}/compare?head={{ $br.Name | urlquery }}" class="no-underline hover:no-underline"> 24 21 <div class="flex items-center justify-between p-2"> 25 22 {{ $br.Name }} 26 - <span class="text-gray-500 dark:text-gray-400"> 27 - {{ template "repo/fragments/time" $br.Commit.Committer.When }} 28 - </span> 23 + <span class="text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" $br.Commit.Committer.When }}</span> 29 24 </div> 30 25 </a> 31 - {{ end }} 32 - </div> 26 + {{ end }} 27 + </div> 33 28 </div> 34 29 </section> 35 30 {{ end }}
+17 -48
appview/pages/templates/repo/empty.html
··· 1 1 {{ define "title" }}{{ .RepoInfo.FullName }}{{ end }} 2 2 3 3 {{ define "extrameta" }} 4 - {{ template "repo/fragments/meta" . }} 5 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }} 4 + {{ template "repo/fragments/meta" . }} 5 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }} 6 6 {{ end }} 7 7 8 8 {{ define "repoContent" }} ··· 10 10 {{ if gt (len .BranchesTrunc) 0 }} 11 11 <div class="flex flex-col items-center"> 12 12 <p class="text-center pt-5 text-gray-400 dark:text-gray-500"> 13 - This branch is empty. Other branches in this repository are populated: 13 + This branch is empty. Other branches in this repository are populated: 14 14 </p> 15 - <div 16 - class="mt-4 grid grid-cols-1 divide-y divide-gray-200 dark:divide-gray-700 rounded border border-gray-200 dark:border-gray-700 w-full md:w-1/2"> 15 + <div class="mt-4 grid grid-cols-1 divide-y divide-gray-200 dark:divide-gray-700 rounded border border-gray-200 dark:border-gray-700 w-full md:w-1/2"> 17 16 {{ range $br := .BranchesTrunc }} 18 - <a 19 - href="/{{ $.RepoInfo.FullName }}/tree/{{ $br.Name | urlquery }}" 20 - class="no-underline hover:no-underline"> 21 - <div class="flex items-center justify-between p-2"> 22 - {{ $br.Name }} 23 - <span class="text-gray-500 dark:text-gray-400"> 24 - {{ template "repo/fragments/time" $br.Commit.Committer.When }} 25 - </span> 26 - </div> 27 - </a> 17 + <a href="/{{ $.RepoInfo.FullName }}/tree/{{$br.Name | urlquery }}" class="no-underline hover:no-underline"> 18 + <div class="flex items-center justify-between p-2"> 19 + {{ $br.Name }} 20 + <span class="text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" $br.Commit.Committer.When }}</span> 21 + </div> 22 + </a> 28 23 {{ end }} 29 24 </div> 30 25 </div> 31 26 {{ else if (and .LoggedInUser (eq .LoggedInUser.Did .RepoInfo.OwnerDid)) }} 32 27 {{ $knot := .RepoInfo.Knot }} 33 28 {{ if eq $knot "knot1.tangled.sh" }} 34 - {{ $knot = "tangled.sh" }} 29 + {{ $knot = "tangled.sh" }} 35 30 {{ end }} 36 31 <div class="w-full flex place-content-center"> 37 32 <div class="py-6 w-fit flex flex-col gap-4"> 38 33 <p>This is an empty repository. To get started:</p> 39 34 {{ $bullet := "mx-2 text-xs bg-gray-200 dark:bg-gray-600 rounded-full size-5 flex items-center justify-center font-mono inline-flex align-middle" }} 40 35 41 - 42 - <p> 43 - <span class="{{ $bullet }}">1</span> 44 - First, generate a new 45 - <a 46 - href="https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key" 47 - class="underline"> 48 - SSH key pair 49 - </a> 50 - . 51 - </p> 52 - <p> 53 - <span class="{{ $bullet }}">2</span> 54 - Then add the public key to your account from the 55 - <a href="/settings" class="underline">settings</a> 56 - page. 57 - </p> 58 - <p> 59 - <span class="{{ $bullet }}">3</span> 60 - Configure your remote to 61 - <code> 62 - git@{{ $knot }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }} 63 - </code> 64 - </p> 65 - <p> 66 - <span class="{{ $bullet }}">4</span> 67 - Push! 68 - </p> 36 + <p><span class="{{$bullet}}">1</span>First, generate a new <a href="https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key" class="underline">SSH key pair</a>.</p> 37 + <p><span class="{{$bullet}}">2</span>Then add the public key to your account from the <a href="/settings" class="underline">settings</a> page.</p> 38 + <p><span class="{{$bullet}}">3</span>Configure your remote to <code>git@{{ $knot }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }}</code></p> 39 + <p><span class="{{$bullet}}">4</span>Push!</p> 69 40 </div> 70 41 </div> 71 42 {{ else }} 72 - <p class="text-gray-400 dark:text-gray-500 py-6 text-center"> 73 - This is an empty repository. 74 - </p> 43 + <p class="text-gray-400 dark:text-gray-500 py-6 text-center">This is an empty repository.</p> 75 44 {{ end }} 76 45 </main> 77 46 {{ end }} 78 47 79 48 {{ define "repoAfter" }} 80 - {{ template "repo/fragments/cloneInstructions" . }} 49 + {{ template "repo/fragments/cloneInstructions" . }} 81 50 {{ end }}
+32 -42
appview/pages/templates/repo/fork.html
··· 1 1 {{ define "title" }}fork &middot; {{ .RepoInfo.FullName }}{{ end }} 2 2 3 3 {{ define "content" }} 4 - <div class="p-6"> 5 - <p class="text-xl font-bold dark:text-white"> 6 - Fork 7 - {{ .RepoInfo.FullName }} 8 - </p> 9 - </div> 10 - <div class="p-6 bg-white dark:bg-gray-800 drop-shadow-sm rounded"> 11 - <form 12 - hx-post="/{{ .RepoInfo.FullName }}/fork" 13 - class="space-y-12" 14 - hx-swap="none"> 15 - <fieldset class="space-y-3"> 16 - <legend class="dark:text-white">Select a knot to fork into</legend> 17 - <div class="space-y-2"> 18 - <div class="flex flex-col"> 19 - {{ range .Knots }} 20 - <div class="flex items-center"> 21 - <input 22 - type="radio" 23 - name="knot" 24 - value="{{ . }}" 25 - class="mr-2" 26 - id="domain-{{ . }}" /> 27 - <span class="dark:text-white">{{ . }}</span> 28 - </div> 29 - {{ else }} 30 - <p class="dark:text-white">No knots available.</p> 31 - {{ end }} 32 - </div> 33 - </div> 34 - <p class="text-sm text-gray-500 dark:text-gray-400"> 35 - A knot hosts repository data. 36 - <a href="/knots" class="underline"> 37 - Learn how to register your own knot. 38 - </a> 39 - </p> 40 - </fieldset> 41 - 4 + <div class="p-6"> 5 + <p class="text-xl font-bold dark:text-white">Fork {{ .RepoInfo.FullName }}</p> 6 + </div> 7 + <div class="p-6 bg-white dark:bg-gray-800 drop-shadow-sm rounded"> 8 + <form hx-post="/{{ .RepoInfo.FullName }}/fork" class="space-y-12" hx-swap="none"> 9 + <fieldset class="space-y-3"> 10 + <legend class="dark:text-white">Select a knot to fork into</legend> 42 11 <div class="space-y-2"> 43 - <button type="submit" class="btn">fork repo</button> 44 - <div id="repo" class="error"></div> 12 + <div class="flex flex-col"> 13 + {{ range .Knots }} 14 + <div class="flex items-center"> 15 + <input 16 + type="radio" 17 + name="knot" 18 + value="{{ . }}" 19 + class="mr-2" 20 + id="domain-{{ . }}" 21 + /> 22 + <span class="dark:text-white">{{ . }}</span> 23 + </div> 24 + {{ else }} 25 + <p class="dark:text-white">No knots available.</p> 26 + {{ end }} 27 + </div> 45 28 </div> 46 - </form> 47 - </div> 29 + <p class="text-sm text-gray-500 dark:text-gray-400">A knot hosts repository data. <a href="/knots" class="underline">Learn how to register your own knot.</a></p> 30 + </fieldset> 31 + 32 + <div class="space-y-2"> 33 + <button type="submit" class="btn">fork repo</button> 34 + <div id="repo" class="error"></div> 35 + </div> 36 + </form> 37 + </div> 48 38 {{ end }}
+13 -27
appview/pages/templates/repo/fragments/artifact.html
··· 1 1 {{ define "repo/fragments/artifact" }} 2 - {{ $unique := .Artifact.BlobCid.String }} 3 - <div 4 - id="artifact-{{ $unique }}" 5 - class="flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-700"> 6 - <div id="left-side" class="flex items-center gap-2 min-w-0 max-w-[60%]"> 7 - {{ i "box" "w-4 h-4" }} 8 - <a 9 - href="/{{ .RepoInfo.FullName }}/tags/{{ .Artifact.Tag.String }}/download/{{ .Artifact.Name | urlquery }}" 10 - class="no-underline hover:no-underline"> 11 - {{ .Artifact.Name }} 12 - </a> 13 - <span class="text-gray-500 dark:text-gray-400 pl-2 text-sm"> 14 - {{ byteFmt .Artifact.Size }} 15 - </span> 16 - </div> 2 + {{ $unique := .Artifact.BlobCid.String }} 3 + <div id="artifact-{{ $unique }}" class="flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-700"> 4 + <div id="left-side" class="flex items-center gap-2 min-w-0 max-w-[60%]"> 5 + {{ i "box" "w-4 h-4" }} 6 + <a href="/{{ .RepoInfo.FullName }}/tags/{{ .Artifact.Tag.String }}/download/{{ .Artifact.Name | urlquery }}" class="no-underline hover:no-underline"> 7 + {{ .Artifact.Name }} 8 + </a> 9 + <span class="text-gray-500 dark:text-gray-400 pl-2 text-sm">{{ byteFmt .Artifact.Size }}</span> 10 + </div> 17 11 18 - <div 19 - id="right-side" 20 - class="text-gray-500 dark:text-gray-400 flex items-center flex-shrink-0 gap-2 text-sm"> 21 - <span class="hidden md:inline"> 22 - {{ template "repo/fragments/time" .Artifact.CreatedAt }} 23 - </span> 24 - <span class=" md:hidden"> 25 - {{ template "repo/fragments/shortTime" .Artifact.CreatedAt }} 26 - </span> 12 + <div id="right-side" class="text-gray-500 dark:text-gray-400 flex items-center flex-shrink-0 gap-2 text-sm"> 13 + <span class="hidden md:inline">{{ template "repo/fragments/time" .Artifact.CreatedAt }}</span> 14 + <span class=" md:hidden">{{ template "repo/fragments/shortTime" .Artifact.CreatedAt }}</span> 27 15 28 16 <span class="select-none after:content-['·'] hidden md:inline"></span> 29 - <span class="truncate max-w-[100px] hidden md:inline"> 30 - {{ .Artifact.MimeType }} 31 - </span> 17 + <span class="truncate max-w-[100px] hidden md:inline">{{ .Artifact.MimeType }}</span> 32 18 33 19 {{ if and .LoggedInUser (eq .LoggedInUser.Did .Artifact.Did) }} 34 20 <button
+50 -49
appview/pages/templates/repo/fragments/cloneInstructions.html
··· 1 1 {{ define "repo/fragments/cloneInstructions" }} 2 - {{ $knot := .RepoInfo.Knot }} 3 - {{ if eq $knot "knot1.tangled.sh" }} 4 - {{ $knot = "tangled.sh" }} 5 - {{ end }} 6 - <section 7 - class="mt-4 p-6 rounded drop-shadow-sm bg-white dark:bg-gray-800 dark:text-white w-full mx-auto overflow-auto flex flex-col gap-4"> 8 - <div class="flex flex-col gap-2"> 9 - <strong>push</strong> 10 - <div class="md:pl-4 overflow-x-auto whitespace-nowrap"> 11 - <code class="dark:text-gray-100"> 12 - git remote add origin 13 - git@{{ $knot }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }} 14 - </code> 15 - </div> 16 - </div> 17 - 18 - <div class="flex flex-col gap-2"> 19 - <strong>clone</strong> 20 - <div class="md:pl-4 flex flex-col gap-2"> 21 - <div class="flex items-center gap-3"> 22 - <span 23 - class="bg-gray-100 dark:bg-gray-700 p-1 mr-1 font-mono text-sm rounded select-none dark:text-white"> 24 - HTTP 25 - </span> 26 - <div class="overflow-x-auto whitespace-nowrap flex-1"> 27 - <code class="dark:text-gray-100"> 28 - git clone 29 - https://tangled.sh/{{ .RepoInfo.OwnerWithAt }}/{{ .RepoInfo.Name }} 30 - </code> 31 - </div> 2 + {{ $knot := .RepoInfo.Knot }} 3 + {{ if eq $knot "knot1.tangled.sh" }} 4 + {{ $knot = "tangled.sh" }} 5 + {{ end }} 6 + <section 7 + class="mt-4 p-6 rounded drop-shadow-sm bg-white dark:bg-gray-800 dark:text-white w-full mx-auto overflow-auto flex flex-col gap-4" 8 + > 9 + <div class="flex flex-col gap-2"> 10 + <strong>push</strong> 11 + <div class="md:pl-4 overflow-x-auto whitespace-nowrap"> 12 + <code class="dark:text-gray-100" 13 + >git remote add origin 14 + git@{{ $knot }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }}</code 15 + > 16 + </div> 32 17 </div> 33 18 34 - <div class="flex items-center gap-3"> 35 - <span 36 - class="bg-gray-100 dark:bg-gray-700 p-1 mr-1 font-mono text-sm rounded select-none dark:text-white"> 37 - SSH 38 - </span> 39 - <div class="overflow-x-auto whitespace-nowrap flex-1"> 40 - <code class="dark:text-gray-100"> 41 - git clone 42 - git@{{ $knot }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }} 43 - </code> 44 - </div> 45 - </div> 46 - </div> 47 - </div> 19 + <div class="flex flex-col gap-2"> 20 + <strong>clone</strong> 21 + <div class="md:pl-4 flex flex-col gap-2"> 22 + <div class="flex items-center gap-3"> 23 + <span 24 + class="bg-gray-100 dark:bg-gray-700 p-1 mr-1 font-mono text-sm rounded select-none dark:text-white" 25 + >HTTP</span 26 + > 27 + <div class="overflow-x-auto whitespace-nowrap flex-1"> 28 + <code class="dark:text-gray-100" 29 + >git clone 30 + https://tangled.sh/{{ .RepoInfo.OwnerWithAt }}/{{ .RepoInfo.Name }}</code 31 + > 32 + </div> 33 + </div> 48 34 49 - <p class="py-2 text-gray-500 dark:text-gray-400"> 50 - Note that for self-hosted knots, clone URLs may be different based on your 51 - setup. 52 - </p> 53 - </section> 35 + <div class="flex items-center gap-3"> 36 + <span 37 + class="bg-gray-100 dark:bg-gray-700 p-1 mr-1 font-mono text-sm rounded select-none dark:text-white" 38 + >SSH</span 39 + > 40 + <div class="overflow-x-auto whitespace-nowrap flex-1"> 41 + <code class="dark:text-gray-100" 42 + >git clone 43 + git@{{ $knot }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }}</code 44 + > 45 + </div> 46 + </div> 47 + </div> 48 + </div> 49 + 50 + <p class="py-2 text-gray-500 dark:text-gray-400"> 51 + Note that for self-hosted knots, clone URLs may be different based 52 + on your setup. 53 + </p> 54 + </section> 54 55 {{ end }}
+22 -20
appview/pages/templates/repo/fragments/compareAllowPull.html
··· 1 1 {{ define "repo/fragments/compareAllowPull" }} 2 - <div 3 - class="flex items-baseline justify-normal gap-4" 4 - id="allow-pull" 5 - hx-oob-swap="true"> 6 - <p> 7 - This comparison can be turned into a pull request to be reviewed and 8 - discussed. 9 - </p> 2 + <div 3 + class="flex items-baseline justify-normal gap-4" 4 + id="allow-pull" 5 + hx-oob-swap="true" 6 + > 7 + <p> 8 + This comparison can be turned into a pull request to be reviewed and 9 + discussed. 10 + </p> 10 11 11 - {{ $newPullUrl := printf "/%s/pulls/new?strategy=branch&targetBranch=%s&sourceBranch=%s" .RepoInfo.FullName .Base .Head }} 12 + {{ $newPullUrl := printf "/%s/pulls/new?strategy=branch&targetBranch=%s&sourceBranch=%s" .RepoInfo.FullName .Base .Head }} 12 13 13 14 14 - <div class="flex justify-start items-center gap-2 mt-2"> 15 - <a 16 - href="{{ $newPullUrl }}" 17 - class="btn flex items-center gap-2 no-underline hover:no-underline"> 18 - {{ i "git-pull-request-create" "w-4 h-4" }} 19 - create pull 20 - <span id="create-pull-spinner" class="group"> 21 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 22 - </span> 23 - </a> 15 + <div class="flex justify-start items-center gap-2 mt-2"> 16 + <a 17 + href="{{ $newPullUrl }}" 18 + class="btn flex items-center gap-2 no-underline hover:no-underline" 19 + > 20 + {{ i "git-pull-request-create" "w-4 h-4" }} 21 + create pull 22 + <span id="create-pull-spinner" class="group"> 23 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 24 + </span> 25 + </a> 26 + </div> 24 27 </div> 25 - </div> 26 28 {{ end }}
+54 -63
appview/pages/templates/repo/fragments/compareForm.html
··· 1 1 {{ define "repo/fragments/compareForm" }} 2 - <div id="compare-select"> 3 - <h2 class="font-bold text-sm mb-2 uppercase dark:text-white"> 4 - Compare changes 5 - </h2> 6 - <p>Choose any two refs to compare.</p> 2 + <div id="compare-select"> 3 + <h2 class="font-bold text-sm mb-2 uppercase dark:text-white"> 4 + Compare changes 5 + </h2> 6 + <p>Choose any two refs to compare.</p> 7 7 8 - <form id="compare-form" class="flex items-center gap-2 py-4"> 9 - <div> 10 - <span class="hidden md:inline">base:</span> 11 - {{ block "dropdown" (list $ "base" $.Base) }}{{ end }} 12 - </div> 13 - <span class="flex-shrink-0"> 14 - {{ i "arrow-left" "w-4 h-4" }} 15 - </span> 16 - <div> 17 - <span class="hidden md:inline">compare:</span> 18 - {{ block "dropdown" (list $ "head" $.Head) }}{{ end }} 19 - </div> 20 - <button 21 - id="compare-button" 22 - class="btn disabled:opacity-50 disabled:cursor-not-allowed" 23 - type="button" 24 - hx-boost="true" 25 - onclick=" 8 + <form id="compare-form" class="flex items-center gap-2 py-4"> 9 + <div> 10 + <span class="hidden md:inline">base:</span> 11 + {{ block "dropdown" (list $ "base" $.Base) }} {{ end }} 12 + </div> 13 + <span class="flex-shrink-0"> 14 + {{ i "arrow-left" "w-4 h-4" }} 15 + </span> 16 + <div> 17 + <span class="hidden md:inline">compare:</span> 18 + {{ block "dropdown" (list $ "head" $.Head) }} {{ end }} 19 + </div> 20 + <button 21 + id="compare-button" 22 + class="btn disabled:opacity-50 disabled:cursor-not-allowed" 23 + type="button" 24 + hx-boost="true" 25 + onclick=" 26 26 const base = document.getElementById('base-select').value; 27 27 const head = document.getElementById('head-select').value; 28 - window.location.href = `/{{ $.RepoInfo.FullName }}/compare/${encodeURIComponent(base)}...${encodeURIComponent(head)}`; 28 + window.location.href = `/{{$.RepoInfo.FullName}}/compare/${encodeURIComponent(base)}...${encodeURIComponent(head)}`; 29 29 "> 30 - go 31 - </button> 32 - </form> 33 - </div> 34 - <script> 35 - const baseSelect = document.getElementById("base-select"); 36 - const headSelect = document.getElementById("head-select"); 37 - const compareButton = document.getElementById("compare-button"); 30 + go 31 + </button> 32 + </form> 33 + </div> 34 + <script> 35 + const baseSelect = document.getElementById('base-select'); 36 + const headSelect = document.getElementById('head-select'); 37 + const compareButton = document.getElementById('compare-button'); 38 38 39 - function toggleButtonState() { 40 - compareButton.disabled = baseSelect.value === headSelect.value; 41 - } 39 + function toggleButtonState() { 40 + compareButton.disabled = baseSelect.value === headSelect.value; 41 + } 42 42 43 - baseSelect.addEventListener("change", toggleButtonState); 44 - headSelect.addEventListener("change", toggleButtonState); 43 + baseSelect.addEventListener('change', toggleButtonState); 44 + headSelect.addEventListener('change', toggleButtonState); 45 45 46 - // Run once on page load 47 - toggleButtonState(); 48 - </script> 46 + // Run once on page load 47 + toggleButtonState(); 48 + </script> 49 49 {{ end }} 50 50 51 51 {{ define "dropdown" }} 52 - {{ $root := index . 0 }} 53 - {{ $name := index . 1 }} 54 - {{ $default := index . 2 }} 55 - <select 56 - name="{{ $name }}" 57 - id="{{ $name }}-select" 58 - class="p-1 border max-w-32 md:max-w-64 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"> 52 + {{ $root := index . 0 }} 53 + {{ $name := index . 1 }} 54 + {{ $default := index . 2 }} 55 + <select name="{{$name}}" id="{{$name}}-select" class="p-1 border max-w-32 md:max-w-64 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"> 59 56 <optgroup label="branches ({{ len $root.Branches }})" class="bold text-sm"> 60 57 {{ range $root.Branches }} 61 - <option 62 - value="{{ .Reference.Name }}" 63 - class="py-1" 64 - {{ if eq .Reference.Name $default }}selected{{ end }}> 58 + <option value="{{ .Reference.Name }}" class="py-1" {{if eq .Reference.Name $default}}selected{{end}}> 65 59 {{ .Reference.Name }} 66 60 </option> 67 61 {{ end }} 68 62 </optgroup> 69 - <optgroup label="tags ({{ len $root.Tags }})" class="bold text-sm"> 70 - {{ range $root.Tags }} 71 - <option 72 - value="{{ .Reference.Name }}" 73 - class="py-1" 74 - {{ if eq .Reference.Name $default }}selected{{ end }}> 75 - {{ .Reference.Name }} 76 - </option> 77 - {{ else }} 78 - <option class="py-1" disabled>no tags found</option> 79 - {{ end }} 80 - </optgroup> 63 + <optgroup label="tags ({{ len $root.Tags }})" class="bold text-sm"> 64 + {{ range $root.Tags }} 65 + <option value="{{ .Reference.Name }}" class="py-1" {{if eq .Reference.Name $default}}selected{{end}}> 66 + {{ .Reference.Name }} 67 + </option> 68 + {{ else }} 69 + <option class="py-1" disabled>no tags found</option> 70 + {{ end }} 71 + </optgroup> 81 72 </select> 82 73 {{ end }}
+80 -129
appview/pages/templates/repo/fragments/diff.html
··· 10 10 {{ $parent := $commit.Parent }} 11 11 {{ $last := sub (len $diff) 1 }} 12 12 13 - 14 13 <div class="flex flex-col gap-4"> 15 14 {{ range $idx, $hunk := $diff }} 16 15 {{ with $hunk }} 17 - <section 18 - class="border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 19 - <div id="file-{{ .Name.New }}"> 20 - <div id="diff-file"> 21 - <details open> 22 - <summary class="list-none cursor-pointer sticky top-0"> 23 - <div 24 - id="diff-file-header" 25 - class="rounded cursor-pointer bg-white dark:bg-gray-800 flex justify-between"> 26 - <div 27 - id="left-side-items" 28 - class="p-2 flex gap-2 items-center overflow-x-auto"> 29 - <div class="flex gap-1 items-center"> 30 - {{ $markerstyle := "diff-type p-1 mr-1 font-mono text-sm rounded select-none" }} 31 - {{ if .IsNew }} 32 - <span 33 - class="bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400 {{ $markerstyle }}"> 34 - ADDED 35 - </span> 36 - {{ else if .IsDelete }} 37 - <span 38 - class="bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400 {{ $markerstyle }}"> 39 - DELETED 40 - </span> 41 - {{ else if .IsCopy }} 42 - <span 43 - class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}"> 44 - COPIED 45 - </span> 46 - {{ else if .IsRename }} 47 - <span 48 - class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}"> 49 - RENAMED 50 - </span> 51 - {{ else }} 52 - <span 53 - class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}"> 54 - MODIFIED 55 - </span> 56 - {{ end }} 57 - 58 - {{ template "repo/fragments/diffStatPill" .Stats }} 59 - </div> 60 - 61 - <div class="flex gap-2 items-center overflow-x-auto"> 62 - {{ if .IsDelete }} 63 - <a 64 - class="dark:text-white whitespace-nowrap overflow-x-auto" 65 - {{ if $this }} 66 - href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.Old }}" 67 - {{ end }}> 68 - {{ .Name.Old }} 69 - </a> 70 - {{ else if (or .IsCopy .IsRename) }} 71 - <a 72 - class="dark:text-white whitespace-nowrap overflow-x-auto" 73 - {{ if $parent }} 74 - href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}" 75 - {{ end }}> 76 - {{ .Name.Old }} 77 - </a> 78 - {{ i "arrow-right" "w-4 h-4" }} 79 - <a 80 - class="dark:text-white whitespace-nowrap overflow-x-auto" 81 - {{ if $this }} 82 - href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}" 83 - {{ end }}> 84 - {{ .Name.New }} 85 - </a> 86 - {{ else }} 87 - <a 88 - class="dark:text-white whitespace-nowrap overflow-x-auto" 89 - {{ if $this }} 90 - href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}" 91 - {{ end }}> 92 - {{ .Name.New }} 93 - </a> 94 - {{ end }} 95 - </div> 96 - </div> 97 - 98 - {{ $iconstyle := "p-1 mx-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" }} 99 - <div id="right-side-items" class="p-2 flex items-center"> 100 - <a 101 - title="top of file" 102 - href="#file-{{ .Name.New }}" 103 - class="{{ $iconstyle }}"> 104 - {{ i "arrow-up-to-line" "w-4 h-4" }} 105 - </a> 106 - {{ if gt $idx 0 }} 107 - {{ $prev := index $diff (sub $idx 1) }} 108 - <a 109 - title="previous file" 110 - href="#file-{{ $prev.Name.New }}" 111 - class="{{ $iconstyle }}"> 112 - {{ i "arrow-up" "w-4 h-4" }} 113 - </a> 16 + <section class="border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 17 + <div id="file-{{ .Name.New }}"> 18 + <div id="diff-file"> 19 + <details open> 20 + <summary class="list-none cursor-pointer sticky top-0"> 21 + <div id="diff-file-header" class="rounded cursor-pointer bg-white dark:bg-gray-800 flex justify-between"> 22 + <div id="left-side-items" class="p-2 flex gap-2 items-center overflow-x-auto"> 23 + <div class="flex gap-1 items-center"> 24 + {{ $markerstyle := "diff-type p-1 mr-1 font-mono text-sm rounded select-none" }} 25 + {{ if .IsNew }} 26 + <span class="bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400 {{ $markerstyle }}">ADDED</span> 27 + {{ else if .IsDelete }} 28 + <span class="bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400 {{ $markerstyle }}">DELETED</span> 29 + {{ else if .IsCopy }} 30 + <span class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}">COPIED</span> 31 + {{ else if .IsRename }} 32 + <span class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}">RENAMED</span> 33 + {{ else }} 34 + <span class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}">MODIFIED</span> 114 35 {{ end }} 115 36 116 - {{ if lt $idx $last }} 117 - {{ $next := index $diff (add $idx 1) }} 118 - <a 119 - title="next file" 120 - href="#file-{{ $next.Name.New }}" 121 - class="{{ $iconstyle }}"> 122 - {{ i "arrow-down" "w-4 h-4" }} 123 - </a> 37 + {{ template "repo/fragments/diffStatPill" .Stats }} 38 + </div> 39 + 40 + <div class="flex gap-2 items-center overflow-x-auto"> 41 + {{ if .IsDelete }} 42 + <a class="dark:text-white whitespace-nowrap overflow-x-auto" {{if $this }}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.Old }}"{{end}}> 43 + {{ .Name.Old }} 44 + </a> 45 + {{ else if (or .IsCopy .IsRename) }} 46 + <a class="dark:text-white whitespace-nowrap overflow-x-auto" {{if $parent}}href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}"{{end}}> 47 + {{ .Name.Old }} 48 + </a> 49 + {{ i "arrow-right" "w-4 h-4" }} 50 + <a class="dark:text-white whitespace-nowrap overflow-x-auto" {{if $this}}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}"{{end}}> 51 + {{ .Name.New }} 52 + </a> 53 + {{ else }} 54 + <a class="dark:text-white whitespace-nowrap overflow-x-auto" {{if $this}}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}"{{end}}> 55 + {{ .Name.New }} 56 + </a> 124 57 {{ end }} 125 58 </div> 126 59 </div> 127 - </summary> 128 60 129 - <div class="transition-all duration-700 ease-in-out"> 130 - {{ if .IsDelete }} 131 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 132 - This file has been deleted. 133 - </p> 134 - {{ else if .IsCopy }} 135 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 136 - This file has been copied. 137 - </p> 138 - {{ else if .IsBinary }} 139 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 140 - This is a binary file and will not be displayed. 141 - </p> 142 - {{ else }} 143 - {{ if $isSplit }} 144 - {{- template "repo/fragments/splitDiff" .Split -}} 145 - {{ else }} 146 - {{- template "repo/fragments/unifiedDiff" . -}} 61 + {{ $iconstyle := "p-1 mx-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" }} 62 + <div id="right-side-items" class="p-2 flex items-center"> 63 + <a title="top of file" href="#file-{{ .Name.New }}" class="{{ $iconstyle }}">{{ i "arrow-up-to-line" "w-4 h-4" }}</a> 64 + {{ if gt $idx 0 }} 65 + {{ $prev := index $diff (sub $idx 1) }} 66 + <a title="previous file" href="#file-{{ $prev.Name.New }}" class="{{ $iconstyle }}">{{ i "arrow-up" "w-4 h-4" }}</a> 147 67 {{ end }} 148 - {{- end -}} 68 + 69 + {{ if lt $idx $last }} 70 + {{ $next := index $diff (add $idx 1) }} 71 + <a title="next file" href="#file-{{ $next.Name.New }}" class="{{ $iconstyle }}">{{ i "arrow-down" "w-4 h-4" }}</a> 72 + {{ end }} 73 + </div> 74 + 149 75 </div> 150 - </details> 151 - </div> 76 + </summary> 77 + 78 + <div class="transition-all duration-700 ease-in-out"> 79 + {{ if .IsDelete }} 80 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 81 + This file has been deleted. 82 + </p> 83 + {{ else if .IsCopy }} 84 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 85 + This file has been copied. 86 + </p> 87 + {{ else if .IsBinary }} 88 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 89 + This is a binary file and will not be displayed. 90 + </p> 91 + {{ else }} 92 + {{ if $isSplit }} 93 + {{- template "repo/fragments/splitDiff" .Split -}} 94 + {{ else }} 95 + {{- template "repo/fragments/unifiedDiff" . -}} 96 + {{ end }} 97 + {{- end -}} 98 + </div> 99 + 100 + </details> 101 + 152 102 </div> 153 - </section> 103 + </div> 104 + </section> 154 105 {{ end }} 155 106 {{ end }} 156 107 </div>
+2 -5
appview/pages/templates/repo/fragments/diffChangedFiles.html
··· 1 1 {{ define "repo/fragments/diffChangedFiles" }} 2 2 {{ $stat := .Stat }} 3 3 {{ $fileTree := fileTree .ChangedFiles }} 4 - <section 5 - class="overflow-x-auto text-sm px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto min-h-full rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 4 + <section class="overflow-x-auto text-sm px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto min-h-full rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 6 5 <div class="diff-stat"> 7 6 <div class="flex gap-2 items-center"> 8 - <strong class="text-sm uppercase dark:text-gray-200"> 9 - Changed files 10 - </strong> 7 + <strong class="text-sm uppercase dark:text-gray-200">Changed files</strong> 11 8 {{ template "repo/fragments/diffStatPill" $stat }} 12 9 </div> 13 10 {{ template "repo/fragments/fileTree" $fileTree }}
+6 -14
appview/pages/templates/repo/fragments/diffOpts.html
··· 1 1 {{ define "repo/fragments/diffOpts" }} 2 - <section 3 - class="flex flex-col gap-2 overflow-x-auto text-sm px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 2 + <section class="flex flex-col gap-2 overflow-x-auto text-sm px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 4 3 <strong class="text-sm uppercase dark:text-gray-200">options</strong> 5 4 {{ $active := "unified" }} 6 5 {{ if .Split }} 7 6 {{ $active = "split" }} 8 7 {{ end }} 9 8 {{ $values := list "unified" "split" }} 10 - {{ block "tabSelector" (dict "Name" "diff" "Values" $values "Active" $active) }} 11 - {{ end }} 9 + {{ block "tabSelector" (dict "Name" "diff" "Values" $values "Active" $active) }} {{ end }} 12 10 </section> 13 11 {{ end }} 14 12 ··· 14 16 {{ $name := .Name }} 15 17 {{ $all := .Values }} 16 18 {{ $active := .Active }} 17 - <div 18 - class="flex justify-between divide-x divide-gray-200 dark:divide-gray-700 rounded border border-gray-200 dark:border-gray-700 overflow-hidden"> 19 + <div class="flex justify-between divide-x divide-gray-200 dark:divide-gray-700 rounded border border-gray-200 dark:border-gray-700 overflow-hidden"> 19 20 {{ $activeTab := "bg-white dark:bg-gray-700 shadow-sm" }} 20 21 {{ $inactiveTab := "bg-gray-100 dark:bg-gray-800 shadow-inner" }} 21 22 {{ range $index, $value := $all }} 22 23 {{ $isActive := eq $value $active }} 23 - <a 24 - href="?{{ $name }}={{ $value }}" 25 - class="py-2 text-sm w-full block hover:no-underline text-center {{ if $isActive }} 26 - {{ $activeTab }} 27 - {{ else }} 28 - {{ $inactiveTab }} 29 - {{ end }}"> 30 - {{ $value }} 24 + <a href="?{{ $name }}={{ $value }}" 25 + class="py-2 text-sm w-full block hover:no-underline text-center {{ if $isActive }} {{$activeTab }} {{ else }} {{ $inactiveTab }} {{ end }}"> 26 + {{ $value }} 31 27 </a> 32 28 {{ end }} 33 29 </div>
+5 -16
appview/pages/templates/repo/fragments/diffStatPill.html
··· 1 1 {{ define "repo/fragments/diffStatPill" }} 2 2 <div class="flex items-center font-mono text-sm"> 3 3 {{ if and .Insertions .Deletions }} 4 - <span 5 - class="rounded-l p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400"> 6 - +{{ .Insertions }} 7 - </span> 8 - <span 9 - class="rounded-r p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400"> 10 - -{{ .Deletions }} 11 - </span> 4 + <span class="rounded-l p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400">+{{ .Insertions }}</span> 5 + <span class="rounded-r p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400">-{{ .Deletions }}</span> 12 6 {{ else if .Insertions }} 13 - <span 14 - class="rounded p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400"> 15 - +{{ .Insertions }} 16 - </span> 7 + <span class="rounded p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400">+{{ .Insertions }}</span> 17 8 {{ else if .Deletions }} 18 - <span 19 - class="rounded p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400"> 20 - -{{ .Deletions }} 21 - </span> 9 + <span class="rounded p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400">-{{ .Deletions }}</span> 22 10 {{ end }} 23 11 </div> 24 12 {{ end }} 13 +
+7 -20
appview/pages/templates/repo/fragments/editRepoDescription.html
··· 1 1 {{ define "repo/fragments/editRepoDescription" }} 2 - <form 3 - hx-put="/{{ .RepoInfo.FullName }}/description" 4 - hx-target="this" 5 - hx-swap="outerHTML" 6 - class="flex flex-wrap gap-2"> 7 - <input 8 - type="text" 9 - class="p-1" 10 - name="description" 11 - value="{{ .RepoInfo.Description }}" /> 12 - <button 13 - type="submit" 14 - class="btn p-1 flex items-center gap-2 no-underline text-sm"> 15 - {{ i "check" "w-3 h-3" }} save 2 + <form hx-put="/{{ .RepoInfo.FullName }}/description" hx-target="this" hx-swap="outerHTML" class="flex flex-wrap gap-2"> 3 + <input type="text" class="p-1" name="description" value="{{ .RepoInfo.Description }}"> 4 + <button type="submit" class="btn p-1 flex items-center gap-2 no-underline text-sm"> 5 + {{ i "check" "w-3 h-3" }} save 16 6 </button> 17 - <button 18 - type="button" 19 - class="btn p-1 flex items-center gap-2 no-underline text-sm" 20 - hx-get="/{{ .RepoInfo.FullName }}/description"> 21 - {{ i "x" "w-3 h-3" }} cancel 7 + <button type="button" class="btn p-1 flex items-center gap-2 no-underline text-sm" hx-get="/{{ .RepoInfo.FullName }}/description" > 8 + {{ i "x" "w-3 h-3" }} cancel 22 9 </button> 23 - </form> 10 + </form> 24 11 {{ end }}
+3 -8
appview/pages/templates/repo/fragments/fileTree.html
··· 4 4 <summary class="cursor-pointer list-none pt-1"> 5 5 <span class="tree-directory inline-flex items-center gap-2 "> 6 6 {{ i "folder" "flex-shrink-0 size-4 fill-current" }} 7 - <span class="filename truncate text-black dark:text-white"> 8 - {{ .Name }} 9 - </span> 7 + <span class="filename truncate text-black dark:text-white">{{ .Name }}</span> 10 8 </span> 11 9 </summary> 12 10 <div class="ml-1 pl-2 border-l border-gray-200 dark:border-gray-700"> ··· 16 18 {{ else if .Name }} 17 19 <div class="tree-file flex items-center gap-2 pt-1"> 18 20 {{ i "file" "flex-shrink-0 size-4" }} 19 - <a 20 - href="#file-{{ .Path }}" 21 - class="filename truncate text-black dark:text-white no-underline hover:underline"> 22 - {{ .Name }} 23 - </a> 21 + <a href="#file-{{ .Path }}" class="filename truncate text-black dark:text-white no-underline hover:underline">{{ .Name }}</a> 24 22 </div> 25 23 {{ else }} 26 24 {{ range $child := .Children }} ··· 24 30 {{ end }} 25 31 {{ end }} 26 32 {{ end }} 33 +
+84 -126
appview/pages/templates/repo/fragments/interdiff.html
··· 1 1 {{ define "repo/fragments/interdiff" }} 2 - {{ $repo := index . 0 }} 3 - {{ $x := index . 1 }} 4 - {{ $opts := index . 2 }} 5 - {{ $fileTree := fileTree $x.AffectedFiles }} 6 - {{ $diff := $x.Files }} 7 - {{ $last := sub (len $diff) 1 }} 8 - {{ $isSplit := $opts.Split }} 2 + {{ $repo := index . 0 }} 3 + {{ $x := index . 1 }} 4 + {{ $opts := index . 2 }} 5 + {{ $fileTree := fileTree $x.AffectedFiles }} 6 + {{ $diff := $x.Files }} 7 + {{ $last := sub (len $diff) 1 }} 8 + {{ $isSplit := $opts.Split }} 9 9 10 - 11 - <div class="flex flex-col gap-4"> 12 - {{ range $idx, $hunk := $diff }} 13 - {{ with $hunk }} 14 - <section 15 - class="border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 16 - <div id="file-{{ .Name }}"> 17 - <div id="diff-file"> 18 - <details {{ if not (.Status.IsOnlyInOne) }}open{{ end }}> 19 - <summary class="list-none cursor-pointer sticky top-0"> 20 - <div 21 - id="diff-file-header" 22 - class="rounded cursor-pointer bg-white dark:bg-gray-800 flex justify-between"> 23 - <div 24 - id="left-side-items" 25 - class="p-2 flex gap-2 items-center overflow-x-auto"> 26 - <div 27 - class="flex gap-1 items-center" 28 - style="direction: ltr;"> 29 - {{ $markerstyle := "diff-type p-1 mr-1 font-mono text-sm rounded select-none" }} 30 - {{ if .Status.IsOk }} 31 - <span 32 - class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}"> 33 - CHANGED 34 - </span> 35 - {{ else if .Status.IsUnchanged }} 36 - <span 37 - class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}"> 38 - UNCHANGED 39 - </span> 40 - {{ else if .Status.IsOnlyInOne }} 41 - <span 42 - class="bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400 {{ $markerstyle }}"> 43 - REVERTED 44 - </span> 45 - {{ else if .Status.IsOnlyInTwo }} 46 - <span 47 - class="bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400 {{ $markerstyle }}"> 48 - NEW 49 - </span> 50 - {{ else if .Status.IsRebased }} 51 - <span 52 - class="bg-amber-100 text-amber-700 dark:bg-amber-800/50 dark:text-amber-400 {{ $markerstyle }}"> 53 - REBASED 54 - </span> 55 - {{ else }} 56 - <span 57 - class="bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400 {{ $markerstyle }}"> 58 - ERROR 59 - </span> 60 - {{ end }} 61 - </div> 62 - 63 - <div 64 - class="flex gap-2 items-center overflow-x-auto" 65 - style="direction: rtl;"> 66 - <a 67 - class="dark:text-white whitespace-nowrap overflow-x-auto" 68 - href=""> 69 - {{ .Name }} 70 - </a> 71 - </div> 72 - </div> 73 - 74 - {{ $iconstyle := "p-1 mx-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" }} 75 - <div id="right-side-items" class="p-2 flex items-center"> 76 - <a 77 - title="top of file" 78 - href="#file-{{ .Name }}" 79 - class="{{ $iconstyle }}"> 80 - {{ i "arrow-up-to-line" "w-4 h-4" }} 81 - </a> 82 - {{ if gt $idx 0 }} 83 - {{ $prev := index $diff (sub $idx 1) }} 84 - <a 85 - title="previous file" 86 - href="#file-{{ $prev.Name }}" 87 - class="{{ $iconstyle }}"> 88 - {{ i "arrow-up" "w-4 h-4" }} 89 - </a> 90 - {{ end }} 91 - 92 - {{ if lt $idx $last }} 93 - {{ $next := index $diff (add $idx 1) }} 94 - <a 95 - title="next file" 96 - href="#file-{{ $next.Name }}" 97 - class="{{ $iconstyle }}"> 98 - {{ i "arrow-down" "w-4 h-4" }} 99 - </a> 100 - {{ end }} 101 - </div> 102 - </div> 103 - </summary> 104 - 105 - <div class="transition-all duration-700 ease-in-out"> 106 - {{ if .Status.IsUnchanged }} 107 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 108 - This file has not been changed. 109 - </p> 110 - {{ else if .Status.IsRebased }} 111 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 112 - This patch was likely rebased, as context lines do not 113 - match. 114 - </p> 115 - {{ else if .Status.IsError }} 116 - <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 117 - Failed to calculate interdiff for this file. 118 - </p> 119 - {{ else }} 120 - {{ if $isSplit }} 121 - {{- template "repo/fragments/splitDiff" .Split -}} 10 + <div class="flex flex-col gap-4"> 11 + {{ range $idx, $hunk := $diff }} 12 + {{ with $hunk }} 13 + <section class="border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 14 + <div id="file-{{ .Name }}"> 15 + <div id="diff-file"> 16 + <details {{ if not (.Status.IsOnlyInOne) }}open{{end}}> 17 + <summary class="list-none cursor-pointer sticky top-0"> 18 + <div id="diff-file-header" class="rounded cursor-pointer bg-white dark:bg-gray-800 flex justify-between"> 19 + <div id="left-side-items" class="p-2 flex gap-2 items-center overflow-x-auto"> 20 + <div class="flex gap-1 items-center" style="direction: ltr;"> 21 + {{ $markerstyle := "diff-type p-1 mr-1 font-mono text-sm rounded select-none" }} 22 + {{ if .Status.IsOk }} 23 + <span class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}">CHANGED</span> 24 + {{ else if .Status.IsUnchanged }} 25 + <span class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}">UNCHANGED</span> 26 + {{ else if .Status.IsOnlyInOne }} 27 + <span class="bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400 {{ $markerstyle }}">REVERTED</span> 28 + {{ else if .Status.IsOnlyInTwo }} 29 + <span class="bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400 {{ $markerstyle }}">NEW</span> 30 + {{ else if .Status.IsRebased }} 31 + <span class="bg-amber-100 text-amber-700 dark:bg-amber-800/50 dark:text-amber-400 {{ $markerstyle }}">REBASED</span> 122 32 {{ else }} 123 - {{- template "repo/fragments/unifiedDiff" . -}} 33 + <span class="bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400 {{ $markerstyle }}">ERROR</span> 124 34 {{ end }} 125 - {{- end -}} 35 + </div> 36 + 37 + <div class="flex gap-2 items-center overflow-x-auto" style="direction: rtl;"> 38 + <a class="dark:text-white whitespace-nowrap overflow-x-auto" href=""> 39 + {{ .Name }} 40 + </a> 41 + </div> 126 42 </div> 127 - </details> 43 + 44 + {{ $iconstyle := "p-1 mx-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" }} 45 + <div id="right-side-items" class="p-2 flex items-center"> 46 + <a title="top of file" href="#file-{{ .Name }}" class="{{ $iconstyle }}">{{ i "arrow-up-to-line" "w-4 h-4" }}</a> 47 + {{ if gt $idx 0 }} 48 + {{ $prev := index $diff (sub $idx 1) }} 49 + <a title="previous file" href="#file-{{ $prev.Name }}" class="{{ $iconstyle }}">{{ i "arrow-up" "w-4 h-4" }}</a> 50 + {{ end }} 51 + 52 + {{ if lt $idx $last }} 53 + {{ $next := index $diff (add $idx 1) }} 54 + <a title="next file" href="#file-{{ $next.Name }}" class="{{ $iconstyle }}">{{ i "arrow-down" "w-4 h-4" }}</a> 55 + {{ end }} 56 + </div> 57 + 58 + </div> 59 + </summary> 60 + 61 + <div class="transition-all duration-700 ease-in-out"> 62 + {{ if .Status.IsUnchanged }} 63 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 64 + This file has not been changed. 65 + </p> 66 + {{ else if .Status.IsRebased }} 67 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 68 + This patch was likely rebased, as context lines do not match. 69 + </p> 70 + {{ else if .Status.IsError }} 71 + <p class="text-center text-gray-400 dark:text-gray-500 p-4"> 72 + Failed to calculate interdiff for this file. 73 + </p> 74 + {{ else }} 75 + {{ if $isSplit }} 76 + {{- template "repo/fragments/splitDiff" .Split -}} 77 + {{ else }} 78 + {{- template "repo/fragments/unifiedDiff" . -}} 79 + {{ end }} 80 + {{- end -}} 128 81 </div> 129 - </div> 130 - </section> 131 - {{ end }} 82 + 83 + </details> 84 + 85 + </div> 86 + </div> 87 + </section> 132 88 {{ end }} 133 - </div> 89 + {{ end }} 90 + </div> 134 91 {{ end }} 92 +
+8 -9
appview/pages/templates/repo/fragments/interdiffFiles.html
··· 1 1 {{ define "repo/fragments/interdiffFiles" }} 2 - {{ $fileTree := fileTree .AffectedFiles }} 3 - <section 4 - class="mt-4 px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm min-h-full text-sm"> 5 - <div class="diff-stat"> 6 - <div class="flex gap-2 items-center"> 7 - <strong class="text-sm uppercase dark:text-gray-200">files</strong> 8 - </div> 9 - {{ template "repo/fragments/fileTree" $fileTree }} 2 + {{ $fileTree := fileTree .AffectedFiles }} 3 + <section class="mt-4 px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm min-h-full text-sm"> 4 + <div class="diff-stat"> 5 + <div class="flex gap-2 items-center"> 6 + <strong class="text-sm uppercase dark:text-gray-200">files</strong> 10 7 </div> 11 - </section> 8 + {{ template "repo/fragments/fileTree" $fileTree }} 9 + </div> 10 + </section> 12 11 {{ end }}
+24 -18
appview/pages/templates/repo/fragments/meta.html
··· 1 1 {{ define "repo/fragments/meta" }} 2 - <meta 3 - name="vcs:clone" 4 - content="https://tangled.sh/{{ .RepoInfo.FullName }}" /> 5 - <meta 6 - name="forge:summary" 7 - content="https://tangled.sh/{{ .RepoInfo.FullName }}" /> 8 - <meta 9 - name="forge:dir" 10 - content="https://tangled.sh/{{ .RepoInfo.FullName }}/tree/{ref}/{path}" /> 11 - <meta 12 - name="forge:file" 13 - content="https://tangled.sh/{{ .RepoInfo.FullName }}/blob/{ref}/{path}" /> 14 - <meta 15 - name="forge:line" 16 - content="https://tangled.sh/{{ .RepoInfo.FullName }}/blob/{ref}/{path}#L{line}" /> 17 - <meta 18 - name="go-import" 19 - content="tangled.sh/{{ .RepoInfo.FullNameWithoutAt }} git https://tangled.sh/{{ .RepoInfo.FullName }}" /> 2 + <meta 3 + name="vcs:clone" 4 + content="https://tangled.sh/{{ .RepoInfo.FullName }}" 5 + /> 6 + <meta 7 + name="forge:summary" 8 + content="https://tangled.sh/{{ .RepoInfo.FullName }}" 9 + /> 10 + <meta 11 + name="forge:dir" 12 + content="https://tangled.sh/{{ .RepoInfo.FullName }}/tree/{ref}/{path}" 13 + /> 14 + <meta 15 + name="forge:file" 16 + content="https://tangled.sh/{{ .RepoInfo.FullName }}/blob/{ref}/{path}" 17 + /> 18 + <meta 19 + name="forge:line" 20 + content="https://tangled.sh/{{ .RepoInfo.FullName }}/blob/{ref}/{path}#L{line}" 21 + /> 22 + <meta 23 + name="go-import" 24 + content="tangled.sh/{{ .RepoInfo.FullNameWithoutAt }} git https://tangled.sh/{{ .RepoInfo.FullName }}" 25 + /> 20 26 {{ end }}
+7 -7
appview/pages/templates/repo/fragments/og.html
··· 1 1 {{ define "repo/fragments/og" }} 2 - {{ $title := or .Title .RepoInfo.FullName }} 3 - {{ $description := or .Description .RepoInfo.Description }} 4 - {{ $url := or .Url (printf "https://tangled.sh/%s" .RepoInfo.FullName) }} 2 + {{ $title := or .Title .RepoInfo.FullName }} 3 + {{ $description := or .Description .RepoInfo.Description }} 4 + {{ $url := or .Url (printf "https://tangled.sh/%s" .RepoInfo.FullName) }} 5 5 6 6 7 - <meta property="og:title" content="{{ unescapeHtml $title }}" /> 8 - <meta property="og:type" content="object" /> 9 - <meta property="og:url" content="{{ $url }}" /> 10 - <meta property="og:description" content="{{ $description }}" /> 7 + <meta property="og:title" content="{{ unescapeHtml $title }}" /> 8 + <meta property="og:type" content="object" /> 9 + <meta property="og:url" content="{{ $url }}" /> 10 + <meta property="og:description" content="{{ $description }}" /> 11 11 {{ end }}
+28 -21
appview/pages/templates/repo/fragments/reaction.html
··· 1 1 {{ define "repo/fragments/reaction" }} 2 - <button 3 - id="reactIndi-{{ .Kind }}" 4 - class="flex justify-center items-center min-w-8 min-h-8 rounded border 2 + <button 3 + id="reactIndi-{{ .Kind }}" 4 + class="flex justify-center items-center min-w-8 min-h-8 rounded border 5 5 leading-4 px-3 gap-1 6 6 {{ if eq .Count 0 }} 7 - hidden 8 - {{ end }} 7 + hidden 8 + {{ end }} 9 9 {{ if .IsReacted }} 10 - bg-sky-100 border-sky-400 dark:bg-sky-900 dark:border-sky-500 11 - {{ else }} 12 - border-gray-200 hover:bg-gray-50 hover:border-gray-300 13 - dark:border-gray-700 dark:hover:bg-gray-700 dark:hover:border-gray-600 14 - {{ end }} 10 + bg-sky-100 11 + border-sky-400 12 + dark:bg-sky-900 13 + dark:border-sky-500 14 + {{ else }} 15 + border-gray-200 16 + hover:bg-gray-50 17 + hover:border-gray-300 18 + dark:border-gray-700 19 + dark:hover:bg-gray-700 20 + dark:hover:border-gray-600 21 + {{ end }} 15 22 " 16 - {{ if .IsReacted }} 17 - hx-delete="/react?subject={{ .ThreadAt }}&kind={{ .Kind }}" 18 - {{ else }} 19 - hx-post="/react?subject={{ .ThreadAt }}&kind={{ .Kind }}" 20 - {{ end }} 21 - hx-swap="outerHTML" 22 - hx-trigger="click from:(#reactBtn-{{ .Kind }}, #reactIndi-{{ .Kind }})" 23 - hx-disabled-elt="this"> 24 - <span>{{ .Kind }}</span> 25 - <span>{{ .Count }}</span> 26 - </button> 23 + {{ if .IsReacted }} 24 + hx-delete="/react?subject={{ .ThreadAt }}&kind={{ .Kind }}" 25 + {{ else }} 26 + hx-post="/react?subject={{ .ThreadAt }}&kind={{ .Kind }}" 27 + {{ end }} 28 + hx-swap="outerHTML" 29 + hx-trigger="click from:(#reactBtn-{{ .Kind }}, #reactIndi-{{ .Kind }})" 30 + hx-disabled-elt="this" 31 + > 32 + <span>{{ .Kind }}</span> <span>{{ .Count }}</span> 33 + </button> 27 34 {{ end }}
+24 -18
appview/pages/templates/repo/fragments/reactionsPopUp.html
··· 1 1 {{ define "repo/fragments/reactionsPopUp" }} 2 - <details id="reactionsPopUp" class="relative inline-block"> 3 - <summary 4 - class="flex justify-center items-center min-w-8 min-h-8 rounded border border-gray-200 dark:border-gray-700 2 + <details 3 + id="reactionsPopUp" 4 + class="relative inline-block" 5 + > 6 + <summary 7 + class="flex justify-center items-center min-w-8 min-h-8 rounded border border-gray-200 dark:border-gray-700 5 8 hover:bg-gray-50 6 9 hover:border-gray-300 7 10 dark:hover:bg-gray-700 8 11 dark:hover:border-gray-600 9 - cursor-pointer list-none"> 10 - {{ i "smile" "size-4" }} 11 - </summary> 12 - <div 13 - class="absolute flex left-0 z-10 mt-4 rounded bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700 shadow-lg"> 14 - {{ range $kind := . }} 15 - <button 16 - id="reactBtn-{{ $kind }}" 17 - class="size-12 hover:bg-gray-100 dark:hover:bg-gray-700" 18 - hx-on:click="this.parentElement.parentElement.removeAttribute('open')"> 19 - {{ $kind }} 20 - </button> 21 - {{ end }} 22 - </div> 23 - </details> 12 + cursor-pointer list-none" 13 + > 14 + {{ i "smile" "size-4" }} 15 + </summary> 16 + <div 17 + class="absolute flex left-0 z-10 mt-4 rounded bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700 shadow-lg" 18 + > 19 + {{ range $kind := . }} 20 + <button 21 + id="reactBtn-{{ $kind }}" 22 + class="size-12 hover:bg-gray-100 dark:hover:bg-gray-700" 23 + hx-on:click="this.parentElement.parentElement.removeAttribute('open')" 24 + > 25 + {{ $kind }} 26 + </button> 27 + {{ end }} 28 + </div> 29 + </details> 24 30 {{ end }}
+7 -13
appview/pages/templates/repo/fragments/repoDescription.html
··· 1 1 {{ define "repo/fragments/repoDescription" }} 2 - <span 3 - id="repo-description" 4 - class="flex flex-wrap items-center gap-2 text-sm" 5 - hx-target="this" 6 - hx-swap="outerHTML"> 2 + <span id="repo-description" class="flex flex-wrap items-center gap-2 text-sm" hx-target="this" hx-swap="outerHTML"> 7 3 {{ if .RepoInfo.Description }} 8 - {{ .RepoInfo.Description }} 4 + {{ .RepoInfo.Description }} 9 5 {{ else }} 10 - <span class="italic">this repo has no description</span> 6 + <span class="italic">this repo has no description</span> 11 7 {{ end }} 12 8 13 9 {{ if .RepoInfo.Roles.IsOwner }} 14 - <button 15 - class="flex items-center gap-2 no-underline text-sm" 16 - hx-get="/{{ .RepoInfo.FullName }}/description/edit"> 17 - {{ i "pencil" "w-3 h-3" }} 18 - </button> 10 + <button class="flex items-center gap-2 no-underline text-sm" hx-get="/{{ .RepoInfo.FullName }}/description/edit"> 11 + {{ i "pencil" "w-3 h-3" }} 12 + </button> 19 13 {{ end }} 20 - </span> 14 + </span> 21 15 {{ end }}
+23 -22
appview/pages/templates/repo/fragments/repoStar.html
··· 1 1 {{ define "repo/fragments/repoStar" }} 2 - <button 3 - id="starBtn" 4 - class="btn disabled:opacity-50 disabled:cursor-not-allowed flex gap-2 items-center group" 5 - {{ if .IsStarred }} 6 - hx-delete="/star?subject={{ .RepoAt }}&countHint={{ .Stats.StarCount }}" 7 - {{ else }} 8 - hx-post="/star?subject={{ .RepoAt }}&countHint={{ .Stats.StarCount }}" 9 - {{ end }} 2 + <button 3 + id="starBtn" 4 + class="btn disabled:opacity-50 disabled:cursor-not-allowed flex gap-2 items-center group" 5 + {{ if .IsStarred }} 6 + hx-delete="/star?subject={{ .RepoAt }}&countHint={{ .Stats.StarCount }}" 7 + {{ else }} 8 + hx-post="/star?subject={{ .RepoAt }}&countHint={{ .Stats.StarCount }}" 9 + {{ end }} 10 10 11 - hx-trigger="click" 12 - hx-target="this" 13 - hx-swap="outerHTML" 14 - hx-disabled-elt="#starBtn"> 15 - {{ if .IsStarred }} 16 - {{ i "star" "w-4 h-4 fill-current" }} 17 - {{ else }} 18 - {{ i "star" "w-4 h-4" }} 19 - {{ end }} 20 - <span class="text-sm"> 21 - {{ .Stats.StarCount }} 22 - </span> 23 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 24 - </button> 11 + hx-trigger="click" 12 + hx-target="this" 13 + hx-swap="outerHTML" 14 + hx-disabled-elt="#starBtn" 15 + > 16 + {{ if .IsStarred }} 17 + {{ i "star" "w-4 h-4 fill-current" }} 18 + {{ else }} 19 + {{ i "star" "w-4 h-4" }} 20 + {{ end }} 21 + <span class="text-sm"> 22 + {{ .Stats.StarCount }} 23 + </span> 24 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 25 + </button> 25 26 {{ end }}
+58 -113
appview/pages/templates/repo/fragments/splitDiff.html
··· 1 1 {{ define "repo/fragments/splitDiff" }} 2 - {{ $name := .Id }} 3 - {{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800" -}} 4 - {{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} 5 - {{- $lineNrSepStyle := "pr-2 border-r border-gray-200 dark:border-gray-700" -}} 6 - {{- $containerStyle := "flex min-w-full items-center target:border target:rounded-sm target:border-yellow-200 target:dark:border-yellow-700 scroll-mt-20" -}} 7 - {{- $emptyStyle := "bg-gray-200/30 dark:bg-gray-700/30" -}} 8 - {{- $addStyle := "bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400" -}} 9 - {{- $delStyle := "bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 " -}} 10 - {{- $ctxStyle := "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400" -}} 11 - {{- $opStyle := "w-5 flex-shrink-0 select-none text-center" -}} 12 - <div class="grid grid-cols-2 divide-x divide-gray-200 dark:divide-gray-700"> 13 - <pre 14 - class="overflow-x-auto col-span-1"><div class="overflow-x-auto"><div class="min-w-full inline-block">{{- range .TextFragments -}} 15 - <div 16 - class="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 select-none text-center"> 17 - &middot;&middot;&middot; 18 - </div> 19 - {{- range .LeftLines -}} 20 - {{- if .IsEmpty -}} 21 - <div class="{{ $emptyStyle }} {{ $containerStyle }}"> 22 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle }}"> 23 - <span aria-hidden="true" class="invisible"> 24 - {{ .LineNumber }} 25 - </span> 26 - </div> 27 - <div class="{{ $opStyle }}"> 28 - <span aria-hidden="true" class="invisible">{{ .Op.String }}</span> 29 - </div> 30 - <div class="px-2 invisible" aria-hidden="true">{{ .Content }}</div> 31 - </div> 32 - {{- else if eq .Op.String "-" -}} 33 - <div 34 - class="{{ $delStyle }} {{ $containerStyle }}" 35 - id="{{ $name }}-O{{ .LineNumber }}"> 36 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle }}"> 37 - <a 38 - class="{{ $linkStyle }}" 39 - href="#{{ $name }}-O{{ .LineNumber }}"> 40 - {{ .LineNumber }} 41 - </a> 42 - </div> 43 - <div class="{{ $opStyle }}">{{ .Op.String }}</div> 44 - <div class="px-2">{{ .Content }}</div> 45 - </div> 46 - {{- else if eq .Op.String " " -}} 47 - <div 48 - class="{{ $ctxStyle }} {{ $containerStyle }}" 49 - id="{{ $name }}-O{{ .LineNumber }}"> 50 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle }}"> 51 - <a 52 - class="{{ $linkStyle }}" 53 - href="#{{ $name }}-O{{ .LineNumber }}"> 54 - {{ .LineNumber }} 55 - </a> 56 - </div> 57 - <div class="{{ $opStyle }}">{{ .Op.String }}</div> 58 - <div class="px-2">{{ .Content }}</div> 59 - </div> 60 - {{- end -}} 61 - {{- end -}} 62 - {{- end -}} 63 - </div></div></pre> 2 + {{ $name := .Id }} 3 + {{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800" -}} 4 + {{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} 5 + {{- $lineNrSepStyle := "pr-2 border-r border-gray-200 dark:border-gray-700" -}} 6 + {{- $containerStyle := "flex min-w-full items-center target:border target:rounded-sm target:border-yellow-200 target:dark:border-yellow-700 scroll-mt-20" -}} 7 + {{- $emptyStyle := "bg-gray-200/30 dark:bg-gray-700/30" -}} 8 + {{- $addStyle := "bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400" -}} 9 + {{- $delStyle := "bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 " -}} 10 + {{- $ctxStyle := "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400" -}} 11 + {{- $opStyle := "w-5 flex-shrink-0 select-none text-center" -}} 12 + <div class="grid grid-cols-2 divide-x divide-gray-200 dark:divide-gray-700"> 13 + <pre class="overflow-x-auto col-span-1"><div class="overflow-x-auto"><div class="min-w-full inline-block">{{- range .TextFragments -}}<div class="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 select-none text-center">&middot;&middot;&middot;</div> 14 + {{- range .LeftLines -}} 15 + {{- if .IsEmpty -}} 16 + <div class="{{ $emptyStyle }} {{ $containerStyle }}"> 17 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle}}"><span aria-hidden="true" class="invisible">{{.LineNumber}}</span></div> 18 + <div class="{{ $opStyle }}"><span aria-hidden="true" class="invisible">{{ .Op.String }}</span></div> 19 + <div class="px-2 invisible" aria-hidden="true">{{ .Content }}</div> 20 + </div> 21 + {{- else if eq .Op.String "-" -}} 22 + <div class="{{ $delStyle }} {{ $containerStyle }}" id="{{$name}}-O{{.LineNumber}}"> 23 + <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle }}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{.LineNumber}}">{{ .LineNumber }}</a></div> 24 + <div class="{{ $opStyle }}">{{ .Op.String }}</div> 25 + <div class="px-2">{{ .Content }}</div> 26 + </div> 27 + {{- else if eq .Op.String " " -}} 28 + <div class="{{ $ctxStyle }} {{ $containerStyle }}" id="{{$name}}-O{{.LineNumber}}"> 29 + <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle }}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{.LineNumber}}">{{ .LineNumber }}</a></div> 30 + <div class="{{ $opStyle }}">{{ .Op.String }}</div> 31 + <div class="px-2">{{ .Content }}</div> 32 + </div> 33 + {{- end -}} 34 + {{- end -}} 35 + {{- end -}}</div></div></pre> 64 36 65 - <pre 66 - class="overflow-x-auto col-span-1"><div class="overflow-x-auto"><div class="min-w-full inline-block">{{- range .TextFragments -}} 67 - <div 68 - class="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 select-none text-center"> 69 - &middot;&middot;&middot; 70 - </div> 71 - {{- range .RightLines -}} 72 - {{- if .IsEmpty -}} 73 - <div class="{{ $emptyStyle }} {{ $containerStyle }}"> 74 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle }}"> 75 - <span aria-hidden="true" class="invisible"> 76 - {{ .LineNumber }} 77 - </span> 78 - </div> 79 - <div class="{{ $opStyle }}"> 80 - <span aria-hidden="true" class="invisible">{{ .Op.String }}</span> 81 - </div> 82 - <div class="px-2 invisible" aria-hidden="true">{{ .Content }}</div> 83 - </div> 84 - {{- else if eq .Op.String "+" -}} 85 - <div 86 - class="{{ $addStyle }} {{ $containerStyle }}" 87 - id="{{ $name }}-N{{ .LineNumber }}"> 88 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle }}"> 89 - <a 90 - class="{{ $linkStyle }}" 91 - href="#{{ $name }}-N{{ .LineNumber }}"> 92 - {{ .LineNumber }} 93 - </a> 94 - </div> 95 - <div class="{{ $opStyle }}">{{ .Op.String }}</div> 96 - <div class="px-2">{{ .Content }}</div> 97 - </div> 98 - {{- else if eq .Op.String " " -}} 99 - <div 100 - class="{{ $ctxStyle }} {{ $containerStyle }}" 101 - id="{{ $name }}-N{{ .LineNumber }}"> 102 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle }}"> 103 - <a 104 - class="{{ $linkStyle }}" 105 - href="#{{ $name }}-N{{ .LineNumber }}"> 106 - {{ .LineNumber }} 107 - </a> 108 - </div> 109 - <div class="{{ $opStyle }}">{{ .Op.String }}</div> 110 - <div class="px-2">{{ .Content }}</div> 111 - </div> 112 - {{- end -}} 113 - {{- end -}} 114 - {{- end -}}</div></div></pre> 115 - </div> 37 + <pre class="overflow-x-auto col-span-1"><div class="overflow-x-auto"><div class="min-w-full inline-block">{{- range .TextFragments -}}<div class="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 select-none text-center">&middot;&middot;&middot;</div> 38 + {{- range .RightLines -}} 39 + {{- if .IsEmpty -}} 40 + <div class="{{ $emptyStyle }} {{ $containerStyle }}"> 41 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle}}"><span aria-hidden="true" class="invisible">{{.LineNumber}}</span></div> 42 + <div class="{{ $opStyle }}"><span aria-hidden="true" class="invisible">{{ .Op.String }}</span></div> 43 + <div class="px-2 invisible" aria-hidden="true">{{ .Content }}</div> 44 + </div> 45 + {{- else if eq .Op.String "+" -}} 46 + <div class="{{ $addStyle }} {{ $containerStyle }}" id="{{$name}}-N{{.LineNumber}}"> 47 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{.LineNumber}}">{{ .LineNumber }}</a></div> 48 + <div class="{{ $opStyle }}">{{ .Op.String }}</div> 49 + <div class="px-2" >{{ .Content }}</div> 50 + </div> 51 + {{- else if eq .Op.String " " -}} 52 + <div class="{{ $ctxStyle }} {{ $containerStyle }}" id="{{$name}}-N{{.LineNumber}}"> 53 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{.LineNumber}}">{{ .LineNumber }}</a></div> 54 + <div class="{{ $opStyle }}">{{ .Op.String }}</div> 55 + <div class="px-2">{{ .Content }}</div> 56 + </div> 57 + {{- end -}} 58 + {{- end -}} 59 + {{- end -}}</div></div></pre> 60 + </div> 116 61 {{ end }}
+5 -13
appview/pages/templates/repo/fragments/time.html
··· 1 1 {{ define "repo/fragments/timeWrapper" }} 2 - <time 3 - datetime="{{ .Time | iso8601DateTimeFmt }}" 4 - title="{{ .Time | longTimeFmt }}"> 5 - {{ .Content }} 6 - </time> 2 + <time datetime="{{ .Time | iso8601DateTimeFmt }}" title="{{ .Time | longTimeFmt }}">{{ .Content }}</time> 7 3 {{ end }} 8 4 9 5 {{ define "repo/fragments/time" }} 10 - {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (. | relTimeFmt)) }} 6 + {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (. | relTimeFmt)) }} 11 7 {{ end }} 12 8 13 9 {{ define "repo/fragments/shortTime" }} 14 - {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (. | shortRelTimeFmt)) }} 10 + {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (. | shortRelTimeFmt)) }} 15 11 {{ end }} 16 12 17 13 {{ define "repo/fragments/shortTimeAgo" }} 18 - {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (print (. | shortRelTimeFmt) " ago")) }} 14 + {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (print (. | shortRelTimeFmt) " ago")) }} 19 15 {{ end }} 20 16 21 17 {{ define "repo/fragments/duration" }} 22 - <time 23 - datetime="{{ . | iso8601DurationFmt }}" 24 - title="{{ . | longDurationFmt }}"> 25 - {{ . | durationFmt }} 26 - </time> 18 + <time datetime="{{ . | iso8601DurationFmt }}" title="{{ . | longDurationFmt }}">{{ . | durationFmt }}</time> 27 19 {{ end }}
+45 -79
appview/pages/templates/repo/fragments/unifiedDiff.html
··· 1 1 {{ define "repo/fragments/unifiedDiff" }} 2 - {{ $name := .Id }} 3 - <pre 4 - class="overflow-x-auto"><div class="overflow-x-auto"><div class="min-w-full inline-block">{{- range .TextFragments -}} 5 - <div 6 - class="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 select-none text-center"> 7 - &middot;&middot;&middot; 8 - </div> 9 - {{- $oldStart := .OldPosition -}} 10 - {{- $newStart := .NewPosition -}} 11 - {{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800 target:bg-yellow-200 target:dark:bg-yellow-600" -}} 12 - {{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} 13 - {{- $lineNrSepStyle1 := "" -}} 14 - {{- $lineNrSepStyle2 := "pr-2 border-r border-gray-200 dark:border-gray-700" -}} 15 - {{- $containerStyle := "flex min-w-full items-center target:border target:rounded-sm target:border-yellow-200 target:dark:border-yellow-700 scroll-mt-20" -}} 16 - {{- $addStyle := "bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400 " -}} 17 - {{- $delStyle := "bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 " -}} 18 - {{- $ctxStyle := "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400" -}} 19 - {{- $opStyle := "w-5 flex-shrink-0 select-none text-center" -}} 20 - {{- range .Lines -}} 21 - {{- if eq .Op.String "+" -}} 22 - <div 23 - class="{{ $addStyle }} {{ $containerStyle }}" 24 - id="{{ $name }}-N{{ $newStart }}"> 25 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle1 }}"> 26 - <span aria-hidden="true" class="invisible">{{ $newStart }}</span> 27 - </div> 28 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle2 }}"> 29 - <a class="{{ $linkStyle }}" href="#{{ $name }}-N{{ $newStart }}"> 30 - {{ $newStart }} 31 - </a> 32 - </div> 33 - <div class="{{ $opStyle }}">{{ .Op.String }}</div> 34 - <div class="px-2">{{ .Line }}</div> 35 - </div> 36 - {{- $newStart = add64 $newStart 1 -}} 37 - {{- end -}} 38 - {{- if eq .Op.String "-" -}} 39 - <div 40 - class="{{ $delStyle }} {{ $containerStyle }}" 41 - id="{{ $name }}-O{{ $oldStart }}"> 42 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle1 }}"> 43 - <a class="{{ $linkStyle }}" href="#{{ $name }}-O{{ $oldStart }}"> 44 - {{ $oldStart }} 45 - </a> 46 - </div> 47 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle2 }}"> 48 - <span aria-hidden="true" class="invisible">{{ $oldStart }}</span> 49 - </div> 50 - <div class="{{ $opStyle }}">{{ .Op.String }}</div> 51 - <div class="px-2">{{ .Line }}</div> 52 - </div> 53 - {{- $oldStart = add64 $oldStart 1 -}} 54 - {{- end -}} 55 - {{- if eq .Op.String " " -}} 56 - <div 57 - class="{{ $ctxStyle }} {{ $containerStyle }}" 58 - id="{{ $name }}-O{{ $oldStart }}-N{{ $newStart }}"> 59 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle1 }}"> 60 - <a 61 - class="{{ $linkStyle }}" 62 - href="#{{ $name }}-O{{ $oldStart }}-N{{ $newStart }}"> 63 - {{ $oldStart }} 64 - </a> 65 - </div> 66 - <div class="{{ $lineNrStyle }} {{ $lineNrSepStyle2 }}"> 67 - <a 68 - class="{{ $linkStyle }}" 69 - href="#{{ $name }}-O{{ $oldStart }}-N{{ $newStart }}"> 70 - {{ $newStart }} 71 - </a> 72 - </div> 73 - <div class="{{ $opStyle }}">{{ .Op.String }}</div> 74 - <div class="px-2">{{ .Line }}</div> 75 - </div> 76 - {{- $newStart = add64 $newStart 1 -}} 77 - {{- $oldStart = add64 $oldStart 1 -}} 78 - {{- end -}} 79 - {{- end -}} 80 - {{- end -}}</div></div></pre> 2 + {{ $name := .Id }} 3 + <pre class="overflow-x-auto"><div class="overflow-x-auto"><div class="min-w-full inline-block">{{- range .TextFragments -}}<div class="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 select-none text-center">&middot;&middot;&middot;</div> 4 + {{- $oldStart := .OldPosition -}} 5 + {{- $newStart := .NewPosition -}} 6 + {{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800 target:bg-yellow-200 target:dark:bg-yellow-600" -}} 7 + {{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} 8 + {{- $lineNrSepStyle1 := "" -}} 9 + {{- $lineNrSepStyle2 := "pr-2 border-r border-gray-200 dark:border-gray-700" -}} 10 + {{- $containerStyle := "flex min-w-full items-center target:border target:rounded-sm target:border-yellow-200 target:dark:border-yellow-700 scroll-mt-20" -}} 11 + {{- $addStyle := "bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400 " -}} 12 + {{- $delStyle := "bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 " -}} 13 + {{- $ctxStyle := "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400" -}} 14 + {{- $opStyle := "w-5 flex-shrink-0 select-none text-center" -}} 15 + {{- range .Lines -}} 16 + {{- if eq .Op.String "+" -}} 17 + <div class="{{ $addStyle }} {{ $containerStyle }}" id="{{$name}}-N{{$newStart}}"> 18 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}"><span aria-hidden="true" class="invisible">{{$newStart}}</span></div> 19 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{$newStart}}">{{ $newStart }}</a></div> 20 + <div class="{{ $opStyle }}">{{ .Op.String }}</div> 21 + <div class="px-2">{{ .Line }}</div> 22 + </div> 23 + {{- $newStart = add64 $newStart 1 -}} 24 + {{- end -}} 25 + {{- if eq .Op.String "-" -}} 26 + <div class="{{ $delStyle }} {{ $containerStyle }}" id="{{$name}}-O{{$oldStart}}"> 27 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}">{{ $oldStart }}</a></div> 28 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}"><span aria-hidden="true" class="invisible">{{$oldStart}}</span></div> 29 + <div class="{{ $opStyle }}">{{ .Op.String }}</div> 30 + <div class="px-2">{{ .Line }}</div> 31 + </div> 32 + {{- $oldStart = add64 $oldStart 1 -}} 33 + {{- end -}} 34 + {{- if eq .Op.String " " -}} 35 + <div class="{{ $ctxStyle }} {{ $containerStyle }}" id="{{$name}}-O{{$oldStart}}-N{{$newStart}}"> 36 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}-N{{$newStart}}">{{ $oldStart }}</a></div> 37 + <div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}-N{{$newStart}}">{{ $newStart }}</a></div> 38 + <div class="{{ $opStyle }}">{{ .Op.String }}</div> 39 + <div class="px-2">{{ .Line }}</div> 40 + </div> 41 + {{- $newStart = add64 $newStart 1 -}} 42 + {{- $oldStart = add64 $oldStart 1 -}} 43 + {{- end -}} 44 + {{- end -}} 45 + {{- end -}}</div></div></pre> 81 46 {{ end }} 47 +
+258 -312
appview/pages/templates/repo/index.html
··· 1 1 {{ define "title" }}{{ .RepoInfo.FullName }} at {{ .Ref }}{{ end }} 2 2 3 - {{ define "extrameta" }} 4 - {{ template "repo/fragments/meta" . }} 5 3 6 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }} 4 + {{ define "extrameta" }} 5 + {{ template "repo/fragments/meta" . }} 6 + 7 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }} 7 8 {{ end }} 8 9 9 10 {{ define "repoContent" }} 10 - <main> 11 - {{ if .Languages }} 12 - {{ block "repoLanguages" . }}{{ end }} 13 - {{ end }} 14 - <div class="flex items-center justify-between pb-5"> 15 - {{ block "branchSelector" . }}{{ end }} 16 - <div class="flex md:hidden items-center gap-4"> 17 - <a 18 - href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" 19 - class="inline-flex items-center text-sm gap-1"> 20 - {{ i "git-commit-horizontal" "w-4" "h-4" }} 21 - {{ .TotalCommits }} 22 - </a> 23 - <a 24 - href="/{{ .RepoInfo.FullName }}/branches" 25 - class="inline-flex items-center text-sm gap-1"> 26 - {{ i "git-branch" "w-4" "h-4" }} 27 - {{ len .Branches }} 28 - </a> 29 - <a 30 - href="/{{ .RepoInfo.FullName }}/tags" 31 - class="inline-flex items-center text-sm gap-1"> 32 - {{ i "tags" "w-4" "h-4" }} 33 - {{ len .Tags }} 34 - </a> 35 - </div> 36 - </div> 37 - <div class="grid grid-cols-1 md:grid-cols-2 gap-2"> 38 - {{ block "fileTree" . }}{{ end }} 39 - {{ block "rightInfo" . }}{{ end }} 40 - </div> 41 - </main> 11 + <main> 12 + {{ if .Languages }} 13 + {{ block "repoLanguages" . }}{{ end }} 14 + {{ end }} 15 + <div class="flex items-center justify-between pb-5"> 16 + {{ block "branchSelector" . }}{{ end }} 17 + <div class="flex md:hidden items-center gap-4"> 18 + <a href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" class="inline-flex items-center text-sm gap-1"> 19 + {{ i "git-commit-horizontal" "w-4" "h-4" }} {{ .TotalCommits }} 20 + </a> 21 + <a href="/{{ .RepoInfo.FullName }}/branches" class="inline-flex items-center text-sm gap-1"> 22 + {{ i "git-branch" "w-4" "h-4" }} {{ len .Branches }} 23 + </a> 24 + <a href="/{{ .RepoInfo.FullName }}/tags" class="inline-flex items-center text-sm gap-1"> 25 + {{ i "tags" "w-4" "h-4" }} {{ len .Tags }} 26 + </a> 27 + </div> 28 + </div> 29 + <div class="grid grid-cols-1 md:grid-cols-2 gap-2"> 30 + {{ block "fileTree" . }}{{ end }} 31 + {{ block "rightInfo" . }}{{ end }} 32 + </div> 33 + </main> 42 34 {{ end }} 43 35 44 36 {{ define "repoLanguages" }} 45 - <div class="flex gap-[1px] -m-6 mb-6 overflow-hidden rounded-t"> 46 - {{ range $value := .Languages }} 47 - <div 48 - title="{{ or $value.Name "Other" }} {{ printf "%.1f" $value.Percentage }}%" 49 - class="h-[4px] rounded-full" 50 - style="background-color: {{ $value.Color }}; width: {{ $value.Percentage }}%"></div> 51 - {{ end }} 52 - </div> 37 + <div class="flex gap-[1px] -m-6 mb-6 overflow-hidden rounded-t"> 38 + {{ range $value := .Languages }} 39 + <div 40 + title='{{ or $value.Name "Other" }} {{ printf "%.1f" $value.Percentage }}%' 41 + class="h-[4px] rounded-full" 42 + style="background-color: {{ $value.Color }}; width: {{ $value.Percentage }}%" 43 + ></div> 44 + {{ end }} 45 + </div> 53 46 {{ end }} 47 + 54 48 55 49 {{ define "branchSelector" }} 56 50 <div class="flex gap-2 items-center items-stretch justify-center"> 57 51 <select 58 - onchange="window.location.href = '/{{ .RepoInfo.FullName }}/tree/' + encodeURIComponent(this.value)" 59 - class="p-1 border max-w-32 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"> 60 - <optgroup label="branches ({{ len .Branches }})" class="bold text-sm"> 61 - {{ range .Branches }} 62 - <option 63 - value="{{ .Reference.Name }}" 64 - class="py-1" 65 - {{ if eq .Reference.Name $.Ref }} 66 - selected 67 - {{ end }}> 68 - {{ .Reference.Name }} 69 - </option> 70 - {{ end }} 71 - </optgroup> 72 - <optgroup label="tags ({{ len .Tags }})" class="bold text-sm"> 73 - {{ range .Tags }} 74 - <option 75 - value="{{ .Reference.Name }}" 76 - class="py-1" 77 - {{ if eq .Reference.Name $.Ref }} 78 - selected 79 - {{ end }}> 80 - {{ .Reference.Name }} 81 - </option> 82 - {{ else }} 83 - <option class="py-1" disabled>no tags found</option> 84 - {{ end }} 85 - </optgroup> 52 + onchange="window.location.href = '/{{ .RepoInfo.FullName }}/tree/' + encodeURIComponent(this.value)" 53 + class="p-1 border max-w-32 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700" 54 + > 55 + <optgroup label="branches ({{len .Branches}})" class="bold text-sm"> 56 + {{ range .Branches }} 57 + <option 58 + value="{{ .Reference.Name }}" 59 + class="py-1" 60 + {{ if eq .Reference.Name $.Ref }} 61 + selected 62 + {{ end }} 63 + > 64 + {{ .Reference.Name }} 65 + </option> 66 + {{ end }} 67 + </optgroup> 68 + <optgroup label="tags ({{len .Tags}})" class="bold text-sm"> 69 + {{ range .Tags }} 70 + <option 71 + value="{{ .Reference.Name }}" 72 + class="py-1" 73 + {{ if eq .Reference.Name $.Ref }} 74 + selected 75 + {{ end }} 76 + > 77 + {{ .Reference.Name }} 78 + </option> 79 + {{ else }} 80 + <option class="py-1" disabled>no tags found</option> 81 + {{ end }} 82 + </optgroup> 86 83 </select> 87 84 <div class="flex items-center gap-2"> 88 - {{ $isOwner := and .LoggedInUser .RepoInfo.Roles.IsOwner }} 89 - {{ $isCollaborator := and .LoggedInUser .RepoInfo.Roles.IsCollaborator }} 90 - {{ if and (or $isOwner $isCollaborator) .ForkInfo .ForkInfo.IsFork }} 85 + {{ $isOwner := and .LoggedInUser .RepoInfo.Roles.IsOwner }} 86 + {{ $isCollaborator := and .LoggedInUser .RepoInfo.Roles.IsCollaborator }} 87 + {{ if and (or $isOwner $isCollaborator) .ForkInfo .ForkInfo.IsFork }} 91 88 {{ $disabled := "" }} 92 89 {{ $title := "" }} 93 90 {{ if eq .ForkInfo.Status 0 }} 94 - {{ $disabled = "disabled" }} 95 - {{ $title = "This branch is not behind the upstream" }} 91 + {{ $disabled = "disabled" }} 92 + {{ $title = "This branch is not behind the upstream" }} 96 93 {{ else if eq .ForkInfo.Status 2 }} 97 - {{ $disabled = "disabled" }} 98 - {{ $title = "This branch has conflicts that must be resolved" }} 94 + {{ $disabled = "disabled" }} 95 + {{ $title = "This branch has conflicts that must be resolved" }} 99 96 {{ else if eq .ForkInfo.Status 3 }} 100 - {{ $disabled = "disabled" }} 101 - {{ $title = "This branch does not exist on the upstream" }} 97 + {{ $disabled = "disabled" }} 98 + {{ $title = "This branch does not exist on the upstream" }} 102 99 {{ end }} 103 100 104 - 105 101 <button 106 - id="syncBtn" 107 - {{ $disabled }} 108 - {{ if $title }}title="{{ $title }}"{{ end }} 109 - class="btn flex gap-2 items-center disabled:opacity-50 disabled:cursor-not-allowed" 110 - hx-post="/{{ .RepoInfo.FullName }}/fork/sync" 111 - hx-trigger="click" 112 - hx-swap="none"> 102 + id="syncBtn" 103 + {{ $disabled }} 104 + {{ if $title }}title="{{ $title }}"{{ end }} 105 + class="btn flex gap-2 items-center disabled:opacity-50 disabled:cursor-not-allowed" 106 + hx-post="/{{ .RepoInfo.FullName }}/fork/sync" 107 + hx-trigger="click" 108 + hx-swap="none" 109 + > 113 110 {{ if $disabled }} 114 - {{ i "refresh-cw-off" "w-4 h-4" }} 111 + {{ i "refresh-cw-off" "w-4 h-4" }} 115 112 {{ else }} 116 - {{ i "refresh-cw" "w-4 h-4" }} 113 + {{ i "refresh-cw" "w-4 h-4" }} 117 114 {{ end }} 118 115 <span>sync</span> 119 116 </button> 120 - {{ end }} 121 - <a 122 - href="/{{ .RepoInfo.FullName }}/compare?base={{ $.Ref | urlquery }}" 123 - class="btn flex items-center gap-2 no-underline hover:no-underline" 124 - title="Compare branches or tags"> 125 - {{ i "git-compare" "w-4 h-4" }} 126 - </a> 117 + {{ end }} 118 + <a 119 + href="/{{ .RepoInfo.FullName }}/compare?base={{ $.Ref | urlquery }}" 120 + class="btn flex items-center gap-2 no-underline hover:no-underline" 121 + title="Compare branches or tags" 122 + > 123 + {{ i "git-compare" "w-4 h-4" }} 124 + </a> 127 125 </div> 128 - </div> 126 + </div> 129 127 {{ end }} 130 128 131 129 {{ define "fileTree" }} 132 - <div 133 - id="file-tree" 134 - class="col-span-1 pr-2 md:border-r md:border-gray-200 dark:md:border-gray-700"> 130 + <div id="file-tree" class="col-span-1 pr-2 md:border-r md:border-gray-200 dark:md:border-gray-700" > 135 131 {{ $linkstyle := "no-underline hover:underline dark:text-white" }} 136 132 137 133 {{ range .Files }} ··· 152 156 153 157 <div class="text-xs col-span-1 text-right"> 154 158 {{ with .LastCommit }} 155 - <a 156 - href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" 157 - class="text-gray-500 dark:text-gray-400"> 158 - {{ template "repo/fragments/time" .When }} 159 - </a> 159 + <a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" class="text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .When }}</a> 160 160 {{ end }} 161 161 </div> 162 162 </div> ··· 161 169 {{ end }} 162 170 163 171 {{ define "rightInfo" }} 164 - <div id="right-info" class="hidden md:block col-span-1"> 165 - {{ block "commitLog" . }}{{ end }} 166 - {{ block "branchList" . }}{{ end }} 167 - {{ block "tagList" . }}{{ end }} 168 - </div> 172 + <div id="right-info" class="hidden md:block col-span-1"> 173 + {{ block "commitLog" . }} {{ end }} 174 + {{ block "branchList" . }} {{ end }} 175 + {{ block "tagList" . }} {{ end }} 176 + </div> 169 177 {{ end }} 170 178 171 179 {{ define "commitLog" }} 172 - <div id="commit-log" class="md:col-span-1 px-2 pb-4"> 173 - <div class="flex justify-between items-center"> 174 - <a 175 - href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" 176 - class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline"> 177 - {{ i "logs" "w-4 h-4" }} commits 178 - <span 179 - class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm"> 180 - {{ .TotalCommits }} 181 - </span> 182 - </a> 183 - </div> 184 - <div class="flex flex-col gap-6"> 185 - {{ range .CommitsTrunc }} 186 - <div> 187 - <div id="commit-message"> 188 - {{ $messageParts := splitN .Message "\n\n" 2 }} 189 - <div class="text-base cursor-pointer"> 190 - <div> 191 - <div> 192 - <a 193 - href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}" 194 - class="inline no-underline hover:underline dark:text-white"> 195 - {{ index $messageParts 0 }} 196 - </a> 197 - {{ if gt (len $messageParts) 1 }} 198 - 199 - <button 200 - class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600" 201 - hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"> 202 - {{ i "ellipsis" "w-3 h-3" }} 203 - </button> 204 - {{ end }} 205 - </div> 206 - {{ if gt (len $messageParts) 1 }} 207 - <p 208 - class="hidden mt-1 text-sm cursor-text pb-2 dark:text-gray-300"> 209 - {{ nl2br (index $messageParts 1) }} 210 - </p> 211 - {{ end }} 212 - </div> 213 - </div> 214 - </div> 215 - 216 - <!-- commit info bar --> 217 - <div 218 - class="text-xs mt-2 text-gray-500 dark:text-gray-400 flex items-center flex-wrap"> 219 - {{ $verified := $.VerifiedCommits.IsVerified .Hash.String }} 220 - {{ $hashStyle := "text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-900" }} 221 - {{ if $verified }} 222 - {{ $hashStyle = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 rounded" }} 223 - {{ end }} 224 - <span class="font-mono"> 180 + <div id="commit-log" class="md:col-span-1 px-2 pb-4"> 181 + <div class="flex justify-between items-center"> 182 + <a href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline"> 183 + {{ i "logs" "w-4 h-4" }} commits 184 + <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ .TotalCommits }}</span> 185 + </a> 186 + </div> 187 + <div class="flex flex-col gap-6"> 188 + {{ range .CommitsTrunc }} 189 + <div> 190 + <div id="commit-message"> 191 + {{ $messageParts := splitN .Message "\n\n" 2 }} 192 + <div class="text-base cursor-pointer"> 193 + <div> 194 + <div> 225 195 <a 226 196 href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}" 227 - class="no-underline hover:underline {{ $hashStyle }} px-2 py-1 rounded flex items-center gap-2"> 228 - {{ slice .Hash.String 0 8 }} 229 - {{ if $verified }} 230 - {{ i "shield-check" "w-3 h-3" }} 197 + class="inline no-underline hover:underline dark:text-white" 198 + >{{ index $messageParts 0 }}</a 199 + > 200 + {{ if gt (len $messageParts) 1 }} 201 + 202 + <button 203 + class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600" 204 + hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')" 205 + > 206 + {{ i "ellipsis" "w-3 h-3" }} 207 + </button> 231 208 {{ end }} 232 - </a> 233 - </span> 234 - <span class="mx-1 before:content-['·'] before:select-none"></span> 235 - <span> 236 - {{ $didOrHandle := index $.EmailToDidOrHandle .Author.Email }} 237 - <a 238 - href="{{ if $didOrHandle }} 239 - /{{ $didOrHandle }} 240 - {{ else }} 241 - mailto:{{ .Author.Email }} 242 - {{ end }}" 243 - class="text-gray-500 dark:text-gray-400 no-underline hover:underline"> 244 - {{ if $didOrHandle }} 245 - {{ template "user/fragments/picHandleLink" $didOrHandle }} 246 - {{ else }} 247 - {{ .Author.Name }} 209 + </div> 210 + {{ if gt (len $messageParts) 1 }} 211 + <p 212 + class="hidden mt-1 text-sm cursor-text pb-2 dark:text-gray-300" 213 + > 214 + {{ nl2br (index $messageParts 1) }} 215 + </p> 248 216 {{ end }} 249 - </a> 250 - </span> 251 - <div 252 - class="inline-block px-1 select-none after:content-['·']"></div> 253 - {{ template "repo/fragments/time" .Committer.When }} 254 - 255 - 256 - <!-- tags/branches --> 257 - {{ $tagsForCommit := index $.TagMap .Hash.String }} 258 - {{ if gt (len $tagsForCommit) 0 }} 259 - <div 260 - class="inline-block px-1 select-none after:content-['·']"></div> 261 - {{ end }} 262 - {{ range $tagsForCommit }} 263 - <span 264 - class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-[2px] inline-flex items-center"> 265 - {{ . }} 266 - </span> 267 - {{ end }} 268 - 269 - 270 - <!-- ci status --> 271 - {{ $pipeline := index $.Pipelines .Hash.String }} 272 - {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }} 273 - <div 274 - class="inline-block px-1 select-none after:content-['·']"></div> 275 - {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "RepoInfo" $.RepoInfo "Pipeline" $pipeline) }} 276 - {{ end }} 277 217 </div> 278 218 </div> 279 - {{ end }} 219 + </div> 220 + 221 + <!-- commit info bar --> 222 + <div class="text-xs mt-2 text-gray-500 dark:text-gray-400 flex items-center flex-wrap"> 223 + {{ $verified := $.VerifiedCommits.IsVerified .Hash.String }} 224 + {{ $hashStyle := "text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-900" }} 225 + {{ if $verified }} 226 + {{ $hashStyle = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 rounded" }} 227 + {{ end }} 228 + <span class="font-mono"> 229 + <a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}" 230 + class="no-underline hover:underline {{ $hashStyle }} px-2 py-1 rounded flex items-center gap-2"> 231 + {{ slice .Hash.String 0 8 }} 232 + {{ if $verified }} 233 + {{ i "shield-check" "w-3 h-3" }} 234 + {{ end }} 235 + </a> 236 + </span> 237 + <span 238 + class="mx-1 before:content-['·'] before:select-none" 239 + ></span> 240 + <span> 241 + {{ $didOrHandle := index $.EmailToDidOrHandle .Author.Email }} 242 + <a 243 + href="{{ if $didOrHandle }} 244 + /{{ $didOrHandle }} 245 + {{ else }} 246 + mailto:{{ .Author.Email }} 247 + {{ end }}" 248 + class="text-gray-500 dark:text-gray-400 no-underline hover:underline" 249 + >{{ if $didOrHandle }} 250 + {{ template "user/fragments/picHandleLink" $didOrHandle }} 251 + {{ else }} 252 + {{ .Author.Name }} 253 + {{ end }}</a 254 + > 255 + </span> 256 + <div class="inline-block px-1 select-none after:content-['·']"></div> 257 + {{ template "repo/fragments/time" .Committer.When }} 258 + 259 + <!-- tags/branches --> 260 + {{ $tagsForCommit := index $.TagMap .Hash.String }} 261 + {{ if gt (len $tagsForCommit) 0 }} 262 + <div class="inline-block px-1 select-none after:content-['·']"></div> 263 + {{ end }} 264 + {{ range $tagsForCommit }} 265 + <span class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-[2px] inline-flex items-center"> 266 + {{ . }} 267 + </span> 268 + {{ end }} 269 + 270 + <!-- ci status --> 271 + {{ $pipeline := index $.Pipelines .Hash.String }} 272 + {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }} 273 + <div class="inline-block px-1 select-none after:content-['·']"></div> 274 + {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "RepoInfo" $.RepoInfo "Pipeline" $pipeline) }} 275 + {{ end }} 276 + </div> 280 277 </div> 278 + {{ end }} 281 279 </div> 280 + </div> 282 281 {{ end }} 283 282 284 283 {{ define "branchList" }} 285 284 {{ if gt (len .BranchesTrunc) 0 }} 286 - <div 287 - id="branches" 288 - class="md:col-span-1 px-2 py-4 border-t border-gray-200 dark:border-gray-700"> 289 - <a 290 - href="/{{ .RepoInfo.FullName }}/branches" 291 - class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline"> 285 + <div id="branches" class="md:col-span-1 px-2 py-4 border-t border-gray-200 dark:border-gray-700"> 286 + <a href="/{{ .RepoInfo.FullName }}/branches" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline"> 292 287 {{ i "git-branch" "w-4 h-4" }} branches 293 - <span 294 - class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm"> 295 - {{ len .Branches }} 296 - </span> 288 + <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ len .Branches }}</span> 297 289 </a> 298 290 <div class="flex flex-col gap-1"> 299 291 {{ range .BranchesTrunc }} 300 - <div 301 - class="text-base flex items-center justify-between overflow-hidden"> 302 - <div class="flex items-center gap-2 min-w-0 flex-1"> 303 - <a 304 - href="/{{ $.RepoInfo.FullName }}/tree/{{ .Reference.Name | urlquery }}" 305 - class="inline-block truncate no-underline hover:underline dark:text-white"> 306 - {{ .Reference.Name }} 307 - </a> 308 - {{ if .Commit }} 309 - <span 310 - class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·'] shrink-0"></span> 311 - <span 312 - class="whitespace-nowrap text-xs text-gray-500 dark:text-gray-400 shrink-0"> 313 - {{ template "repo/fragments/time" .Commit.Committer.When }} 314 - </span> 315 - {{ end }} 316 - {{ if .IsDefault }} 317 - <span 318 - class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·'] shrink-0"></span> 319 - <span 320 - class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-xs font-mono shrink-0"> 321 - default 322 - </span> 323 - {{ end }} 324 - </div> 325 - {{ if ne $.Ref .Reference.Name }} 326 - <a 327 - href="/{{ $.RepoInfo.FullName }}/compare/{{ $.Ref | urlquery }}...{{ .Reference.Name | urlquery }}" 328 - class="text-xs flex gap-2 items-center shrink-0 ml-2" 329 - title="Compare branches or tags"> 330 - {{ i "git-compare" "w-3 h-3" }} compare 331 - </a> 292 + <div class="text-base flex items-center justify-between overflow-hidden"> 293 + <div class="flex items-center gap-2 min-w-0 flex-1"> 294 + <a href="/{{ $.RepoInfo.FullName }}/tree/{{ .Reference.Name | urlquery }}" 295 + class="inline-block truncate no-underline hover:underline dark:text-white"> 296 + {{ .Reference.Name }} 297 + </a> 298 + {{ if .Commit }} 299 + <span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·'] shrink-0"></span> 300 + <span class="whitespace-nowrap text-xs text-gray-500 dark:text-gray-400 shrink-0">{{ template "repo/fragments/time" .Commit.Committer.When }}</span> 301 + {{ end }} 302 + {{ if .IsDefault }} 303 + <span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·'] shrink-0"></span> 304 + <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-xs font-mono shrink-0">default</span> 332 305 {{ end }} 333 306 </div> 307 + {{ if ne $.Ref .Reference.Name }} 308 + <a href="/{{ $.RepoInfo.FullName }}/compare/{{ $.Ref | urlquery }}...{{ .Reference.Name | urlquery }}" 309 + class="text-xs flex gap-2 items-center shrink-0 ml-2" 310 + title="Compare branches or tags"> 311 + {{ i "git-compare" "w-3 h-3" }} compare 312 + </a> 313 + {{ end }} 314 + </div> 334 315 {{ end }} 335 316 </div> 336 317 </div> ··· 312 347 313 348 {{ define "tagList" }} 314 349 {{ if gt (len .TagsTrunc) 0 }} 315 - <div 316 - id="tags" 317 - class="md:col-span-1 px-2 py-4 border-t border-gray-200 dark:border-gray-700"> 350 + <div id="tags" class="md:col-span-1 px-2 py-4 border-t border-gray-200 dark:border-gray-700"> 318 351 <div class="flex justify-between items-center"> 319 - <a 320 - href="/{{ .RepoInfo.FullName }}/tags" 321 - class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline"> 352 + <a href="/{{ .RepoInfo.FullName }}/tags" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline"> 322 353 {{ i "tags" "w-4 h-4" }} tags 323 - <span 324 - class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm"> 325 - {{ len .Tags }} 326 - </span> 354 + <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ len .Tags }}</span> 327 355 </a> 328 356 </div> 329 357 <div class="flex flex-col gap-1"> 330 358 {{ range $idx, $tag := .TagsTrunc }} 331 - {{ with $tag }} 332 - <div> 333 - <div class="text-base flex items-center gap-2"> 334 - <a 335 - href="/{{ $.RepoInfo.FullName }}/tree/{{ .Reference.Name | urlquery }}" 336 - class="inline no-underline hover:underline dark:text-white"> 337 - {{ .Reference.Name }} 338 - </a> 339 - </div> 340 - <div> 341 - {{ with .Tag }} 342 - <span class="text-xs text-gray-500 dark:text-gray-400"> 343 - {{ template "repo/fragments/time" .Tagger.When }} 344 - </span> 345 - {{ end }} 346 - {{ if eq $idx 0 }} 347 - {{ with .Tag }} 348 - <span 349 - class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·']"></span> 350 - {{ end }} 351 - <span 352 - class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-xs font-mono"> 353 - latest 354 - </span> 355 - {{ end }} 356 - </div> 357 - </div> 358 - {{ end }} 359 + {{ with $tag }} 360 + <div> 361 + <div class="text-base flex items-center gap-2"> 362 + <a href="/{{ $.RepoInfo.FullName }}/tree/{{ .Reference.Name | urlquery }}" 363 + class="inline no-underline hover:underline dark:text-white"> 364 + {{ .Reference.Name }} 365 + </a> 366 + </div> 367 + <div> 368 + {{ with .Tag }} 369 + <span class="text-xs text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .Tagger.When }}</span> 370 + {{ end }} 371 + {{ if eq $idx 0 }} 372 + {{ with .Tag }}<span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·']"></span>{{ end }} 373 + <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-xs font-mono">latest</span> 374 + {{ end }} 375 + </div> 376 + </div> 377 + {{ end }} 359 378 {{ end }} 360 379 </div> 361 380 </div> ··· 347 398 {{ end }} 348 399 349 400 {{ define "repoAfter" }} 350 - {{- if or .HTMLReadme .Readme -}} 351 - <section 352 - class="p-6 mt-4 rounded-br rounded-bl bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm w-full mx-auto overflow-auto {{ if not .Raw }} 353 - prose dark:prose-invert dark:[&_pre]:bg-gray-900 354 - dark:[&_code]:text-gray-300 dark:[&_pre_code]:bg-gray-900 355 - dark:[&_pre]:border dark:[&_pre]:border-gray-700 356 - {{ end }}"> 357 - <article class="{{ if .Raw }}whitespace-pre{{ end }}"> 358 - {{- if .Raw -}} 359 - <pre class="dark:bg-gray-800 dark:text-white overflow-x-auto"> 401 + {{- if or .HTMLReadme .Readme -}} 402 + <section 403 + class="p-6 mt-4 rounded-br rounded-bl bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm w-full mx-auto overflow-auto {{ if not .Raw }} 404 + prose dark:prose-invert dark:[&_pre]:bg-gray-900 405 + dark:[&_code]:text-gray-300 dark:[&_pre_code]:bg-gray-900 406 + dark:[&_pre]:border dark:[&_pre]:border-gray-700 407 + {{ end }}" 408 + > 409 + <article class="{{ if .Raw }}whitespace-pre{{ end }}">{{- if .Raw -}}<pre class="dark:bg-gray-800 dark:text-white overflow-x-auto"> 360 410 {{- .Readme -}} 361 - </pre 362 - > 363 - {{- else -}} 364 - {{ .HTMLReadme }} 365 - {{- end -}} 366 - </article> 367 - </section> 368 - {{- end -}} 411 + </pre> 412 + {{- else -}} 413 + {{ .HTMLReadme }} 414 + {{- end -}}</article> 415 + </section> 416 + {{- end -}} 369 417 370 - {{ template "repo/fragments/cloneInstructions" . }} 418 + {{ template "repo/fragments/cloneInstructions" . }} 371 419 {{ end }}
+40 -45
appview/pages/templates/repo/issues/fragments/editIssueComment.html
··· 1 1 {{ define "repo/issues/fragments/editIssueComment" }} 2 2 {{ with .Comment }} 3 - <div id="comment-container-{{ .CommentId }}"> 4 - <div 5 - class="flex items-center gap-2 mb-2 text-gray-500 dark:text-gray-400 text-sm flex-wrap"> 6 - {{ $owner := didOrHandle $.LoggedInUser.Did $.LoggedInUser.Handle }} 7 - <a href="/{{ $owner }}" class="no-underline hover:underline"> 8 - {{ $owner }} 9 - </a> 3 + <div id="comment-container-{{.CommentId}}"> 4 + <div class="flex items-center gap-2 mb-2 text-gray-500 dark:text-gray-400 text-sm flex-wrap"> 5 + {{ $owner := didOrHandle $.LoggedInUser.Did $.LoggedInUser.Handle }} 6 + <a href="/{{ $owner }}" class="no-underline hover:underline">{{ $owner }}</a> 10 7 11 - <!-- show user "hats" --> 12 - {{ $isIssueAuthor := eq .OwnerDid $.Issue.OwnerDid }} 13 - {{ if $isIssueAuthor }} 14 - <span class="before:content-['·']"></span> 15 - author 16 - {{ end }} 8 + <!-- show user "hats" --> 9 + {{ $isIssueAuthor := eq .OwnerDid $.Issue.OwnerDid }} 10 + {{ if $isIssueAuthor }} 11 + <span class="before:content-['·']"></span> 12 + author 13 + {{ end }} 17 14 18 - 19 - <span class="before:content-['·']"></span> 20 - <a 15 + <span class="before:content-['·']"></span> 16 + <a 21 17 href="#{{ .CommentId }}" 22 18 class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-400 hover:underline no-underline" 23 19 id="{{ .CommentId }}"> 24 - {{ template "repo/fragments/time" .Created }} 25 - </a> 20 + {{ template "repo/fragments/time" .Created }} 21 + </a> 26 22 27 - <button 28 - class="btn px-2 py-1 flex items-center gap-2 text-sm group" 29 - hx-post="/{{ $.RepoInfo.FullName }}/issues/{{ .Issue }}/comment/{{ .CommentId }}/edit" 30 - hx-include="#edit-textarea-{{ .CommentId }}" 31 - hx-target="#comment-container-{{ .CommentId }}" 32 - hx-swap="outerHTML"> 33 - {{ i "check" "w-4 h-4" }} 34 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 35 - </button> 36 - <button 37 - class="btn px-2 py-1 flex items-center gap-2 text-sm" 38 - hx-get="/{{ $.RepoInfo.FullName }}/issues/{{ .Issue }}/comment/{{ .CommentId }}/" 39 - hx-target="#comment-container-{{ .CommentId }}" 40 - hx-swap="outerHTML"> 41 - {{ i "x" "w-4 h-4" }} 42 - </button> 43 - <span id="comment-{{ .CommentId }}-status"></span> 44 - </div> 45 - 46 - <div> 47 - <textarea 48 - id="edit-textarea-{{ .CommentId }}" 49 - name="body" 50 - class="w-full p-2 border rounded min-h-[100px]"> 51 - {{ .Body }}</textarea 52 - > 53 - </div> 23 + <button 24 + class="btn px-2 py-1 flex items-center gap-2 text-sm group" 25 + hx-post="/{{ $.RepoInfo.FullName }}/issues/{{ .Issue }}/comment/{{ .CommentId }}/edit" 26 + hx-include="#edit-textarea-{{ .CommentId }}" 27 + hx-target="#comment-container-{{ .CommentId }}" 28 + hx-swap="outerHTML"> 29 + {{ i "check" "w-4 h-4" }} 30 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 31 + </button> 32 + <button 33 + class="btn px-2 py-1 flex items-center gap-2 text-sm" 34 + hx-get="/{{ $.RepoInfo.FullName }}/issues/{{ .Issue }}/comment/{{ .CommentId }}/" 35 + hx-target="#comment-container-{{ .CommentId }}" 36 + hx-swap="outerHTML"> 37 + {{ i "x" "w-4 h-4" }} 38 + </button> 39 + <span id="comment-{{.CommentId}}-status"></span> 54 40 </div> 41 + 42 + <div> 43 + <textarea 44 + id="edit-textarea-{{ .CommentId }}" 45 + name="body" 46 + class="w-full p-2 border rounded min-h-[100px]">{{ .Body }}</textarea> 47 + </div> 48 + </div> 55 49 {{ end }} 56 50 {{ end }} 51 +
+45 -48
appview/pages/templates/repo/issues/fragments/issueComment.html
··· 1 1 {{ define "repo/issues/fragments/issueComment" }} 2 2 {{ with .Comment }} 3 - <div id="comment-container-{{ .CommentId }}"> 4 - <div 5 - class="flex items-center gap-2 mb-2 text-gray-500 dark:text-gray-400 text-sm flex-wrap"> 6 - {{ template "user/fragments/picHandleLink" .OwnerDid }} 3 + <div id="comment-container-{{.CommentId}}"> 4 + <div class="flex items-center gap-2 mb-2 text-gray-500 dark:text-gray-400 text-sm flex-wrap"> 5 + {{ template "user/fragments/picHandleLink" .OwnerDid }} 7 6 8 - 9 - <!-- show user "hats" --> 10 - {{ $isIssueAuthor := eq .OwnerDid $.Issue.OwnerDid }} 11 - {{ if $isIssueAuthor }} 12 - <span class="before:content-['·']"></span> 13 - author 14 - {{ end }} 15 - 16 - 7 + <!-- show user "hats" --> 8 + {{ $isIssueAuthor := eq .OwnerDid $.Issue.OwnerDid }} 9 + {{ if $isIssueAuthor }} 17 10 <span class="before:content-['·']"></span> 18 - <a 11 + author 12 + {{ end }} 13 + 14 + <span class="before:content-['·']"></span> 15 + <a 19 16 href="#{{ .CommentId }}" 20 17 class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-400 hover:underline no-underline" 21 18 id="{{ .CommentId }}"> 22 - {{ if .Deleted }} 23 - deleted 24 - {{ template "repo/fragments/time" .Deleted }} 25 - {{ else if .Edited }} 26 - edited 27 - {{ template "repo/fragments/time" .Edited }} 28 - {{ else }} 29 - {{ template "repo/fragments/time" .Created }} 30 - {{ end }} 31 - </a> 32 - 33 - {{ $isCommentOwner := and $.LoggedInUser (eq $.LoggedInUser.Did .OwnerDid) }} 34 - {{ if and $isCommentOwner (not .Deleted) }} 35 - <button 36 - class="btn px-2 py-1 text-sm" 37 - hx-get="/{{ $.RepoInfo.FullName }}/issues/{{ .Issue }}/comment/{{ .CommentId }}/edit" 38 - hx-swap="outerHTML" 39 - hx-target="#comment-container-{{ .CommentId }}"> 40 - {{ i "pencil" "w-4 h-4" }} 41 - </button> 42 - <button 43 - class="btn px-2 py-1 text-sm text-red-500 flex gap-2 items-center group" 44 - hx-delete="/{{ $.RepoInfo.FullName }}/issues/{{ .Issue }}/comment/{{ .CommentId }}/" 45 - hx-confirm="Are you sure you want to delete your comment?" 46 - hx-swap="outerHTML" 47 - hx-target="#comment-container-{{ .CommentId }}"> 48 - {{ i "trash-2" "w-4 h-4" }} 49 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 50 - </button> 19 + {{ if .Deleted }} 20 + deleted {{ template "repo/fragments/time" .Deleted }} 21 + {{ else if .Edited }} 22 + edited {{ template "repo/fragments/time" .Edited }} 23 + {{ else }} 24 + {{ template "repo/fragments/time" .Created }} 51 25 {{ end }} 26 + </a> 52 27 53 - </div> 54 - {{ if not .Deleted }} 55 - <div class="prose dark:prose-invert"> 56 - {{ .Body | markdown }} 57 - </div> 28 + {{ $isCommentOwner := and $.LoggedInUser (eq $.LoggedInUser.Did .OwnerDid) }} 29 + {{ if and $isCommentOwner (not .Deleted) }} 30 + <button 31 + class="btn px-2 py-1 text-sm" 32 + hx-get="/{{ $.RepoInfo.FullName }}/issues/{{ .Issue }}/comment/{{ .CommentId }}/edit" 33 + hx-swap="outerHTML" 34 + hx-target="#comment-container-{{.CommentId}}" 35 + > 36 + {{ i "pencil" "w-4 h-4" }} 37 + </button> 38 + <button 39 + class="btn px-2 py-1 text-sm text-red-500 flex gap-2 items-center group" 40 + hx-delete="/{{ $.RepoInfo.FullName }}/issues/{{ .Issue }}/comment/{{ .CommentId }}/" 41 + hx-confirm="Are you sure you want to delete your comment?" 42 + hx-swap="outerHTML" 43 + hx-target="#comment-container-{{.CommentId}}" 44 + > 45 + {{ i "trash-2" "w-4 h-4" }} 46 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 47 + </button> 58 48 {{ end }} 49 + 59 50 </div> 51 + {{ if not .Deleted }} 52 + <div class="prose dark:prose-invert"> 53 + {{ .Body | markdown }} 54 + </div> 55 + {{ end }} 56 + </div> 60 57 {{ end }} 61 58 {{ end }}
+119 -123
appview/pages/templates/repo/issues/issue.html
··· 1 - {{ define "title" }} 2 - {{ .Issue.Title }} &middot; issue #{{ .Issue.IssueId }} &middot; 3 - {{ .RepoInfo.FullName }} 4 - {{ end }} 1 + {{ define "title" }}{{ .Issue.Title }} &middot; issue #{{ .Issue.IssueId }} &middot; {{ .RepoInfo.FullName }}{{ end }} 2 + 5 3 6 4 {{ define "extrameta" }} 7 - {{ $title := printf "%s &middot; issue #%d &middot; %s" .Issue.Title .Issue.IssueId .RepoInfo.FullName }} 8 - {{ $url := printf "https://tangled.sh/%s/issues/%d" .RepoInfo.FullName .Issue.IssueId }} 5 + {{ $title := printf "%s &middot; issue #%d &middot; %s" .Issue.Title .Issue.IssueId .RepoInfo.FullName }} 6 + {{ $url := printf "https://tangled.sh/%s/issues/%d" .RepoInfo.FullName .Issue.IssueId }} 9 7 10 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 8 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 11 9 {{ end }} 12 10 13 11 {{ define "repoContent" }} 14 - <header class="pb-4"> 15 - <h1 class="text-2xl"> 12 + <header class="pb-4"> 13 + <h1 class="text-2xl"> 16 14 {{ .Issue.Title }} 17 - <span class="text-gray-500 dark:text-gray-400"> 18 - #{{ .Issue.IssueId }} 19 - </span> 20 - </h1> 21 - </header> 15 + <span class="text-gray-500 dark:text-gray-400">#{{ .Issue.IssueId }}</span> 16 + </h1> 17 + </header> 22 18 23 - {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 24 - {{ $icon := "ban" }} 25 - {{ if eq .State "open" }} 26 - {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 27 - {{ $icon = "circle-dot" }} 28 - {{ end }} 29 - 30 - 31 - <section class="mt-2"> 32 - <div class="inline-flex items-center gap-2"> 33 - <div 34 - id="state" 35 - class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}"> 36 - {{ i $icon "w-4 h-4 mr-1.5 text-white" }} 37 - <span class="text-white">{{ .State }}</span> 38 - </div> 39 - <span 40 - class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1"> 41 - opened by 42 - {{ $owner := didOrHandle .Issue.OwnerDid .IssueOwnerHandle }} 43 - {{ template "user/fragments/picHandleLink" $owner }} 44 - <span class="select-none before:content-['\00B7']"></span> 45 - {{ template "repo/fragments/time" .Issue.Created }} 46 - </span> 47 - </div> 48 - 49 - {{ if .Issue.Body }} 50 - <article id="body" class="mt-8 prose dark:prose-invert"> 51 - {{ .Issue.Body | markdown }} 52 - </article> 19 + {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 20 + {{ $icon := "ban" }} 21 + {{ if eq .State "open" }} 22 + {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 23 + {{ $icon = "circle-dot" }} 53 24 {{ end }} 54 25 26 + <section class="mt-2"> 27 + <div class="inline-flex items-center gap-2"> 28 + <div id="state" 29 + class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}"> 30 + {{ i $icon "w-4 h-4 mr-1.5 text-white" }} 31 + <span class="text-white">{{ .State }}</span> 32 + </div> 33 + <span class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1"> 34 + opened by 35 + {{ $owner := didOrHandle .Issue.OwnerDid .IssueOwnerHandle }} 36 + {{ template "user/fragments/picHandleLink" $owner }} 37 + <span class="select-none before:content-['\00B7']"></span> 38 + {{ template "repo/fragments/time" .Issue.Created }} 39 + </span> 40 + </div> 55 41 56 - <div class="flex items-center gap-2 mt-2"> 57 - {{ template "repo/fragments/reactionsPopUp" .OrderedReactionKinds }} 58 - {{ range $kind := .OrderedReactionKinds }} 59 - {{ template "repo/fragments/reaction" 60 - (dict 61 - "Kind" $kind 62 - "Count" (index $.Reactions $kind) 63 - "IsReacted" (index $.UserReacted $kind) 64 - "ThreadAt" $.Issue.IssueAt) 65 - }} 66 - {{ end }} 67 - </div> 68 - </section> 42 + {{ if .Issue.Body }} 43 + <article id="body" class="mt-8 prose dark:prose-invert"> 44 + {{ .Issue.Body | markdown }} 45 + </article> 46 + {{ end }} 47 + 48 + <div class="flex items-center gap-2 mt-2"> 49 + {{ template "repo/fragments/reactionsPopUp" .OrderedReactionKinds }} 50 + {{ range $kind := .OrderedReactionKinds }} 51 + {{ 52 + template "repo/fragments/reaction" 53 + (dict 54 + "Kind" $kind 55 + "Count" (index $.Reactions $kind) 56 + "IsReacted" (index $.UserReacted $kind) 57 + "ThreadAt" $.Issue.IssueAt) 58 + }} 59 + {{ end }} 60 + </div> 61 + </section> 69 62 {{ end }} 70 63 71 64 {{ define "repoAfter" }} 72 - <section id="comments" class="my-2 mt-2 space-y-2 relative"> 73 - {{ range $index, $comment := .Comments }} 74 - <div 75 - id="comment-{{ .CommentId }}" 76 - class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full md:max-w-3/5 md:w-fit"> 77 - {{ if gt $index 0 }} 78 - <div 79 - class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div> 65 + <section id="comments" class="my-2 mt-2 space-y-2 relative"> 66 + {{ range $index, $comment := .Comments }} 67 + <div 68 + id="comment-{{ .CommentId }}" 69 + class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full md:max-w-3/5 md:w-fit"> 70 + {{ if gt $index 0 }} 71 + <div class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div> 72 + {{ end }} 73 + {{ template "repo/issues/fragments/issueComment" (dict "RepoInfo" $.RepoInfo "LoggedInUser" $.LoggedInUser "Issue" $.Issue "Comment" .)}} 74 + </div> 80 75 {{ end }} 81 - {{ template "repo/issues/fragments/issueComment" (dict "RepoInfo" $.RepoInfo "LoggedInUser" $.LoggedInUser "Issue" $.Issue "Comment" .) }} 82 - </div> 83 - {{ end }} 84 - </section> 76 + </section> 85 77 86 - {{ block "newComment" . }}{{ end }} 78 + {{ block "newComment" . }} {{ end }} 87 79 88 80 {{ end }} 89 81 90 82 {{ define "newComment" }} 91 83 {{ if .LoggedInUser }} 92 - <form 84 + <form 93 85 id="comment-form" 94 86 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment" 95 - hx-on::after-request="if(event.detail.successful) this.reset()"> 96 - <div 97 - class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-full md:w-3/5"> 98 - <div class="text-sm pb-2 text-gray-500 dark:text-gray-400"> 99 - {{ template "user/fragments/picHandleLink" (didOrHandle .LoggedInUser.Did .LoggedInUser.Handle) }} 100 - </div> 101 - <textarea 102 - id="comment-textarea" 103 - name="body" 104 - class="w-full p-2 rounded border border-gray-200 dark:border-gray-700" 105 - placeholder="Add to the discussion. Markdown is supported." 106 - onkeyup="updateCommentForm()"></textarea> 107 - <div id="issue-comment"></div> 108 - <div id="issue-action" class="error"></div> 87 + hx-on::after-request="if(event.detail.successful) this.reset()" 88 + > 89 + <div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-full md:w-3/5"> 90 + <div class="text-sm pb-2 text-gray-500 dark:text-gray-400"> 91 + {{ template "user/fragments/picHandleLink" (didOrHandle .LoggedInUser.Did .LoggedInUser.Handle) }} 109 92 </div> 93 + <textarea 94 + id="comment-textarea" 95 + name="body" 96 + class="w-full p-2 rounded border border-gray-200 dark:border-gray-700" 97 + placeholder="Add to the discussion. Markdown is supported." 98 + onkeyup="updateCommentForm()" 99 + ></textarea> 100 + <div id="issue-comment"></div> 101 + <div id="issue-action" class="error"></div> 102 + </div> 110 103 111 - <div class="flex gap-2 mt-2"> 104 + <div class="flex gap-2 mt-2"> 112 105 <button 113 - id="comment-button" 114 - hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment" 115 - type="submit" 116 - hx-disabled-elt="#comment-button" 117 - class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group" 118 - disabled> 119 - {{ i "message-square-plus" "w-4 h-4" }} 120 - comment 121 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 106 + id="comment-button" 107 + hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment" 108 + type="submit" 109 + hx-disabled-elt="#comment-button" 110 + class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group" 111 + disabled 112 + > 113 + {{ i "message-square-plus" "w-4 h-4" }} 114 + comment 115 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 122 116 </button> 123 117 124 118 {{ $isIssueAuthor := and .LoggedInUser (eq .LoggedInUser.Did .Issue.OwnerDid) }} 125 119 {{ $isRepoCollaborator := .RepoInfo.Roles.IsCollaborator }} 126 120 {{ $isRepoOwner := .RepoInfo.Roles.IsOwner }} 127 121 {{ if and (or $isIssueAuthor $isRepoCollaborator $isRepoOwner) (eq .State "open") }} 128 - <button 122 + <button 129 123 id="close-button" 130 124 type="button" 131 125 class="btn flex items-center gap-2" 132 126 hx-indicator="#close-spinner" 133 - hx-trigger="click"> 127 + hx-trigger="click" 128 + > 134 129 {{ i "ban" "w-4 h-4" }} 135 130 close 136 131 <span id="close-spinner" class="group"> 137 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 132 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 138 133 </span> 139 - </button> 140 - <div 134 + </button> 135 + <div 141 136 id="close-with-comment" 142 137 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment" 143 138 hx-trigger="click from:#close-button" ··· 140 145 hx-target="#issue-comment" 141 146 hx-indicator="#close-spinner" 142 147 hx-vals="js:{body: document.getElementById('comment-textarea').value.trim() !== '' ? document.getElementById('comment-textarea').value : ''}" 143 - hx-swap="none"></div> 144 - <div 148 + hx-swap="none" 149 + > 150 + </div> 151 + <div 145 152 id="close-issue" 146 153 hx-disabled-elt="#close-issue" 147 154 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/close" 148 155 hx-trigger="click from:#close-button" 149 156 hx-target="#issue-action" 150 157 hx-indicator="#close-spinner" 151 - hx-swap="none"></div> 152 - <script> 153 - document.addEventListener("htmx:configRequest", function (evt) { 154 - if (evt.target.id === "close-with-comment") { 155 - const commentText = document 156 - .getElementById("comment-textarea") 157 - .value.trim(); 158 - if (commentText === "") { 159 - evt.detail.parameters = {}; 160 - evt.preventDefault(); 158 + hx-swap="none" 159 + > 160 + </div> 161 + <script> 162 + document.addEventListener('htmx:configRequest', function(evt) { 163 + if (evt.target.id === 'close-with-comment') { 164 + const commentText = document.getElementById('comment-textarea').value.trim(); 165 + if (commentText === '') { 166 + evt.detail.parameters = {}; 167 + evt.preventDefault(); 168 + } 161 169 } 162 - } 163 170 }); 164 - </script> 171 + </script> 165 172 {{ else if and (or $isIssueAuthor $isRepoCollaborator $isRepoOwner) (eq .State "closed") }} 166 - <button 173 + <button 167 174 type="button" 168 175 class="btn flex items-center gap-2" 169 176 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/reopen" 170 177 hx-indicator="#reopen-spinner" 171 - hx-swap="none"> 178 + hx-swap="none" 179 + > 172 180 {{ i "refresh-ccw-dot" "w-4 h-4" }} 173 181 reopen 174 182 <span id="reopen-spinner" class="group"> 175 183 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 176 184 </span> 177 - </button> 185 + </button> 178 186 {{ end }} 179 187 180 188 <script> ··· 215 217 updateCommentForm(); 216 218 }); 217 219 </script> 218 - </div> 219 - </form> 220 + </div> 221 + </form> 220 222 {{ else }} 221 - <div 222 - class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-fit"> 223 - <a href="/login" class="underline">login</a> 224 - to join the discussion 223 + <div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-fit"> 224 + <a href="/login" class="underline">login</a> to join the discussion 225 225 </div> 226 226 {{ end }} 227 227 {{ end }}
+84 -95
appview/pages/templates/repo/issues/issues.html
··· 1 1 {{ define "title" }}issues &middot; {{ .RepoInfo.FullName }}{{ end }} 2 2 3 3 {{ define "extrameta" }} 4 - {{ $title := "issues" }} 5 - {{ $url := printf "https://tangled.sh/%s/issues" .RepoInfo.FullName }} 4 + {{ $title := "issues"}} 5 + {{ $url := printf "https://tangled.sh/%s/issues" .RepoInfo.FullName }} 6 6 7 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 7 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 8 8 {{ end }} 9 9 10 10 {{ define "repoContent" }} 11 - <div class="flex justify-between items-center gap-4"> 12 - <div class="flex gap-4"> 13 - <a 11 + <div class="flex justify-between items-center gap-4"> 12 + <div class="flex gap-4"> 13 + <a 14 14 href="?state=open" 15 - class="flex items-center gap-2 {{ if .FilteringByOpen }} 16 - font-bold 17 - {{ else }} 18 - text-gray-500 dark:text-gray-400 19 - {{ end }}"> 15 + class="flex items-center gap-2 {{ if .FilteringByOpen }}font-bold {{ else }}text-gray-500 dark:text-gray-400{{ end }}" 16 + > 20 17 {{ i "circle-dot" "w-4 h-4" }} 21 18 <span>{{ .RepoInfo.Stats.IssueCount.Open }} open</span> 22 - </a> 23 - <a 19 + </a> 20 + <a 24 21 href="?state=closed" 25 - class="flex items-center gap-2 {{ if not .FilteringByOpen }} 26 - font-bold 27 - {{ else }} 28 - text-gray-500 dark:text-gray-400 29 - {{ end }}"> 22 + class="flex items-center gap-2 {{ if not .FilteringByOpen }}font-bold {{ else }}text-gray-500 dark:text-gray-400{{ end }}" 23 + > 30 24 {{ i "ban" "w-4 h-4" }} 31 25 <span>{{ .RepoInfo.Stats.IssueCount.Closed }} closed</span> 32 - </a> 33 - </div> 34 - <a 35 - href="/{{ .RepoInfo.FullName }}/issues/new" 36 - class="btn-create text-sm flex items-center justify-center gap-2 no-underline hover:no-underline hover:text-white"> 37 - {{ i "circle-plus" "w-4 h-4" }} 38 - <span>new</span> 39 26 </a> 40 27 </div> 41 - <div class="error" id="issues"></div> 28 + <a 29 + href="/{{ .RepoInfo.FullName }}/issues/new" 30 + class="btn-create text-sm flex items-center justify-center gap-2 no-underline hover:no-underline hover:text-white" 31 + > 32 + {{ i "circle-plus" "w-4 h-4" }} 33 + <span>new</span> 34 + </a> 35 + </div> 36 + <div class="error" id="issues"></div> 42 37 {{ end }} 43 38 44 39 {{ define "repoAfter" }} 45 - <div class="flex flex-col gap-2 mt-2"> 46 - {{ range .Issues }} 47 - <div 48 - class="rounded drop-shadow-sm bg-white px-6 py-4 dark:bg-gray-800 dark:border-gray-700"> 49 - <div class="pb-2"> 50 - <a 51 - href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" 52 - class="no-underline hover:underline"> 53 - {{ .Title }} 54 - <span class="text-gray-500">#{{ .IssueId }}</span> 55 - </a> 56 - </div> 57 - <p 58 - class="text-sm text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-1"> 59 - {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 60 - {{ $icon := "ban" }} 61 - {{ $state := "closed" }} 62 - {{ if .Open }} 63 - {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 64 - {{ $icon = "circle-dot" }} 65 - {{ $state = "open" }} 66 - {{ end }} 40 + <div class="flex flex-col gap-2 mt-2"> 41 + {{ range .Issues }} 42 + <div class="rounded drop-shadow-sm bg-white px-6 py-4 dark:bg-gray-800 dark:border-gray-700"> 43 + <div class="pb-2"> 44 + <a 45 + href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" 46 + class="no-underline hover:underline" 47 + > 48 + {{ .Title }} 49 + <span class="text-gray-500">#{{ .IssueId }}</span> 50 + </a> 51 + </div> 52 + <p class="text-sm text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-1"> 53 + {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 54 + {{ $icon := "ban" }} 55 + {{ $state := "closed" }} 56 + {{ if .Open }} 57 + {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 58 + {{ $icon = "circle-dot" }} 59 + {{ $state = "open" }} 60 + {{ end }} 67 61 62 + <span class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm"> 63 + {{ i $icon "w-3 h-3 mr-1.5 text-white dark:text-white" }} 64 + <span class="text-white dark:text-white">{{ $state }}</span> 65 + </span> 68 66 69 - <span 70 - class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm"> 71 - {{ i $icon "w-3 h-3 mr-1.5 text-white dark:text-white" }} 72 - <span class="text-white dark:text-white">{{ $state }}</span> 73 - </span> 67 + <span class="ml-1"> 68 + {{ template "user/fragments/picHandleLink" .OwnerDid }} 69 + </span> 74 70 75 - <span class="ml-1"> 76 - {{ template "user/fragments/picHandleLink" .OwnerDid }} 77 - </span> 71 + <span class="before:content-['·']"> 72 + {{ template "repo/fragments/time" .Created }} 73 + </span> 78 74 79 - <span class="before:content-['·']"> 80 - {{ template "repo/fragments/time" .Created }} 81 - </span> 82 - 83 - <span class="before:content-['·']"> 84 - {{ $s := "s" }} 85 - {{ if eq .Metadata.CommentCount 1 }} 86 - {{ $s = "" }} 87 - {{ end }} 88 - <a 89 - href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" 90 - class="text-gray-500 dark:text-gray-400"> 91 - {{ .Metadata.CommentCount }} 92 - comment{{ $s }} 93 - </a> 94 - </span> 95 - </p> 96 - </div> 97 - {{ end }} 75 + <span class="before:content-['·']"> 76 + {{ $s := "s" }} 77 + {{ if eq .Metadata.CommentCount 1 }} 78 + {{ $s = "" }} 79 + {{ end }} 80 + <a href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" class="text-gray-500 dark:text-gray-400">{{ .Metadata.CommentCount }} comment{{$s}}</a> 81 + </span> 82 + </p> 98 83 </div> 84 + {{ end }} 85 + </div> 99 86 100 - {{ block "pagination" . }}{{ end }} 87 + {{ block "pagination" . }} {{ end }} 101 88 102 89 {{ end }} 103 90 104 91 {{ define "pagination" }} 105 - <div class="flex justify-end mt-4 gap-2"> 92 + <div class="flex justify-end mt-4 gap-2"> 106 93 {{ $currentState := "closed" }} 107 94 {{ if .FilteringByOpen }} 108 95 {{ $currentState = "open" }} 109 96 {{ end }} 110 97 111 98 {{ if gt .Page.Offset 0 }} 112 - {{ $prev := .Page.Previous }} 113 - <a 114 - class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700" 115 - hx-boost="true" 116 - href="/{{ $.RepoInfo.FullName }}/issues?state={{ $currentState }}&offset={{ $prev.Offset }}&limit={{ $prev.Limit }}"> 117 - {{ i "chevron-left" "w-4 h-4" }} 118 - previous 119 - </a> 99 + {{ $prev := .Page.Previous }} 100 + <a 101 + class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700" 102 + hx-boost="true" 103 + href = "/{{ $.RepoInfo.FullName }}/issues?state={{ $currentState }}&offset={{ $prev.Offset }}&limit={{ $prev.Limit }}" 104 + > 105 + {{ i "chevron-left" "w-4 h-4" }} 106 + previous 107 + </a> 120 108 {{ else }} 121 - <div></div> 109 + <div></div> 122 110 {{ end }} 123 111 124 112 {{ if eq (len .Issues) .Page.Limit }} 125 - {{ $next := .Page.Next }} 126 - <a 127 - class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700" 128 - hx-boost="true" 129 - href="/{{ $.RepoInfo.FullName }}/issues?state={{ $currentState }}&offset={{ $next.Offset }}&limit={{ $next.Limit }}"> 130 - next 131 - {{ i "chevron-right" "w-4 h-4" }} 132 - </a> 113 + {{ $next := .Page.Next }} 114 + <a 115 + class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700" 116 + hx-boost="true" 117 + href = "/{{ $.RepoInfo.FullName }}/issues?state={{ $currentState }}&offset={{ $next.Offset }}&limit={{ $next.Limit }}" 118 + > 119 + next 120 + {{ i "chevron-right" "w-4 h-4" }} 121 + </a> 133 122 {{ end }} 134 - </div> 123 + </div> 135 124 {{ end }}
+33 -31
appview/pages/templates/repo/issues/new.html
··· 1 1 {{ define "title" }}new issue &middot; {{ .RepoInfo.FullName }}{{ end }} 2 2 3 3 {{ define "repoContent" }} 4 - <form 5 - hx-post="/{{ .RepoInfo.FullName }}/issues/new" 6 - class="mt-6 space-y-6" 7 - hx-swap="none" 8 - hx-indicator="#spinner"> 9 - <div class="flex flex-col gap-4"> 10 - <div> 11 - <label for="title">title</label> 12 - <input type="text" name="title" id="title" class="w-full" /> 13 - </div> 14 - <div> 15 - <label for="body">body</label> 16 - <textarea 17 - name="body" 18 - id="body" 19 - rows="6" 20 - class="w-full resize-y" 21 - placeholder="Describe your issue. Markdown is supported."></textarea> 22 - </div> 23 - <div> 24 - <button type="submit" class="btn-create flex items-center gap-2"> 25 - {{ i "circle-plus" "w-4 h-4" }} 26 - create issue 27 - <span id="create-pull-spinner" class="group"> 28 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 29 - </span> 30 - </button> 31 - </div> 32 - </div> 33 - <div id="issues" class="error"></div> 34 - </form> 4 + <form 5 + hx-post="/{{ .RepoInfo.FullName }}/issues/new" 6 + class="mt-6 space-y-6" 7 + hx-swap="none" 8 + hx-indicator="#spinner" 9 + > 10 + <div class="flex flex-col gap-4"> 11 + <div> 12 + <label for="title">title</label> 13 + <input type="text" name="title" id="title" class="w-full" /> 14 + </div> 15 + <div> 16 + <label for="body">body</label> 17 + <textarea 18 + name="body" 19 + id="body" 20 + rows="6" 21 + class="w-full resize-y" 22 + placeholder="Describe your issue. Markdown is supported." 23 + ></textarea> 24 + </div> 25 + <div> 26 + <button type="submit" class="btn-create flex items-center gap-2"> 27 + {{ i "circle-plus" "w-4 h-4" }} 28 + create issue 29 + <span id="create-pull-spinner" class="group"> 30 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 31 + </span> 32 + </button> 33 + </div> 34 + </div> 35 + <div id="issues" class="error"></div> 36 + </form> 35 37 {{ end }}
+137 -210
appview/pages/templates/repo/log.html
··· 1 1 {{ define "title" }}commits &middot; {{ .RepoInfo.FullName }}{{ end }} 2 2 3 3 {{ define "extrameta" }} 4 - {{ $title := printf "commits &middot; %s" .RepoInfo.FullName }} 5 - {{ $url := printf "https://tangled.sh/%s/commits" .RepoInfo.FullName }} 4 + {{ $title := printf "commits &middot; %s" .RepoInfo.FullName }} 5 + {{ $url := printf "https://tangled.sh/%s/commits" .RepoInfo.FullName }} 6 6 7 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 7 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 8 8 {{ end }} 9 9 10 10 {{ define "repoContent" }} 11 - <section id="commit-table" class="overflow-x-auto"> 12 - <h2 class="font-bold text-sm mb-4 uppercase dark:text-white">commits</h2> 11 + <section id="commit-table" class="overflow-x-auto"> 12 + <h2 class="font-bold text-sm mb-4 uppercase dark:text-white"> 13 + commits 14 + </h2> 13 15 14 16 <!-- desktop view (hidden on small screens) --> 15 - <div 16 - class="hidden md:flex md:flex-col divide-y divide-gray-200 dark:divide-gray-700"> 17 + <div class="hidden md:flex md:flex-col divide-y divide-gray-200 dark:divide-gray-700"> 17 18 {{ $grid := "grid grid-cols-14 gap-4" }} 18 19 <div class="{{ $grid }}"> 19 - <div 20 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-2"> 21 - Author 22 - </div> 23 - <div 24 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-3"> 25 - Commit 26 - </div> 27 - <div 28 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-6"> 29 - Message 30 - </div> 31 - <div 32 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-1"></div> 33 - <div 34 - class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-2 justify-self-end"> 35 - Date 36 - </div> 20 + <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-2">Author</div> 21 + <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-3">Commit</div> 22 + <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-6">Message</div> 23 + <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-1"></div> 24 + <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-2 justify-self-end">Date</div> 37 25 </div> 38 26 {{ range $index, $commit := .Commits }} 39 27 {{ $messageParts := splitN $commit.Message "\n\n" 2 }} 40 28 <div class="{{ $grid }} py-3"> 41 29 <div class="align-top truncate col-span-2"> 42 - {{ $didOrHandle := index $.EmailToDidOrHandle $commit.Author.Email }} 43 - {{ if $didOrHandle }} 44 - {{ template "user/fragments/picHandleLink" $didOrHandle }} 45 - {{ else }} 46 - <a 47 - href="mailto:{{ $commit.Author.Email }}" 48 - class="text-gray-700 dark:text-gray-300 no-underline hover:underline"> 49 - {{ $commit.Author.Name }} 50 - </a> 51 - {{ end }} 30 + {{ $didOrHandle := index $.EmailToDidOrHandle $commit.Author.Email }} 31 + {{ if $didOrHandle }} 32 + {{ template "user/fragments/picHandleLink" $didOrHandle }} 33 + {{ else }} 34 + <a href="mailto:{{ $commit.Author.Email }}" class="text-gray-700 dark:text-gray-300 no-underline hover:underline">{{ $commit.Author.Name }}</a> 35 + {{ end }} 52 36 </div> 53 37 <div class="align-top font-mono flex items-start col-span-3"> 54 - {{ $verified := $.VerifiedCommits.IsVerified $commit.Hash.String }} 55 - {{ $hashStyle := "text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-900" }} 56 - {{ if $verified }} 57 - {{ $hashStyle = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 rounded" }} 58 - {{ end }} 59 - <a 60 - href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" 61 - class="no-underline hover:underline {{ $hashStyle }} px-2 py-1/2 rounded flex items-center gap-2"> 62 - {{ slice $commit.Hash.String 0 8 }} 38 + {{ $verified := $.VerifiedCommits.IsVerified $commit.Hash.String }} 39 + {{ $hashStyle := "text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-900" }} 63 40 {{ if $verified }} 64 - {{ i "shield-check" "w-4 h-4" }} 41 + {{ $hashStyle = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 rounded" }} 65 42 {{ end }} 66 - </a> 67 - <div class="{{ if not $verified }}ml-6{{ end }}inline-flex"> 68 - <button 69 - class="p-1 mx-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" 70 - title="Copy SHA" 71 - onclick="navigator.clipboard.writeText('{{ $commit.Hash.String }}'); this.innerHTML=`{{ i "copy-check" "w-4 h-4" }}`; setTimeout(() => this.innerHTML=`{{ i "copy" "w-4 h-4" }}`, 1500)"> 72 - {{ i "copy" "w-4 h-4" }} 73 - </button> 74 - <a 75 - href="/{{ $.RepoInfo.FullName }}/tree/{{ $commit.Hash.String }}" 76 - class="p-1 mx-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" 77 - title="Browse repository at this commit"> 78 - {{ i "folder-code" "w-4 h-4" }} 43 + <a href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" class="no-underline hover:underline {{ $hashStyle }} px-2 py-1/2 rounded flex items-center gap-2"> 44 + {{ slice $commit.Hash.String 0 8 }} 45 + {{ if $verified }} 46 + {{ i "shield-check" "w-4 h-4" }} 47 + {{ end }} 79 48 </a> 80 - </div> 49 + <div class="{{ if not $verified }} ml-6 {{ end }}inline-flex"> 50 + <button class="p-1 mx-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" 51 + title="Copy SHA" 52 + onclick="navigator.clipboard.writeText('{{ $commit.Hash.String }}'); this.innerHTML=`{{ i "copy-check" "w-4 h-4" }}`; setTimeout(() => this.innerHTML=`{{ i "copy" "w-4 h-4" }}`, 1500)"> 53 + {{ i "copy" "w-4 h-4" }} 54 + </button> 55 + <a href="/{{ $.RepoInfo.FullName }}/tree/{{ $commit.Hash.String }}" class="p-1 mx-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" title="Browse repository at this commit"> 56 + {{ i "folder-code" "w-4 h-4" }} 57 + </a> 58 + </div> 59 + 81 60 </div> 82 61 <div class="align-top col-span-6"> 83 62 <div> 84 - <a 85 - href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" 86 - class="dark:text-white no-underline hover:underline"> 87 - {{ index $messageParts 0 }} 88 - </a> 89 - {{ if gt (len $messageParts) 1 }} 90 - <button 91 - class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 dark:bg-gray-700 dark:hover:bg-gray-600 rounded" 92 - hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"> 93 - {{ i "ellipsis" "w-3 h-3" }} 94 - </button> 95 - {{ end }} 96 - 97 - {{ if index $.TagMap $commit.Hash.String }} 98 - {{ range $tag := index $.TagMap $commit.Hash.String }} 99 - <span 100 - class="ml-2 text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 inline-flex items-center"> 101 - {{ $tag }} 102 - </span> 63 + <a href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" class="dark:text-white no-underline hover:underline">{{ index $messageParts 0 }}</a> 64 + {{ if gt (len $messageParts) 1 }} 65 + <button class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 dark:bg-gray-700 dark:hover:bg-gray-600 rounded" hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')">{{ i "ellipsis" "w-3 h-3" }}</button> 103 66 {{ end }} 104 - {{ end }} 67 + 68 + {{ if index $.TagMap $commit.Hash.String }} 69 + {{ range $tag := index $.TagMap $commit.Hash.String }} 70 + <span class="ml-2 text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 inline-flex items-center"> 71 + {{ $tag }} 72 + </span> 73 + {{ end }} 74 + {{ end }} 105 75 </div> 106 76 107 77 {{ if gt (len $messageParts) 1 }} 108 - <p class="hidden mt-1 text-sm text-gray-600 dark:text-gray-400"> 109 - {{ nl2br (index $messageParts 1) }} 110 - </p> 78 + <p class="hidden mt-1 text-sm text-gray-600 dark:text-gray-400">{{ nl2br (index $messageParts 1) }}</p> 111 79 {{ end }} 112 80 </div> 113 81 <div class="align-top col-span-1"> 114 - <!-- ci status --> 115 - {{ $pipeline := index $.Pipelines .Hash.String }} 116 - {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }} 117 - {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" $pipeline "RepoInfo" $.RepoInfo) }} 118 - {{ end }} 82 + <!-- ci status --> 83 + {{ $pipeline := index $.Pipelines .Hash.String }} 84 + {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }} 85 + {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" $pipeline "RepoInfo" $.RepoInfo) }} 86 + {{ end }} 119 87 </div> 120 - <div 121 - class="align-top justify-self-end text-gray-500 dark:text-gray-400 col-span-2"> 122 - {{ template "repo/fragments/shortTimeAgo" $commit.Committer.When }} 123 - </div> 88 + <div class="align-top justify-self-end text-gray-500 dark:text-gray-400 col-span-2">{{ template "repo/fragments/shortTimeAgo" $commit.Committer.When }}</div> 124 89 </div> 125 90 {{ end }} 126 91 </div> 127 92 128 93 <!-- mobile view (visible only on small screens) --> 129 94 <div class="md:hidden"> 130 - {{ range $index, $commit := .Commits }} 131 - <div 132 - class="relative p-2 mb-2 {{ if ne $index (sub (len $.Commits) 1) }} 133 - border-b border-gray-200 dark:border-gray-700 134 - {{ end }}"> 135 - <div id="commit-message"> 136 - {{ $messageParts := splitN $commit.Message "\n\n" 2 }} 137 - <div class="text-base cursor-pointer"> 138 - <div class="flex items-center justify-between"> 139 - <div class="flex-1"> 140 - <div> 141 - <a 142 - href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" 143 - class="inline no-underline hover:underline dark:text-white"> 144 - {{ index $messageParts 0 }} 145 - </a> 146 - {{ if gt (len $messageParts) 1 }} 147 - <button 148 - class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600" 149 - hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"> 150 - {{ i "ellipsis" "w-3 h-3" }} 151 - </button> 152 - {{ end }} 95 + {{ range $index, $commit := .Commits }} 96 + <div class="relative p-2 mb-2 {{ if ne $index (sub (len $.Commits) 1) }}border-b border-gray-200 dark:border-gray-700{{ end }}"> 97 + <div id="commit-message"> 98 + {{ $messageParts := splitN $commit.Message "\n\n" 2 }} 99 + <div class="text-base cursor-pointer"> 100 + <div class="flex items-center justify-between"> 101 + <div class="flex-1"> 102 + <div> 103 + <a href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" 104 + class="inline no-underline hover:underline dark:text-white"> 105 + {{ index $messageParts 0 }} 106 + </a> 107 + {{ if gt (len $messageParts) 1 }} 108 + <button 109 + class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600" 110 + hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"> 111 + {{ i "ellipsis" "w-3 h-3" }} 112 + </button> 113 + {{ end }} 153 114 154 - {{ if index $.TagMap $commit.Hash.String }} 155 - {{ range $tag := index $.TagMap $commit.Hash.String }} 156 - <span 157 - class="ml-2 text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 inline-flex items-center"> 158 - {{ $tag }} 159 - </span> 160 - {{ end }} 161 - {{ end }} 162 - </div> 115 + {{ if index $.TagMap $commit.Hash.String }} 116 + {{ range $tag := index $.TagMap $commit.Hash.String }} 117 + <span class="ml-2 text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 inline-flex items-center"> 118 + {{ $tag }} 119 + </span> 120 + {{ end }} 121 + {{ end }} 122 + </div> 163 123 164 - {{ if gt (len $messageParts) 1 }} 165 - <p 166 - class="hidden mt-1 text-sm cursor-text pb-2 dark:text-gray-300"> 167 - {{ nl2br (index $messageParts 1) }} 168 - </p> 169 - {{ end }} 124 + {{ if gt (len $messageParts) 1 }} 125 + <p class="hidden mt-1 text-sm cursor-text pb-2 dark:text-gray-300"> 126 + {{ nl2br (index $messageParts 1) }} 127 + </p> 128 + {{ end }} 129 + </div> 130 + <a href="/{{ $.RepoInfo.FullName }}/tree/{{ $commit.Hash.String }}" 131 + class="p-1 mr-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" 132 + title="Browse repository at this commit"> 133 + {{ i "folder-code" "w-4 h-4" }} 134 + </a> 135 + </div> 136 + </div> 170 137 </div> 171 - <a 172 - href="/{{ $.RepoInfo.FullName }}/tree/{{ $commit.Hash.String }}" 173 - class="p-1 mr-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" 174 - title="Browse repository at this commit"> 175 - {{ i "folder-code" "w-4 h-4" }} 176 - </a> 177 - </div> 138 + 139 + <div class="text-xs mt-2 text-gray-500 dark:text-gray-400 flex items-center"> 140 + {{ $verified := $.VerifiedCommits.IsVerified $commit.Hash.String }} 141 + {{ $hashStyle := "text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-900" }} 142 + {{ if $verified }} 143 + {{ $hashStyle = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 rounded" }} 144 + {{ end }} 145 + <span class="font-mono"> 146 + <a href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" 147 + class="no-underline hover:underline {{ $hashStyle }} px-2 py-1 rounded flex items-center gap-2"> 148 + {{ slice $commit.Hash.String 0 8 }} 149 + {{ if $verified }} 150 + {{ i "shield-check" "w-3 h-3" }} 151 + {{ end }} 152 + </a> 153 + </span> 154 + <span class="mx-2 before:content-['·'] before:select-none"></span> 155 + <span> 156 + {{ $didOrHandle := index $.EmailToDidOrHandle $commit.Author.Email }} 157 + <a href="{{ if $didOrHandle }}/{{ $didOrHandle }}{{ else }}mailto:{{ $commit.Author.Email }}{{ end }}" 158 + class="text-gray-500 dark:text-gray-400 no-underline hover:underline"> 159 + {{ if $didOrHandle }}{{ template "user/fragments/picHandleLink" $didOrHandle }}{{ else }}{{ $commit.Author.Name }}{{ end }} 160 + </a> 161 + </span> 162 + <div class="inline-block px-1 select-none after:content-['·']"></div> 163 + <span>{{ template "repo/fragments/shortTime" $commit.Committer.When }}</span> 164 + 165 + <!-- ci status --> 166 + {{ $pipeline := index $.Pipelines .Hash.String }} 167 + {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }} 168 + <div class="inline-block px-1 select-none after:content-['·']"></div> 169 + <span class="text-sm"> 170 + {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" $pipeline "RepoInfo" $.RepoInfo) }} 171 + </span> 172 + {{ end }} 173 + </div> 178 174 </div> 179 - </div> 180 - 181 - <div 182 - class="text-xs mt-2 text-gray-500 dark:text-gray-400 flex items-center"> 183 - {{ $verified := $.VerifiedCommits.IsVerified $commit.Hash.String }} 184 - {{ $hashStyle := "text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-900" }} 185 - {{ if $verified }} 186 - {{ $hashStyle = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 rounded" }} 187 - {{ end }} 188 - <span class="font-mono"> 189 - <a 190 - href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" 191 - class="no-underline hover:underline {{ $hashStyle }} px-2 py-1 rounded flex items-center gap-2"> 192 - {{ slice $commit.Hash.String 0 8 }} 193 - {{ if $verified }} 194 - {{ i "shield-check" "w-3 h-3" }} 195 - {{ end }} 196 - </a> 197 - </span> 198 - <span class="mx-2 before:content-['·'] before:select-none"></span> 199 - <span> 200 - {{ $didOrHandle := index $.EmailToDidOrHandle $commit.Author.Email }} 201 - <a 202 - href="{{ if $didOrHandle }} 203 - /{{ $didOrHandle }} 204 - {{ else }} 205 - mailto:{{ $commit.Author.Email }} 206 - {{ end }}" 207 - class="text-gray-500 dark:text-gray-400 no-underline hover:underline"> 208 - {{ if $didOrHandle }} 209 - {{ template "user/fragments/picHandleLink" $didOrHandle }} 210 - {{ else }} 211 - {{ $commit.Author.Name }} 212 - {{ end }} 213 - </a> 214 - </span> 215 - <div 216 - class="inline-block px-1 select-none after:content-['·']"></div> 217 - <span> 218 - {{ template "repo/fragments/shortTime" $commit.Committer.When }} 219 - </span> 220 - 221 - <!-- ci status --> 222 - {{ $pipeline := index $.Pipelines .Hash.String }} 223 - {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }} 224 - <div 225 - class="inline-block px-1 select-none after:content-['·']"></div> 226 - <span class="text-sm"> 227 - {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" $pipeline "RepoInfo" $.RepoInfo) }} 228 - </span> 229 - {{ end }} 230 - </div> 231 - </div> 232 - {{ end }} 175 + {{ end }} 233 176 </div> 234 - </section> 177 + </section> 178 + 235 179 {{ end }} 236 180 237 181 {{ define "repoAfter" }} 238 182 {{ $commits_len := len .Commits }} 239 183 <div class="flex justify-end mt-4 gap-2"> 240 - {{ if gt .Page 1 }} 241 - <a 242 - class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700" 243 - hx-boost="true" 244 - onclick="window.location.href = window.location.pathname + '?page={{ sub .Page 1 }}'"> 245 - {{ i "chevron-left" "w-4 h-4" }} previous 246 - </a> 247 - {{ else }} 248 - <div></div> 249 - {{ end }} 250 - {{ if eq $commits_len 60 }} 251 - <a 252 - class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700" 253 - hx-boost="true" 254 - onclick="window.location.href = window.location.pathname + '?page={{ add .Page 1 }}'"> 255 - next 256 - {{ i "chevron-right" "w-4 h-4" }} 257 - </a> 258 - {{ end }} 184 + {{ if gt .Page 1 }}<a class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700" hx-boost="true" onclick="window.location.href = window.location.pathname + '?page={{ sub .Page 1 }}'">{{ i "chevron-left" "w-4 h-4" }} previous</a>{{ else }}<div></div>{{ end }} 185 + {{ if eq $commits_len 60 }}<a class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700" hx-boost="true" onclick="window.location.href = window.location.pathname + '?page={{ add .Page 1 }}'">next {{ i "chevron-right" "w-4 h-4" }}</a>{{ end }} 259 186 </div> 260 187 {{ end }}
+51 -58
appview/pages/templates/repo/new.html
··· 1 1 {{ define "title" }}new repo{{ end }} 2 2 3 3 {{ define "content" }} 4 - <div class="p-6"> 5 - <p class="text-xl font-bold dark:text-white">Create a new repository</p> 6 - </div> 7 - <div class="p-6 bg-white dark:bg-gray-800 drop-shadow-sm rounded"> 8 - <form 9 - hx-post="/repo/new" 10 - class="space-y-12" 11 - hx-swap="none" 12 - hx-indicator="#spinner"> 13 - <div class="space-y-2"> 14 - <label for="name" class="-mb-1 dark:text-white">Repository name</label> 15 - <input 4 + <div class="p-6"> 5 + <p class="text-xl font-bold dark:text-white">Create a new repository</p> 6 + </div> 7 + <div class="p-6 bg-white dark:bg-gray-800 drop-shadow-sm rounded"> 8 + <form hx-post="/repo/new" class="space-y-12" hx-swap="none" hx-indicator="#spinner"> 9 + <div class="space-y-2"> 10 + <label for="name" class="-mb-1 dark:text-white">Repository name</label> 11 + <input 16 12 type="text" 17 13 id="name" 18 14 name="name" 19 15 required 20 - class="w-full max-w-md dark:bg-gray-700 dark:text-white dark:border-gray-600" /> 21 - <p class="text-sm text-gray-500 dark:text-gray-400"> 22 - All repositories are publicly visible. 23 - </p> 16 + class="w-full max-w-md dark:bg-gray-700 dark:text-white dark:border-gray-600" 17 + /> 18 + <p class="text-sm text-gray-500 dark:text-gray-400">All repositories are publicly visible.</p> 24 19 25 - <label for="branch" class="dark:text-white">Default branch</label> 26 - <input 20 + <label for="branch" class="dark:text-white">Default branch</label> 21 + <input 27 22 type="text" 28 23 id="branch" 29 24 name="branch" 30 25 value="main" 31 26 required 32 - class="w-full max-w-md dark:bg-gray-700 dark:text-white dark:border-gray-600" /> 27 + class="w-full max-w-md dark:bg-gray-700 dark:text-white dark:border-gray-600" 28 + /> 33 29 34 - <label for="description" class="dark:text-white">Description</label> 35 - <input 30 + <label for="description" class="dark:text-white">Description</label> 31 + <input 36 32 type="text" 37 33 id="description" 38 34 name="description" 39 - class="w-full max-w-md dark:bg-gray-700 dark:text-white dark:border-gray-600" /> 40 - </div> 35 + class="w-full max-w-md dark:bg-gray-700 dark:text-white dark:border-gray-600" 36 + /> 37 + </div> 41 38 42 - <fieldset class="space-y-3"> 43 - <legend class="dark:text-white">Select a knot</legend> 44 - <div class="space-y-2"> 45 - <div class="flex flex-col"> 46 - {{ range .Knots }} 47 - <div class="flex items-center"> 48 - <input 49 - type="radio" 50 - name="domain" 51 - value="{{ . }}" 52 - class="mr-2" 53 - id="domain-{{ . }}" /> 54 - <span class="dark:text-white">{{ . }}</span> 55 - </div> 56 - {{ else }} 57 - <p class="dark:text-white">No knots available.</p> 58 - {{ end }} 59 - </div> 60 - </div> 61 - <p class="text-sm text-gray-500 dark:text-gray-400"> 62 - A knot hosts repository data. 63 - <a href="/knots" class="underline"> 64 - Learn how to register your own knot. 65 - </a> 66 - </p> 67 - </fieldset> 68 - 39 + <fieldset class="space-y-3"> 40 + <legend class="dark:text-white">Select a knot</legend> 69 41 <div class="space-y-2"> 42 + <div class="flex flex-col"> 43 + {{ range .Knots }} 44 + <div class="flex items-center"> 45 + <input 46 + type="radio" 47 + name="domain" 48 + value="{{ . }}" 49 + class="mr-2" 50 + id="domain-{{ . }}" 51 + /> 52 + <span class="dark:text-white">{{ . }}</span> 53 + </div> 54 + {{ else }} 55 + <p class="dark:text-white">No knots available.</p> 56 + {{ end }} 57 + </div> 58 + </div> 59 + <p class="text-sm text-gray-500 dark:text-gray-400">A knot hosts repository data. <a href="/knots" class="underline">Learn how to register your own knot.</a></p> 60 + </fieldset> 61 + 62 + <div class="space-y-2"> 70 63 <button type="submit" class="btn-create flex items-center gap-2"> 71 - {{ i "book-plus" "w-4 h-4" }} 72 - create repo 73 - <span id="create-pull-spinner" class="group"> 74 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 75 - </span> 64 + {{ i "book-plus" "w-4 h-4" }} 65 + create repo 66 + <span id="create-pull-spinner" class="group"> 67 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 68 + </span> 76 69 </button> 77 70 <div id="repo" class="error"></div> 78 - </div> 79 - </form> 80 - </div> 71 + </div> 72 + </form> 73 + </div> 81 74 {{ end }}
+12 -21
appview/pages/templates/repo/pipelines/fragments/logBlock.html
··· 1 1 {{ define "repo/pipelines/fragments/logBlock" }} 2 - <div id="lines" hx-swap-oob="beforeend"> 3 - <details 4 - id="step-{{ .Id }}" 5 - {{ if not .Collapsed }}open{{ end }} 6 - class="group pb-2 rounded-sm border border-gray-200 dark:border-gray-700"> 7 - <summary 8 - class="sticky top-0 pt-2 px-2 group-open:pb-2 group-open:mb-2 list-none cursor-pointer group-open:border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 hover:text-gray-500 hover:dark:text-gray-400"> 9 - <div class="group-open:hidden flex items-center gap-1"> 10 - {{ i "chevron-right" "w-4 h-4" }} 11 - {{ .Name }} 12 - </div> 13 - <div class="hidden group-open:flex items-center gap-1"> 14 - {{ i "chevron-down" "w-4 h-4" }} 15 - {{ .Name }} 16 - </div> 17 - </summary> 18 - <div class="font-mono whitespace-pre overflow-x-auto px-2"> 19 - <div class="text-blue-600 dark:text-blue-300">{{ .Command }}</div> 20 - <div id="step-body-{{ .Id }}"></div> 2 + <div id="lines" hx-swap-oob="beforeend"> 3 + <details id="step-{{ .Id }}" {{if not .Collapsed}}open{{end}} class="group pb-2 rounded-sm border border-gray-200 dark:border-gray-700"> 4 + <summary class="sticky top-0 pt-2 px-2 group-open:pb-2 group-open:mb-2 list-none cursor-pointer group-open:border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 hover:text-gray-500 hover:dark:text-gray-400"> 5 + <div class="group-open:hidden flex items-center gap-1"> 6 + {{ i "chevron-right" "w-4 h-4" }} {{ .Name }} 21 7 </div> 22 - </details> 23 - </div> 8 + <div class="hidden group-open:flex items-center gap-1"> 9 + {{ i "chevron-down" "w-4 h-4" }} {{ .Name }} 10 + </div> 11 + </summary> 12 + <div class="font-mono whitespace-pre overflow-x-auto px-2"><div class="text-blue-600 dark:text-blue-300">{{ .Command }}</div><div id="step-body-{{ .Id }}"></div></div> 13 + </details> 14 + </div> 24 15 {{ end }}
+2 -3
appview/pages/templates/repo/pipelines/fragments/logLine.html
··· 1 1 {{ define "repo/pipelines/fragments/logLine" }} 2 - <div id="step-body-{{ .Id }}" hx-swap-oob="beforeend" class="whitespace-pre"> 3 - <p>{{ .Content }}</p> 4 - </div> 2 + <div id="step-body-{{ .Id }}" hx-swap-oob="beforeend" class="whitespace-pre"><p>{{ .Content }}</p></div> 5 3 {{ end }} 4 +
+9 -22
appview/pages/templates/repo/pipelines/fragments/pipelineSymbol.html
··· 37 37 {{ $offset := 0.0 }} 38 38 <div class="flex gap-1 items-center"> 39 39 <svg class="w-4 h-4 transform -rotate-90" viewBox="0 0 20 20"> 40 - <circle 41 - cx="10" 42 - cy="10" 43 - r="{{ $radius }}" 44 - fill="none" 45 - stroke="#f3f4f633" 46 - stroke-width="2" /> 40 + <circle cx="10" cy="10" r="{{ $radius }}" fill="none" stroke="#f3f4f633" stroke-width="2"/> 47 41 48 42 {{ range $kind, $count := $c }} 49 43 {{ $color := "" }} 50 44 {{ if or (eq $kind "pending") (eq $kind "running") }} 51 - {{ $color = "#eab308" }} 52 - {{/* amber-500 */}} 45 + {{ $color = "#eab308" }} {{/* amber-500 */}} 53 46 {{ else if eq $kind "success" }} 54 - {{ $color = "#10b981" }} 55 - {{/* green-500 */}} 47 + {{ $color = "#10b981" }} {{/* green-500 */}} 56 48 {{ else if eq $kind "cancelled" }} 57 - {{ $color = "#6b7280" }} 58 - {{/* gray-500 */}} 49 + {{ $color = "#6b7280" }} {{/* gray-500 */}} 59 50 {{ else if eq $kind "timeout" }} 60 - {{ $color = "#fb923c" }} 61 - {{/* orange-400 */}} 51 + {{ $color = "#fb923c" }} {{/* orange-400 */}} 62 52 {{ else }} 63 - {{ $color = "#ef4444" }} 64 - {{/* red-500 for failed or unknown */}} 53 + {{ $color = "#ef4444" }} {{/* red-500 for failed or unknown */}} 65 54 {{ end }} 66 55 67 56 {{ $percent := divf64 (f64 $count) (f64 $total) }} 68 57 {{ $length := mulf64 $percent $circumference }} 69 58 70 - 71 59 <circle 72 - cx="10" 73 - cy="10" 74 - r="{{ $radius }}" 60 + cx="10" cy="10" r="{{ $radius }}" 75 61 fill="none" 76 62 stroke="{{ $color }}" 77 63 stroke-width="2" 78 64 stroke-dasharray="{{ printf "%.2f %.2f" $length (subf64 $circumference $length) }}" 79 - stroke-dashoffset="{{ printf "%.2f" (negf64 $offset) }}" /> 65 + stroke-dashoffset="{{ printf "%.2f" (negf64 $offset) }}" 66 + /> 80 67 {{ $offset = addf64 $offset $length }} 81 68 {{ end }} 82 69 </svg>
+22 -27
appview/pages/templates/repo/pipelines/fragments/tooltip.html
··· 2 2 {{ $repoinfo := .RepoInfo }} 3 3 {{ $pipeline := .Pipeline }} 4 4 {{ $id := $pipeline.Id }} 5 - <div 6 - class="absolute z-[9999] bg-white dark:bg-gray-900 text-black dark:text-white rounded shadow-sm w-80 top-full mt-2 p-2"> 5 + <div class="absolute z-[9999] bg-white dark:bg-gray-900 text-black dark:text-white rounded shadow-sm w-80 top-full mt-2 p-2"> 7 6 <div class="flex flex-col divide-y divide-gray-200 dark:divide-gray-700"> 8 7 {{ range $name, $all := $pipeline.Statuses }} 9 - <a 10 - href="/{{ $repoinfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" 11 - class="hover:no-underline"> 12 - <div class="flex items-center justify-between p-2"> 13 - {{ $lastStatus := $all.Latest }} 14 - {{ $kind := $lastStatus.Status.String }} 8 + <a href="/{{ $repoinfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" class="hover:no-underline"> 9 + <div class="flex items-center justify-between p-2"> 10 + {{ $lastStatus := $all.Latest }} 11 + {{ $kind := $lastStatus.Status.String }} 15 12 16 - 17 - <div id="left" class="flex items-center gap-2 flex-shrink-0"> 18 - {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 19 - {{ $name }} 20 - </div> 21 - <div id="right" class="flex items-center gap-2 flex-shrink-0"> 22 - <span class="font-bold">{{ $kind }}</span> 23 - {{ if .TimeTaken }} 24 - {{ template "repo/fragments/duration" .TimeTaken }} 25 - {{ else }} 26 - {{ template "repo/fragments/shortTimeAgo" $pipeline.Created }} 27 - {{ end }} 28 - </div> 13 + <div id="left" class="flex items-center gap-2 flex-shrink-0"> 14 + {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 15 + {{ $name }} 29 16 </div> 30 - </a> 31 - {{ else }} 32 - <div 33 - class="flex items-center gap-2 p-2 italic text-gray-600 dark:text-gray-400 "> 34 - {{ i "hourglass" "size-4" }} 35 - Waiting for spindle ... 17 + <div id="right" class="flex items-center gap-2 flex-shrink-0"> 18 + <span class="font-bold">{{ $kind }}</span> 19 + {{ if .TimeTaken }} 20 + {{ template "repo/fragments/duration" .TimeTaken }} 21 + {{ else }} 22 + {{ template "repo/fragments/shortTimeAgo" $pipeline.Created }} 23 + {{ end }} 24 + </div> 36 25 </div> 26 + </a> 27 + {{ else }} 28 + <div class="flex items-center gap-2 p-2 italic text-gray-600 dark:text-gray-400 "> 29 + {{ i "hourglass" "size-4" }} 30 + Waiting for spindle ... 31 + </div> 37 32 {{ end }} 38 33 </div> 39 34 </div>
+72 -82
appview/pages/templates/repo/pipelines/pipelines.html
··· 1 1 {{ define "title" }}pipelines &middot; {{ .RepoInfo.FullName }}{{ end }} 2 2 3 3 {{ define "extrameta" }} 4 - {{ $title := "pipelines" }} 5 - {{ $url := printf "https://tangled.sh/%s/pipelines" .RepoInfo.FullName }} 6 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 4 + {{ $title := "pipelines"}} 5 + {{ $url := printf "https://tangled.sh/%s/pipelines" .RepoInfo.FullName }} 6 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 7 7 {{ end }} 8 8 9 9 {{ define "repoContent" }} 10 - <div class="flex justify-between items-center gap-4"> 11 - <div class="w-full flex flex-col gap-2"> 12 - {{ range .Pipelines }} 13 - {{ block "pipeline" (list $ .) }}{{ end }} 14 - {{ else }} 15 - <p class="text-center pt-5 text-gray-400 dark:text-gray-500"> 16 - No pipelines run for this repository. 17 - </p> 18 - {{ end }} 19 - </div> 10 + <div class="flex justify-between items-center gap-4"> 11 + <div class="w-full flex flex-col gap-2"> 12 + {{ range .Pipelines }} 13 + {{ block "pipeline" (list $ .) }} {{ end }} 14 + {{ else }} 15 + <p class="text-center pt-5 text-gray-400 dark:text-gray-500"> 16 + No pipelines run for this repository. 17 + </p> 18 + {{ end }} 20 19 </div> 20 + </div> 21 21 {{ end }} 22 + 22 23 23 24 {{ define "pipeline" }} 24 25 {{ $root := index . 0 }} 25 26 {{ $p := index . 1 }} 26 27 <div class="py-2 bg-white dark:bg-gray-800 dark:text-white"> 27 - {{ block "pipelineHeader" $ }}{{ end }} 28 + {{ block "pipelineHeader" $ }} {{ end }} 28 29 </div> 29 30 {{ end }} 30 31 ··· 33 32 {{ $root := index . 0 }} 34 33 {{ $p := index . 1 }} 35 34 {{ with $p }} 36 - <div class="grid grid-cols-6 md:grid-cols-12 gap-2 items-center w-full"> 37 - <div class="text-sm md:text-base col-span-1"> 38 - {{ .Trigger.Kind.String }} 39 - </div> 35 + <div class="grid grid-cols-6 md:grid-cols-12 gap-2 items-center w-full"> 36 + <div class="text-sm md:text-base col-span-1"> 37 + {{ .Trigger.Kind.String }} 38 + </div> 40 39 41 - <div class="col-span-2 md:col-span-7 flex items-center gap-4"> 42 - {{ $target := .Trigger.TargetRef }} 43 - {{ $workflows := .Workflows }} 44 - {{ $link := "" }} 45 - {{ if .IsResponding }} 46 - {{ $link = printf "/%s/pipelines/%s/workflow/%d" $root.RepoInfo.FullName .Id (index $workflows 0) }} 47 - {{ end }} 48 - {{ if .Trigger.IsPush }} 49 - <span class="font-bold">{{ $target }}</span> 50 - <span 51 - class="hidden md:inline-flex gap-2 items-center font-mono text-sm"> 52 - {{ $old := deref .Trigger.PushOldSha }} 53 - {{ $new := deref .Trigger.PushNewSha }} 54 - 55 - 56 - <a href="/{{ $root.RepoInfo.FullName }}/commit/{{ $new }}"> 57 - {{ slice $new 0 8 }} 58 - </a> 59 - {{ i "arrow-left" "size-4" }} 60 - <a href="/{{ $root.RepoInfo.FullName }}/commit/{{ $old }}"> 61 - {{ slice $old 0 8 }} 62 - </a> 63 - </span> 64 - {{ else if .Trigger.IsPullRequest }} 65 - {{ $sha := deref .Trigger.PRSourceSha }} 66 - <span class="inline-flex gap-2 items-center"> 40 + <div class="col-span-2 md:col-span-7 flex items-center gap-4"> 41 + {{ $target := .Trigger.TargetRef }} 42 + {{ $workflows := .Workflows }} 43 + {{ $link := "" }} 44 + {{ if .IsResponding }} 45 + {{ $link = printf "/%s/pipelines/%s/workflow/%d" $root.RepoInfo.FullName .Id (index $workflows 0) }} 46 + {{ end }} 47 + {{ if .Trigger.IsPush }} 67 48 <span class="font-bold">{{ $target }}</span> 68 - {{ i "arrow-left" "size-4" }} 69 - {{ .Trigger.PRSourceBranch }} 70 - <span class="text-sm font-mono"> 71 - @ 72 - <a href="/{{ $root.RepoInfo.FullName }}/commit/{{ $sha }}"> 73 - {{ slice $sha 0 8 }} 74 - </a> 49 + <span class="hidden md:inline-flex gap-2 items-center font-mono text-sm"> 50 + {{ $old := deref .Trigger.PushOldSha }} 51 + {{ $new := deref .Trigger.PushNewSha }} 52 + 53 + <a href="/{{ $root.RepoInfo.FullName }}/commit/{{ $new }}">{{ slice $new 0 8 }}</a> 54 + {{ i "arrow-left" "size-4" }} 55 + <a href="/{{ $root.RepoInfo.FullName }}/commit/{{ $old }}">{{ slice $old 0 8 }}</a> 75 56 </span> 76 - </span> 77 - {{ end }} 78 - </div> 57 + {{ else if .Trigger.IsPullRequest }} 58 + {{ $sha := deref .Trigger.PRSourceSha }} 59 + <span class="inline-flex gap-2 items-center"> 60 + <span class="font-bold">{{ $target }}</span> 61 + {{ i "arrow-left" "size-4" }} 62 + {{ .Trigger.PRSourceBranch }} 63 + <span class="text-sm font-mono"> 64 + @ 65 + <a href="/{{ $root.RepoInfo.FullName }}/commit/{{ $sha }}">{{ slice $sha 0 8 }}</a> 66 + </span> 67 + </span> 68 + {{ end }} 69 + </div> 79 70 80 - <div class="text-sm md:text-base col-span-1"> 81 - {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" . "RepoInfo" $root.RepoInfo) }} 82 - </div> 71 + <div class="text-sm md:text-base col-span-1"> 72 + {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" . "RepoInfo" $root.RepoInfo) }} 73 + </div> 83 74 84 - <div class="text-sm md:text-base col-span-1 text-right"> 85 - {{ template "repo/fragments/shortTimeAgo" .Created }} 86 - </div> 75 + <div class="text-sm md:text-base col-span-1 text-right"> 76 + {{ template "repo/fragments/shortTimeAgo" .Created }} 77 + </div> 87 78 88 - {{ $t := .TimeTaken }} 89 - <div class="text-sm md:text-base col-span-1 text-right"> 90 - {{ if $t }} 91 - <time title="{{ $t }}">{{ $t | durationFmt }}</time> 92 - {{ else }} 93 - <time>--</time> 94 - {{ end }} 95 - </div> 79 + {{ $t := .TimeTaken }} 80 + <div class="text-sm md:text-base col-span-1 text-right"> 81 + {{ if $t }} 82 + <time title="{{ $t }}">{{ $t | durationFmt }}</time> 83 + {{ else }} 84 + <time>--</time> 85 + {{ end }} 86 + </div> 96 87 97 - <div class="col-span-1 flex justify-end"> 98 - {{ if $link }} 99 - <a 100 - class="md:hidden" 101 - href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ .Id }}/workflow/{{ index $workflows 0 }}"> 102 - {{ i "arrow-up-right" "size-4" }} 103 - </a> 104 - <a 105 - class="hidden md:inline underline" 106 - href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ .Id }}/workflow/{{ index $workflows 0 }}"> 107 - view 108 - </a> 109 - {{ end }} 88 + <div class="col-span-1 flex justify-end"> 89 + {{ if $link }} 90 + <a class="md:hidden" href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ .Id }}/workflow/{{ index $workflows 0 }}"> 91 + {{ i "arrow-up-right" "size-4" }} 92 + </a> 93 + <a class="hidden md:inline underline" href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ .Id }}/workflow/{{ index $workflows 0 }}"> 94 + view 95 + </a> 96 + {{ end }} 97 + </div> 98 + 110 99 </div> 111 - </div> 112 100 {{ end }} 113 101 {{ end }}
+37 -48
appview/pages/templates/repo/pipelines/workflow.html
··· 1 - {{ define "title" }} 2 - {{ .Workflow }} &middot; pipeline {{ .Pipeline.Id }} &middot; 3 - {{ .RepoInfo.FullName }} 4 - {{ end }} 1 + {{ define "title" }} {{ .Workflow }} &middot; pipeline {{ .Pipeline.Id }} &middot; {{ .RepoInfo.FullName }}{{ end }} 5 2 6 3 {{ define "extrameta" }} 7 - {{ $title := "pipelines" }} 8 - {{ $url := printf "https://tangled.sh/%s/pipelines" .RepoInfo.FullName }} 9 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 4 + {{ $title := "pipelines"}} 5 + {{ $url := printf "https://tangled.sh/%s/pipelines" .RepoInfo.FullName }} 6 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 10 7 {{ end }} 11 8 12 9 {{ define "repoContent" }} 13 - <section class="w-full grid grid-cols-1 md:grid-cols-4 gap-2 mt-2"> 14 - <div class="col-span-1"> 15 - {{ block "sidebar" . }}{{ end }} 16 - </div> 17 - <div class="col-span-1 md:col-span-3"> 18 - {{ block "logs" . }}{{ end }} 19 - </div> 20 - </section> 10 + <section class="w-full grid grid-cols-1 md:grid-cols-4 gap-2 mt-2"> 11 + <div class="col-span-1"> 12 + {{ block "sidebar" . }} {{ end }} 13 + </div> 14 + <div class="col-span-1 md:col-span-3"> 15 + {{ block "logs" . }} {{ end }} 16 + </div> 17 + </section> 21 18 {{ end }} 22 19 23 20 {{ define "sidebar" }} ··· 25 28 26 29 {{ with .Pipeline }} 27 30 {{ $id := .Id }} 28 - <div 29 - class="sticky top-2 grid grid-cols-1 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700"> 31 + <div class="sticky top-2 grid grid-cols-1 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700"> 30 32 {{ range $name, $all := .Statuses }} 31 - <a 32 - href="/{{ $.RepoInfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" 33 - class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 34 - <div 35 - class="flex gap-2 items-center justify-between p-2 {{ if eq $name $active }} 36 - {{ $activeTab }} 37 - {{ else }} 38 - {{ $inactiveTab }} 39 - {{ end }}"> 40 - {{ $lastStatus := $all.Latest }} 41 - {{ $kind := $lastStatus.Status.String }} 33 + <a href="/{{ $.RepoInfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 34 + <div 35 + class="flex gap-2 items-center justify-between p-2 {{ if eq $name $active }} {{ $activeTab }} {{ else }} {{ $inactiveTab }} {{ end }}"> 36 + {{ $lastStatus := $all.Latest }} 37 + {{ $kind := $lastStatus.Status.String }} 42 38 43 - 44 - <div id="left" class="flex items-center gap-2 flex-shrink-0"> 45 - {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 46 - {{ $name }} 47 - </div> 48 - <div id="right" class="flex items-center gap-2 flex-shrink-0"> 49 - <span class="font-bold">{{ $kind }}</span> 50 - {{ if .TimeTaken }} 51 - {{ template "repo/fragments/duration" .TimeTaken }} 52 - {{ else }} 53 - {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }} 54 - {{ end }} 55 - </div> 39 + <div id="left" class="flex items-center gap-2 flex-shrink-0"> 40 + {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 41 + {{ $name }} 56 42 </div> 57 - </a> 43 + <div id="right" class="flex items-center gap-2 flex-shrink-0"> 44 + <span class="font-bold">{{ $kind }}</span> 45 + {{ if .TimeTaken }} 46 + {{ template "repo/fragments/duration" .TimeTaken }} 47 + {{ else }} 48 + {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }} 49 + {{ end }} 50 + </div> 51 + </div> 52 + </a> 58 53 {{ end }} 59 54 </div> 60 55 {{ end }} 61 56 {{ end }} 62 57 63 58 {{ define "logs" }} 64 - <div 65 - id="log-stream" 66 - class="text-sm" 67 - hx-ext="ws" 68 - ws-connect="/{{ $.RepoInfo.FullName }}/pipelines/{{ .Pipeline.Id }}/workflow/{{ .Workflow }}/logs"> 69 - <div id="lines" class="flex flex-col gap-2"></div> 59 + <div id="log-stream" 60 + class="text-sm" 61 + hx-ext="ws" 62 + ws-connect="/{{ $.RepoInfo.FullName }}/pipelines/{{ .Pipeline.Id }}/workflow/{{ .Workflow }}/logs"> 63 + <div id="lines" class="flex flex-col gap-2"> 64 + </div> 70 65 </div> 71 66 {{ end }}
+64 -63
appview/pages/templates/repo/pulls/fragments/pullActions.html
··· 23 23 {{ $isSameRepoBranch := .Pull.IsBranchBased }} 24 24 {{ $isUpToDate := .ResubmitCheck.No }} 25 25 <div class="relative w-fit"> 26 - <div id="actions-{{ $roundNumber }}" class="flex flex-wrap gap-2"> 27 - <button 28 - hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ $roundNumber }}/comment" 29 - hx-target="#actions-{{ $roundNumber }}" 30 - hx-swap="outerHtml" 31 - class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group"> 32 - {{ i "message-square-plus" "w-4 h-4" }} 33 - <span>comment</span> 34 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 35 - </button> 36 - {{ if and $isPushAllowed $isOpen $isLastRound }} 37 - {{ $disabled := "" }} 38 - {{ if $isConflicted }} 39 - {{ $disabled = "disabled" }} 40 - {{ end }} 41 - <button 42 - hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/merge" 43 - hx-swap="none" 44 - hx-confirm="Are you sure you want to merge pull #{{ .Pull.PullId }} into the `{{ .Pull.TargetBranch }}` branch?" 45 - class="btn p-2 flex items-center gap-2 group" 46 - {{ $disabled }}> 47 - {{ i "git-merge" "w-4 h-4" }} 48 - <span>merge{{ if $stackCount }}{{ $stackCount }}{{ end }}</span> 49 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 26 + <div id="actions-{{$roundNumber}}" class="flex flex-wrap gap-2"> 27 + <button 28 + hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ $roundNumber }}/comment" 29 + hx-target="#actions-{{$roundNumber}}" 30 + hx-swap="outerHtml" 31 + class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group"> 32 + {{ i "message-square-plus" "w-4 h-4" }} 33 + <span>comment</span> 34 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 50 35 </button> 51 - {{ end }} 52 - 53 - {{ if and $isPullAuthor $isOpen $isLastRound }} 54 - {{ $disabled := "" }} 55 - {{ if $isUpToDate }} 56 - {{ $disabled = "disabled" }} 57 - {{ end }} 58 - <button 59 - id="resubmitBtn" 60 - {{ if not .Pull.IsPatchBased }} 61 - hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit" 62 - {{ else }} 63 - hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit" 64 - hx-target="#actions-{{ $roundNumber }}" hx-swap="outerHtml" 36 + {{ if and $isPushAllowed $isOpen $isLastRound }} 37 + {{ $disabled := "" }} 38 + {{ if $isConflicted }} 39 + {{ $disabled = "disabled" }} 65 40 {{ end }} 41 + <button 42 + hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/merge" 43 + hx-swap="none" 44 + hx-confirm="Are you sure you want to merge pull #{{ .Pull.PullId }} into the `{{ .Pull.TargetBranch }}` branch?" 45 + class="btn p-2 flex items-center gap-2 group" {{ $disabled }}> 46 + {{ i "git-merge" "w-4 h-4" }} 47 + <span>merge{{if $stackCount}} {{$stackCount}}{{end}}</span> 48 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 49 + </button> 50 + {{ end }} 66 51 67 - hx-disabled-elt="#resubmitBtn" 68 - class="btn p-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed group" 69 - {{ $disabled }} 52 + {{ if and $isPullAuthor $isOpen $isLastRound }} 53 + {{ $disabled := "" }} 54 + {{ if $isUpToDate }} 55 + {{ $disabled = "disabled" }} 56 + {{ end }} 57 + <button id="resubmitBtn" 58 + {{ if not .Pull.IsPatchBased }} 59 + hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit" 60 + {{ else }} 61 + hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit" 62 + hx-target="#actions-{{$roundNumber}}" 63 + hx-swap="outerHtml" 64 + {{ end }} 70 65 71 - {{ if $disabled }} 72 - title="Update this branch to resubmit this pull request" 73 - {{ else }} 74 - title="Resubmit this pull request" 75 - {{ end }}> 76 - {{ i "rotate-ccw" "w-4 h-4" }} 77 - <span>resubmit</span> 78 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 79 - </button> 80 - {{ end }} 66 + hx-disabled-elt="#resubmitBtn" 67 + class="btn p-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed group" {{ $disabled }} 81 68 82 - {{ if and (or $isPullAuthor $isPushAllowed) $isOpen $isLastRound }} 83 - <button 69 + {{ if $disabled }} 70 + title="Update this branch to resubmit this pull request" 71 + {{ else }} 72 + title="Resubmit this pull request" 73 + {{ end }} 74 + > 75 + {{ i "rotate-ccw" "w-4 h-4" }} 76 + <span>resubmit</span> 77 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 78 + </button> 79 + {{ end }} 80 + 81 + {{ if and (or $isPullAuthor $isPushAllowed) $isOpen $isLastRound }} 82 + <button 84 83 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/close" 85 84 hx-swap="none" 86 85 class="btn p-2 flex items-center gap-2 group"> 87 - {{ i "ban" "w-4 h-4" }} 88 - <span>close</span> 89 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 86 + {{ i "ban" "w-4 h-4" }} 87 + <span>close</span> 88 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 90 89 </button> 91 - {{ end }} 90 + {{ end }} 92 91 93 - {{ if and (or $isPullAuthor $isPushAllowed) $isClosed $isLastRound }} 94 - <button 92 + {{ if and (or $isPullAuthor $isPushAllowed) $isClosed $isLastRound }} 93 + <button 95 94 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/reopen" 96 95 hx-swap="none" 97 96 class="btn p-2 flex items-center gap-2 group"> 98 - {{ i "refresh-ccw-dot" "w-4 h-4" }} 99 - <span>reopen</span> 100 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 97 + {{ i "refresh-ccw-dot" "w-4 h-4" }} 98 + <span>reopen</span> 99 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 101 100 </button> 102 - {{ end }} 101 + {{ end }} 103 102 </div> 104 103 </div> 105 104 {{ end }} 105 + 106 +
+39 -42
appview/pages/templates/repo/pulls/fragments/pullCompareBranches.html
··· 1 1 {{ define "repo/pulls/fragments/pullCompareBranches" }} 2 - <div id="patch-upload"> 3 - <label for="targetBranch" class="dark:text-white"> 4 - select a source branch 5 - </label> 6 - <div class="flex flex-wrap gap-2 items-center"> 7 - <select 8 - name="sourceBranch" 9 - class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"> 10 - <option disabled selected>source branch</option> 2 + <div id="patch-upload"> 3 + <label for="targetBranch" class="dark:text-white">select a source branch</label> 4 + <div class="flex flex-wrap gap-2 items-center"> 5 + <select 6 + name="sourceBranch" 7 + class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600" 8 + > 9 + <option disabled selected>source branch</option> 11 10 12 - {{ $recent := index .Branches 0 }} 13 - {{ range .Branches }} 14 - {{ $isRecent := eq .Reference.Name $recent.Reference.Name }} 15 - {{ $preset := false }} 16 - {{ if $.SourceBranch }} 17 - {{ $preset = eq .Reference.Name $.SourceBranch }} 18 - {{ else }} 19 - {{ $preset = $isRecent }} 20 - {{ end }} 21 - 22 - 23 - <option 24 - value="{{ .Reference.Name }}" 25 - {{ if $preset }} 26 - selected 27 - {{ end }} 28 - class="py-1"> 29 - {{ .Reference.Name }} 30 - {{ if $isRecent }}(new){{ end }} 31 - </option> 32 - {{ end }} 33 - </select> 11 + {{ $recent := index .Branches 0 }} 12 + {{ range .Branches }} 13 + {{ $isRecent := eq .Reference.Name $recent.Reference.Name }} 14 + {{ $preset := false }} 15 + {{ if $.SourceBranch }} 16 + {{ $preset = eq .Reference.Name $.SourceBranch }} 17 + {{ else }} 18 + {{ $preset = $isRecent }} 19 + {{ end }} 20 + 21 + <option 22 + value="{{ .Reference.Name }}" 23 + {{ if $preset }} 24 + selected 25 + {{ end }} 26 + class="py-1" 27 + > 28 + {{ .Reference.Name }} 29 + {{ if $isRecent }}(new){{ end }} 30 + </option> 31 + {{ end }} 32 + </select> 33 + </div> 34 34 </div> 35 - </div> 36 35 37 - <div class="flex items-center gap-2"> 38 - <input type="checkbox" id="isStacked" name="isStacked" value="on" /> 39 - <label for="isStacked" class="my-0 py-0 normal-case font-normal"> 40 - Submit as stacked PRs 41 - </label> 42 - </div> 36 + <div class="flex items-center gap-2"> 37 + <input type="checkbox" id="isStacked" name="isStacked" value="on"> 38 + <label for="isStacked" class="my-0 py-0 normal-case font-normal">Submit as stacked PRs</label> 39 + </div> 43 40 44 - <p class="mt-4"> 45 - Title and description are optional; if left out, they will be extracted from 46 - the first commit. 47 - </p> 41 + <p class="mt-4"> 42 + Title and description are optional; if left out, they will be extracted 43 + from the first commit. 44 + </p> 48 45 {{ end }}
+45 -45
appview/pages/templates/repo/pulls/fragments/pullCompareForks.html
··· 1 1 {{ define "repo/pulls/fragments/pullCompareForks" }} 2 - <div id="patch-upload"> 3 - <label for="forkSelect" class="dark:text-white"> 4 - select a fork to compare 5 - </label> 6 - selected: 7 - {{ .Selected }} 8 - <div class="flex flex-wrap gap-4 items-center"> 9 - <div class="flex flex-wrap gap-2 items-center"> 10 - <select 11 - id="forkSelect" 12 - name="fork" 13 - required 14 - class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600" 15 - hx-get="/{{ $.RepoInfo.FullName }}/pulls/new/fork-branches" 16 - hx-target="#branch-selection" 17 - hx-vals='{"fork": this.value}' 18 - hx-swap="innerHTML" 19 - onchange="document.getElementById('hiddenForkInput').value = this.value;"> 20 - <option disabled selected>select a fork</option> 21 - {{ range .Forks }} 22 - <option 23 - value="{{ .Name }}" 24 - {{ if eq .Name $.Selected }}selected{{ end }} 25 - class="py-1"> 26 - {{ .Name }} 27 - </option> 28 - {{ end }} 29 - </select> 2 + <div id="patch-upload"> 3 + <label for="forkSelect" class="dark:text-white" 4 + >select a fork to compare</label 5 + > 6 + selected: {{ .Selected }} 7 + <div class="flex flex-wrap gap-4 items-center"> 8 + <div class="flex flex-wrap gap-2 items-center"> 9 + <select 10 + id="forkSelect" 11 + name="fork" 12 + required 13 + class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600" 14 + hx-get="/{{ $.RepoInfo.FullName }}/pulls/new/fork-branches" 15 + hx-target="#branch-selection" 16 + hx-vals='{"fork": this.value}' 17 + hx-swap="innerHTML" 18 + onchange="document.getElementById('hiddenForkInput').value = this.value;" 19 + > 20 + <option disabled selected>select a fork</option> 21 + {{ range .Forks }} 22 + <option value="{{ .Name }}" {{ if eq .Name $.Selected }}selected{{ end }} class="py-1"> 23 + {{ .Name }} 24 + </option> 25 + {{ end }} 26 + </select> 30 27 31 - <input type="hidden" id="hiddenForkInput" name="fork" value="" /> 32 - </div> 28 + <input 29 + type="hidden" 30 + id="hiddenForkInput" 31 + name="fork" 32 + value="" 33 + /> 34 + </div> 33 35 34 - <div id="branch-selection"> 35 - <div class="text-sm text-gray-500 dark:text-gray-400"> 36 - Select a fork first to view available branches 36 + <div id="branch-selection"> 37 + <div class="text-sm text-gray-500 dark:text-gray-400"> 38 + Select a fork first to view available branches 39 + </div> 40 + </div> 37 41 </div> 38 - </div> 39 42 </div> 40 - </div> 41 43 42 - <div class="flex items-center gap-2"> 43 - <input type="checkbox" id="isStacked" name="isStacked" value="on" /> 44 - <label for="isStacked" class="my-0 py-0 normal-case font-normal"> 45 - Submit as stacked PRs 46 - </label> 47 - </div> 44 + <div class="flex items-center gap-2"> 45 + <input type="checkbox" id="isStacked" name="isStacked" value="on"> 46 + <label for="isStacked" class="my-0 py-0 normal-case font-normal">Submit as stacked PRs</label> 47 + </div> 48 48 49 - <p class="mt-4"> 50 - Title and description are optional; if left out, they will be extracted from 51 - the first commit. 52 - </p> 49 + <p class="mt-4"> 50 + Title and description are optional; if left out, they will be extracted 51 + from the first commit. 52 + </p> 53 53 {{ end }}
+22 -20
appview/pages/templates/repo/pulls/fragments/pullCompareForksBranches.html
··· 1 1 {{ define "repo/pulls/fragments/pullCompareForksBranches" }} 2 - <div class="flex flex-wrap gap-2 items-center"> 3 - <select 4 - name="sourceBranch" 5 - class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"> 6 - <option disabled selected>source branch</option> 2 + <div class="flex flex-wrap gap-2 items-center"> 3 + <select 4 + name="sourceBranch" 5 + class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600" 6 + > 7 + <option disabled selected>source branch</option> 7 8 8 - {{ $recent := index .SourceBranches 0 }} 9 - {{ range .SourceBranches }} 10 - {{ $isRecent := eq .Reference.Name $recent.Reference.Name }} 11 - <option 12 - value="{{ .Reference.Name }}" 13 - {{ if $isRecent }} 14 - selected 15 - {{ end }} 16 - class="py-1"> 17 - {{ .Reference.Name }} 18 - {{ if $isRecent }}(new){{ end }} 19 - </option> 20 - {{ end }} 21 - </select> 22 - </div> 9 + {{ $recent := index .SourceBranches 0 }} 10 + {{ range .SourceBranches }} 11 + {{ $isRecent := eq .Reference.Name $recent.Reference.Name }} 12 + <option 13 + value="{{ .Reference.Name }}" 14 + {{ if $isRecent }} 15 + selected 16 + {{ end }} 17 + class="py-1" 18 + > 19 + {{ .Reference.Name }} 20 + {{ if $isRecent }}(new){{ end }} 21 + </option> 22 + {{ end }} 23 + </select> 24 + </div> 23 25 {{ end }}
+59 -68
appview/pages/templates/repo/pulls/fragments/pullHeader.html
··· 1 1 {{ define "repo/pulls/fragments/pullHeader" }} 2 - <header class="pb-4"> 2 + <header class="pb-4"> 3 3 <h1 class="text-2xl dark:text-white"> 4 - {{ .Pull.Title }} 5 - <span class="text-gray-500 dark:text-gray-400">#{{ .Pull.PullId }}</span> 4 + {{ .Pull.Title }} 5 + <span class="text-gray-500 dark:text-gray-400">#{{ .Pull.PullId }}</span> 6 6 </h1> 7 - </header> 7 + </header> 8 8 9 - {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 10 - {{ $icon := "ban" }} 9 + {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 10 + {{ $icon := "ban" }} 11 11 12 - {{ if .Pull.State.IsOpen }} 12 + {{ if .Pull.State.IsOpen }} 13 13 {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 14 14 {{ $icon = "git-pull-request" }} 15 - {{ else if .Pull.State.IsMerged }} 15 + {{ else if .Pull.State.IsMerged }} 16 16 {{ $bgColor = "bg-purple-600 dark:bg-purple-700" }} 17 17 {{ $icon = "git-merge" }} 18 - {{ end }} 18 + {{ end }} 19 19 20 - {{ $owner := resolve .Pull.OwnerDid }} 21 - <section class="mt-2"> 20 + {{ $owner := resolve .Pull.OwnerDid }} 21 + <section class="mt-2"> 22 22 <div class="flex items-center gap-2"> 23 - <div 24 - id="state" 25 - class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}"> 26 - {{ i $icon "w-4 h-4 mr-1.5 text-white" }} 27 - <span class="text-white">{{ .Pull.State.String }}</span> 28 - </div> 29 - <span 30 - class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1"> 31 - opened by 32 - {{ template "user/fragments/picHandleLink" .Pull.OwnerDid }} 33 - <span class="select-none before:content-['\00B7']"></span> 34 - {{ template "repo/fragments/time" .Pull.Created }} 23 + <div 24 + id="state" 25 + class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}" 26 + > 27 + {{ i $icon "w-4 h-4 mr-1.5 text-white" }} 28 + <span class="text-white">{{ .Pull.State.String }}</span> 29 + </div> 30 + <span class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1"> 31 + opened by 32 + {{ template "user/fragments/picHandleLink" .Pull.OwnerDid }} 33 + <span class="select-none before:content-['\00B7']"></span> 34 + {{ template "repo/fragments/time" .Pull.Created }} 35 35 36 - 37 - <span class="select-none before:content-['\00B7']"></span> 38 - <span> 39 - targeting 40 - <span 41 - class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-1/2 inline-flex items-center"> 42 - <a 43 - href="/{{ .RepoInfo.FullName }}/tree/{{ .Pull.TargetBranch }}" 44 - class="no-underline hover:underline"> 45 - {{ .Pull.TargetBranch }} 46 - </a> 47 - </span> 36 + <span class="select-none before:content-['\00B7']"></span> 37 + <span> 38 + targeting 39 + <span class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-1/2 inline-flex items-center"> 40 + <a href="/{{ .RepoInfo.FullName }}/tree/{{ .Pull.TargetBranch }}" class="no-underline hover:underline">{{ .Pull.TargetBranch }}</a> 41 + </span> 42 + </span> 43 + {{ if not .Pull.IsPatchBased }} 44 + from 45 + <span class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-1/2 inline-flex items-center"> 46 + {{ if .Pull.IsForkBased }} 47 + {{ if .Pull.PullSource.Repo }} 48 + <a href="/{{ $owner }}/{{ .Pull.PullSource.Repo.Name }}" class="no-underline hover:underline">{{ $owner }}/{{ .Pull.PullSource.Repo.Name }}</a>: 49 + {{- else -}} 50 + <span class="italic">[deleted fork]</span> 51 + {{- end -}} 52 + {{- end -}} 53 + {{- .Pull.PullSource.Branch -}} 54 + </span> 55 + {{ end }} 48 56 </span> 49 - {{ if not .Pull.IsPatchBased }} 50 - from 51 - <span 52 - class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-1/2 inline-flex items-center"> 53 - {{ if .Pull.IsForkBased }} 54 - {{ if .Pull.PullSource.Repo }} 55 - <a 56 - href="/{{ $owner }}/{{ .Pull.PullSource.Repo.Name }}" 57 - class="no-underline hover:underline"> 58 - {{ $owner }}/{{ .Pull.PullSource.Repo.Name }} 59 - </a> 60 - : 61 - {{- else -}} 62 - <span class="italic">[deleted fork]</span> 63 - {{- end -}} 64 - {{- end -}} 65 - {{- .Pull.PullSource.Branch -}} 66 - </span> 67 - {{ end }} 68 - </span> 69 57 </div> 70 58 71 59 {{ if .Pull.Body }} 72 - <article id="body" class="mt-8 prose dark:prose-invert"> 73 - {{ .Pull.Body | markdown }} 74 - </article> 60 + <article id="body" class="mt-8 prose dark:prose-invert"> 61 + {{ .Pull.Body | markdown }} 62 + </article> 75 63 {{ end }} 76 64 77 65 {{ with .OrderedReactionKinds }} 78 - <div class="flex items-center gap-2 mt-2"> 66 + <div class="flex items-center gap-2 mt-2"> 79 67 {{ template "repo/fragments/reactionsPopUp" . }} 80 68 {{ range $kind := . }} 81 - {{ template "repo/fragments/reaction" 82 - (dict 83 - "Kind" $kind 84 - "Count" (index $.Reactions $kind) 85 - "IsReacted" (index $.UserReacted $kind) 86 - "ThreadAt" $.Pull.PullAt) 87 - }} 69 + {{ 70 + template "repo/fragments/reaction" 71 + (dict 72 + "Kind" $kind 73 + "Count" (index $.Reactions $kind) 74 + "IsReacted" (index $.UserReacted $kind) 75 + "ThreadAt" $.Pull.PullAt) 76 + }} 88 77 {{ end }} 89 - </div> 78 + </div> 90 79 {{ end }} 91 - </section> 80 + </section> 81 + 82 + 92 83 {{ end }}
+31 -28
appview/pages/templates/repo/pulls/fragments/pullNewComment.html
··· 1 1 {{ define "repo/pulls/fragments/pullNewComment" }} 2 - <div 3 - id="pull-comment-card-{{ .RoundNumber }}" 4 - class="bg-white dark:bg-gray-800 rounded drop-shadow-sm p-4 relative w-full flex flex-col gap-2"> 5 - <div class="text-sm text-gray-500 dark:text-gray-400"> 6 - {{ didOrHandle .LoggedInUser.Did .LoggedInUser.Handle }} 7 - </div> 8 - <form 9 - hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/comment" 10 - hx-indicator="#create-comment-spinner" 11 - hx-swap="none" 12 - class="w-full flex flex-wrap gap-2"> 13 - <textarea 2 + <div 3 + id="pull-comment-card-{{ .RoundNumber }}" 4 + class="bg-white dark:bg-gray-800 rounded drop-shadow-sm p-4 relative w-full flex flex-col gap-2"> 5 + <div class="text-sm text-gray-500 dark:text-gray-400"> 6 + {{ didOrHandle .LoggedInUser.Did .LoggedInUser.Handle }} 7 + </div> 8 + <form 9 + hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/comment" 10 + hx-indicator="#create-comment-spinner" 11 + hx-swap="none" 12 + class="w-full flex flex-wrap gap-2" 13 + > 14 + <textarea 14 15 name="body" 15 16 class="w-full p-2 rounded border border-gray-200" 16 - placeholder="Add to the discussion..."></textarea> 17 - <button type="submit" class="btn flex items-center gap-2"> 17 + placeholder="Add to the discussion..."></textarea 18 + > 19 + <button type="submit" class="btn flex items-center gap-2"> 18 20 {{ i "message-square" "w-4 h-4" }} 19 21 <span>comment</span> 20 22 <span id="create-comment-spinner" class="group"> 21 23 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 22 24 </span> 23 - </button> 24 - <button 25 - type="button" 26 - class="btn flex items-center gap-2 group" 27 - hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/actions" 28 - hx-swap="outerHTML" 29 - hx-target="#pull-comment-card-{{ .RoundNumber }}"> 30 - {{ i "x" "w-4 h-4" }} 31 - <span>cancel</span> 32 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 33 - </button> 34 - <div id="pull-comment"></div> 35 - </form> 36 - </div> 25 + </button> 26 + <button 27 + type="button" 28 + class="btn flex items-center gap-2 group" 29 + hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/actions" 30 + hx-swap="outerHTML" 31 + hx-target="#pull-comment-card-{{ .RoundNumber }}" 32 + > 33 + {{ i "x" "w-4 h-4" }} 34 + <span>cancel</span> 35 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 36 + </button> 37 + <div id="pull-comment"></div> 38 + </form> 39 + </div> 37 40 {{ end }}
+17 -19
appview/pages/templates/repo/pulls/fragments/pullPatchUpload.html
··· 1 1 {{ define "repo/pulls/fragments/pullPatchUpload" }} 2 - <div id="patch-upload"> 3 - <p> 4 - You can paste a 5 - <code>git diff</code> 6 - or a 7 - <code>git format-patch</code> 8 - patch series here. 9 - </p> 10 - <textarea 11 - hx-trigger="keyup changed delay:500ms, paste delay:500ms" 12 - hx-post="/{{ .RepoInfo.FullName }}/pulls/new/validate-patch" 13 - hx-swap="none" 14 - name="patch" 15 - id="patch" 16 - rows="12" 17 - class="w-full mt-2 resize-y font-mono dark:bg-gray-700 dark:text-white dark:border-gray-600" 18 - placeholder="diff --git a/file.txt b/file.txt 2 + <div id="patch-upload"> 3 + <p> 4 + You can paste a <code>git diff</code> or a 5 + <code>git format-patch</code> patch series here. 6 + </p> 7 + <textarea 8 + hx-trigger="keyup changed delay:500ms, paste delay:500ms" 9 + hx-post="/{{ .RepoInfo.FullName }}/pulls/new/validate-patch" 10 + hx-swap="none" 11 + name="patch" 12 + id="patch" 13 + rows="12" 14 + class="w-full mt-2 resize-y font-mono dark:bg-gray-700 dark:text-white dark:border-gray-600" 15 + placeholder="diff --git a/file.txt b/file.txt 19 16 index 1234567..abcdefg 100644 20 17 --- a/file.txt 21 - +++ b/file.txt"></textarea> 22 - </div> 18 + +++ b/file.txt" 19 + ></textarea> 20 + </div> 23 21 {{ end }}
+57 -53
appview/pages/templates/repo/pulls/fragments/pullResubmit.html
··· 1 1 {{ define "repo/pulls/fragments/pullResubmit" }} 2 2 <div 3 - id="resubmit-pull-card" 4 - class="rounded relative border bg-amber-50 dark:bg-amber-900 border-amber-200 dark:border-amber-500 px-6 py-2"> 5 - <div class="flex items-center gap-2 text-amber-500 dark:text-amber-50"> 6 - {{ i "pencil" "w-4 h-4" }} 7 - <span class="font-medium">resubmit your patch</span> 8 - </div> 3 + id="resubmit-pull-card" 4 + class="rounded relative border bg-amber-50 dark:bg-amber-900 border-amber-200 dark:border-amber-500 px-6 py-2"> 9 5 10 - <div class="mt-2 text-sm text-gray-700 dark:text-gray-200"> 11 - You can update this patch to address any reviews. This will begin a new 12 - round of reviews, but you'll still be able to view your previous 13 - submissions and feedback. 14 - </div> 6 + <div class="flex items-center gap-2 text-amber-500 dark:text-amber-50"> 7 + {{ i "pencil" "w-4 h-4" }} 8 + <span class="font-medium">resubmit your patch</span> 9 + </div> 15 10 16 - <div class="mt-4 flex flex-col"> 17 - <form 18 - hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit" 19 - hx-swap="none" 20 - class="w-full flex flex-wrap gap-2" 21 - hx-indicator="#resubmit-spinner"> 22 - <textarea 23 - name="patch" 24 - class="w-full p-2 mb-2" 25 - placeholder="Paste your updated patch here." 26 - rows="15"> 27 - {{ .Pull.LatestPatch }} 28 - </textarea 11 + <div class="mt-2 text-sm text-gray-700 dark:text-gray-200"> 12 + You can update this patch to address any reviews. 13 + This will begin a new round of reviews, 14 + but you'll still be able to view your previous submissions and feedback. 15 + </div> 16 + 17 + <div class="mt-4 flex flex-col"> 18 + <form 19 + hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit" 20 + hx-swap="none" 21 + class="w-full flex flex-wrap gap-2" 22 + hx-indicator="#resubmit-spinner" 29 23 > 30 - <button 31 - type="submit" 32 - class="btn flex items-center gap-2" 33 - {{ if or .Pull.State.IsClosed }} 34 - disabled 35 - {{ end }}> 36 - {{ i "rotate-ccw" "w-4 h-4" }} 37 - <span>resubmit</span> 38 - <span id="resubmit-spinner" class="group"> 39 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 40 - </span> 41 - </button> 42 - <button 43 - type="button" 44 - class="btn flex items-center gap-2" 45 - hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .Pull.LastRoundNumber }}/actions" 46 - hx-swap="outerHTML" 47 - hx-target="#resubmit-pull-card" 48 - hx-indicator="#cancel-resubmit-spinner"> 49 - {{ i "x" "w-4 h-4" }} 50 - <span>cancel</span> 51 - <span id="cancel-resubmit-spinner" class="group"> 52 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 53 - </span> 54 - </button> 55 - </form> 24 + <textarea 25 + name="patch" 26 + class="w-full p-2 mb-2" 27 + placeholder="Paste your updated patch here." 28 + rows="15" 29 + > 30 + {{.Pull.LatestPatch}} 31 + </textarea> 32 + <button 33 + type="submit" 34 + class="btn flex items-center gap-2" 35 + {{ if or .Pull.State.IsClosed }} 36 + disabled 37 + {{ end }} 38 + > 39 + {{ i "rotate-ccw" "w-4 h-4" }} 40 + <span>resubmit</span> 41 + <span id="resubmit-spinner" class="group"> 42 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 43 + </span> 44 + </button> 45 + <button 46 + type="button" 47 + class="btn flex items-center gap-2" 48 + hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .Pull.LastRoundNumber }}/actions" 49 + hx-swap="outerHTML" 50 + hx-target="#resubmit-pull-card" 51 + hx-indicator="#cancel-resubmit-spinner" 52 + > 53 + {{ i "x" "w-4 h-4" }} 54 + <span>cancel</span> 55 + <span id="cancel-resubmit-spinner" class="group"> 56 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 57 + </span> 58 + </button> 59 + </form> 56 60 57 - <div id="resubmit-error" class="error"></div> 58 - <div id="resubmit-success" class="success"></div> 59 - </div> 61 + <div id="resubmit-error" class="error"></div> 62 + <div id="resubmit-success" class="success"></div> 63 + </div> 60 64 </div> 61 65 {{ end }}
+10 -27
appview/pages/templates/repo/pulls/fragments/pullStack.html
··· 1 1 {{ define "repo/pulls/fragments/pullStack" }} 2 2 <details class="bg-white dark:bg-gray-800 group" open> 3 - <summary 4 - class="p-2 text-sm font-bold list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 3 + <summary class="p-2 text-sm font-bold list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 5 4 <span class="flex items-center gap-2"> 6 5 <span class="group-open:hidden"> 7 6 {{ i "chevrons-up-down" "w-4 h-4" }} ··· 9 10 {{ i "chevrons-down-up" "w-4 h-4" }} 10 11 </span> 11 12 STACK 12 - <span 13 - class="bg-gray-200 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm"> 14 - {{ len .Stack }} 15 - </span> 13 + <span class="bg-gray-200 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ len .Stack }}</span> 16 14 </span> 17 15 </summary> 18 - {{ block "pullList" (list .Stack $) }}{{ end }} 16 + {{ block "pullList" (list .Stack $) }} {{ end }} 19 17 </details> 20 18 21 19 {{ if gt (len .AbandonedPulls) 0 }} 22 20 <details class="mt-4 bg-white dark:bg-gray-800 group" open> 23 - <summary 24 - class="p-2 text-sm font-bold list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 21 + <summary class="p-2 text-sm font-bold list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 25 22 <span class="flex items-center gap-2"> 26 23 <span class="group-open:hidden"> 27 24 {{ i "chevrons-up-down" "w-4 h-4" }} ··· 26 31 {{ i "chevrons-down-up" "w-4 h-4" }} 27 32 </span> 28 33 ABANDONED PULLS 29 - <span 30 - class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-sm ml-1"> 31 - {{ len .AbandonedPulls }} 32 - </span> 34 + <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-sm ml-1">{{ len .AbandonedPulls }}</span> 33 35 </span> 34 36 </summary> 35 - {{ block "pullList" (list .AbandonedPulls $) }}{{ end }} 37 + {{ block "pullList" (list .AbandonedPulls $) }} {{ end }} 36 38 </details> 37 39 {{ end }} 38 40 {{ end }} ··· 37 45 {{ define "pullList" }} 38 46 {{ $list := index . 0 }} 39 47 {{ $root := index . 1 }} 40 - <div 41 - class="grid grid-cols-1 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700"> 48 + <div class="grid grid-cols-1 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700"> 42 49 {{ range $pull := $list }} 43 50 {{ $isCurrent := false }} 44 51 {{ $pipeline := index $root.Pipelines $pull.LatestSha }} 45 52 {{ with $root.Pull }} 46 53 {{ $isCurrent = eq $pull.PullId $root.Pull.PullId }} 47 54 {{ end }} 48 - <a 49 - href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $pull.PullId }}" 50 - class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 51 - <div 52 - class="flex gap-2 items-center px-2 {{ if $isCurrent }} 53 - bg-gray-100/50 dark:bg-gray-700/50 54 - {{ end }}"> 55 + <a href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $pull.PullId }}" class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 56 + <div class="flex gap-2 items-center px-2 {{ if $isCurrent }}bg-gray-100/50 dark:bg-gray-700/50{{ end }}"> 55 57 {{ if $isCurrent }} 56 58 <div class="flex-shrink-0"> 57 59 {{ i "arrow-right" "w-4 h-4" }} 58 60 </div> 59 61 {{ end }} 60 - <div 61 - class="{{ if not $isCurrent }} 62 - pl-6 63 - {{ end }} flex-grow min-w-0 w-full py-2"> 62 + <div class="{{ if not $isCurrent }} pl-6 {{ end }} flex-grow min-w-0 w-full py-2"> 64 63 {{ template "repo/pulls/fragments/summarizedHeader" (list $pull $pipeline) }} 65 64 </div> 66 65 </div>
+4 -7
appview/pages/templates/repo/pulls/fragments/summarizedPullHeader.html
··· 19 19 {{ $commentCount := len $lastSubmission.Comments }} 20 20 {{ if and $pipeline $pipeline.Id }} 21 21 {{ template "repo/pipelines/fragments/pipelineSymbol" $pipeline }} 22 - <span 23 - class="before:content-['·'] before:select-none text-gray-500 dark:text-gray-400"></span> 22 + <span class="before:content-['·'] before:select-none text-gray-500 dark:text-gray-400"></span> 24 23 {{ end }} 25 24 <span> 26 25 <div class="inline-flex items-center gap-1"> 27 26 {{ i "message-square" "w-3 h-3 md:hidden" }} 28 27 {{ $commentCount }} 29 - <span class="hidden md:inline"> 30 - comment{{ if ne $commentCount 1 }}s{{ end }} 31 - </span> 28 + <span class="hidden md:inline">comment{{if ne $commentCount 1}}s{{end}}</span> 32 29 </div> 33 30 </span> 34 - <span 35 - class="before:content-['·'] before:select-none text-gray-500 dark:text-gray-400"></span> 31 + <span class="before:content-['·'] before:select-none text-gray-500 dark:text-gray-400"></span> 36 32 <span> 37 33 <span class="hidden md:inline">round</span> 38 34 <span class="font-mono">#{{ $latestRound }}</span> ··· 37 41 </div> 38 42 {{ end }} 39 43 {{ end }} 44 +
+1
appview/pages/templates/repo/pulls/fragments/summarizedPullState.html
··· 17 17 18 18 {{ i $icon $style }} 19 19 {{ end }} 20 +
+20 -23
appview/pages/templates/repo/pulls/interdiff.html
··· 1 1 {{ define "title" }} 2 - interdiff of round #{{ .Round }} and #{{ sub .Round 1 }} &middot; pull 3 - #{{ .Pull.PullId }} &middot; 4 - {{ .RepoInfo.FullName }} 2 + interdiff of round #{{ .Round }} and #{{ sub .Round 1 }} &middot; pull #{{ .Pull.PullId }} &middot; {{ .RepoInfo.FullName }} 5 3 {{ end }} 6 4 7 - {{ define "extrameta" }} 8 - {{ $title := printf "interdiff of %d and %d &middot; %s &middot; pull #%d &middot; %s" .Round (sub .Round 1) .Pull.Title .Pull.PullId .RepoInfo.FullName }} 9 - {{ $url := printf "https://tangled.sh/%s/pulls/%d/round/%d" .RepoInfo.FullName .Pull.PullId .Round }} 10 5 11 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" (unescapeHtml $title) "Url" $url) }} 6 + {{ define "extrameta" }} 7 + {{ $title := printf "interdiff of %d and %d &middot; %s &middot; pull #%d &middot; %s" .Round (sub .Round 1) .Pull.Title .Pull.PullId .RepoInfo.FullName }} 8 + {{ $url := printf "https://tangled.sh/%s/pulls/%d/round/%d" .RepoInfo.FullName .Pull.PullId .Round }} 9 + 10 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" (unescapeHtml $title) "Url" $url) }} 12 11 {{ end }} 13 12 14 13 {{ define "content" }} 15 - <section 16 - class="rounded drop-shadow-sm bg-white dark:bg-gray-800 py-4 px-6 dark:text-white"> 14 + <section class="rounded drop-shadow-sm bg-white dark:bg-gray-800 py-4 px-6 dark:text-white"> 17 15 <header class="pb-2"> 18 16 <div class="flex gap-3 items-center mb-3"> 19 - <a 20 - href="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/" 21 - class="flex items-center gap-2 font-medium"> 17 + <a href="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/" class="flex items-center gap-2 font-medium"> 22 18 {{ i "arrow-left" "w-5 h-5" }} 23 19 back 24 20 </a> 25 21 <span class="select-none before:content-['\00B7']"></span> 26 - interdiff of round #{{ .Round }} and 27 - #{{ sub .Round 1 }} 22 + interdiff of round #{{ .Round }} and #{{ sub .Round 1 }} 28 23 </div> 29 24 <div class="border-t border-gray-200 dark:border-gray-700 my-2"></div> 30 25 {{ template "repo/pulls/fragments/pullHeader" . }} 31 26 </header> 32 27 </section> 28 + 33 29 {{ end }} 34 30 35 31 {{ define "topbarLayout" }} ··· 41 45 {{ end }} 42 46 43 47 {{ block "contentAfterLayout" . }} 44 - <div class="flex-grow grid grid-cols-1 md:grid-cols-12 gap-4"> 45 - <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> 46 - {{ block "contentAfterLeft" . }}{{ end }} 47 - </div> 48 - <main class="col-span-1 md:col-span-10"> 49 - {{ block "contentAfter" . }}{{ end }} 50 - </main> 48 + <div class="flex-grow grid grid-cols-1 md:grid-cols-12 gap-4"> 49 + <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> 50 + {{ block "contentAfterLeft" . }} {{ end }} 51 51 </div> 52 + <main class="col-span-1 md:col-span-10"> 53 + {{ block "contentAfter" . }}{{ end }} 54 + </main> 55 + </div> 52 56 {{ end }} 53 57 </div> 54 58 {{ end }} ··· 59 63 </footer> 60 64 {{ end }} 61 65 66 + 62 67 {{ define "contentAfter" }} 63 68 {{ template "repo/fragments/interdiff" (list .RepoInfo.FullName .Interdiff .DiffOpts) }} 64 - {{ end }} 69 + {{end}} 65 70 66 71 {{ define "contentAfterLeft" }} 67 72 <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> ··· 71 74 <div class="sticky top-0 flex-grow max-h-screen"> 72 75 {{ template "repo/fragments/interdiffFiles" .Interdiff }} 73 76 </div> 74 - {{ end }} 77 + {{end}}
+133 -123
appview/pages/templates/repo/pulls/new.html
··· 1 1 {{ define "title" }}new pull &middot; {{ .RepoInfo.FullName }}{{ end }} 2 2 3 3 {{ define "repoContent" }} 4 - <h2 class="font-bold text-sm mb-4 uppercase dark:text-white"> 5 - Create new pull request 6 - </h2> 4 + <h2 class="font-bold text-sm mb-4 uppercase dark:text-white"> 5 + Create new pull request 6 + </h2> 7 7 8 - <form 9 - hx-post="/{{ .RepoInfo.FullName }}/pulls/new" 10 - hx-indicator="#create-pull-spinner" 11 - hx-swap="none"> 12 - <div class="flex flex-col gap-6"> 13 - <div class="flex gap-2 items-center"> 14 - <p>First, choose a target branch on {{ .RepoInfo.FullName }}:</p> 15 - <div> 16 - <select 17 - required 18 - name="targetBranch" 19 - class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"> 20 - <option disabled selected>target branch</option> 21 - 22 - {{ range .Branches }} 23 - {{ $preset := false }} 24 - {{ if $.TargetBranch }} 25 - {{ $preset = eq .Reference.Name $.TargetBranch }} 26 - {{ else }} 27 - {{ $preset = .IsDefault }} 28 - {{ end }} 8 + <form 9 + hx-post="/{{ .RepoInfo.FullName }}/pulls/new" 10 + hx-indicator="#create-pull-spinner" 11 + hx-swap="none" 12 + > 13 + <div class="flex flex-col gap-6"> 14 + <div class="flex gap-2 items-center"> 15 + <p>First, choose a target branch on {{ .RepoInfo.FullName }}:</p> 16 + <div> 17 + <select 18 + required 19 + name="targetBranch" 20 + class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600" 21 + > 22 + <option disabled selected>target branch</option> 29 23 30 24 31 - <option 32 - value="{{ .Reference.Name }}" 33 - class="py-1" 34 - {{ if $preset }}selected{{ end }}> 35 - {{ .Reference.Name }} 36 - </option> 37 - {{ end }} 38 - </select> 39 - </div> 40 - </div> 25 + {{ range .Branches }} 41 26 42 - <div class="flex flex-col gap-2"> 43 - <h2 class="font-bold text-sm mb-4 uppercase dark:text-white"> 44 - Choose pull strategy 45 - </h2> 46 - <nav class="flex space-x-4 items-center"> 47 - <button 48 - type="button" 49 - class="btn" 50 - hx-get="/{{ .RepoInfo.FullName }}/pulls/new/patch-upload" 51 - hx-target="#patch-strategy" 52 - hx-swap="innerHTML"> 53 - paste patch 54 - </button> 27 + {{ $preset := false }} 28 + {{ if $.TargetBranch }} 29 + {{ $preset = eq .Reference.Name $.TargetBranch }} 30 + {{ else }} 31 + {{ $preset = .IsDefault }} 32 + {{ end }} 55 33 56 - {{ if .RepoInfo.Roles.IsPushAllowed }} 57 - <span class="text-sm text-gray-500 dark:text-gray-400">or</span> 58 - <button 59 - type="button" 60 - class="btn" 61 - hx-get="/{{ .RepoInfo.FullName }}/pulls/new/compare-branches" 62 - hx-target="#patch-strategy" 63 - hx-swap="innerHTML"> 64 - compare branches 65 - </button> 66 - {{ end }} 34 + <option value="{{ .Reference.Name }}" class="py-1" {{if $preset}}selected{{end}}> 35 + {{ .Reference.Name }} 36 + </option> 37 + {{ end }} 38 + </select> 39 + </div> 40 + </div> 41 + 42 + <div class="flex flex-col gap-2"> 43 + <h2 class="font-bold text-sm mb-4 uppercase dark:text-white"> 44 + Choose pull strategy 45 + </h2> 46 + <nav class="flex space-x-4 items-center"> 47 + <button 48 + type="button" 49 + class="btn" 50 + hx-get="/{{ .RepoInfo.FullName }}/pulls/new/patch-upload" 51 + hx-target="#patch-strategy" 52 + hx-swap="innerHTML" 53 + > 54 + paste patch 55 + </button> 56 + 57 + {{ if .RepoInfo.Roles.IsPushAllowed }} 58 + <span class="text-sm text-gray-500 dark:text-gray-400"> 59 + or 60 + </span> 61 + <button 62 + type="button" 63 + class="btn" 64 + hx-get="/{{ .RepoInfo.FullName }}/pulls/new/compare-branches" 65 + hx-target="#patch-strategy" 66 + hx-swap="innerHTML" 67 + > 68 + compare branches 69 + </button> 70 + {{ end }} 67 71 68 72 69 - <span class="text-sm text-gray-500 dark:text-gray-400">or</span> 70 - <script> 71 - function getQueryParams() { 72 - return Object.fromEntries( 73 - new URLSearchParams(window.location.search), 74 - ); 75 - } 76 - </script> 77 - <!-- 73 + <span class="text-sm text-gray-500 dark:text-gray-400"> 74 + or 75 + </span> 76 + <script> 77 + function getQueryParams() { 78 + return Object.fromEntries(new URLSearchParams(window.location.search)); 79 + } 80 + </script> 81 + <!-- 78 82 since compare-forks need the server to load forks, we 79 83 hx-get this button; unlike simply loading the pullCompareForks template 80 84 as we do for the rest of the gang below. the hx-vals thing just populates 81 85 the query params so the forks page gets it. 82 86 --> 83 - <button 84 - type="button" 85 - class="btn" 86 - hx-get="/{{ .RepoInfo.FullName }}/pulls/new/compare-forks" 87 - hx-target="#patch-strategy" 88 - hx-swap="innerHTML" 89 - {{ if eq .Strategy "fork" }} 90 - hx-trigger="click, load" hx-vals='js:{...getQueryParams()}' 91 - {{ end }}> 92 - compare forks 93 - </button> 94 - </nav> 95 - <section id="patch-strategy" class="flex flex-col gap-2"> 96 - {{ if eq .Strategy "patch" }} 97 - {{ template "repo/pulls/fragments/pullPatchUpload" . }} 98 - {{ else if eq .Strategy "branch" }} 99 - {{ template "repo/pulls/fragments/pullCompareBranches" . }} 100 - {{ else }} 101 - {{ template "repo/pulls/fragments/pullPatchUpload" . }} 102 - {{ end }} 103 - </section> 87 + <button 88 + type="button" 89 + class="btn" 90 + hx-get="/{{ .RepoInfo.FullName }}/pulls/new/compare-forks" 91 + hx-target="#patch-strategy" 92 + hx-swap="innerHTML" 93 + {{ if eq .Strategy "fork" }} 94 + hx-trigger="click, load" 95 + hx-vals='js:{...getQueryParams()}' 96 + {{ end }} 97 + > 98 + compare forks 99 + </button> 104 100 105 - <div id="patch-error" class="error dark:text-red-300"></div> 106 - </div> 107 101 108 - <div> 109 - <label for="title" class="dark:text-white">write a title</label> 102 + </nav> 103 + <section id="patch-strategy" class="flex flex-col gap-2"> 104 + {{ if eq .Strategy "patch" }} 105 + {{ template "repo/pulls/fragments/pullPatchUpload" . }} 106 + {{ else if eq .Strategy "branch" }} 107 + {{ template "repo/pulls/fragments/pullCompareBranches" . }} 108 + {{ else }} 109 + {{ template "repo/pulls/fragments/pullPatchUpload" . }} 110 + {{ end }} 111 + </section> 110 112 111 - <input 112 - type="text" 113 - name="title" 114 - id="title" 115 - value="{{ .Title }}" 116 - class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600" 117 - placeholder="One-line summary of your change." /> 118 - </div> 113 + <div id="patch-error" class="error dark:text-red-300"></div> 114 + </div> 119 115 120 - <div> 121 - <label for="body" class="dark:text-white">add a description</label> 116 + <div> 117 + <label for="title" class="dark:text-white">write a title</label> 122 118 123 - <textarea 124 - name="body" 125 - id="body" 126 - rows="6" 127 - class="w-full resize-y dark:bg-gray-700 dark:text-white dark:border-gray-600" 128 - placeholder="Describe your change. Markdown is supported."> 129 - {{ .Body }}</textarea 130 - > 131 - </div> 119 + <input 120 + type="text" 121 + name="title" 122 + id="title" 123 + value="{{ .Title }}" 124 + class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600" 125 + placeholder="One-line summary of your change." 126 + /> 127 + </div> 132 128 133 - <div class="flex justify-start items-center gap-2 mt-4"> 134 - <button type="submit" class="btn-create flex items-center gap-2"> 135 - {{ i "git-pull-request-create" "w-4 h-4" }} 136 - create pull 137 - <span id="create-pull-spinner" class="group"> 138 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 139 - </span> 140 - </button> 141 - </div> 142 - </div> 143 - <div id="pull" class="error dark:text-red-300"></div> 144 - </form> 129 + <div> 130 + <label for="body" class="dark:text-white" 131 + >add a description</label 132 + > 133 + 134 + <textarea 135 + name="body" 136 + id="body" 137 + rows="6" 138 + class="w-full resize-y dark:bg-gray-700 dark:text-white dark:border-gray-600" 139 + placeholder="Describe your change. Markdown is supported." 140 + >{{ .Body }}</textarea> 141 + </div> 142 + 143 + <div class="flex justify-start items-center gap-2 mt-4"> 144 + <button type="submit" class="btn-create flex items-center gap-2"> 145 + {{ i "git-pull-request-create" "w-4 h-4" }} 146 + create pull 147 + <span id="create-pull-spinner" class="group"> 148 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 149 + </span> 150 + </button> 151 + </div> 152 + </div> 153 + <div id="pull" class="error dark:text-red-300"></div> 154 + </form> 145 155 {{ end }}
+34 -39
appview/pages/templates/repo/pulls/patch.html
··· 1 1 {{ define "title" }} 2 - patch of {{ .Pull.Title }} &middot; round #{{ .Round }} &middot; pull 3 - #{{ .Pull.PullId }} &middot; 4 - {{ .RepoInfo.FullName }} 2 + patch of {{ .Pull.Title }} &middot; round #{{ .Round }} &middot; pull #{{ .Pull.PullId }} &middot; {{ .RepoInfo.FullName }} 5 3 {{ end }} 4 + 6 5 7 6 {{ define "extrameta" }} 8 - {{ $title := printf "patch of %s &middot; pull #%d &middot; %s" .Pull.Title .Pull.PullId .RepoInfo.FullName }} 9 - {{ $url := printf "https://tangled.sh/%s/pulls/%d/round/%d" .RepoInfo.FullName .Pull.PullId .Round }} 10 - 11 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 7 + {{ $title := printf "patch of %s &middot; pull #%d &middot; %s" .Pull.Title .Pull.PullId .RepoInfo.FullName }} 8 + {{ $url := printf "https://tangled.sh/%s/pulls/%d/round/%d" .RepoInfo.FullName .Pull.PullId .Round }} 9 + 10 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 12 11 {{ end }} 13 12 13 + 14 14 {{ define "content" }} 15 - <section> 15 + <section> 16 16 <section 17 - class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 18 - <div class="flex gap-3 items-center mb-3"> 19 - <a 20 - href="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/" 21 - class="flex items-center gap-2 font-medium"> 22 - {{ i "arrow-left" "w-5 h-5" }} 23 - back 24 - </a> 25 - <span class="select-none before:content-['\00B7']"></span> 26 - round 27 - <span class="flex items-center"> 28 - {{ i "hash" "w-4 h-4" }}{{ .Round }} 29 - </span> 30 - <span class="select-none before:content-['\00B7']"></span> 31 - <a 32 - href="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .Round }}.patch"> 33 - view raw 34 - </a> 35 - </div> 36 - <div class="border-t border-gray-200 dark:border-gray-700 my-2"></div> 37 - {{ template "repo/pulls/fragments/pullHeader" . }} 17 + class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white" 18 + > 19 + <div class="flex gap-3 items-center mb-3"> 20 + <a href="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/" class="flex items-center gap-2 font-medium"> 21 + {{ i "arrow-left" "w-5 h-5" }} 22 + back 23 + </a> 24 + <span class="select-none before:content-['\00B7']"></span> 25 + round<span class="flex items-center">{{ i "hash" "w-4 h-4" }}{{ .Round }}</span> 26 + <span class="select-none before:content-['\00B7']"></span> 27 + <a href="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .Round }}.patch"> 28 + view raw 29 + </a> 30 + </div> 31 + <div class="border-t border-gray-200 dark:border-gray-700 my-2"></div> 32 + {{ template "repo/pulls/fragments/pullHeader" . }} 38 33 </section> 39 - </section> 34 + </section> 40 35 {{ end }} 41 36 42 37 {{ define "topbarLayout" }} ··· 47 52 {{ end }} 48 53 49 54 {{ block "contentAfterLayout" . }} 50 - <div class="flex-grow grid grid-cols-1 md:grid-cols-12 gap-4"> 51 - <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> 52 - {{ block "contentAfterLeft" . }}{{ end }} 53 - </div> 54 - <main class="col-span-1 md:col-span-10"> 55 - {{ block "contentAfter" . }}{{ end }} 56 - </main> 55 + <div class="flex-grow grid grid-cols-1 md:grid-cols-12 gap-4"> 56 + <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> 57 + {{ block "contentAfterLeft" . }} {{ end }} 57 58 </div> 59 + <main class="col-span-1 md:col-span-10"> 60 + {{ block "contentAfter" . }}{{ end }} 61 + </main> 62 + </div> 58 63 {{ end }} 59 64 </div> 60 65 {{ end }} ··· 67 72 68 73 {{ define "contentAfter" }} 69 74 {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff .DiffOpts) }} 70 - {{ end }} 75 + {{end}} 71 76 72 77 {{ define "contentAfterLeft" }} 73 78 <div class="flex flex-col gap-4 col-span-1 md:col-span-2"> ··· 76 81 <div class="sticky top-0 flex-grow max-h-screen"> 77 82 {{ template "repo/fragments/diffChangedFiles" .Diff }} 78 83 </div> 79 - {{ end }} 84 + {{end}}
+153 -204
appview/pages/templates/repo/pulls/pull.html
··· 1 1 {{ define "title" }} 2 - {{ .Pull.Title }} &middot; pull #{{ .Pull.PullId }} &middot; 3 - {{ .RepoInfo.FullName }} 2 + {{ .Pull.Title }} &middot; pull #{{ .Pull.PullId }} &middot; {{ .RepoInfo.FullName }} 4 3 {{ end }} 5 4 6 5 {{ define "extrameta" }} 7 - {{ $title := printf "%s &middot; pull #%d &middot; %s" .Pull.Title .Pull.PullId .RepoInfo.FullName }} 8 - {{ $url := printf "https://tangled.sh/%s/pulls/%d" .RepoInfo.FullName .Pull.PullId }} 6 + {{ $title := printf "%s &middot; pull #%d &middot; %s" .Pull.Title .Pull.PullId .RepoInfo.FullName }} 7 + {{ $url := printf "https://tangled.sh/%s/pulls/%d" .RepoInfo.FullName .Pull.PullId }} 9 8 10 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 9 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 11 10 {{ end }} 11 + 12 12 13 13 {{ define "repoContent" }} 14 14 {{ template "repo/pulls/fragments/pullHeader" . }} ··· 21 21 {{ end }} 22 22 23 23 {{ define "repoAfter" }} 24 - <section id="submissions" class="mt-4"> 25 - <div class="flex flex-col gap-4"> 26 - {{ block "submissions" . }}{{ end }} 27 - </div> 28 - </section> 24 + <section id="submissions" class="mt-4"> 25 + <div class="flex flex-col gap-4"> 26 + {{ block "submissions" . }} {{ end }} 27 + </div> 28 + </section> 29 29 30 - <div id="pull-close"></div> 31 - <div id="pull-reopen"></div> 30 + <div id="pull-close"></div> 31 + <div id="pull-reopen"></div> 32 32 {{ end }} 33 33 34 34 {{ define "submissions" }} ··· 37 37 {{ $repoName := .RepoInfo.FullName }} 38 38 {{ range $idx, $item := .Pull.Submissions }} 39 39 {{ with $item }} 40 - <details {{ if eq $idx $lastIdx }}open{{ end }}> 41 - <summary 42 - id="round-#{{ .RoundNumber }}" 43 - class="list-none cursor-pointer"> 40 + <details {{ if eq $idx $lastIdx }}open{{ end }}> 41 + <summary id="round-#{{ .RoundNumber }}" class="list-none cursor-pointer"> 44 42 <div class="flex flex-wrap gap-2 items-center"> 45 43 <!-- round number --> 46 - <div 47 - class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-3 py-2 dark:text-white"> 48 - <span class="flex items-center"> 49 - {{ i "hash" "w-4 h-4" }}{{ .RoundNumber }} 50 - </span> 44 + <div class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-3 py-2 dark:text-white"> 45 + <span class="flex items-center">{{ i "hash" "w-4 h-4" }}{{ .RoundNumber }}</span> 51 46 </div> 52 47 <!-- round summary --> 53 - <div 54 - class="rounded drop-shadow-sm bg-white dark:bg-gray-800 p-2 text-gray-500 dark:text-gray-400"> 48 + <div class="rounded drop-shadow-sm bg-white dark:bg-gray-800 p-2 text-gray-500 dark:text-gray-400"> 55 49 <span class="gap-1 flex items-center"> 56 50 {{ $owner := resolve $.Pull.OwnerDid }} 57 51 {{ $re := "re" }} 58 52 {{ if eq .RoundNumber 0 }} 59 53 {{ $re = "" }} 60 54 {{ end }} 61 - <span class="hidden md:inline">{{ $re }}submitted</span> 62 - by 63 - {{ template "user/fragments/picHandleLink" $.Pull.OwnerDid }} 55 + <span class="hidden md:inline">{{$re}}submitted</span> 56 + by {{ template "user/fragments/picHandleLink" $.Pull.OwnerDid }} 64 57 <span class="select-none before:content-['\00B7']"></span> 65 - <a 66 - class="text-gray-500 dark:text-gray-400 hover:text-gray-500" 67 - href="#round-#{{ .RoundNumber }}"> 68 - {{ template "repo/fragments/shortTime" .Created }} 69 - </a> 58 + <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500" href="#round-#{{ .RoundNumber }}">{{ template "repo/fragments/shortTime" .Created }}</a> 70 59 <span class="select-none before:content-['·']"></span> 71 60 {{ $s := "s" }} 72 61 {{ if eq (len .Comments) 1 }} 73 62 {{ $s = "" }} 74 63 {{ end }} 75 - {{ len .Comments }} 76 - comment{{ $s }} 64 + {{ len .Comments }} comment{{$s}} 77 65 </span> 78 66 </div> 79 67 80 - <a 81 - class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group" 82 - hx-boost="true" 83 - href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{ .RoundNumber }}"> 68 + <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group" 69 + hx-boost="true" 70 + href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{.RoundNumber}}"> 84 71 {{ i "file-diff" "w-4 h-4" }} 85 72 <span class="hidden md:inline">diff</span> 86 73 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 87 74 </a> 88 75 {{ if not (eq .RoundNumber 0) }} 89 - <a 90 - class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group" 91 - hx-boost="true" 92 - href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{ .RoundNumber }}/interdiff"> 93 - {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }} 94 - <span class="hidden md:inline">interdiff</span> 95 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 96 - </a> 97 - <span id="interdiff-error-{{ .RoundNumber }}"></span> 76 + <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group" 77 + hx-boost="true" 78 + href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{.RoundNumber}}/interdiff"> 79 + {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }} 80 + <span class="hidden md:inline">interdiff</span> 81 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 82 + </a> 83 + <span id="interdiff-error-{{.RoundNumber}}"></span> 98 84 {{ end }} 99 85 </div> 100 86 </summary> 101 87 102 88 {{ if .IsFormatPatch }} 103 - {{ $patches := .AsFormatPatch }} 104 - {{ $round := .RoundNumber }} 105 - <details 106 - class="group py-2 md:ml-[3.5rem] text-gray-500 dark:text-gray-400 flex flex-col gap-2 relative text-sm"> 107 - <summary 108 - class="py-1 list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 109 - {{ $s := "s" }} 110 - {{ if eq (len $patches) 1 }} 111 - {{ $s = "" }} 112 - {{ end }} 113 - <div class="group-open:hidden flex items-center gap-2 ml-2"> 114 - {{ i "chevrons-up-down" "w-4 h-4" }} expand 115 - {{ len $patches }} 116 - commit{{ $s }} 117 - </div> 118 - <div class="hidden group-open:flex items-center gap-2 ml-2"> 119 - {{ i "chevrons-down-up" "w-4 h-4" }} hide 120 - {{ len $patches }} 121 - commit{{ $s }} 122 - </div> 123 - </summary> 124 - {{ range $patches }} 125 - <div 126 - id="commit-{{ .SHA }}" 127 - class="py-1 px-2 relative w-full md:max-w-3/5 md:w-fit flex flex-col"> 128 - <div class="flex items-center gap-2"> 129 - {{ i "git-commit-horizontal" "w-4 h-4" }} 130 - <div class="text-sm text-gray-500 dark:text-gray-400"> 131 - <!-- attempt to resolve $fullRepo: this is possible only on non-deleted forks and branches --> 132 - {{ $fullRepo := "" }} 133 - {{ if and $.Pull.IsForkBased $.Pull.PullSource.Repo }} 134 - {{ $fullRepo = printf "%s/%s" $owner $.Pull.PullSource.Repo.Name }} 135 - {{ else if $.Pull.IsBranchBased }} 136 - {{ $fullRepo = $.RepoInfo.FullName }} 137 - {{ end }} 138 - 139 - 140 - <!-- if $fullRepo was resolved, link to it, otherwise just span without a link --> 141 - {{ if $fullRepo }} 142 - <a 143 - href="/{{ $fullRepo }}/commit/{{ .SHA }}" 144 - class="font-mono text-gray-500 dark:text-gray-400"> 145 - {{ slice .SHA 0 8 }} 146 - </a> 147 - {{ else }} 148 - <span class="font-mono">{{ slice .SHA 0 8 }}</span> 149 - {{ end }} 150 - </div> 151 - <div class="flex items-center"> 152 - <span>{{ .Title }}</span> 153 - {{ if gt (len .Body) 0 }} 154 - <button 155 - class="py-1/2 px-1 mx-2 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600" 156 - hx-on:click="document.getElementById('body-{{ $round }}-{{ .SHA }}').classList.toggle('hidden')"> 157 - {{ i "ellipsis" "w-3 h-3" }} 158 - </button> 159 - {{ end }} 160 - </div> 161 - </div> 162 - {{ if gt (len .Body) 0 }} 163 - <p 164 - id="body-{{ $round }}-{{ .SHA }}" 165 - class="hidden mt-1 text-sm pb-2"> 166 - {{ nl2br .Body }} 167 - </p> 168 - {{ end }} 169 - </div> 89 + {{ $patches := .AsFormatPatch }} 90 + {{ $round := .RoundNumber }} 91 + <details class="group py-2 md:ml-[3.5rem] text-gray-500 dark:text-gray-400 flex flex-col gap-2 relative text-sm"> 92 + <summary class="py-1 list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 93 + {{ $s := "s" }} 94 + {{ if eq (len $patches) 1 }} 95 + {{ $s = "" }} 170 96 {{ end }} 171 - </details> 97 + <div class="group-open:hidden flex items-center gap-2 ml-2"> 98 + {{ i "chevrons-up-down" "w-4 h-4" }} expand {{ len $patches }} commit{{$s}} 99 + </div> 100 + <div class="hidden group-open:flex items-center gap-2 ml-2"> 101 + {{ i "chevrons-down-up" "w-4 h-4" }} hide {{ len $patches }} commit{{$s}} 102 + </div> 103 + </summary> 104 + {{ range $patches }} 105 + <div id="commit-{{.SHA}}" class="py-1 px-2 relative w-full md:max-w-3/5 md:w-fit flex flex-col"> 106 + <div class="flex items-center gap-2"> 107 + {{ i "git-commit-horizontal" "w-4 h-4" }} 108 + <div class="text-sm text-gray-500 dark:text-gray-400"> 109 + <!-- attempt to resolve $fullRepo: this is possible only on non-deleted forks and branches --> 110 + {{ $fullRepo := "" }} 111 + {{ if and $.Pull.IsForkBased $.Pull.PullSource.Repo }} 112 + {{ $fullRepo = printf "%s/%s" $owner $.Pull.PullSource.Repo.Name }} 113 + {{ else if $.Pull.IsBranchBased }} 114 + {{ $fullRepo = $.RepoInfo.FullName }} 115 + {{ end }} 116 + 117 + <!-- if $fullRepo was resolved, link to it, otherwise just span without a link --> 118 + {{ if $fullRepo }} 119 + <a href="/{{ $fullRepo }}/commit/{{ .SHA }}" class="font-mono text-gray-500 dark:text-gray-400">{{ slice .SHA 0 8 }}</a> 120 + {{ else }} 121 + <span class="font-mono">{{ slice .SHA 0 8 }}</span> 122 + {{ end }} 123 + </div> 124 + <div class="flex items-center"> 125 + <span>{{ .Title }}</span> 126 + {{ if gt (len .Body) 0 }} 127 + <button 128 + class="py-1/2 px-1 mx-2 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600" 129 + hx-on:click="document.getElementById('body-{{$round}}-{{.SHA}}').classList.toggle('hidden')" 130 + > 131 + {{ i "ellipsis" "w-3 h-3" }} 132 + </button> 133 + {{ end }} 134 + </div> 135 + </div> 136 + {{ if gt (len .Body) 0 }} 137 + <p id="body-{{$round}}-{{.SHA}}" class="hidden mt-1 text-sm pb-2"> 138 + {{ nl2br .Body }} 139 + </p> 140 + {{ end }} 141 + </div> 142 + {{ end }} 143 + </details> 172 144 {{ end }} 173 145 174 146 175 147 <div class="md:pl-[3.5rem] flex flex-col gap-2 mt-2 relative"> 176 148 {{ range $cidx, $c := .Comments }} 177 - <div 178 - id="comment-{{ $c.ID }}" 179 - class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full md:max-w-3/5 md:w-fit"> 149 + <div id="comment-{{$c.ID}}" class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full md:max-w-3/5 md:w-fit"> 180 150 {{ if gt $cidx 0 }} 181 - <div 182 - class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div> 151 + <div class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div> 183 152 {{ end }} 184 - <div 185 - class="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1"> 153 + <div class="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1"> 186 154 {{ template "user/fragments/picHandleLink" $c.OwnerDid }} 187 155 <span class="before:content-['·']"></span> 188 - <a 189 - class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" 190 - href="#comment-{{ .ID }}"> 191 - {{ template "repo/fragments/time" $c.Created }} 192 - </a> 156 + <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="#comment-{{.ID}}">{{ template "repo/fragments/time" $c.Created }}</a> 193 157 </div> 194 158 <div class="prose dark:prose-invert"> 195 159 {{ $c.Body | markdown }} ··· 161 197 </div> 162 198 {{ end }} 163 199 164 - {{ block "pipelineStatus" (list $ .) }}{{ end }} 200 + {{ block "pipelineStatus" (list $ .) }} {{ end }} 165 201 166 202 {{ if eq $lastIdx .RoundNumber }} 167 - {{ block "mergeStatus" $ }}{{ end }} 168 - {{ block "resubmitStatus" $ }}{{ end }} 203 + {{ block "mergeStatus" $ }} {{ end }} 204 + {{ block "resubmitStatus" $ }} {{ end }} 169 205 {{ end }} 170 206 171 207 {{ if $.LoggedInUser }} 172 208 {{ template "repo/pulls/fragments/pullActions" (dict "LoggedInUser" $.LoggedInUser "Pull" $.Pull "RepoInfo" $.RepoInfo "RoundNumber" .RoundNumber "MergeCheck" $.MergeCheck "ResubmitCheck" $.ResubmitCheck "Stack" $.Stack) }} 173 209 {{ else }} 174 - <div 175 - class="bg-white dark:bg-gray-800 rounded drop-shadow-sm px-6 py-4 w-fit dark:text-white"> 176 - <div 177 - class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div> 178 - <a href="/login" class="underline">login</a> 179 - to join the discussion 210 + <div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm px-6 py-4 w-fit dark:text-white"> 211 + <div class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div> 212 + <a href="/login" class="underline">login</a> to join the discussion 180 213 </div> 181 214 {{ end }} 182 215 </div> 183 - </details> 216 + </details> 184 217 {{ end }} 185 218 {{ end }} 186 219 {{ end }} 187 220 188 221 {{ define "mergeStatus" }} 189 222 {{ if .Pull.State.IsClosed }} 190 - <div 191 - class="bg-gray-50 dark:bg-gray-700 border border-black dark:border-gray-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 192 - <div class="flex items-center gap-2 text-black dark:text-white"> 193 - {{ i "ban" "w-4 h-4" }} 194 - <span class="font-medium">closed without merging</span> 195 - </div> 223 + <div class="bg-gray-50 dark:bg-gray-700 border border-black dark:border-gray-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 224 + <div class="flex items-center gap-2 text-black dark:text-white"> 225 + {{ i "ban" "w-4 h-4" }} 226 + <span class="font-medium">closed without merging</span 227 + > 196 228 </div> 229 + </div> 197 230 {{ else if .Pull.State.IsMerged }} 198 - <div 199 - class="bg-purple-50 dark:bg-purple-900 border border-purple-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 200 - <div class="flex items-center gap-2 text-purple-500 dark:text-purple-300"> 201 - {{ i "git-merge" "w-4 h-4" }} 202 - <span class="font-medium">pull request successfully merged</span> 203 - </div> 231 + <div class="bg-purple-50 dark:bg-purple-900 border border-purple-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 232 + <div class="flex items-center gap-2 text-purple-500 dark:text-purple-300"> 233 + {{ i "git-merge" "w-4 h-4" }} 234 + <span class="font-medium">pull request successfully merged</span 235 + > 204 236 </div> 237 + </div> 205 238 {{ else if .Pull.State.IsDeleted }} 206 - <div 207 - class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 208 - <div class="flex items-center gap-2 text-red-500 dark:text-red-300"> 209 - {{ i "git-pull-request-closed" "w-4 h-4" }} 210 - <span class="font-medium"> 211 - This pull has been deleted (possibly by jj abandon or jj squash) 212 - </span> 213 - </div> 239 + <div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 240 + <div class="flex items-center gap-2 text-red-500 dark:text-red-300"> 241 + {{ i "git-pull-request-closed" "w-4 h-4" }} 242 + <span class="font-medium">This pull has been deleted (possibly by jj abandon or jj squash)</span> 214 243 </div> 244 + </div> 215 245 {{ else if and .MergeCheck .MergeCheck.Error }} 216 - <div 217 - class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 246 + <div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 218 247 <div class="flex items-center gap-2 text-red-500 dark:text-red-300"> 219 248 {{ i "triangle-alert" "w-4 h-4" }} 220 249 <span class="font-medium">{{ .MergeCheck.Error }}</span> 221 250 </div> 222 251 </div> 223 252 {{ else if and .MergeCheck .MergeCheck.IsConflicted }} 224 - <div 225 - class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 253 + <div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 226 254 <div class="flex flex-col gap-2 text-red-500 dark:text-red-300"> 227 255 <div class="flex items-center gap-2"> 228 256 {{ i "triangle-alert" "w-4 h-4" }} ··· 224 268 <ul class="space-y-1"> 225 269 {{ range .MergeCheck.Conflicts }} 226 270 {{ if .Filename }} 227 - <li class="flex items-center"> 228 - {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }} 229 - <span class="font-mono">{{ .Filename }}</span> 230 - </li> 271 + <li class="flex items-center"> 272 + {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }} 273 + <span class="font-mono">{{ .Filename }}</span> 274 + </li> 231 275 {{ else if .Reason }} 232 - <li class="flex items-center"> 233 - {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }} 234 - <span>{{ .Reason }}</span> 235 - </li> 276 + <li class="flex items-center"> 277 + {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }} 278 + <span>{{.Reason}}</span> 279 + </li> 236 280 {{ end }} 237 281 {{ end }} 238 282 </ul> ··· 240 284 </div> 241 285 </div> 242 286 {{ else if .MergeCheck }} 243 - <div 244 - class="bg-green-50 dark:bg-green-900 border border-green-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 245 - <div class="flex items-center gap-2 text-green-500 dark:text-green-300"> 246 - {{ i "circle-check-big" "w-4 h-4" }} 247 - <span class="font-medium">no conflicts, ready to merge</span> 248 - </div> 287 + <div class="bg-green-50 dark:bg-green-900 border border-green-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 288 + <div class="flex items-center gap-2 text-green-500 dark:text-green-300"> 289 + {{ i "circle-check-big" "w-4 h-4" }} 290 + <span class="font-medium">no conflicts, ready to merge</span> 249 291 </div> 292 + </div> 250 293 {{ end }} 251 294 {{ end }} 252 295 253 296 {{ define "resubmitStatus" }} 254 297 {{ if .ResubmitCheck.Yes }} 255 - <div 256 - class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 257 - <div class="flex items-center gap-2 text-amber-500 dark:text-amber-300"> 258 - {{ i "triangle-alert" "w-4 h-4" }} 259 - <span class="font-medium"> 260 - this branch has been updated, consider resubmitting 261 - </span> 262 - </div> 298 + <div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm px-6 py-2 relative w-fit"> 299 + <div class="flex items-center gap-2 text-amber-500 dark:text-amber-300"> 300 + {{ i "triangle-alert" "w-4 h-4" }} 301 + <span class="font-medium">this branch has been updated, consider resubmitting</span> 263 302 </div> 303 + </div> 264 304 {{ end }} 265 305 {{ end }} 266 306 ··· 267 315 {{ with $pipeline }} 268 316 {{ $id := .Id }} 269 317 {{ if .Statuses }} 270 - <div 271 - class="max-w-80 grid grid-cols-1 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700"> 318 + <div class="max-w-80 grid grid-cols-1 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700"> 272 319 {{ range $name, $all := .Statuses }} 273 - <a 274 - href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" 275 - class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 276 - <div class="flex gap-2 items-center justify-between p-2"> 277 - {{ $lastStatus := $all.Latest }} 278 - {{ $kind := $lastStatus.Status.String }} 320 + <a href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 321 + <div 322 + class="flex gap-2 items-center justify-between p-2"> 323 + {{ $lastStatus := $all.Latest }} 324 + {{ $kind := $lastStatus.Status.String }} 279 325 280 - 281 - <div id="left" class="flex items-center gap-2 flex-shrink-0"> 282 - {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 283 - {{ $name }} 284 - </div> 285 - <div id="right" class="flex items-center gap-2 flex-shrink-0"> 286 - <span class="font-bold">{{ $kind }}</span> 287 - {{ if .TimeTaken }} 288 - {{ template "repo/fragments/duration" .TimeTaken }} 289 - {{ else }} 290 - {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }} 291 - {{ end }} 292 - </div> 326 + <div id="left" class="flex items-center gap-2 flex-shrink-0"> 327 + {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 328 + {{ $name }} 293 329 </div> 294 - </a> 330 + <div id="right" class="flex items-center gap-2 flex-shrink-0"> 331 + <span class="font-bold">{{ $kind }}</span> 332 + {{ if .TimeTaken }} 333 + {{ template "repo/fragments/duration" .TimeTaken }} 334 + {{ else }} 335 + {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }} 336 + {{ end }} 337 + </div> 338 + </div> 339 + </a> 295 340 {{ end }} 296 341 </div> 297 342 {{ end }}
+114 -133
appview/pages/templates/repo/pulls/pulls.html
··· 1 1 {{ define "title" }}pulls &middot; {{ .RepoInfo.FullName }}{{ end }} 2 2 3 3 {{ define "extrameta" }} 4 - {{ $title := "pulls" }} 5 - {{ $url := printf "https://tangled.sh/%s/pulls" .RepoInfo.FullName }} 4 + {{ $title := "pulls"}} 5 + {{ $url := printf "https://tangled.sh/%s/pulls" .RepoInfo.FullName }} 6 6 7 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 7 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 8 8 {{ end }} 9 9 10 10 {{ define "repoContent" }} 11 - <div class="flex justify-between items-center"> 12 - <div class="flex gap-4"> 13 - <a 14 - href="?state=open" 15 - class="flex items-center gap-2 {{ if .FilteringBy.IsOpen }} 16 - font-bold 17 - {{ else }} 18 - text-gray-500 dark:text-gray-400 19 - {{ end }}"> 20 - {{ i "git-pull-request" "w-4 h-4" }} 21 - <span>{{ .RepoInfo.Stats.PullCount.Open }} open</span> 22 - </a> 23 - <a 24 - href="?state=merged" 25 - class="flex items-center gap-2 {{ if .FilteringBy.IsMerged }} 26 - font-bold 27 - {{ else }} 28 - text-gray-500 dark:text-gray-400 29 - {{ end }}"> 30 - {{ i "git-merge" "w-4 h-4" }} 31 - <span>{{ .RepoInfo.Stats.PullCount.Merged }} merged</span> 32 - </a> 33 - <a 34 - href="?state=closed" 35 - class="flex items-center gap-2 {{ if .FilteringBy.IsClosed }} 36 - font-bold 37 - {{ else }} 38 - text-gray-500 dark:text-gray-400 39 - {{ end }}"> 40 - {{ i "ban" "w-4 h-4" }} 41 - <span>{{ .RepoInfo.Stats.PullCount.Closed }} closed</span> 42 - </a> 11 + <div class="flex justify-between items-center"> 12 + <div class="flex gap-4"> 13 + <a 14 + href="?state=open" 15 + class="flex items-center gap-2 {{ if .FilteringBy.IsOpen }}font-bold {{ else }}text-gray-500 dark:text-gray-400{{ end }}" 16 + > 17 + {{ i "git-pull-request" "w-4 h-4" }} 18 + <span>{{ .RepoInfo.Stats.PullCount.Open }} open</span> 19 + </a> 20 + <a 21 + href="?state=merged" 22 + class="flex items-center gap-2 {{ if .FilteringBy.IsMerged }}font-bold {{ else }}text-gray-500 dark:text-gray-400{{ end }}" 23 + > 24 + {{ i "git-merge" "w-4 h-4" }} 25 + <span>{{ .RepoInfo.Stats.PullCount.Merged }} merged</span> 26 + </a> 27 + <a 28 + href="?state=closed" 29 + class="flex items-center gap-2 {{ if .FilteringBy.IsClosed }}font-bold {{ else }}text-gray-500 dark:text-gray-400{{ end }}" 30 + > 31 + {{ i "ban" "w-4 h-4" }} 32 + <span>{{ .RepoInfo.Stats.PullCount.Closed }} closed</span> 33 + </a> 34 + </div> 35 + <a 36 + href="/{{ .RepoInfo.FullName }}/pulls/new" 37 + class="btn-create text-sm flex items-center gap-2 no-underline hover:no-underline hover:text-white" 38 + > 39 + {{ i "git-pull-request-create" "w-4 h-4" }} 40 + <span>new</span> 41 + </a> 43 42 </div> 44 - <a 45 - href="/{{ .RepoInfo.FullName }}/pulls/new" 46 - class="btn-create text-sm flex items-center gap-2 no-underline hover:no-underline hover:text-white"> 47 - {{ i "git-pull-request-create" "w-4 h-4" }} 48 - <span>new</span> 49 - </a> 50 - </div> 51 - <div class="error" id="pulls"></div> 43 + <div class="error" id="pulls"></div> 52 44 {{ end }} 53 45 54 46 {{ define "repoAfter" }} 55 - <div class="flex flex-col gap-2 mt-2"> 56 - {{ range .Pulls }} 57 - <div class="rounded bg-white dark:bg-gray-800"> 58 - <div class="px-6 py-4 z-5"> 59 - <div class="pb-2"> 60 - <a 61 - href="/{{ $.RepoInfo.FullName }}/pulls/{{ .PullId }}" 62 - class="dark:text-white"> 63 - {{ .Title }} 64 - <span class="text-gray-500 dark:text-gray-400"> 65 - #{{ .PullId }} 66 - </span> 67 - </a> 68 - </div> 69 - <div 70 - class="text-sm text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-1"> 71 - {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 72 - {{ $icon := "ban" }} 47 + <div class="flex flex-col gap-2 mt-2"> 48 + {{ range .Pulls }} 49 + <div class="rounded bg-white dark:bg-gray-800"> 50 + <div class="px-6 py-4 z-5"> 51 + <div class="pb-2"> 52 + <a href="/{{ $.RepoInfo.FullName }}/pulls/{{ .PullId }}" class="dark:text-white"> 53 + {{ .Title }} 54 + <span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span> 55 + </a> 56 + </div> 57 + <div class="text-sm text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-1"> 58 + {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 59 + {{ $icon := "ban" }} 73 60 74 - {{ if .State.IsOpen }} 75 - {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 76 - {{ $icon = "git-pull-request" }} 77 - {{ else if .State.IsMerged }} 78 - {{ $bgColor = "bg-purple-600 dark:bg-purple-700" }} 79 - {{ $icon = "git-merge" }} 80 - {{ end }} 61 + {{ if .State.IsOpen }} 62 + {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 63 + {{ $icon = "git-pull-request" }} 64 + {{ else if .State.IsMerged }} 65 + {{ $bgColor = "bg-purple-600 dark:bg-purple-700" }} 66 + {{ $icon = "git-merge" }} 67 + {{ end }} 81 68 82 69 83 - <span 84 - class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm"> 85 - {{ i $icon "w-3 h-3 mr-1.5 text-white" }} 86 - <span class="text-white">{{ .State.String }}</span> 87 - </span> 70 + <span 71 + class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm" 72 + > 73 + {{ i $icon "w-3 h-3 mr-1.5 text-white" }} 74 + <span class="text-white">{{ .State.String }}</span> 75 + </span> 88 76 89 - <span class="ml-1"> 90 - {{ template "user/fragments/picHandleLink" .OwnerDid }} 91 - </span> 77 + <span class="ml-1"> 78 + {{ template "user/fragments/picHandleLink" .OwnerDid }} 79 + </span> 92 80 93 - <span class="before:content-['·']"> 94 - {{ template "repo/fragments/time" .Created }} 95 - </span> 96 - 97 - {{ $latestRound := .LastRoundNumber }} 98 - {{ $lastSubmission := index .Submissions $latestRound }} 81 + <span class="before:content-['·']"> 82 + {{ template "repo/fragments/time" .Created }} 83 + </span> 99 84 100 85 101 - <span class="before:content-['·']"> 102 - {{ $commentCount := len $lastSubmission.Comments }} 103 - {{ $s := "s" }} 104 - {{ if eq $commentCount 1 }} 105 - {{ $s = "" }} 106 - {{ end }} 86 + {{ $latestRound := .LastRoundNumber }} 87 + {{ $lastSubmission := index .Submissions $latestRound }} 107 88 108 - {{ len $lastSubmission.Comments }} 109 - comment{{ $s }} 110 - </span> 89 + <span class="before:content-['·']"> 90 + {{ $commentCount := len $lastSubmission.Comments }} 91 + {{ $s := "s" }} 92 + {{ if eq $commentCount 1 }} 93 + {{ $s = "" }} 94 + {{ end }} 111 95 112 - <span class="before:content-['·']"> 113 - round 114 - <span class="font-mono"> 115 - #{{ .LastRoundNumber }} 116 - </span> 117 - </span> 96 + {{ len $lastSubmission.Comments}} comment{{$s}} 97 + </span> 118 98 119 - {{ $pipeline := index $.Pipelines .LatestSha }} 120 - {{ if and $pipeline $pipeline.Id }} 121 - <span class="before:content-['·']"></span> 122 - {{ template "repo/pipelines/fragments/pipelineSymbol" $pipeline }} 123 - {{ end }} 124 - </div> 125 - </div> 126 - {{ if .StackId }} 127 - {{ $otherPulls := index $.Stacks .StackId }} 128 - {{ if gt (len $otherPulls) 0 }} 129 - <details class="bg-white dark:bg-gray-800 group"> 130 - <summary 131 - class="pb-4 px-6 text-xs list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 132 - {{ $s := "s" }} 133 - {{ if eq (len $otherPulls) 1 }} 134 - {{ $s = "" }} 99 + <span class="before:content-['·']"> 100 + round 101 + <span class="font-mono"> 102 + #{{ .LastRoundNumber }} 103 + </span> 104 + </span> 105 + 106 + {{ $pipeline := index $.Pipelines .LatestSha }} 107 + {{ if and $pipeline $pipeline.Id }} 108 + <span class="before:content-['·']"></span> 109 + {{ template "repo/pipelines/fragments/pipelineSymbol" $pipeline }} 110 + {{ end }} 111 + </div> 112 + </div> 113 + {{ if .StackId }} 114 + {{ $otherPulls := index $.Stacks .StackId }} 115 + {{ if gt (len $otherPulls) 0 }} 116 + <details class="bg-white dark:bg-gray-800 group"> 117 + <summary class="pb-4 px-6 text-xs list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 118 + {{ $s := "s" }} 119 + {{ if eq (len $otherPulls) 1 }} 120 + {{ $s = "" }} 121 + {{ end }} 122 + <div class="group-open:hidden flex items-center gap-2"> 123 + {{ i "chevrons-up-down" "w-4 h-4" }} expand {{ len $otherPulls }} pull{{$s}} in this stack 124 + </div> 125 + <div class="hidden group-open:flex items-center gap-2"> 126 + {{ i "chevrons-down-up" "w-4 h-4" }} hide {{ len $otherPulls }} pull{{$s}} in this stack 127 + </div> 128 + </summary> 129 + {{ block "pullList" (list $otherPulls $) }} {{ end }} 130 + </details> 135 131 {{ end }} 136 - <div class="group-open:hidden flex items-center gap-2"> 137 - {{ i "chevrons-up-down" "w-4 h-4" }} expand 138 - {{ len $otherPulls }} pull{{ $s }} in this stack 139 - </div> 140 - <div class="hidden group-open:flex items-center gap-2"> 141 - {{ i "chevrons-down-up" "w-4 h-4" }} hide 142 - {{ len $otherPulls }} pull{{ $s }} in this stack 143 - </div> 144 - </summary> 145 - {{ block "pullList" (list $otherPulls $) }}{{ end }} 146 - </details> 147 - {{ end }} 132 + {{ end }} 133 + </div> 148 134 {{ end }} 149 - </div> 150 - {{ end }} 151 - </div> 135 + </div> 152 136 {{ end }} 153 137 154 138 {{ define "pullList" }} 155 139 {{ $list := index . 0 }} 156 140 {{ $root := index . 1 }} 157 - <div 158 - class="grid grid-cols-1 rounded-b border-b border-t border-gray-200 dark:border-gray-900 divide-y divide-gray-200 dark:divide-gray-900"> 141 + <div class="grid grid-cols-1 rounded-b border-b border-t border-gray-200 dark:border-gray-900 divide-y divide-gray-200 dark:divide-gray-900"> 159 142 {{ range $pull := $list }} 160 143 {{ $pipeline := index $root.Pipelines $pull.LatestSha }} 161 - <a 162 - href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $pull.PullId }}" 163 - class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 144 + <a href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $pull.PullId }}" class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 164 145 <div class="flex gap-2 items-center px-6"> 165 146 <div class="flex-grow min-w-0 w-full py-2"> 166 147 {{ template "repo/pulls/fragments/summarizedHeader" (list $pull $pipeline) }}
+39 -45
appview/pages/templates/repo/settings/access.html
··· 1 - {{ define "title" }} 2 - {{ .Tab }} settings &middot; 3 - {{ .RepoInfo.FullName }} 4 - {{ end }} 1 + {{ define "title" }}{{ .Tab }} settings &middot; {{ .RepoInfo.FullName }}{{ end }} 5 2 6 3 {{ define "repoContent" }} 7 4 <section class="w-full grid grid-cols-1 md:grid-cols-4 gap-2"> ··· 16 19 <div class="col-span-1"> 17 20 <h2 class="text-sm pb-2 uppercase font-bold">Collaborators</h2> 18 21 <p class="text-gray-500 dark:text-gray-400"> 19 - Any user added as a collaborator will be able to push commits and tags 20 - to this repository, upload releases, and workflows. 22 + Any user added as a collaborator will be able to push commits and tags to this repository, upload releases, and workflows. 21 23 </p> 22 24 </div> 23 25 {{ template "collaboratorsGrid" . }} ··· 34 38 <img 35 39 src="{{ fullAvatar .Handle }}" 36 40 alt="{{ .Handle }}" 37 - class="rounded-full h-10 w-10 border border-gray-300 dark:border-gray-600 flex-shrink-0" /> 41 + class="rounded-full h-10 w-10 border border-gray-300 dark:border-gray-600 flex-shrink-0"/> 38 42 39 43 <div class="flex-1 min-w-0"> 40 44 <a href="/{{ .Handle }}" class="block truncate"> ··· 54 58 popovertarget="add-collaborator-modal" 55 59 popovertargetaction="toggle"> 56 60 <div class="flex items-center gap-3"> 57 - <div 58 - class="w-10 h-10 rounded-full bg-gray-100 dark:bg-gray-700 flex items-center justify-center"> 61 + <div class="w-10 h-10 rounded-full bg-gray-100 dark:bg-gray-700 flex items-center justify-center"> 59 62 {{ i "user-plus" "size-4" }} 60 63 </div> 61 64 ··· 72 77 {{ end }} 73 78 74 79 {{ define "addCollaboratorModal" }} 75 - <form 76 - hx-put="/{{ $.RepoInfo.FullName }}/settings/collaborator" 77 - hx-indicator="#spinner" 78 - hx-swap="none" 79 - class="flex flex-col gap-2"> 80 - <label for="add-collaborator" class="uppercase p-0">ADD COLLABORATOR</label> 81 - <p class="text-sm text-gray-500 dark:text-gray-400"> 82 - Collaborators can push to this repository. 83 - </p> 84 - <input 85 - type="text" 86 - id="add-collaborator" 87 - name="collaborator" 88 - required 89 - placeholder="@foo.bsky.social" /> 90 - <div class="flex gap-2 pt-2"> 91 - <button 92 - type="button" 93 - popovertarget="add-collaborator-modal" 94 - popovertargetaction="hide" 95 - class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"> 96 - {{ i "x" "size-4" }} cancel 97 - </button> 98 - <button type="submit" class="btn w-1/2 flex items-center"> 99 - <span class="inline-flex gap-2 items-center"> 100 - {{ i "user-plus" "size-4" }} add 101 - </span> 102 - <span id="spinner" class="group"> 103 - {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 104 - </span> 105 - </button> 106 - </div> 107 - <div 108 - id="add-collaborator-error" 109 - class="text-red-500 dark:text-red-400"></div> 110 - </form> 80 + <form 81 + hx-put="/{{ $.RepoInfo.FullName }}/settings/collaborator" 82 + hx-indicator="#spinner" 83 + hx-swap="none" 84 + class="flex flex-col gap-2" 85 + > 86 + <label for="add-collaborator" class="uppercase p-0"> 87 + ADD COLLABORATOR 88 + </label> 89 + <p class="text-sm text-gray-500 dark:text-gray-400">Collaborators can push to this repository.</p> 90 + <input 91 + type="text" 92 + id="add-collaborator" 93 + name="collaborator" 94 + required 95 + placeholder="@foo.bsky.social" 96 + /> 97 + <div class="flex gap-2 pt-2"> 98 + <button 99 + type="button" 100 + popovertarget="add-collaborator-modal" 101 + popovertargetaction="hide" 102 + class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300" 103 + > 104 + {{ i "x" "size-4" }} cancel 105 + </button> 106 + <button type="submit" class="btn w-1/2 flex items-center"> 107 + <span class="inline-flex gap-2 items-center">{{ i "user-plus" "size-4" }} add</span> 108 + <span id="spinner" class="group"> 109 + {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 110 + </span> 111 + </button> 112 + </div> 113 + <div id="add-collaborator-error" class="text-red-500 dark:text-red-400"></div> 114 + </form> 111 115 {{ end }}
+8 -15
appview/pages/templates/repo/settings/fragments/secretListing.html
··· 1 1 {{ define "repo/settings/fragments/secretListing" }} 2 2 {{ $root := index . 0 }} 3 3 {{ $secret := index . 1 }} 4 - <div 5 - id="secret-{{ $secret.Key }}" 6 - class="flex items-center justify-between p-2"> 7 - <div 8 - class="hover:no-underline flex flex-col gap-1 text-sm min-w-0 max-w-[80%]"> 4 + <div id="secret-{{$secret.Key}}" class="flex items-center justify-between p-2"> 5 + <div class="hover:no-underline flex flex-col gap-1 text-sm min-w-0 max-w-[80%]"> 9 6 <span class="font-mono"> 10 7 {{ $secret.Key }} 11 8 </span> 12 - <div 13 - class="flex flex-wrap text items-center gap-1 text-gray-500 dark:text-gray-400"> 9 + <div class="flex flex-wrap text items-center gap-1 text-gray-500 dark:text-gray-400"> 14 10 <span>added by</span> 15 - <span> 16 - {{ template "user/fragments/picHandleLink" $secret.CreatedBy }} 17 - </span> 11 + <span>{{ template "user/fragments/picHandleLink" $secret.CreatedBy }}</span> 18 12 <span class="before:content-['·'] before:select-none"></span> 19 - <span> 20 - {{ template "repo/fragments/shortTimeAgo" $secret.CreatedAt }} 21 - </span> 13 + <span>{{ template "repo/fragments/shortTimeAgo" $secret.CreatedAt }}</span> 22 14 </div> 23 15 </div> 24 16 <button ··· 19 27 hx-delete="/{{ $root.RepoInfo.FullName }}/settings/secrets" 20 28 hx-swap="none" 21 29 hx-vals='{"key": "{{ $secret.Key }}"}' 22 - hx-confirm="Are you sure you want to delete the secret {{ $secret.Key }}?"> 30 + hx-confirm="Are you sure you want to delete the secret {{ $secret.Key }}?" 31 + > 23 32 {{ i "trash-2" "w-5 h-5" }} 24 - <span class="hidden md:inline">delete</span> 33 + <span class="hidden md:inline">delete</span> 25 34 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 26 35 </button> 27 36 </div>
+7 -15
appview/pages/templates/repo/settings/fragments/sidebar.html
··· 1 1 {{ define "repo/settings/fragments/sidebar" }} 2 2 {{ $active := .Tab }} 3 3 {{ $tabs := .Tabs }} 4 - <div 5 - class="sticky top-2 grid grid-cols-1 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700 shadow-inner"> 4 + <div class="sticky top-2 grid grid-cols-1 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700 shadow-inner"> 6 5 {{ $activeTab := "bg-white dark:bg-gray-700 drop-shadow-sm" }} 7 6 {{ $inactiveTab := "bg-gray-100 dark:bg-gray-800" }} 8 7 {{ range $tabs }} 9 - <a 10 - href="/{{ $.RepoInfo.FullName }}/settings?tab={{ .Name }}" 11 - class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 12 - <div 13 - class="flex gap-3 items-center p-2 {{ if eq .Name $active }} 14 - {{ $activeTab }} 15 - {{ else }} 16 - {{ $inactiveTab }} 17 - {{ end }}"> 18 - {{ i .Icon "size-4" }} 19 - {{ .Name }} 20 - </div> 21 - </a> 8 + <a href="/{{ $.RepoInfo.FullName }}/settings?tab={{.Name}}" class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 9 + <div class="flex gap-3 items-center p-2 {{ if eq .Name $active }} {{ $activeTab }} {{ else }} {{ $inactiveTab }} {{ end }}"> 10 + {{ i .Icon "size-4" }} 11 + {{ .Name }} 12 + </div> 13 + </a> 22 14 {{ end }} 23 15 </div> 24 16 {{ end }}
+23 -38
appview/pages/templates/repo/settings/general.html
··· 1 - {{ define "title" }} 2 - {{ .Tab }} settings &middot; 3 - {{ .RepoInfo.FullName }} 4 - {{ end }} 1 + {{ define "title" }}{{ .Tab }} settings &middot; {{ .RepoInfo.FullName }}{{ end }} 5 2 6 3 {{ define "repoContent" }} 7 4 <section class="w-full grid grid-cols-1 md:grid-cols-4 gap-2"> ··· 22 25 unless you specify a different branch. 23 26 </p> 24 27 </div> 25 - <form 26 - hx-put="/{{ $.RepoInfo.FullName }}/settings/branches/default" 27 - class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch"> 28 - <select 29 - id="branch" 30 - name="branch" 31 - required 32 - class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"> 33 - <option value="" disabled selected>Choose a default branch</option> 28 + <form hx-put="/{{ $.RepoInfo.FullName }}/settings/branches/default" class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch"> 29 + <select id="branch" name="branch" required class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"> 30 + <option value="" disabled selected > 31 + Choose a default branch 32 + </option> 34 33 {{ range .Branches }} 35 - <option 36 - value="{{ .Name }}" 37 - class="py-1" 38 - {{ if .IsDefault }}selected{{ end }}> 34 + <option value="{{ .Name }}" class="py-1" {{ if .IsDefault }}selected{{ end }} > 39 35 {{ .Name }} 40 36 </option> 41 37 {{ end }} ··· 43 53 44 54 {{ define "deleteRepo" }} 45 55 {{ if .RepoInfo.Roles.RepoDeleteAllowed }} 46 - <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-center"> 47 - <div class="col-span-1 md:col-span-2"> 48 - <h2 49 - class="text-sm pb-2 uppercase text-red-500 dark:text-red-400 font-bold"> 50 - Delete Repository 51 - </h2> 52 - <p class="text-red-500 dark:text-red-400 "> 53 - Deleting a repository is irreversible and permanent. Be certain before 54 - deleting a repository. 55 - </p> 56 - </div> 57 - <div class="col-span-1 md:col-span-1 md:justify-self-end"> 58 - <button 59 - class="btn group text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 flex gap-2 items-center" 60 - type="button" 61 - hx-delete="/{{ $.RepoInfo.FullName }}/settings/delete" 62 - hx-confirm="Are you sure you want to delete {{ $.RepoInfo.FullName }}?"> 56 + <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-center"> 57 + <div class="col-span-1 md:col-span-2"> 58 + <h2 class="text-sm pb-2 uppercase text-red-500 dark:text-red-400 font-bold">Delete Repository</h2> 59 + <p class="text-red-500 dark:text-red-400 "> 60 + Deleting a repository is irreversible and permanent. Be certain before deleting a repository. 61 + </p> 62 + </div> 63 + <div class="col-span-1 md:col-span-1 md:justify-self-end"> 64 + <button 65 + class="btn group text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 flex gap-2 items-center" 66 + type="button" 67 + hx-delete="/{{ $.RepoInfo.FullName }}/settings/delete" 68 + hx-confirm="Are you sure you want to delete {{ $.RepoInfo.FullName }}?"> 63 69 {{ i "trash-2" "size-4" }} 64 70 delete 65 - <span 66 - class="ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline"> 71 + <span class="ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline"> 67 72 {{ i "loader-circle" "w-4 h-4" }} 68 73 </span> 69 - </button> 70 - </div> 74 + </button> 71 75 </div> 76 + </div> 72 77 {{ end }} 73 78 {{ end }}
+53 -72
appview/pages/templates/repo/settings/pipelines.html
··· 1 - {{ define "title" }} 2 - {{ .Tab }} settings &middot; 3 - {{ .RepoInfo.FullName }} 4 - {{ end }} 1 + {{ define "title" }}{{ .Tab }} settings &middot; {{ .RepoInfo.FullName }}{{ end }} 5 2 6 3 {{ define "repoContent" }} 7 4 <section class="w-full grid grid-cols-1 md:grid-cols-4 gap-2"> ··· 22 25 <p class="text-gray-500 dark:text-gray-400"> 23 26 Choose a spindle to execute your workflows on. Only repository owners 24 27 can configure spindles. Spindles can be selfhosted, 25 - <a 26 - class="text-gray-500 dark:text-gray-400 underline" 27 - href="https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md"> 28 + <a class="text-gray-500 dark:text-gray-400 underline" href="https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md"> 28 29 click to learn more. 29 30 </a> 30 31 </p> 31 32 </div> 32 33 {{ if not $.RepoInfo.Roles.IsOwner }} 33 - <div 34 - class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch"> 34 + <div class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch"> 35 35 {{ or $.CurrentSpindle "No spindle configured" }} 36 36 </div> 37 37 {{ else }} 38 - <form 39 - hx-post="/{{ $.RepoInfo.FullName }}/settings/spindle" 40 - class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch"> 38 + <form hx-post="/{{ $.RepoInfo.FullName }}/settings/spindle" class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch"> 41 39 <select 42 40 id="spindle" 43 41 name="spindle" 44 42 required 45 43 class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"> 46 44 {{/* For some reason, we can't use an empty string in a <select> in all scenarios unless it is preceded by a disabled select?? No idea, could just be a Firefox thing? */}} 47 - <option 48 - value="[[none]]" 49 - class="py-1" 50 - {{ if not $.CurrentSpindle }}selected{{ end }}> 45 + <option value="[[none]]" class="py-1" {{ if not $.CurrentSpindle }}selected{{ end }}> 51 46 {{ if not $.CurrentSpindle }} 52 - Choose a spindle 47 + Choose a spindle 53 48 {{ else }} 54 - Disable pipelines 49 + Disable pipelines 55 50 {{ end }} 56 51 </option> 57 52 {{ range $.Spindles }} 58 - <option 59 - value="{{ . }}" 60 - class="py-1" 61 - {{ if eq . $.CurrentSpindle }}selected{{ end }}> 53 + <option value="{{ . }}" class="py-1" {{ if eq . $.CurrentSpindle }}selected{{ end }}> 62 54 {{ . }} 63 55 </option> 64 56 {{ end }} 65 57 </select> 66 - <button 67 - class="btn flex gap-2 items-center" 68 - type="submit" 69 - {{ if not $.RepoInfo.Roles.IsOwner }}disabled{{ end }}> 58 + <button class="btn flex gap-2 items-center" type="submit" {{ if not $.RepoInfo.Roles.IsOwner }}disabled{{ end }}> 70 59 {{ i "check" "size-4" }} 71 60 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 72 61 </button> ··· 66 83 <div class="col-span-1 md:col-span-2"> 67 84 <h2 class="text-sm pb-2 uppercase font-bold">SECRETS</h2> 68 85 <p class="text-gray-500 dark:text-gray-400"> 69 - Secrets are accessible in workflow runs via environment variables. 70 - Anyone with collaborator access to this repository can add and use 71 - secrets in workflow runs. 86 + Secrets are accessible in workflow runs via environment variables. Anyone 87 + with collaborator access to this repository can add and use secrets in 88 + workflow runs. 72 89 </p> 73 90 </div> 74 91 <div class="col-span-1 md:col-span-1 md:justify-self-end"> 75 92 {{ template "addSecretButton" . }} 76 93 </div> 77 94 </div> 78 - <div 79 - class="flex flex-col rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700 w-full"> 95 + <div class="flex flex-col rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700 w-full"> 80 96 {{ range .Secrets }} 81 97 {{ template "repo/settings/fragments/secretListing" (list $ .) }} 82 98 {{ else }} ··· 100 118 class="bg-white w-full md:w-96 dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 drop-shadow dark:text-white backdrop:bg-gray-400/50 dark:backdrop:bg-gray-800/50"> 101 119 {{ template "addSecretModal" . }} 102 120 </div> 103 - {{ end }} 121 + {{ end}} 104 122 105 123 {{ define "addSecretModal" }} 106 - <form 107 - hx-put="/{{ $.RepoInfo.FullName }}/settings/secrets" 108 - hx-indicator="#spinner" 109 - hx-swap="none" 110 - class="flex flex-col gap-2"> 111 - <p class="uppercase p-0">ADD SECRET</p> 112 - <p class="text-sm text-gray-500 dark:text-gray-400"> 113 - Secrets are available as environment variables in the workflow. 114 - </p> 115 - <input 116 - type="text" 117 - id="secret-key" 118 - name="key" 119 - required 120 - placeholder="SECRET_NAME" /> 121 - <textarea 122 - type="text" 123 - id="secret-value" 124 - name="value" 125 - required 126 - placeholder="secret value"></textarea> 127 - <div class="flex gap-2 pt-2"> 128 - <button 129 - type="button" 130 - popovertarget="add-secret-modal" 131 - popovertargetaction="hide" 132 - class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"> 133 - {{ i "x" "size-4" }} cancel 134 - </button> 135 - <button type="submit" class="btn w-1/2 flex items-center"> 136 - <span class="inline-flex gap-2 items-center"> 137 - {{ i "plus" "size-4" }} add 138 - </span> 139 - <span id="spinner" class="group"> 140 - {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 141 - </span> 142 - </button> 143 - </div> 144 - <div id="add-secret-error" class="text-red-500 dark:text-red-400"></div> 145 - </form> 124 + <form 125 + hx-put="/{{ $.RepoInfo.FullName }}/settings/secrets" 126 + hx-indicator="#spinner" 127 + hx-swap="none" 128 + class="flex flex-col gap-2" 129 + > 130 + <p class="uppercase p-0">ADD SECRET</p> 131 + <p class="text-sm text-gray-500 dark:text-gray-400">Secrets are available as environment variables in the workflow.</p> 132 + <input 133 + type="text" 134 + id="secret-key" 135 + name="key" 136 + required 137 + placeholder="SECRET_NAME" 138 + /> 139 + <textarea 140 + type="text" 141 + id="secret-value" 142 + name="value" 143 + required 144 + placeholder="secret value"></textarea> 145 + <div class="flex gap-2 pt-2"> 146 + <button 147 + type="button" 148 + popovertarget="add-secret-modal" 149 + popovertargetaction="hide" 150 + class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300" 151 + > 152 + {{ i "x" "size-4" }} cancel 153 + </button> 154 + <button type="submit" class="btn w-1/2 flex items-center"> 155 + <span class="inline-flex gap-2 items-center">{{ i "plus" "size-4" }} add</span> 156 + <span id="spinner" class="group"> 157 + {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 158 + </span> 159 + </button> 160 + </div> 161 + <div id="add-secret-error" class="text-red-500 dark:text-red-400"></div> 162 + </form> 146 163 {{ end }}
+74 -106
appview/pages/templates/repo/tree.html
··· 1 - {{ define "title" }} 2 - {{ range .BreadCrumbs }}{{ pathUnescape (index . 0) }}/{{ end }} at 3 - {{ .Ref }} 4 - &middot; 5 - {{ .RepoInfo.FullName }} 6 - {{ end }} 1 + {{ define "title"}}{{ range .BreadCrumbs }}{{ pathUnescape (index . 0)}}/{{ end }} at {{ .Ref }} &middot; {{ .RepoInfo.FullName }}{{ end }} 2 + 7 3 8 4 {{ define "extrameta" }} 9 5 10 - {{ $path := "" }} 11 - {{ range .BreadCrumbs }} 6 + {{ $path := "" }} 7 + {{ range .BreadCrumbs }} 12 8 {{ $path = printf "%s/%s" $path (index . 0) }} 13 - {{ end }} 9 + {{ end }} 14 10 15 - {{ template "repo/fragments/meta" . }} 16 - {{ $title := printf "%s at %s &middot; %s" $path .Ref .RepoInfo.FullName }} 17 - {{ $url := printf "https://tangled.sh/%s/tree/%s%s" .RepoInfo.FullName .Ref $path }} 11 + {{ template "repo/fragments/meta" . }} 12 + {{ $title := printf "%s at %s &middot; %s" $path .Ref .RepoInfo.FullName }} 13 + {{ $url := printf "https://tangled.sh/%s/tree/%s%s" .RepoInfo.FullName .Ref $path }} 18 14 19 - {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 15 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 20 16 {{ end }} 21 17 22 - {{ define "repoContent" }} 23 - <main> 24 - <div class="tree"> 25 - {{ $linkstyle := "no-underline hover:underline" }} 26 18 19 + {{define "repoContent"}} 20 + <main> 21 + <div class="tree"> 22 + {{ $linkstyle := "no-underline hover:underline" }} 27 23 28 - <div 29 - class="pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700"> 30 - <div class="flex flex-col md:flex-row md:justify-between gap-2"> 31 - <div 32 - id="breadcrumbs" 33 - class="overflow-x-auto whitespace-nowrap text-gray-400 dark:text-gray-500"> 34 - {{ range .BreadCrumbs }} 35 - <a 36 - href="{{ index . 1 }}" 37 - class="text-bold text-gray-500 dark:text-gray-400 {{ $linkstyle }}"> 38 - {{ pathUnescape (index . 0) }} 39 - </a> 40 - / 41 - {{ end }} 42 - </div> 43 - <div 44 - id="dir-info" 45 - class="text-gray-500 dark:text-gray-400 text-xs md:text-sm flex flex-wrap items-center gap-1 md:gap-0"> 46 - {{ $stats := .TreeStats }} 24 + <div class="pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700"> 25 + <div class="flex flex-col md:flex-row md:justify-between gap-2"> 26 + <div id="breadcrumbs" class="overflow-x-auto whitespace-nowrap text-gray-400 dark:text-gray-500"> 27 + {{ range .BreadCrumbs }} 28 + <a href="{{ index . 1}}" class="text-bold text-gray-500 dark:text-gray-400 {{ $linkstyle }}">{{ pathUnescape (index . 0) }}</a> / 29 + {{ end }} 30 + </div> 31 + <div id="dir-info" class="text-gray-500 dark:text-gray-400 text-xs md:text-sm flex flex-wrap items-center gap-1 md:gap-0"> 32 + {{ $stats := .TreeStats }} 47 33 34 + <span>at <a href="/{{ $.RepoInfo.FullName }}/tree/{{ $.Ref }}">{{ $.Ref }}</a></span> 35 + {{ if eq $stats.NumFolders 1 }} 36 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 37 + <span>{{ $stats.NumFolders }} folder</span> 38 + {{ else if gt $stats.NumFolders 1 }} 39 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 40 + <span>{{ $stats.NumFolders }} folders</span> 41 + {{ end }} 48 42 49 - <span> 50 - at 51 - <a href="/{{ $.RepoInfo.FullName }}/tree/{{ $.Ref }}"> 52 - {{ $.Ref }} 53 - </a> 54 - </span> 55 - {{ if eq $stats.NumFolders 1 }} 56 - <span 57 - class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 58 - <span>{{ $stats.NumFolders }} folder</span> 59 - {{ else if gt $stats.NumFolders 1 }} 60 - <span 61 - class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 62 - <span>{{ $stats.NumFolders }} folders</span> 63 - {{ end }} 43 + {{ if eq $stats.NumFiles 1 }} 44 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 45 + <span>{{ $stats.NumFiles }} file</span> 46 + {{ else if gt $stats.NumFiles 1 }} 47 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 48 + <span>{{ $stats.NumFiles }} files</span> 49 + {{ end }} 64 50 65 - {{ if eq $stats.NumFiles 1 }} 66 - <span 67 - class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 68 - <span>{{ $stats.NumFiles }} file</span> 69 - {{ else if gt $stats.NumFiles 1 }} 70 - <span 71 - class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 72 - <span>{{ $stats.NumFiles }} files</span> 73 - {{ end }} 74 - 75 - </div> 76 51 </div> 77 52 </div> 78 - 79 - {{ range .Files }} 80 - <div class="grid grid-cols-12 gap-4 items-center py-1"> 81 - <div class="col-span-6 md:col-span-4"> 82 - {{ $link := printf "/%s/%s/%s/%s/%s" $.RepoInfo.FullName "tree" (urlquery $.Ref) $.TreePath .Name }} 83 - {{ $icon := "folder" }} 84 - {{ $iconStyle := "size-4 fill-current" }} 85 - 86 - {{ if .IsFile }} 87 - {{ $icon = "file" }} 88 - {{ $iconStyle = "size-4" }} 89 - {{ end }} 90 - <a href="{{ $link }}" class="{{ $linkstyle }}"> 91 - <div class="flex items-center gap-2"> 92 - {{ i $icon $iconStyle "flex-shrink-0" }} 93 - <span class="truncate">{{ .Name }}</span> 94 - </div> 95 - </a> 96 - </div> 97 - 98 - <div class="col-span-0 md:col-span-6 hidden md:block overflow-hidden"> 99 - {{ with .LastCommit }} 100 - <a 101 - href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" 102 - class="text-gray-500 dark:text-gray-400 block truncate"> 103 - {{ .Message }} 104 - </a> 105 - {{ end }} 106 - </div> 107 - 108 - <div class="col-span-6 md:col-span-2 text-right"> 109 - {{ with .LastCommit }} 110 - <a 111 - href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" 112 - class="text-gray-500 dark:text-gray-400"> 113 - {{ template "repo/fragments/time" .When }} 114 - </a> 115 - {{ end }} 116 - </div> 117 - </div> 118 - {{ end }} 119 - 120 53 </div> 121 - </main> 122 - {{ end }} 54 + 55 + {{ range .Files }} 56 + <div class="grid grid-cols-12 gap-4 items-center py-1"> 57 + <div class="col-span-6 md:col-span-4"> 58 + {{ $link := printf "/%s/%s/%s/%s/%s" $.RepoInfo.FullName "tree" (urlquery $.Ref) $.TreePath .Name }} 59 + {{ $icon := "folder" }} 60 + {{ $iconStyle := "size-4 fill-current" }} 61 + 62 + {{ if .IsFile }} 63 + {{ $icon = "file" }} 64 + {{ $iconStyle = "size-4" }} 65 + {{ end }} 66 + <a href="{{ $link }}" class="{{ $linkstyle }}"> 67 + <div class="flex items-center gap-2"> 68 + {{ i $icon $iconStyle "flex-shrink-0" }} 69 + <span class="truncate">{{ .Name }}</span> 70 + </div> 71 + </a> 72 + </div> 73 + 74 + <div class="col-span-0 md:col-span-6 hidden md:block overflow-hidden"> 75 + {{ with .LastCommit }} 76 + <a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" class="text-gray-500 dark:text-gray-400 block truncate">{{ .Message }}</a> 77 + {{ end }} 78 + </div> 79 + 80 + <div class="col-span-6 md:col-span-2 text-right"> 81 + {{ with .LastCommit }} 82 + <a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" class="text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .When }}</a> 83 + {{ end }} 84 + </div> 85 + </div> 86 + {{ end }} 87 + 88 + </div> 89 + </main> 90 + {{end}}
+143 -174
appview/pages/templates/settings.html
··· 5 5 <p class="text-xl font-bold dark:text-white">Settings</p> 6 6 </div> 7 7 <div class="flex flex-col"> 8 - {{ block "profile" . }}{{ end }} 9 - {{ block "keys" . }}{{ end }} 10 - {{ block "emails" . }}{{ end }} 8 + {{ block "profile" . }} {{ end }} 9 + {{ block "keys" . }} {{ end }} 10 + {{ block "emails" . }} {{ end }} 11 11 </div> 12 12 {{ end }} 13 13 14 14 {{ define "profile" }} 15 - <h2 class="text-sm font-bold py-2 px-6 uppercase dark:text-gray-300"> 16 - profile 17 - </h2> 18 - <section 19 - class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit"> 20 - <dl class="grid grid-cols-[auto_1fr] gap-x-4 dark:text-gray-200"> 21 - {{ if .LoggedInUser.Handle }} 22 - <dt class="font-bold">handle</dt> 23 - <dd>@{{ .LoggedInUser.Handle }}</dd> 24 - {{ end }} 25 - <dt class="font-bold">did</dt> 26 - <dd>{{ .LoggedInUser.Did }}</dd> 27 - <dt class="font-bold">pds</dt> 28 - <dd>{{ .LoggedInUser.Pds }}</dd> 29 - </dl> 30 - </section> 15 + <h2 class="text-sm font-bold py-2 px-6 uppercase dark:text-gray-300">profile</h2> 16 + <section class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit"> 17 + <dl class="grid grid-cols-[auto_1fr] gap-x-4 dark:text-gray-200"> 18 + {{ if .LoggedInUser.Handle }} 19 + <dt class="font-bold">handle</dt> 20 + <dd>@{{ .LoggedInUser.Handle }}</dd> 21 + {{ end }} 22 + <dt class="font-bold">did</dt> 23 + <dd>{{ .LoggedInUser.Did }}</dd> 24 + <dt class="font-bold">pds</dt> 25 + <dd>{{ .LoggedInUser.Pds }}</dd> 26 + </dl> 27 + </section> 31 28 {{ end }} 32 29 33 30 {{ define "keys" }} 34 - <h2 class="text-sm font-bold py-2 px-6 uppercase dark:text-gray-300"> 35 - ssh keys 36 - </h2> 37 - <section 38 - class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit"> 39 - <p class="mb-8 dark:text-gray-300"> 40 - SSH public keys added here will be broadcasted to knots that you are a 41 - member of, 42 - <br /> 43 - allowing you to push to repositories there. 44 - </p> 45 - <div id="key-list" class="flex flex-col gap-6 mb-8"> 46 - {{ range $index, $key := .PubKeys }} 47 - <div class="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-4"> 48 - <div class="flex flex-col gap-1"> 49 - <div class="inline-flex items-center gap-4"> 50 - {{ i "key" "w-3 h-3 dark:text-gray-300" }} 51 - <p class="font-bold dark:text-white">{{ .Name }}</p> 52 - </div> 53 - <p class="text-sm text-gray-500 dark:text-gray-400"> 54 - added 55 - {{ template "repo/fragments/time" .Created }} 56 - </p> 57 - <div class="overflow-x-auto whitespace-nowrap flex-1 max-w-full"> 58 - <code class="text-sm text-gray-500 dark:text-gray-400"> 59 - {{ .Key }} 60 - </code> 61 - </div> 62 - </div> 63 - <button 64 - class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 gap-2 group" 65 - title="Delete key" 66 - hx-delete="/settings/keys?name={{ urlquery .Name }}&rkey={{ urlquery .Rkey }}&key={{ urlquery .Key }}" 67 - hx-confirm="Are you sure you want to delete the key '{{ .Name }}'?"> 68 - {{ i "trash-2" "w-5 h-5" }} 69 - <span class="hidden md:inline">delete</span> 70 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 71 - </button> 31 + <h2 class="text-sm font-bold py-2 px-6 uppercase dark:text-gray-300">ssh keys</h2> 32 + <section class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit"> 33 + <p class="mb-8 dark:text-gray-300">SSH public keys added here will be broadcasted to knots that you are a member of, <br> allowing you to push to repositories there.</p> 34 + <div id="key-list" class="flex flex-col gap-6 mb-8"> 35 + {{ range $index, $key := .PubKeys }} 36 + <div class="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-4"> 37 + <div class="flex flex-col gap-1"> 38 + <div class="inline-flex items-center gap-4"> 39 + {{ i "key" "w-3 h-3 dark:text-gray-300" }} 40 + <p class="font-bold dark:text-white">{{ .Name }}</p> 72 41 </div> 73 - {{ end }} 42 + <p class="text-sm text-gray-500 dark:text-gray-400">added {{ template "repo/fragments/time" .Created }}</p> 43 + <div class="overflow-x-auto whitespace-nowrap flex-1 max-w-full"> 44 + <code class="text-sm text-gray-500 dark:text-gray-400">{{ .Key }}</code> 45 + </div> 46 + </div> 47 + <button 48 + class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 gap-2 group" 49 + title="Delete key" 50 + hx-delete="/settings/keys?name={{urlquery .Name}}&rkey={{urlquery .Rkey}}&key={{urlquery .Key}}" 51 + hx-confirm="Are you sure you want to delete the key '{{ .Name }}'?" 52 + > 53 + {{ i "trash-2" "w-5 h-5" }} 54 + <span class="hidden md:inline">delete</span> 55 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 56 + </button> 74 57 </div> 75 - <form 58 + {{ end }} 59 + </div> 60 + <form 76 61 hx-put="/settings/keys" 77 62 hx-indicator="#add-sshkey-spinner" 78 63 hx-swap="none" 79 - class="max-w-2xl mb-8 space-y-4"> 64 + class="max-w-2xl mb-8 space-y-4" 65 + > 80 66 <input 81 - type="text" 82 - id="name" 83 - name="name" 84 - placeholder="key name" 85 - required 86 - class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400" /> 67 + type="text" 68 + id="name" 69 + name="name" 70 + placeholder="key name" 71 + required 72 + class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400"/> 87 73 88 74 <input 89 - id="key" 90 - name="key" 91 - placeholder="ssh-rsa AAAAAA..." 92 - required 93 - class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400" /> 75 + id="key" 76 + name="key" 77 + placeholder="ssh-rsa AAAAAA..." 78 + required 79 + class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400"/> 94 80 95 - <button 96 - class="btn dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 flex gap-2 items-center" 97 - type="submit"> 98 - <span>add key</span> 99 - <span id="add-sshkey-spinner" class="group"> 100 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 101 - </span> 81 + <button class="btn dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 flex gap-2 items-center" type="submit"> 82 + <span>add key</span> 83 + <span id="add-sshkey-spinner" class="group"> 84 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 85 + </span> 102 86 </button> 103 87 104 88 <div id="settings-keys" class="error dark:text-red-400"></div> 105 - </form> 106 - </section> 89 + </form> 90 + </section> 107 91 {{ end }} 108 92 109 93 {{ define "emails" }} 110 - <h2 class="text-sm font-bold py-2 px-6 uppercase dark:text-gray-300"> 111 - email addresses 112 - </h2> 113 - <section 114 - class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit"> 115 - <p class="mb-8 dark:text-gray-300"> 116 - Commits authored using emails listed here will be associated with your 117 - Tangled profile. 118 - </p> 119 - <div id="email-list" class="flex flex-col gap-6 mb-8"> 120 - {{ range $index, $email := .Emails }} 121 - <div class="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-4"> 122 - <div class="flex flex-col gap-2"> 123 - <div class="inline-flex items-center gap-4"> 124 - {{ i "mail" "w-3 h-3 dark:text-gray-300" }} 125 - <p class="font-bold dark:text-white">{{ .Address }}</p> 126 - <div class="inline-flex items-center gap-1"> 127 - {{ if .Verified }} 128 - <span 129 - class="text-xs bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 py-1 rounded"> 130 - verified 131 - </span> 132 - {{ else }} 133 - <span 134 - class="text-xs bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 px-2 py-1 rounded"> 135 - unverified 136 - </span> 137 - {{ end }} 138 - {{ if .Primary }} 139 - <span 140 - class="text-xs bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 px-2 py-1 rounded"> 141 - primary 142 - </span> 143 - {{ end }} 144 - </div> 145 - </div> 146 - <p class="text-sm text-gray-500 dark:text-gray-400"> 147 - added 148 - {{ template "repo/fragments/time" .CreatedAt }} 149 - </p> 150 - </div> 151 - <div class="flex gap-2 items-center"> 152 - {{ if not .Verified }} 153 - <button 154 - class="btn flex gap-2 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600" 155 - hx-post="/settings/emails/verify/resend" 156 - hx-swap="none" 157 - href="#" 158 - hx-vals='{"email": "{{ .Address }}"}'> 159 - {{ i "rotate-cw" "w-5 h-5" }} 160 - <span class="hidden md:inline">resend</span> 161 - </button> 94 + <h2 class="text-sm font-bold py-2 px-6 uppercase dark:text-gray-300">email addresses</h2> 95 + <section class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit"> 96 + <p class="mb-8 dark:text-gray-300">Commits authored using emails listed here will be associated with your Tangled profile.</p> 97 + <div id="email-list" class="flex flex-col gap-6 mb-8"> 98 + {{ range $index, $email := .Emails }} 99 + <div class="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-4"> 100 + <div class="flex flex-col gap-2"> 101 + <div class="inline-flex items-center gap-4"> 102 + {{ i "mail" "w-3 h-3 dark:text-gray-300" }} 103 + <p class="font-bold dark:text-white">{{ .Address }}</p> 104 + <div class="inline-flex items-center gap-1"> 105 + {{ if .Verified }} 106 + <span class="text-xs bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 py-1 rounded">verified</span> 107 + {{ else }} 108 + <span class="text-xs bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 px-2 py-1 rounded">unverified</span> 162 109 {{ end }} 163 - {{ if and (not .Primary) .Verified }} 164 - <a 165 - class="text-sm dark:text-blue-400 dark:hover:text-blue-300" 166 - hx-post="/settings/emails/primary" 167 - hx-swap="none" 168 - href="#" 169 - hx-vals='{"email": "{{ .Address }}"}'> 170 - set as primary 171 - </a> 172 - {{ end }} 173 - {{ if not .Primary }} 174 - <form 175 - hx-delete="/settings/emails" 176 - hx-confirm="Are you sure you wish to delete the email '{{ .Address }}'?" 177 - hx-indicator="#delete-email-{{ $index }}-spinner"> 178 - <input type="hidden" name="email" value="{{ .Address }}" /> 179 - <button 180 - class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 flex gap-2 items-center" 181 - title="Delete email" 182 - type="submit"> 183 - {{ i "trash-2" "w-5 h-5" }} 184 - <span class="hidden md:inline">delete</span> 185 - <span id="delete-email-{{ $index }}-spinner" class="group"> 186 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 187 - </span> 188 - </button> 189 - </form> 110 + {{ if .Primary }} 111 + <span class="text-xs bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 px-2 py-1 rounded">primary</span> 190 112 {{ end }} 191 113 </div> 192 114 </div> 193 - {{ end }} 115 + <p class="text-sm text-gray-500 dark:text-gray-400">added {{ template "repo/fragments/time" .CreatedAt }}</p> 116 + </div> 117 + <div class="flex gap-2 items-center"> 118 + {{ if not .Verified }} 119 + <button 120 + class="btn flex gap-2 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600" 121 + hx-post="/settings/emails/verify/resend" 122 + hx-swap="none" 123 + href="#" 124 + hx-vals='{"email": "{{ .Address }}"}'> 125 + {{ i "rotate-cw" "w-5 h-5" }} 126 + <span class="hidden md:inline">resend</span> 127 + </button> 128 + {{ end }} 129 + {{ if and (not .Primary) .Verified }} 130 + <a 131 + class="text-sm dark:text-blue-400 dark:hover:text-blue-300" 132 + hx-post="/settings/emails/primary" 133 + hx-swap="none" 134 + href="#" 135 + hx-vals='{"email": "{{ .Address }}"}'> 136 + set as primary 137 + </a> 138 + {{ end }} 139 + {{ if not .Primary }} 140 + <form 141 + hx-delete="/settings/emails" 142 + hx-confirm="Are you sure you wish to delete the email '{{ .Address }}'?" 143 + hx-indicator="#delete-email-{{ $index }}-spinner" 144 + > 145 + <input type="hidden" name="email" value="{{ .Address }}"> 146 + <button 147 + class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 flex gap-2 items-center" 148 + title="Delete email" 149 + type="submit" 150 + > 151 + {{ i "trash-2" "w-5 h-5" }} 152 + <span class="hidden md:inline">delete</span> 153 + <span id="delete-email-{{ $index }}-spinner" class="group"> 154 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 155 + </span> 156 + </button> 157 + </form> 158 + {{ end }} 159 + </div> 194 160 </div> 195 - <form 161 + {{ end }} 162 + </div> 163 + <form 196 164 hx-put="/settings/emails" 197 165 hx-swap="none" 198 166 class="max-w-2xl mb-8 space-y-4" 199 - hx-indicator="#add-email-spinner"> 167 + hx-indicator="#add-email-spinner" 168 + > 200 169 <input 201 - type="email" 202 - id="email" 203 - name="email" 204 - placeholder="your@email.com" 205 - required 206 - class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400" /> 170 + type="email" 171 + id="email" 172 + name="email" 173 + placeholder="your@email.com" 174 + required 175 + class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400" 176 + > 207 177 208 178 <button 209 179 class="btn dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 flex gap-2 items-center" 210 - type="submit"> 180 + type="submit" 181 + > 211 182 <span>add email</span> 212 183 <span id="add-email-spinner" class="group"> 213 184 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} ··· 186 215 </button> 187 216 188 217 <div id="settings-emails-error" class="error dark:text-red-400"></div> 189 - <div 190 - id="settings-emails-success" 191 - class="success dark:text-green-400"></div> 192 - </form> 193 - </section> 218 + <div id="settings-emails-success" class="success dark:text-green-400"></div> 219 + </form> 220 + </section> 194 221 {{ end }}
+54 -54
appview/pages/templates/spindles/dashboard.html
··· 1 - {{ define "title" }}{{ .Spindle.Instance }} &middot; spindles{{ end }} 1 + {{ define "title" }}{{.Spindle.Instance}} &middot; spindles{{ end }} 2 2 3 3 {{ define "content" }} 4 - <div class="px-6 py-4"> 5 - <div class="flex justify-between items-center"> 6 - <h1 class="text-xl font-bold dark:text-white">{{ .Spindle.Instance }}</h1> 7 - <div id="right-side" class="flex gap-2"> 8 - {{ $style := "px-2 py-1 rounded flex items-center flex-shrink-0 gap-2" }} 9 - {{ $isOwner := and .LoggedInUser (eq .LoggedInUser.Did .Spindle.Owner) }} 10 - {{ if .Spindle.Verified }} 11 - <span 12 - class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 {{ $style }}"> 13 - {{ i "shield-check" "w-4 h-4" }} verified 14 - </span> 15 - {{ if $isOwner }} 16 - {{ template "spindles/fragments/addMemberModal" .Spindle }} 17 - {{ end }} 18 - {{ else }} 19 - <span 20 - class="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 {{ $style }}"> 21 - {{ i "shield-off" "w-4 h-4" }} unverified 22 - </span> 23 - {{ if $isOwner }} 24 - {{ block "retryButton" .Spindle }}{{ end }} 25 - {{ end }} 26 - {{ end }} 27 - 4 + <div class="px-6 py-4"> 5 + <div class="flex justify-between items-center"> 6 + <h1 class="text-xl font-bold dark:text-white">{{ .Spindle.Instance }}</h1> 7 + <div id="right-side" class="flex gap-2"> 8 + {{ $style := "px-2 py-1 rounded flex items-center flex-shrink-0 gap-2" }} 9 + {{ $isOwner := and .LoggedInUser (eq .LoggedInUser.Did .Spindle.Owner) }} 10 + {{ if .Spindle.Verified }} 11 + <span class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 {{$style}}">{{ i "shield-check" "w-4 h-4" }} verified</span> 28 12 {{ if $isOwner }} 29 - {{ block "deleteButton" .Spindle }}{{ end }} 13 + {{ template "spindles/fragments/addMemberModal" .Spindle }} 30 14 {{ end }} 31 - </div> 32 - </div> 33 - <div id="operation-error" class="dark:text-red-400"></div> 34 - </div> 15 + {{ else }} 16 + <span class="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 {{$style}}">{{ i "shield-off" "w-4 h-4" }} unverified</span> 17 + {{ if $isOwner }} 18 + {{ block "retryButton" .Spindle }} {{ end }} 19 + {{ end }} 20 + {{ end }} 35 21 36 - {{ if .Members }} 37 - <section 38 - class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 39 - <div class="flex flex-col gap-2"> 40 - {{ block "member" . }}{{ end }} 41 - </div> 42 - </section> 43 - {{ end }} 22 + {{ if $isOwner }} 23 + {{ block "deleteButton" .Spindle }} {{ end }} 24 + {{ end }} 25 + </div> 26 + </div> 27 + <div id="operation-error" class="dark:text-red-400"></div> 28 + </div> 29 + 30 + {{ if .Members }} 31 + <section class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 32 + <div class="flex flex-col gap-2"> 33 + {{ block "member" . }} {{ end }} 34 + </div> 35 + </section> 44 36 {{ end }} 37 + {{ end }} 38 + 45 39 46 40 {{ define "member" }} 47 41 {{ range .Members }} ··· 45 51 {{ template "user/fragments/picHandleLink" . }} 46 52 </div> 47 53 {{ if ne $.LoggedInUser.Did . }} 48 - {{ block "removeMemberButton" (list $ . ) }}{{ end }} 54 + {{ block "removeMemberButton" (list $ . ) }} {{ end }} 49 55 {{ end }} 50 56 </div> 51 57 <div class="ml-2 pl-2 pt-2 border-l border-gray-200 dark:border-gray-700"> ··· 74 80 hx-delete="/spindles/{{ .Instance }}" 75 81 hx-swap="outerHTML" 76 82 hx-confirm="Are you sure you want to delete the spindle '{{ .Instance }}'?" 77 - hx-headers='{"shouldRedirect": "true"}'> 83 + hx-headers='{"shouldRedirect": "true"}' 84 + > 78 85 {{ i "trash-2" "w-5 h-5" }} 79 - <span class="hidden md:inline">delete</span> 86 + <span class="hidden md:inline">delete</span> 80 87 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 81 88 </button> 82 89 {{ end }} 90 + 83 91 84 92 {{ define "retryButton" }} 85 93 <button ··· 89 93 title="Retry spindle verification" 90 94 hx-post="/spindles/{{ .Instance }}/retry" 91 95 hx-swap="none" 92 - hx-headers='{"shouldRefresh": "true"}'> 96 + hx-headers='{"shouldRefresh": "true"}' 97 + > 93 98 {{ i "rotate-ccw" "w-5 h-5" }} 94 - <span class="hidden md:inline">retry</span> 99 + <span class="hidden md:inline">retry</span> 95 100 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 96 101 </button> 97 102 {{ end }} 98 103 104 + 99 105 {{ define "removeMemberButton" }} 100 106 {{ $root := index . 0 }} 101 107 {{ $member := index . 1 }} 102 - <button 103 - class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 gap-2 group" 104 - title="Remove member" 105 - hx-post="/spindles/{{ $root.Spindle.Instance }}/remove" 106 - hx-swap="none" 107 - hx-vals='{"member": "{{ $member }}" }' 108 - hx-confirm="Are you sure you want to remove {{ resolve $member }} from this instance?"> 109 - {{ i "user-minus" "w-4 h-4" }} 110 - remove 111 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 112 - </button> 108 + <button 109 + class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 gap-2 group" 110 + title="Remove member" 111 + hx-post="/spindles/{{ $root.Spindle.Instance }}/remove" 112 + hx-swap="none" 113 + hx-vals='{"member": "{{$member}}" }' 114 + hx-confirm="Are you sure you want to remove {{ resolve $member }} from this instance?" 115 + > 116 + {{ i "user-minus" "w-4 h-4" }} 117 + remove 118 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 119 + </button> 113 120 {{ end }} 121 +
+39 -39
appview/pages/templates/spindles/fragments/addMemberModal.html
··· 3 3 class="btn gap-2 group" 4 4 title="Add member to this spindle" 5 5 popovertarget="add-member-{{ .Instance }}" 6 - popovertargetaction="toggle"> 6 + popovertargetaction="toggle" 7 + > 7 8 {{ i "user-plus" "w-5 h-5" }} 8 - <span class="hidden md:inline">add member</span> 9 + <span class="hidden md:inline">add member</span> 9 10 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 10 11 </button> 11 12 ··· 14 13 id="add-member-{{ .Instance }}" 15 14 popover 16 15 class="bg-white w-full md:w-96 dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 drop-shadow dark:text-white backdrop:bg-gray-400/50 dark:backdrop:bg-gray-800/50"> 17 - {{ block "addMemberPopover" . }}{{ end }} 16 + {{ block "addMemberPopover" . }} {{ end }} 18 17 </div> 19 18 {{ end }} 20 19 21 20 {{ define "addMemberPopover" }} 22 - <form 23 - hx-post="/spindles/{{ .Instance }}/add" 24 - hx-indicator="#spinner" 25 - hx-swap="none" 26 - class="flex flex-col gap-2"> 27 - <label for="member-did-{{ .Id }}" class="uppercase p-0">ADD MEMBER</label> 28 - <p class="text-sm text-gray-500 dark:text-gray-400"> 29 - Members can register repositories and run workflows on this spindle. 30 - </p> 31 - <input 32 - type="text" 33 - id="member-did-{{ .Id }}" 34 - name="member" 35 - required 36 - placeholder="@foo.bsky.social" /> 37 - <div class="flex gap-2 pt-2"> 38 - <button 39 - type="button" 40 - popovertarget="add-member-{{ .Instance }}" 41 - popovertargetaction="hide" 42 - class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"> 43 - {{ i "x" "size-4" }} cancel 44 - </button> 45 - <button type="submit" class="btn w-1/2 flex items-center"> 46 - <span class="inline-flex gap-2 items-center"> 47 - {{ i "user-plus" "size-4" }} add 48 - </span> 49 - <span id="spinner" class="group"> 50 - {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 51 - </span> 52 - </button> 53 - </div> 54 - <div 55 - id="add-member-error-{{ .Id }}" 56 - class="text-red-500 dark:text-red-400"></div> 57 - </form> 21 + <form 22 + hx-post="/spindles/{{ .Instance }}/add" 23 + hx-indicator="#spinner" 24 + hx-swap="none" 25 + class="flex flex-col gap-2" 26 + > 27 + <label for="member-did-{{ .Id }}" class="uppercase p-0"> 28 + ADD MEMBER 29 + </label> 30 + <p class="text-sm text-gray-500 dark:text-gray-400">Members can register repositories and run workflows on this spindle.</p> 31 + <input 32 + type="text" 33 + id="member-did-{{ .Id }}" 34 + name="member" 35 + required 36 + placeholder="@foo.bsky.social" 37 + /> 38 + <div class="flex gap-2 pt-2"> 39 + <button 40 + type="button" 41 + popovertarget="add-member-{{ .Instance }}" 42 + popovertargetaction="hide" 43 + class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300" 44 + > 45 + {{ i "x" "size-4" }} cancel 46 + </button> 47 + <button type="submit" class="btn w-1/2 flex items-center"> 48 + <span class="inline-flex gap-2 items-center">{{ i "user-plus" "size-4" }} add</span> 49 + <span id="spinner" class="group"> 50 + {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 51 + </span> 52 + </button> 53 + </div> 54 + <div id="add-member-error-{{ .Id }}" class="text-red-500 dark:text-red-400"></div> 55 + </form> 58 56 {{ end }}
+29 -36
appview/pages/templates/spindles/fragments/spindleListing.html
··· 1 1 {{ define "spindles/fragments/spindleListing" }} 2 - <div 3 - id="spindle-{{ .Id }}" 4 - class="flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-700"> 5 - {{ block "leftSide" . }}{{ end }} 6 - {{ block "rightSide" . }}{{ end }} 2 + <div id="spindle-{{.Id}}" class="flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-700"> 3 + {{ block "leftSide" . }} {{ end }} 4 + {{ block "rightSide" . }} {{ end }} 7 5 </div> 8 6 {{ end }} 9 7 10 8 {{ define "leftSide" }} 11 9 {{ if .Verified }} 12 - <a 13 - href="/spindles/{{ .Instance }}" 14 - class="hover:no-underline flex items-center gap-2 min-w-0 max-w-[60%]"> 15 - {{ i "hard-drive" "w-4 h-4" }} 16 - {{ .Instance }} 17 - <span class="text-gray-500"> 18 - {{ template "repo/fragments/shortTimeAgo" .Created }} 19 - </span> 20 - </a> 10 + <a href="/spindles/{{ .Instance }}" class="hover:no-underline flex items-center gap-2 min-w-0 max-w-[60%]"> 11 + {{ i "hard-drive" "w-4 h-4" }} 12 + {{ .Instance }} 13 + <span class="text-gray-500"> 14 + {{ template "repo/fragments/shortTimeAgo" .Created }} 15 + </span> 16 + </a> 21 17 {{ else }} 22 - <div class="hover:no-underline flex items-center gap-2 min-w-0 max-w-[60%]"> 23 - {{ i "hard-drive" "w-4 h-4" }} 24 - {{ .Instance }} 25 - <span class="text-gray-500"> 26 - {{ template "repo/fragments/shortTimeAgo" .Created }} 27 - </span> 28 - </div> 18 + <div class="hover:no-underline flex items-center gap-2 min-w-0 max-w-[60%]"> 19 + {{ i "hard-drive" "w-4 h-4" }} 20 + {{ .Instance }} 21 + <span class="text-gray-500"> 22 + {{ template "repo/fragments/shortTimeAgo" .Created }} 23 + </span> 24 + </div> 29 25 {{ end }} 30 26 {{ end }} 31 27 ··· 29 33 <div id="right-side" class="flex gap-2"> 30 34 {{ $style := "px-2 py-1 rounded flex items-center flex-shrink-0 gap-2 text-sm" }} 31 35 {{ if .Verified }} 32 - <span 33 - class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 {{ $style }}"> 34 - {{ i "shield-check" "w-4 h-4" }} verified 35 - </span> 36 + <span class="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 {{$style}}">{{ i "shield-check" "w-4 h-4" }} verified</span> 36 37 {{ template "spindles/fragments/addMemberModal" . }} 37 38 {{ else }} 38 - <span 39 - class="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 {{ $style }}"> 40 - {{ i "shield-off" "w-4 h-4" }} unverified 41 - </span> 42 - {{ block "retryButton" . }}{{ end }} 39 + <span class="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 {{$style}}">{{ i "shield-off" "w-4 h-4" }} unverified</span> 40 + {{ block "retryButton" . }} {{ end }} 43 41 {{ end }} 44 - {{ block "deleteButton" . }}{{ end }} 42 + {{ block "deleteButton" . }} {{ end }} 45 43 </div> 46 44 {{ end }} 47 45 ··· 45 55 title="Delete spindle" 46 56 hx-delete="/spindles/{{ .Instance }}" 47 57 hx-swap="outerHTML" 48 - hx-target="#spindle-{{ .Id }}" 49 - hx-confirm="Are you sure you want to delete the spindle '{{ .Instance }}'?"> 58 + hx-target="#spindle-{{.Id}}" 59 + hx-confirm="Are you sure you want to delete the spindle '{{ .Instance }}'?" 60 + > 50 61 {{ i "trash-2" "w-5 h-5" }} 51 - <span class="hidden md:inline">delete</span> 62 + <span class="hidden md:inline">delete</span> 52 63 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 53 64 </button> 54 65 {{ end }} 66 + 55 67 56 68 {{ define "retryButton" }} 57 69 <button ··· 61 69 title="Retry spindle verification" 62 70 hx-post="/spindles/{{ .Instance }}/retry" 63 71 hx-swap="none" 64 - hx-target="#spindle-{{ .Id }}"> 72 + hx-target="#spindle-{{.Id}}" 73 + > 65 74 {{ i "rotate-ccw" "w-5 h-5" }} 66 - <span class="hidden md:inline">retry</span> 75 + <span class="hidden md:inline">retry</span> 67 76 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 68 77 </button> 69 78 {{ end }}
+23 -29
appview/pages/templates/spindles/index.html
··· 1 1 {{ define "title" }}spindles{{ end }} 2 2 3 3 {{ define "content" }} 4 - <div class="px-6 py-4"> 5 - <h1 class="text-xl font-bold dark:text-white">Spindles</h1> 6 - </div> 4 + <div class="px-6 py-4"> 5 + <h1 class="text-xl font-bold dark:text-white">Spindles</h1> 6 + </div> 7 7 8 - <section 9 - class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 10 - <div class="flex flex-col gap-6"> 11 - {{ block "about" . }}{{ end }} 12 - {{ block "list" . }}{{ end }} 13 - {{ block "register" . }}{{ end }} 14 - </div> 15 - </section> 8 + <section class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 9 + <div class="flex flex-col gap-6"> 10 + {{ block "about" . }} {{ end }} 11 + {{ block "list" . }} {{ end }} 12 + {{ block "register" . }} {{ end }} 13 + </div> 14 + </section> 16 15 {{ end }} 17 16 18 17 {{ define "about" }} 19 18 <section class="rounded flex flex-col gap-2"> 20 19 <p class="dark:text-gray-300"> 21 20 Spindles are small CI runners. 22 - <a 23 - href="https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md"> 21 + <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md"> 24 22 Checkout the documentation if you're interested in self-hosting. 25 23 </a> 26 24 </p> ··· 27 29 28 30 {{ define "list" }} 29 31 <section class="rounded w-full flex flex-col gap-2"> 30 - <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300"> 31 - your spindles 32 - </h2> 33 - <div 34 - class="flex flex-col rounded border border-gray-200 dark:border-gray-700 w-full"> 32 + <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300">your spindles</h2> 33 + <div class="flex flex-col rounded border border-gray-200 dark:border-gray-700 w-full"> 35 34 {{ range $spindle := .Spindles }} 36 35 {{ template "spindles/fragments/spindleListing" . }} 37 36 {{ else }} 38 - <div 39 - class="flex items-center justify-center p-2 border-b border-gray-200 dark:border-gray-700 text-gray-500"> 37 + <div class="flex items-center justify-center p-2 border-b border-gray-200 dark:border-gray-700 text-gray-500"> 40 38 no spindles registered yet 41 39 </div> 42 40 {{ end }} ··· 43 49 44 50 {{ define "register" }} 45 51 <section class="rounded w-full lg:w-fit flex flex-col gap-2"> 46 - <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300"> 47 - register a spindle 48 - </h2> 49 - <p class="mb-2 dark:text-gray-300"> 50 - Enter the hostname of your spindle to get started. 51 - </p> 52 + <h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300">register a spindle</h2> 53 + <p class="mb-2 dark:text-gray-300">Enter the hostname of your spindle to get started.</p> 52 54 <form 53 55 hx-post="/spindles/register" 54 56 class="max-w-2xl mb-2 space-y-4" 55 57 hx-indicator="#register-button" 56 - hx-swap="none"> 58 + hx-swap="none" 59 + > 57 60 <div class="flex gap-2"> 58 61 <input 59 62 type="text" ··· 58 67 name="instance" 59 68 placeholder="spindle.example.com" 60 69 required 61 - class="flex-1 w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" /> 70 + class="flex-1 w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" 71 + > 62 72 <button 63 73 type="submit" 64 74 id="register-button" 65 - class="btn rounded flex items-center py-2 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 group"> 75 + class="btn rounded flex items-center py-2 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 group" 76 + > 66 77 <span class="inline-flex items-center gap-2"> 67 78 {{ i "plus" "w-4 h-4" }} 68 79 register ··· 77 84 78 85 <div id="register-error" class="dark:text-red-400"></div> 79 86 </form> 87 + 80 88 </section> 81 89 {{ end }}
+14 -25
appview/pages/templates/strings/dashboard.html
··· 1 - {{ define "title" }}strings by {{ or .Card.UserHandle .Card.UserDid }}{{ end }} 1 + {{ define "title" }}strings by {{ or .Card.UserHandle .Card.UserDid }}{{ end }} 2 2 3 3 {{ define "extrameta" }} 4 - <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}" /> 5 - <meta property="og:type" content="profile" /> 6 - <meta 7 - property="og:url" 8 - content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}" /> 9 - <meta 10 - property="og:description" 11 - content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 4 + <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}" /> 5 + <meta property="og:type" content="profile" /> 6 + <meta property="og:url" content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}" /> 7 + <meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 12 8 {{ end }} 13 9 10 + 14 11 {{ define "content" }} 15 - <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 12 + <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 16 13 <div class="md:col-span-3 order-1 md:order-1"> 17 - {{ template "user/fragments/profileCard" .Card }} 14 + {{ template "user/fragments/profileCard" .Card }} 18 15 </div> 19 16 <div id="all-strings" class="md:col-span-8 order-2 md:order-2"> 20 - {{ block "allStrings" . }}{{ end }} 17 + {{ block "allStrings" . }}{{ end }} 21 18 </div> 22 - </div> 19 + </div> 23 20 {{ end }} 24 21 25 22 {{ define "allStrings" }} ··· 25 28 {{ range .Strings }} 26 29 {{ template "singleString" (list $ .) }} 27 30 {{ else }} 28 - <p class="px-6 dark:text-white"> 29 - This user does not have any strings yet. 30 - </p> 31 + <p class="px-6 dark:text-white">This user does not have any strings yet.</p> 31 32 {{ end }} 32 33 </div> 33 34 {{ end }} ··· 35 40 {{ $s := index . 1 }} 36 41 <div class="py-4 px-6 drop-shadow-sm rounded bg-white dark:bg-gray-800"> 37 42 <div class="font-medium dark:text-white flex gap-2 items-center"> 38 - <a 39 - href="/strings/{{ or $root.Card.UserHandle $root.Card.UserDid }}/{{ $s.Rkey }}"> 40 - {{ $s.Filename }} 41 - </a> 43 + <a href="/strings/{{ or $root.Card.UserHandle $root.Card.UserDid }}/{{ $s.Rkey }}">{{ $s.Filename }}</a> 42 44 </div> 43 45 {{ with $s.Description }} 44 46 <div class="text-gray-600 dark:text-gray-300 text-sm"> 45 - {{ . }} 47 + {{ . }} 46 48 </div> 47 49 {{ end }} 48 50 49 51 {{ $stat := $s.Stats }} 50 52 <div class="text-gray-400 pt-4 text-sm font-mono inline-flex gap-2 mt-auto"> 51 - <span> 52 - {{ $stat.LineCount }} 53 - line{{ if ne $stat.LineCount 1 }}s{{ end }} 54 - </span> 53 + <span>{{ $stat.LineCount }} line{{if ne $stat.LineCount 1}}s{{end}}</span> 55 54 <span class="select-none [&:before]:content-['·']"></span> 56 55 {{ with $s.Edited }} 57 56 <span>edited {{ template "repo/fragments/shortTimeAgo" . }}</span>
+20 -20
appview/pages/templates/strings/fragments/form.html
··· 3 3 {{ if eq .Action "new" }} 4 4 hx-post="/strings/new" 5 5 {{ else }} 6 - hx-post="/strings/{{ .String.Did }}/{{ .String.Rkey }}/edit" 6 + hx-post="/strings/{{.String.Did}}/{{.String.Rkey}}/edit" 7 7 {{ end }} 8 8 hx-indicator="#new-button" 9 9 class="p-6 pb-4 dark:text-white flex flex-col gap-2 bg-white dark:bg-gray-800 drop-shadow-sm rounded" ··· 16 16 placeholder="Filename with extension" 17 17 required 18 18 value="{{ .String.Filename }}" 19 - class="md:max-w-64 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" /> 19 + class="md:max-w-64 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" 20 + > 20 21 <input 21 22 type="text" 22 23 id="description" 23 24 name="description" 24 25 value="{{ .String.Description }}" 25 26 placeholder="Description ..." 26 - class="flex-1 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" /> 27 + class="flex-1 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" 28 + > 27 29 </div> 28 30 <textarea 29 - name="content" 31 + name="content" 30 32 id="content-textarea" 31 33 wrap="off" 32 34 class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400" 33 35 rows="20" 34 36 placeholder="Paste your string here!" 35 - required> 36 - {{ .String.Contents }}</textarea 37 - > 37 + required>{{ .String.Contents }}</textarea> 38 38 <div class="flex justify-between items-center"> 39 39 <div id="content-stats" class="text-sm text-gray-500 dark:text-gray-400"> 40 40 <span id="line-count">0 lines</span> ··· 43 43 </div> 44 44 <div id="actions" class="flex gap-2 items-center"> 45 45 {{ if eq .Action "edit" }} 46 - <a 47 - class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 " 48 - href="/strings/{{ .String.Did }}/{{ .String.Rkey }}"> 46 + <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 " 47 + href="/strings/{{ .String.Did }}/{{ .String.Rkey }}"> 49 48 {{ i "x" "size-4" }} 50 49 <span class="hidden md:inline">cancel</span> 51 50 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} ··· 53 54 <button 54 55 type="submit" 55 56 id="new-button" 56 - class="w-fit btn-create rounded flex items-center py-0 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 group"> 57 + class="w-fit btn-create rounded flex items-center py-0 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 group" 58 + > 57 59 <span class="inline-flex items-center gap-2"> 58 60 {{ i "arrow-up" "w-4 h-4" }} 59 61 publish ··· 66 66 </div> 67 67 </div> 68 68 <script> 69 - (function () { 70 - const textarea = document.getElementById("content-textarea"); 71 - const lineCount = document.getElementById("line-count"); 72 - const byteCount = document.getElementById("byte-count"); 69 + (function() { 70 + const textarea = document.getElementById('content-textarea'); 71 + const lineCount = document.getElementById('line-count'); 72 + const byteCount = document.getElementById('byte-count'); 73 73 function updateStats() { 74 74 const content = textarea.value; 75 - const lines = content === "" ? 0 : content.split("\n").length; 75 + const lines = content === '' ? 0 : content.split('\n').length; 76 76 const bytes = new TextEncoder().encode(content).length; 77 - lineCount.textContent = `${lines} line${lines !== 1 ? "s" : ""}`; 78 - byteCount.textContent = `${bytes} byte${bytes !== 1 ? "s" : ""}`; 77 + lineCount.textContent = `${lines} line${lines !== 1 ? 's' : ''}`; 78 + byteCount.textContent = `${bytes} byte${bytes !== 1 ? 's' : ''}`; 79 79 } 80 - textarea.addEventListener("input", updateStats); 81 - textarea.addEventListener("paste", () => { 80 + textarea.addEventListener('input', updateStats); 81 + textarea.addEventListener('paste', () => { 82 82 setTimeout(updateStats, 0); 83 83 }); 84 84 updateStats();
+21 -40
appview/pages/templates/strings/string.html
··· 1 - {{ define "title" }} 2 - {{ .String.Filename }} · by 3 - {{ didOrHandle .Owner.DID.String .Owner.Handle.String }} 4 - {{ end }} 1 + {{ define "title" }}{{ .String.Filename }} · by {{ didOrHandle .Owner.DID.String .Owner.Handle.String }}{{ end }} 5 2 6 3 {{ define "extrameta" }} 7 4 {{ $ownerId := didOrHandle .Owner.DID.String .Owner.Handle.String }} 8 - <meta 9 - property="og:title" 10 - content="{{ .String.Filename }} · by {{ $ownerId }}" /> 5 + <meta property="og:title" content="{{ .String.Filename }} · by {{ $ownerId }}" /> 11 6 <meta property="og:type" content="object" /> 12 - <meta 13 - property="og:url" 14 - content="https://tangled.sh/strings/{{ $ownerId }}/{{ .String.Rkey }}" /> 7 + <meta property="og:url" content="https://tangled.sh/strings/{{ $ownerId }}/{{ .String.Rkey }}" /> 15 8 <meta property="og:description" content="{{ .String.Description }}" /> 16 9 {{ end }} 17 10 ··· 13 20 {{ end }} 14 21 15 22 {{ define "content" }} 16 - {{ $ownerId := didOrHandle .Owner.DID.String .Owner.Handle.String }} 23 + {{ $ownerId := didOrHandle .Owner.DID.String .Owner.Handle.String }} 17 24 <section id="string-header" class="mb-4 py-2 px-6 dark:text-white"> 18 25 <div class="text-lg flex items-center justify-between"> 19 26 <div> 20 27 <a href="/strings/{{ $ownerId }}">{{ $ownerId }}</a> 21 28 <span class="select-none">/</span> 22 - <a href="/strings/{{ $ownerId }}/{{ .String.Rkey }}" class="font-bold"> 23 - {{ .String.Filename }} 24 - </a> 29 + <a href="/strings/{{ $ownerId }}/{{ .String.Rkey }}" class="font-bold">{{ .String.Filename }}</a> 25 30 </div> 26 31 {{ if and .LoggedInUser (eq .LoggedInUser.Did .String.Did) }} 27 32 <div class="flex gap-2 text-base"> 28 - <a 29 - class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group" 30 - hx-boost="true" 31 - href="/strings/{{ .String.Did }}/{{ .String.Rkey }}/edit"> 33 + <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group" 34 + hx-boost="true" 35 + href="/strings/{{ .String.Did }}/{{ .String.Rkey }}/edit"> 32 36 {{ i "pencil" "size-4" }} 33 - <span class="hidden md:inline">edit</span> 37 + <span class="hidden md:inline">edit</span> 34 38 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 35 39 </a> 36 40 <button ··· 35 45 title="Delete string" 36 46 hx-delete="/strings/{{ .String.Did }}/{{ .String.Rkey }}/" 37 47 hx-swap="none" 38 - hx-confirm="Are you sure you want to delete the gist `{{ .String.Filename }}`?"> 48 + hx-confirm="Are you sure you want to delete the gist `{{ .String.Filename }}`?" 49 + > 39 50 {{ i "trash-2" "size-4" }} 40 - <span class="hidden md:inline">delete</span> 51 + <span class="hidden md:inline">delete</span> 41 52 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 42 53 </button> 43 54 </div> ··· 50 59 {{ end }} 51 60 </span> 52 61 </section> 53 - <section 54 - class="bg-white dark:bg-gray-800 px-6 py-4 rounded relative w-full dark:text-white"> 55 - <div 56 - class="flex justify-between items-center text-gray-500 dark:text-gray-400 text-sm md:text-base pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700"> 62 + <section class="bg-white dark:bg-gray-800 px-6 py-4 rounded relative w-full dark:text-white"> 63 + <div class="flex justify-between items-center text-gray-500 dark:text-gray-400 text-sm md:text-base pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700"> 57 64 <span> 58 65 {{ .String.Filename }} 59 66 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 60 67 <span> 61 68 {{ with .String.Edited }} 62 - edited 63 - {{ template "repo/fragments/shortTimeAgo" . }} 69 + edited {{ template "repo/fragments/shortTimeAgo" . }} 64 70 {{ else }} 65 71 {{ template "repo/fragments/shortTimeAgo" .String.Created }} 66 72 {{ end }} ··· 70 82 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 71 83 <a href="/strings/{{ $ownerId }}/{{ .String.Rkey }}/raw">view raw</a> 72 84 {{ if .RenderToggle }} 73 - <span 74 - class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 75 - <a href="?code={{ .ShowRendered }}" hx-boost="true"> 76 - view {{ if .ShowRendered }}code{{ else }}rendered{{ end }} 77 - </a> 85 + <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span> 86 + <a href="?code={{ .ShowRendered }}" hx-boost="true"> 87 + view {{ if .ShowRendered }}code{{ else }}rendered{{ end }} 88 + </a> 78 89 {{ end }} 79 90 </div> 80 91 </div> 81 92 <div class="overflow-auto relative"> 82 93 {{ if .ShowRendered }} 83 - <div id="blob-contents" class="prose dark:prose-invert"> 84 - {{ .RenderedContents }} 85 - </div> 94 + <div id="blob-contents" class="prose dark:prose-invert">{{ .RenderedContents }}</div> 86 95 {{ else }} 87 - <div 88 - id="blob-contents" 89 - class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900"> 90 - {{ .String.Contents | escapeHtml }} 91 - </div> 96 + <div id="blob-contents" class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900">{{ .String.Contents | escapeHtml }}</div> 92 97 {{ end }} 93 98 </div> 94 99 </section>
+84 -119
appview/pages/templates/timeline.html
··· 1 1 {{ define "title" }}timeline{{ end }} 2 2 3 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.sh" /> 7 - <meta property="og:description" content="see what's tangling" /> 4 + <meta property="og:title" content="timeline · tangled" /> 5 + <meta property="og:type" content="object" /> 6 + <meta property="og:url" content="https://tangled.sh" /> 7 + <meta property="og:description" content="see what's tangling" /> 8 8 {{ end }} 9 9 10 10 {{ define "topbar" }} ··· 12 12 {{ end }} 13 13 14 14 {{ define "content" }} 15 - {{ with .LoggedInUser }} 16 - {{ block "timeline" $ }}{{ end }} 17 - {{ else }} 18 - {{ block "hero" $ }}{{ end }} 19 - {{ block "timeline" $ }}{{ end }} 20 - {{ end }} 15 + {{ with .LoggedInUser }} 16 + {{ block "timeline" $ }}{{ end }} 17 + {{ else }} 18 + {{ block "hero" $ }}{{ end }} 19 + {{ block "timeline" $ }}{{ end }} 20 + {{ end }} 21 21 {{ end }} 22 22 23 23 {{ define "hero" }} 24 - <div class="flex flex-col text-black dark:text-white p-6 gap-6 max-w-xl"> 25 - <div class="font-bold text-4xl"> 26 - tightly-knit 27 - <br /> 28 - social coding. 29 - </div> 24 + <div class="flex flex-col text-black dark:text-white p-6 gap-6 max-w-xl"> 25 + <div class="font-bold text-4xl">tightly-knit<br>social coding.</div> 30 26 31 - <p class="text-lg"> 32 - tangled is new social-enabled git collaboration platform built on 33 - <a class="underline" href="https://atproto.com/">atproto</a> 34 - . 35 - </p> 36 - <p class="text-lg"> 37 - we envision a place where developers have complete ownership of their 38 - code, open source communities can freely self-govern and most importantly, 39 - coding can be social and fun again. 40 - </p> 27 + <p class="text-lg"> 28 + tangled is new social-enabled git collaboration platform built on <a class="underline" href="https://atproto.com/">atproto</a>. 29 + </p> 30 + <p class="text-lg"> 31 + we envision a place where developers have complete ownership of their 32 + code, open source communities can freely self-govern and most 33 + importantly, coding can be social and fun again. 34 + </p> 41 35 42 - <div class="flex gap-6 items-center"> 43 - <a href="/signup" class="no-underline hover:no-underline "> 44 - <button class="btn-create flex gap-2 px-4 items-center"> 45 - join now 46 - {{ i "arrow-right" "size-4" }} 47 - </button> 48 - </a> 36 + <div class="flex gap-6 items-center"> 37 + <a href="/signup" class="no-underline hover:no-underline "> 38 + <button class="btn-create flex gap-2 px-4 items-center"> 39 + join now {{ i "arrow-right" "size-4" }} 40 + </button> 41 + </a> 42 + </div> 49 43 </div> 50 - </div> 51 44 {{ end }} 52 45 53 46 {{ define "timeline" }} 54 - <div> 55 - <div class="p-6"> 56 - <p class="text-xl font-bold dark:text-white">Timeline</p> 57 - </div> 47 + <div> 48 + <div class="p-6"> 49 + <p class="text-xl font-bold dark:text-white">Timeline</p> 50 + </div> 58 51 59 - <div class="flex flex-col gap-4"> 60 - {{ range $i, $e := .Timeline }} 61 - <div class="relative"> 62 - {{ if ne $i 0 }} 63 - <div 64 - class="absolute left-8 -top-4 w-px h-4 bg-gray-300 dark:bg-gray-600"></div> 65 - {{ end }} 66 - {{ with $e }} 67 - <div 68 - class="flex flex-col divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded-sm"> 69 - {{ if .Repo }} 70 - {{ block "repoEvent" (list $ .Repo .Source) }}{{ end }} 71 - {{ else if .Star }} 72 - {{ block "starEvent" (list $ .Star) }}{{ end }} 73 - {{ else if .Follow }} 74 - {{ block "followEvent" (list $ .Follow .Profile .FollowStats) }} 75 - {{ end }} 52 + <div class="flex flex-col gap-4"> 53 + {{ range $i, $e := .Timeline }} 54 + <div class="relative"> 55 + {{ if ne $i 0 }} 56 + <div class="absolute left-8 -top-4 w-px h-4 bg-gray-300 dark:bg-gray-600"></div> 57 + {{ end }} 58 + {{ with $e }} 59 + <div class="flex flex-col divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded-sm"> 60 + {{ if .Repo }} 61 + {{ block "repoEvent" (list $ .Repo .Source) }} {{ end }} 62 + {{ else if .Star }} 63 + {{ block "starEvent" (list $ .Star) }} {{ end }} 64 + {{ else if .Follow }} 65 + {{ block "followEvent" (list $ .Follow .Profile .FollowStats) }} {{ end }} 66 + {{ end }} 67 + </div> 76 68 {{ end }} 77 69 </div> 78 70 {{ end }} 79 71 </div> 80 - {{ end }} 81 72 </div> 82 - </div> 83 73 {{ end }} 84 74 85 75 {{ define "repoEvent" }} ··· 77 87 {{ $repo := index . 1 }} 78 88 {{ $source := index . 2 }} 79 89 {{ $userHandle := resolve $repo.Did }} 80 - <div 81 - class="pl-6 py-2 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 flex flex-wrap items-center gap-2 text-sm"> 82 - {{ template "user/fragments/picHandleLink" $repo.Did }} 83 - {{ with $source }} 84 - {{ $sourceDid := resolve .Did }} 85 - forked 86 - <a 87 - href="/{{ $sourceDid }}/{{ .Name }}" 88 - class="no-underline hover:underline"> 89 - {{ $sourceDid }}/{{ .Name }} 90 - </a> 91 - to 92 - <a 93 - href="/{{ $userHandle }}/{{ $repo.Name }}" 94 - class="no-underline hover:underline"> 95 - {{ $repo.Name }} 96 - </a> 97 - {{ else }} 98 - created 99 - <a 100 - href="/{{ $userHandle }}/{{ $repo.Name }}" 101 - class="no-underline hover:underline"> 102 - {{ $repo.Name }} 103 - </a> 104 - {{ end }} 105 - <span class="text-gray-700 dark:text-gray-400 text-xs"> 106 - {{ template "repo/fragments/time" $repo.Created }} 107 - </span> 108 - </div> 90 + <div class="pl-6 py-2 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 flex flex-wrap items-center gap-2 text-sm"> 91 + {{ template "user/fragments/picHandleLink" $repo.Did }} 92 + {{ with $source }} 93 + {{ $sourceDid := resolve .Did }} 94 + forked 95 + <a href="/{{ $sourceDid }}/{{ .Name }}"class="no-underline hover:underline"> 96 + {{ $sourceDid }}/{{ .Name }} 97 + </a> 98 + to 99 + <a href="/{{ $userHandle }}/{{ $repo.Name }}" class="no-underline hover:underline">{{ $repo.Name }}</a> 100 + {{ else }} 101 + created 102 + <a href="/{{ $userHandle }}/{{ $repo.Name }}" class="no-underline hover:underline"> 103 + {{ $repo.Name }} 104 + </a> 105 + {{ end }} 106 + <span class="text-gray-700 dark:text-gray-400 text-xs">{{ template "repo/fragments/time" $repo.Created }}</span> 107 + </div> 109 108 {{ with $repo }} 110 109 {{ template "user/fragments/repoCard" (list $root . true) }} 111 110 {{ end }} ··· 106 127 {{ with $star }} 107 128 {{ $starrerHandle := resolve .StarredByDid }} 108 129 {{ $repoOwnerHandle := resolve .Repo.Did }} 109 - <div 110 - class="pl-6 py-2 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 flex flex-wrap items-center gap-2 text-sm"> 111 - {{ template "user/fragments/picHandleLink" $starrerHandle }} 112 - starred 113 - <a 114 - href="/{{ $repoOwnerHandle }}/{{ .Repo.Name }}" 115 - class="no-underline hover:underline"> 116 - {{ $repoOwnerHandle | truncateAt30 }}/{{ .Repo.Name }} 117 - </a> 118 - <span class="text-gray-700 dark:text-gray-400 text-xs"> 119 - {{ template "repo/fragments/time" .Created }} 120 - </span> 130 + <div class="pl-6 py-2 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 flex flex-wrap items-center gap-2 text-sm"> 131 + {{ template "user/fragments/picHandleLink" $starrerHandle }} 132 + starred 133 + <a href="/{{ $repoOwnerHandle }}/{{ .Repo.Name }}" class="no-underline hover:underline"> 134 + {{ $repoOwnerHandle | truncateAt30 }}/{{ .Repo.Name }} 135 + </a> 136 + <span class="text-gray-700 dark:text-gray-400 text-xs">{{ template "repo/fragments/time" .Created }}</span> 121 137 </div> 122 138 {{ with .Repo }} 123 139 {{ template "user/fragments/repoCard" (list $root . true) }} 124 140 {{ end }} 125 141 {{ end }} 126 142 {{ end }} 143 + 127 144 128 145 {{ define "followEvent" }} 129 146 {{ $root := index . 0 }} ··· 129 154 130 155 {{ $userHandle := resolve $follow.UserDid }} 131 156 {{ $subjectHandle := resolve $follow.SubjectDid }} 132 - <div 133 - class="pl-6 py-2 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 flex flex-wrap items-center gap-2 text-sm"> 134 - {{ template "user/fragments/picHandleLink" $userHandle }} 135 - followed 136 - {{ template "user/fragments/picHandleLink" $subjectHandle }} 137 - <span class="text-gray-700 dark:text-gray-400 text-xs"> 138 - {{ template "repo/fragments/time" $follow.FollowedAt }} 139 - </span> 157 + <div class="pl-6 py-2 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 flex flex-wrap items-center gap-2 text-sm"> 158 + {{ template "user/fragments/picHandleLink" $userHandle }} 159 + followed 160 + {{ template "user/fragments/picHandleLink" $subjectHandle }} 161 + <span class="text-gray-700 dark:text-gray-400 text-xs">{{ template "repo/fragments/time" $follow.FollowedAt }}</span> 140 162 </div> 141 - <div 142 - class="py-4 px-6 drop-shadow-sm rounded bg-white dark:bg-gray-800 flex items-center gap-4"> 163 + <div class="py-4 px-6 drop-shadow-sm rounded bg-white dark:bg-gray-800 flex items-center gap-4"> 143 164 <div class="flex-shrink-0 max-h-full w-24 h-24"> 144 - <img 145 - class="object-cover rounded-full p-2" 146 - src="{{ fullAvatar $subjectHandle }}" /> 165 + <img class="object-cover rounded-full p-2" src="{{ fullAvatar $subjectHandle }}" /> 147 166 </div> 148 167 149 168 <div class="flex-1 min-h-0 justify-around flex flex-col"> 150 169 <a href="/{{ $subjectHandle }}"> 151 - <span 152 - class="font-bold dark:text-white overflow-hidden text-ellipsis whitespace-nowrap max-w-full"> 153 - {{ $subjectHandle | truncateAt30 }} 154 - </span> 170 + <span class="font-bold dark:text-white overflow-hidden text-ellipsis whitespace-nowrap max-w-full">{{ $subjectHandle | truncateAt30 }}</span> 155 171 </a> 156 172 {{ with $profile }} 157 173 {{ with .Description }} 158 - <p class="text-sm pb-2 md:pb-2">{{ . }}</p> 174 + <p class="text-sm pb-2 md:pb-2">{{.}}</p> 159 175 {{ end }} 160 176 {{ end }} 161 177 {{ with $stat }} 162 - <div 163 - class="text-sm flex items-center gap-2 my-2 overflow-hidden text-ellipsis whitespace-nowrap max-w-full text-sm"> 178 + <div class="text-sm flex items-center gap-2 my-2 overflow-hidden text-ellipsis whitespace-nowrap max-w-full text-sm"> 164 179 <span class="flex-shrink-0">{{ i "users" "size-4" }}</span> 165 180 <span id="followers">{{ .Followers }} followers</span> 166 181 <span class="select-none after:content-['·']"></span> 167 - <span id="following">{{ .Following }} following</span> 182 + <span id="following">{{ .Following }} following</span> 168 183 </div> 169 184 {{ end }} 170 185 </div>
+99 -83
appview/pages/templates/user/completeSignup.html
··· 1 1 {{ define "user/completeSignup" }} 2 - <!doctype html> 3 - <html lang="en" class="dark:bg-gray-900"> 4 - <head> 5 - <meta charset="UTF-8" /> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <meta property="og:title" content="complete signup · tangled" /> 8 - <meta property="og:url" content="https://tangled.sh/complete-signup" /> 9 - <meta 10 - property="og:description" 11 - content="complete your signup for tangled" /> 12 - <script src="/static/htmx.min.js"></script> 13 - <link 14 - rel="stylesheet" 15 - href="/static/tw.css?{{ cssContentHash }}" 16 - type="text/css" /> 17 - <title>complete signup &middot; tangled</title> 18 - </head> 19 - <body class="flex items-center justify-center min-h-screen"> 20 - <main class="max-w-md px-6 -mt-4"> 21 - <h1 class="text-center text-2xl font-semibold italic dark:text-white"> 22 - tangled 23 - </h1> 24 - <h2 class="text-center text-xl italic dark:text-white"> 25 - tightly-knit social coding. 26 - </h2> 27 - <form 28 - class="mt-4 max-w-sm mx-auto flex flex-col gap-4" 29 - hx-post="/signup/complete" 30 - hx-swap="none" 31 - hx-disabled-elt="#complete-signup-button"> 32 - <div class="flex flex-col"> 33 - <label for="code">verification code</label> 34 - <input 35 - type="text" 36 - id="code" 37 - name="code" 38 - tabindex="1" 39 - required 40 - placeholder="tngl-sh-foo-bar" /> 41 - <span class="text-sm text-gray-500 mt-1"> 42 - Enter the code sent to your email. 43 - </span> 44 - </div> 2 + <!doctype html> 3 + <html lang="en" class="dark:bg-gray-900"> 4 + <head> 5 + <meta charset="UTF-8" /> 6 + <meta 7 + name="viewport" 8 + content="width=device-width, initial-scale=1.0" 9 + /> 10 + <meta 11 + property="og:title" 12 + content="complete signup · tangled" 13 + /> 14 + <meta 15 + property="og:url" 16 + content="https://tangled.sh/complete-signup" 17 + /> 18 + <meta 19 + property="og:description" 20 + content="complete your signup for tangled" 21 + /> 22 + <script src="/static/htmx.min.js"></script> 23 + <link 24 + rel="stylesheet" 25 + href="/static/tw.css?{{ cssContentHash }}" 26 + type="text/css" 27 + /> 28 + <title>complete signup &middot; tangled</title> 29 + </head> 30 + <body class="flex items-center justify-center min-h-screen"> 31 + <main class="max-w-md px-6 -mt-4"> 32 + <h1 33 + class="text-center text-2xl font-semibold italic dark:text-white" 34 + > 35 + tangled 36 + </h1> 37 + <h2 class="text-center text-xl italic dark:text-white"> 38 + tightly-knit social coding. 39 + </h2> 40 + <form 41 + class="mt-4 max-w-sm mx-auto flex flex-col gap-4" 42 + hx-post="/signup/complete" 43 + hx-swap="none" 44 + hx-disabled-elt="#complete-signup-button" 45 + > 46 + <div class="flex flex-col"> 47 + <label for="code">verification code</label> 48 + <input 49 + type="text" 50 + id="code" 51 + name="code" 52 + tabindex="1" 53 + required 54 + placeholder="tngl-sh-foo-bar" 55 + /> 56 + <span class="text-sm text-gray-500 mt-1"> 57 + Enter the code sent to your email. 58 + </span> 59 + </div> 45 60 46 - <div class="flex flex-col"> 47 - <label for="username">username</label> 48 - <input 49 - type="text" 50 - id="username" 51 - name="username" 52 - tabindex="2" 53 - required 54 - placeholder="jason" /> 55 - <span class="text-sm text-gray-500 mt-1"> 56 - Your complete handle will be of the form 57 - <code>user.tngl.sh</code> 58 - . 59 - </span> 60 - </div> 61 + <div class="flex flex-col"> 62 + <label for="username">username</label> 63 + <input 64 + type="text" 65 + id="username" 66 + name="username" 67 + tabindex="2" 68 + required 69 + placeholder="jason" 70 + /> 71 + <span class="text-sm text-gray-500 mt-1"> 72 + Your complete handle will be of the form <code>user.tngl.sh</code>. 73 + </span> 74 + </div> 61 75 62 - <div class="flex flex-col"> 63 - <label for="password">password</label> 64 - <input 65 - type="password" 66 - id="password" 67 - name="password" 68 - tabindex="3" 69 - required /> 70 - <span class="text-sm text-gray-500 mt-1"> 71 - Choose a strong password for your account. 72 - </span> 73 - </div> 76 + <div class="flex flex-col"> 77 + <label for="password">password</label> 78 + <input 79 + type="password" 80 + id="password" 81 + name="password" 82 + tabindex="3" 83 + required 84 + /> 85 + <span class="text-sm text-gray-500 mt-1"> 86 + Choose a strong password for your account. 87 + </span> 88 + </div> 74 89 75 - <button 76 - class="btn-create w-full my-2 mt-6 text-base" 77 - type="submit" 78 - id="complete-signup-button" 79 - tabindex="4"> 80 - <span>complete signup</span> 81 - </button> 82 - </form> 83 - <p id="signup-error" class="error w-full"></p> 84 - <p id="signup-msg" class="dark:text-white w-full"></p> 85 - </main> 86 - </body> 87 - </html> 90 + <button 91 + class="btn-create w-full my-2 mt-6 text-base" 92 + type="submit" 93 + id="complete-signup-button" 94 + tabindex="4" 95 + > 96 + <span>complete signup</span> 97 + </button> 98 + </form> 99 + <p id="signup-error" class="error w-full"></p> 100 + <p id="signup-msg" class="dark:text-white w-full"></p> 101 + </main> 102 + </body> 103 + </html> 88 104 {{ end }}
+4 -12
appview/pages/templates/user/fragments/bluesky.html
··· 1 1 {{ define "user/fragments/bluesky" }} 2 - <svg 3 - class="{{ . }}" 4 - xmlns="http://www.w3.org/2000/svg" 5 - role="img" 6 - viewBox="-3 -3 30 30"> 7 - <title>Bluesky</title> 8 - <path 9 - fill="none" 10 - stroke="currentColor" 11 - d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z" 12 - stroke-width="2.25" /> 13 - </svg> 2 + <svg class="{{.}}" xmlns="http://www.w3.org/2000/svg" role="img" viewBox="-3 -3 30 30"> 3 + <title>Bluesky</title> 4 + <path fill="none" stroke="currentColor" d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z" stroke-width="2.25"/> 5 + </svg> 14 6 {{ end }}
+29 -61
appview/pages/templates/user/fragments/editBio.html
··· 11 11 {{ $description = .Profile.Description }} 12 12 {{ end }} 13 13 <label class="m-0 p-0" for="description">bio</label> 14 - <textarea 15 - type="text" 16 - class="py-1 px-1 w-full" 17 - name="description" 14 + <textarea 15 + type="text" 16 + class="py-1 px-1 w-full" 17 + name="description" 18 18 rows="3" 19 - placeholder="write a bio"> 20 - {{ $description }}</textarea 21 - > 19 + placeholder="write a bio">{{ $description }}</textarea> 22 20 </div> 23 21 24 22 <div class="flex flex-col gap-1"> ··· 27 29 {{ $location = .Profile.Location }} 28 30 {{ end }} 29 31 <span class="flex-shrink-0">{{ i "map-pin" "size-4" }}</span> 30 - <input 31 - type="text" 32 - class="py-1 px-1 w-full" 33 - name="location" 34 - value="{{ $location }}" /> 32 + <input type="text" class="py-1 px-1 w-full" name="location" value="{{ $location }}"> 35 33 </div> 36 34 </div> 37 35 ··· 38 44 {{ if and .Profile .Profile.IncludeBluesky }} 39 45 {{ $includeBsky = true }} 40 46 {{ end }} 41 - <input 42 - type="checkbox" 43 - id="includeBluesky" 44 - name="includeBluesky" 45 - value="on" 46 - {{ if $includeBsky }}checked{{ end }} /> 47 - <label for="includeBluesky" class="my-0 py-0 normal-case font-normal"> 48 - Link to Bluesky account 49 - </label> 47 + <input type="checkbox" id="includeBluesky" name="includeBluesky" value="on" {{if $includeBsky}}checked{{end}}> 48 + <label for="includeBluesky" class="my-0 py-0 normal-case font-normal">Link to Bluesky account</label> 50 49 </div> 51 50 52 51 {{ $profile := .Profile }} ··· 51 64 {{ end }} 52 65 {{ end }} 53 66 54 - 55 67 <div class="flex items-center gap-2 w-full"> 56 68 <span class="flex-shrink-0">{{ i "link" "size-4" }}</span> 57 - <input 58 - type="text" 59 - class="py-1 px-1 w-full" 60 - name="link{{ $idx }}" 61 - value="{{ $link }}" 62 - placeholder="social link {{ add $idx 1 }}" /> 69 + <input type="text" class="py-1 px-1 w-full" name="link{{$idx}}" value="{{ $link }}" placeholder="social link {{add $idx 1}}"> 63 70 </div> 64 71 {{ end }} 65 72 </div> ··· 61 80 <div class="flex flex-col gap-1"> 62 81 <label class="m-0 p-0">vanity stats</label> 63 82 {{ range $idx, $s := (sequence 2) }} 64 - {{ $stat := "" }} 65 - {{ if and $profile $profile.Stats }} 66 - {{ if lt $idx (len $profile.Stats) }} 67 - {{ $s := index $profile.Stats $idx }} 68 - {{ $stat = $s.Kind }} 83 + {{ $stat := "" }} 84 + {{ if and $profile $profile.Stats }} 85 + {{ if lt $idx (len $profile.Stats) }} 86 + {{ $s := index $profile.Stats $idx }} 87 + {{ $stat = $s.Kind }} 88 + {{ end }} 69 89 {{ end }} 70 - {{ end }} 71 90 72 - {{ block "stat" (list $idx $stat) }}{{ end }} 91 + {{ block "stat" (list $idx $stat) }} {{ end }} 73 92 {{ end }} 74 93 </div> 75 94 76 95 <div class="flex items-center gap-2 justify-between"> 77 - <button 78 - id="save-btn" 79 - type="submit" 80 - class="btn p-1 w-full flex items-center gap-2 no-underline text-sm"> 96 + <button id="save-btn" type="submit" class="btn p-1 w-full flex items-center gap-2 no-underline text-sm"> 81 97 {{ i "check" "size-4" }} save 82 98 <span id="spinner" class="group"> 83 99 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 84 100 </span> 85 101 </button> 86 - <a 87 - href="/{{ .LoggedInUser.Did }}" 88 - class="w-full no-underline hover:no-underline"> 89 - <button 90 - id="cancel-btn" 91 - type="button" 92 - class="btn p-1 w-full flex items-center gap-2 no-underline text-sm"> 102 + <a href="/{{.LoggedInUser.Did}}" class="w-full no-underline hover:no-underline"> 103 + <button id="cancel-btn" type="button" class="btn p-1 w-full flex items-center gap-2 no-underline text-sm"> 93 104 {{ i "x" "size-4" }} cancel 94 105 </button> 95 106 </a> ··· 92 119 {{ define "stat" }} 93 120 {{ $id := index . 0 }} 94 121 {{ $stat := index . 1 }} 95 - <select 96 - class="stat-group w-full p-1 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700 text-sm" 97 - id="stat{{ $id }}" 98 - name="stat{{ $id }}"> 122 + <select class="stat-group w-full p-1 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700 text-sm" id="stat{{$id}}" name="stat{{$id}}"> 99 123 <option value="">choose stat</option> 100 124 {{ $stats := assoc 101 - "merged-pull-request-count" "Merged PR Count" 102 - "closed-pull-request-count" "Closed PR Count" 103 - "open-pull-request-count" "Open PR Count" 104 - "open-issue-count" "Open Issue Count" 105 - "closed-issue-count" "Closed Issue Count" 106 - "repository-count" "Repository Count" 125 + "merged-pull-request-count" "Merged PR Count" 126 + "closed-pull-request-count" "Closed PR Count" 127 + "open-pull-request-count" "Open PR Count" 128 + "open-issue-count" "Open Issue Count" 129 + "closed-issue-count" "Closed Issue Count" 130 + "repository-count" "Repository Count" 107 131 }} 108 132 {{ range $s := $stats }} 109 - {{ $value := index $s 0 }} 110 - {{ $label := index $s 1 }} 111 - <option value="{{ $value }}" {{ if eq $stat $value }}selected{{ end }}> 112 - {{ $label }} 113 - </option> 133 + {{ $value := index $s 0 }} 134 + {{ $label := index $s 1 }} 135 + <option value="{{ $value }}"{{ if eq $stat $value }} selected{{ end }}>{{ $label }}</option> 114 136 {{ end }} 115 137 </select> 116 138 {{ end }}
+29 -48
appview/pages/templates/user/fragments/editPins.html
··· 1 1 {{ define "user/fragments/editPins" }} 2 2 {{ $profile := .Profile }} 3 - <form 4 - hx-post="/profile/pins" 5 - hx-disabled-elt="#save-btn,#cancel-btn" 6 - hx-swap="none" 7 - hx-indicator="#spinner"> 8 - <div class="flex items-center justify-between mb-2"> 9 - <p class="text-sm font-bold p-2 dark:text-white">SELECT PINNED REPOS</p> 10 - <div class="flex items-center gap-2"> 11 - <button 12 - id="save-btn" 13 - type="submit" 14 - class="btn px-2 flex items-center gap-2 no-underline text-sm"> 15 - {{ i "check" "w-3 h-3" }} save 16 - <span id="spinner" class="group"> 17 - {{ i "loader-circle" "w-3 h-3 animate-spin hidden group-[.htmx-request]:inline" }} 18 - </span> 19 - </button> 20 - <a 21 - href="/{{ .LoggedInUser.Did }}" 22 - class="w-full no-underline hover:no-underline"> 23 - <button 24 - id="cancel-btn" 25 - type="button" 26 - class="btn px-2 w-full flex items-center gap-2 no-underline text-sm"> 27 - {{ i "x" "w-3 h-3" }} cancel 3 + <form 4 + hx-post="/profile/pins" 5 + hx-disabled-elt="#save-btn,#cancel-btn" 6 + hx-swap="none" 7 + hx-indicator="#spinner"> 8 + <div class="flex items-center justify-between mb-2"> 9 + <p class="text-sm font-bold p-2 dark:text-white">SELECT PINNED REPOS</p> 10 + <div class="flex items-center gap-2"> 11 + <button id="save-btn" type="submit" class="btn px-2 flex items-center gap-2 no-underline text-sm"> 12 + {{ i "check" "w-3 h-3" }} save 13 + <span id="spinner" class="group"> 14 + {{ i "loader-circle" "w-3 h-3 animate-spin hidden group-[.htmx-request]:inline" }} 15 + </span> 28 16 </button> 29 - </a> 17 + <a href="/{{.LoggedInUser.Did}}" class="w-full no-underline hover:no-underline"> 18 + <button id="cancel-btn" type="button" class="btn px-2 w-full flex items-center gap-2 no-underline text-sm"> 19 + {{ i "x" "w-3 h-3" }} cancel 20 + </button> 21 + </a> 22 + </div> 30 23 </div> 31 - </div> 32 - <div 33 - id="repos" 34 - class="grid grid-cols-1 gap-1 mb-6 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700"> 35 - {{ range $idx, $r := .AllRepos }} 36 - <div 37 - class="flex items-center gap-2 text-base p-2 border-b border-gray-200 dark:border-gray-700"> 38 - <input 39 - type="checkbox" 40 - id="repo-{{ $idx }}" 41 - name="pinnedRepo{{ $idx }}" 42 - value="{{ .RepoAt }}" 43 - {{ if .IsPinned }}checked{{ end }} /> 44 - <label 45 - for="repo-{{ $idx }}" 46 - class="my-0 py-0 normal-case font-normal w-full"> 24 + <div id="repos" class="grid grid-cols-1 gap-1 mb-6 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700"> 25 + {{ range $idx, $r := .AllRepos }} 26 + <div class="flex items-center gap-2 text-base p-2 border-b border-gray-200 dark:border-gray-700"> 27 + <input type="checkbox" id="repo-{{$idx}}" name="pinnedRepo{{$idx}}" value="{{.RepoAt}}" {{if .IsPinned}}checked{{end}}> 28 + <label for="repo-{{$idx}}" class="my-0 py-0 normal-case font-normal w-full"> 47 29 <div class="flex justify-between items-center w-full"> 48 - <span class="flex-shrink-0 overflow-hidden text-ellipsis "> 49 - {{ resolve .Did }}/{{ .Name }} 50 - </span> 30 + <span class="flex-shrink-0 overflow-hidden text-ellipsis ">{{ resolve .Did }}/{{.Name}}</span> 51 31 <div class="flex gap-1 items-center"> 52 32 {{ i "star" "size-4 fill-current" }} 53 33 <span>{{ .RepoStats.StarCount }}</span> ··· 35 55 </div> 36 56 </label> 37 57 </div> 38 - {{ end }} 39 - </div> 40 - </form> 58 + {{ end }} 59 + </div> 60 + 61 + </form> 41 62 {{ end }}
+7 -10
appview/pages/templates/user/fragments/follow.html
··· 1 1 {{ define "user/fragments/follow" }} 2 - <button 3 - id="followBtn" 2 + <button id="followBtn" 4 3 class="btn mt-2 w-full flex gap-2 items-center group" 4 + 5 5 {{ if eq .FollowStatus.String "IsNotFollowing" }} 6 - hx-post="/follow?subject={{ .UserDid }}" 6 + hx-post="/follow?subject={{.UserDid}}" 7 7 {{ else }} 8 - hx-delete="/follow?subject={{ .UserDid }}" 8 + hx-delete="/follow?subject={{.UserDid}}" 9 9 {{ end }} 10 10 11 11 hx-trigger="click" 12 12 hx-target="#followBtn" 13 - hx-swap="outerHTML"> 14 - {{ if eq .FollowStatus.String "IsNotFollowing" }} 15 - Follow 16 - {{ else }} 17 - Unfollow 18 - {{ end }} 13 + hx-swap="outerHTML" 14 + > 15 + {{ if eq .FollowStatus.String "IsNotFollowing" }}Follow{{ else }}Unfollow{{ end }} 19 16 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 20 17 </button> 21 18 {{ end }}
+4 -3
appview/pages/templates/user/fragments/picHandle.html
··· 1 1 {{ define "user/fragments/picHandle" }} 2 - <img 2 + <img 3 3 src="{{ tinyAvatar . }}" 4 4 alt="{{ . }}" 5 - class="rounded-full h-6 w-6 mr-1 border border-gray-300 dark:border-gray-700" /> 6 - {{ . | truncateAt30 }} 5 + class="rounded-full h-6 w-6 mr-1 border border-gray-300 dark:border-gray-700" 6 + /> 7 + {{ . | truncateAt30 }} 7 8 {{ end }}
+3 -3
appview/pages/templates/user/fragments/picHandleLink.html
··· 1 1 {{ define "user/fragments/picHandleLink" }} 2 - {{ $resolved := resolve . }} 3 - <a href="/{{ $resolved }}" class="flex items-center"> 2 + {{ $resolved := resolve . }} 3 + <a href="/{{ $resolved }}" class="flex items-center"> 4 4 {{ template "user/fragments/picHandle" $resolved }} 5 - </a> 5 + </a> 6 6 {{ end }}
+44 -59
appview/pages/templates/user/fragments/profileCard.html
··· 1 1 {{ define "user/fragments/profileCard" }} 2 - <div 3 - class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm max-h-fit"> 2 + <div class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm max-h-fit"> 4 3 <div class="grid grid-cols-3 md:grid-cols-1 gap-1 items-center"> 5 4 <div id="avatar" class="col-span-1 flex justify-center items-center"> 6 5 <div class="w-3/4 aspect-square relative"> 7 - <img 8 - class="absolute inset-0 w-full h-full object-cover rounded-full p-2" 9 - src="{{ fullAvatar .UserDid }}" /> 6 + <img class="absolute inset-0 w-full h-full object-cover rounded-full p-2" src="{{ fullAvatar .UserDid }}" /> 10 7 </div> 11 8 </div> 12 9 <div class="col-span-2"> 13 10 <div class="flex items-center flex-row flex-nowrap gap-2"> 14 - <p 15 - title="{{ didOrHandle .UserDid .UserHandle }}" 16 - class="text-lg font-bold dark:text-white overflow-hidden text-ellipsis whitespace-nowrap"> 11 + <p title="{{ didOrHandle .UserDid .UserHandle }}" 12 + class="text-lg font-bold dark:text-white overflow-hidden text-ellipsis whitespace-nowrap"> 17 13 {{ didOrHandle .UserDid .UserHandle }} 18 14 </p> 19 - <a href="/{{ didOrHandle .UserDid .UserHandle }}/feed.atom"> 20 - {{ i "rss" "size-4" }} 21 - </a> 15 + <a href="/{{ didOrHandle .UserDid .UserHandle }}/feed.atom">{{ i "rss" "size-4" }}</a> 22 16 </div> 23 17 24 18 <div class="md:hidden"> 25 - {{ block "followerFollowing" (list .Followers .Following) }}{{ end }} 19 + {{ block "followerFollowing" (list .Followers .Following) }} {{ end }} 26 20 </div> 27 21 </div> 28 22 <div class="col-span-3 md:col-span-full"> 29 23 <div id="profile-bio" class="text-sm"> 30 24 {{ $profile := .Profile }} 31 25 {{ with .Profile }} 32 - {{ if .Description }} 33 - <p class="text-base pb-4 md:pb-2">{{ .Description }}</p> 34 - {{ end }} 35 26 27 + {{ if .Description }} 28 + <p class="text-base pb-4 md:pb-2">{{ .Description }}</p> 29 + {{ end }} 36 30 37 - <div class="hidden md:block"> 38 - {{ block "followerFollowing" (list $.Followers $.Following) }} 39 - {{ end }} 31 + <div class="hidden md:block"> 32 + {{ block "followerFollowing" (list $.Followers $.Following) }} {{ end }} 33 + </div> 34 + 35 + <div class="flex flex-col gap-2 mb-2 overflow-hidden text-ellipsis whitespace-nowrap max-w-full"> 36 + {{ if .Location }} 37 + <div class="flex items-center gap-2"> 38 + <span class="flex-shrink-0">{{ i "map-pin" "size-4" }}</span> 39 + <span>{{ .Location }}</span> 40 40 </div> 41 - 42 - <div 43 - class="flex flex-col gap-2 mb-2 overflow-hidden text-ellipsis whitespace-nowrap max-w-full"> 44 - {{ if .Location }} 45 - <div class="flex items-center gap-2"> 46 - <span class="flex-shrink-0">{{ i "map-pin" "size-4" }}</span> 47 - <span>{{ .Location }}</span> 48 - </div> 41 + {{ end }} 42 + {{ if .IncludeBluesky }} 43 + <div class="flex items-center gap-2"> 44 + <span class="flex-shrink-0">{{ template "user/fragments/bluesky" "w-4 h-4 text-black dark:text-white" }}</span> 45 + <a id="bluesky-link" href="https://bsky.app/profile/{{ $.UserDid }}">{{ didOrHandle $.UserDid $.UserHandle }}</a> 46 + </div> 47 + {{ end }} 48 + {{ range $link := .Links }} 49 + {{ if $link }} 50 + <div class="flex items-center gap-2"> 51 + <span class="flex-shrink-0">{{ i "link" "size-4" }}</span> 52 + <a href="{{ $link }}">{{ $link }}</a> 53 + </div> 49 54 {{ end }} 50 - {{ if .IncludeBluesky }} 51 - <div class="flex items-center gap-2"> 52 - <span class="flex-shrink-0"> 53 - {{ template "user/fragments/bluesky" "w-4 h-4 text-black dark:text-white" }} 54 - </span> 55 - <a 56 - id="bluesky-link" 57 - href="https://bsky.app/profile/{{ $.UserDid }}"> 58 - {{ didOrHandle $.UserDid $.UserHandle }} 59 - </a> 60 - </div> 61 - {{ end }} 62 - {{ range $link := .Links }} 63 - {{ if $link }} 64 - <div class="flex items-center gap-2"> 65 - <span class="flex-shrink-0">{{ i "link" "size-4" }}</span> 66 - <a href="{{ $link }}">{{ $link }}</a> 55 + {{ end }} 56 + {{ if not $profile.IsStatsEmpty }} 57 + <div class="flex items-center justify-evenly gap-2 py-2"> 58 + {{ range $stat := .Stats }} 59 + {{ if $stat.Kind }} 60 + <div class="flex flex-col items-center gap-2"> 61 + <span class="text-xl font-bold">{{ $stat.Value }}</span> 62 + <span>{{ $stat.Kind.String }}</span> 67 63 </div> 68 64 {{ end }} 69 65 {{ end }} 70 - {{ if not $profile.IsStatsEmpty }} 71 - <div class="flex items-center justify-evenly gap-2 py-2"> 72 - {{ range $stat := .Stats }} 73 - {{ if $stat.Kind }} 74 - <div class="flex flex-col items-center gap-2"> 75 - <span class="text-xl font-bold">{{ $stat.Value }}</span> 76 - <span>{{ $stat.Kind.String }}</span> 77 - </div> 78 - {{ end }} 79 - {{ end }} 80 - </div> 81 - {{ end }} 82 66 </div> 67 + {{ end }} 68 + </div> 83 69 {{ end }} 84 70 {{ if ne .FollowStatus.String "IsSelf" }} 85 71 {{ template "user/fragments/follow" . }} 86 72 {{ else }} 87 - <button 88 - id="editBtn" 73 + <button id="editBtn" 89 74 class="btn mt-2 w-full flex items-center gap-2 group" 90 75 hx-target="#profile-bio" 91 76 hx-get="/profile/edit-bio" ··· 90 105 {{ define "followerFollowing" }} 91 106 {{ $followers := index . 0 }} 92 107 {{ $following := index . 1 }} 93 - <div 94 - class="flex items-center gap-2 my-2 overflow-hidden text-ellipsis whitespace-nowrap max-w-full text-sm"> 108 + <div class="flex items-center gap-2 my-2 overflow-hidden text-ellipsis whitespace-nowrap max-w-full text-sm"> 95 109 <span class="flex-shrink-0">{{ i "users" "size-4" }}</span> 96 110 <span id="followers">{{ $followers }} followers</span> 97 111 <span class="select-none after:content-['·']"></span> 98 112 <span id="following">{{ $following }} following</span> 99 113 </div> 100 114 {{ end }} 115 +
+3 -7
appview/pages/templates/user/fragments/repoCard.html
··· 4 4 {{ $fullName := index . 2 }} 5 5 6 6 {{ with $repo }} 7 - <div 8 - class="py-4 px-6 gap-2 flex flex-col drop-shadow-sm rounded bg-white dark:bg-gray-800"> 7 + <div class="py-4 px-6 gap-2 flex flex-col drop-shadow-sm rounded bg-white dark:bg-gray-800"> 9 8 <div class="font-medium dark:text-white flex items-center"> 10 9 {{ if .Source }} 11 10 {{ i "git-fork" "w-4 h-4 mr-1.5 shrink-0" }} ··· 14 15 15 16 {{ $repoOwner := resolve .Did }} 16 17 {{- if $fullName -}} 17 - <a href="/{{ $repoOwner }}/{{ .Name }}"> 18 - {{ $repoOwner }}/{{ .Name }} 19 - </a> 18 + <a href="/{{ $repoOwner }}/{{ .Name }}">{{ $repoOwner }}/{{ .Name }}</a> 20 19 {{- else -}} 21 20 <a href="/{{ $repoOwner }}/{{ .Name }}">{{ .Name }}</a> 22 21 {{- end -}} ··· 36 39 <div class="text-gray-400 text-sm font-mono inline-flex gap-4 mt-auto"> 37 40 {{ with .Language }} 38 41 <div class="flex gap-2 items-center text-sm"> 39 - <div 40 - class="size-2 rounded-full" 42 + <div class="size-2 rounded-full" 41 43 style="background: radial-gradient(circle at 35% 35%, color-mix(in srgb, {{ langColor . }} 70%, white), {{ langColor . }} 30%, color-mix(in srgb, {{ langColor . }} 85%, black));"></div> 42 44 <span>{{ . }}</span> 43 45 </div>
+59 -67
appview/pages/templates/user/login.html
··· 1 1 {{ define "user/login" }} 2 - <!doctype html> 3 - <html lang="en" class="dark:bg-gray-900"> 4 - <head> 5 - <meta charset="UTF-8" /> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <meta property="og:title" content="login · tangled" /> 8 - <meta property="og:url" content="https://tangled.sh/login" /> 9 - <meta property="og:description" content="login to for tangled" /> 10 - <script src="/static/htmx.min.js"></script> 11 - <link 12 - rel="stylesheet" 13 - href="/static/tw.css?{{ cssContentHash }}" 14 - type="text/css" /> 15 - <title>login &middot; tangled</title> 16 - </head> 17 - <body class="flex items-center justify-center min-h-screen"> 18 - <main class="max-w-md px-6 -mt-4"> 19 - <h1 class="text-center text-2xl font-semibold italic dark:text-white"> 20 - tangled 21 - </h1> 22 - <h2 class="text-center text-xl italic dark:text-white"> 23 - tightly-knit social coding. 24 - </h2> 25 - <form 26 - class="mt-4 max-w-sm mx-auto" 27 - hx-post="/login" 28 - hx-swap="none" 29 - hx-disabled-elt="#login-button"> 30 - <div class="flex flex-col"> 31 - <label for="handle">handle</label> 32 - <input 33 - type="text" 34 - id="handle" 35 - name="handle" 36 - tabindex="1" 37 - required 38 - placeholder="akshay.tngl.sh" /> 39 - <span class="text-sm text-gray-500 mt-1"> 40 - Use your 41 - <a href="https://atproto.com">ATProto</a> 42 - handle to log in. If you're unsure, this is likely your Tangled ( 43 - <code>.tngl.sh</code> 44 - ) or 45 - <a href="https://bsky.app">Bluesky</a> 46 - ( 47 - <code>.bsky.social</code> 48 - ) account. 49 - </span> 50 - </div> 51 - <input type="hidden" name="return_url" value="{{ .ReturnUrl }}" /> 2 + <!doctype html> 3 + <html lang="en" class="dark:bg-gray-900"> 4 + <head> 5 + <meta charset="UTF-8" /> 6 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 + <meta property="og:title" content="login · tangled" /> 8 + <meta property="og:url" content="https://tangled.sh/login" /> 9 + <meta property="og:description" content="login to for tangled" /> 10 + <script src="/static/htmx.min.js"></script> 11 + <link rel="stylesheet" href="/static/tw.css?{{ cssContentHash }}" type="text/css" /> 12 + <title>login &middot; tangled</title> 13 + </head> 14 + <body class="flex items-center justify-center min-h-screen"> 15 + <main class="max-w-md px-6 -mt-4"> 16 + <h1 class="text-center text-2xl font-semibold italic dark:text-white" > 17 + tangled 18 + </h1> 19 + <h2 class="text-center text-xl italic dark:text-white"> 20 + tightly-knit social coding. 21 + </h2> 22 + <form 23 + class="mt-4 max-w-sm mx-auto" 24 + hx-post="/login" 25 + hx-swap="none" 26 + hx-disabled-elt="#login-button" 27 + > 28 + <div class="flex flex-col"> 29 + <label for="handle">handle</label> 30 + <input 31 + type="text" 32 + id="handle" 33 + name="handle" 34 + tabindex="1" 35 + required 36 + placeholder="akshay.tngl.sh" 37 + /> 38 + <span class="text-sm text-gray-500 mt-1"> 39 + Use your <a href="https://atproto.com">ATProto</a> 40 + handle to log in. If you're unsure, this is likely 41 + your Tangled (<code>.tngl.sh</code>) or <a href="https://bsky.app">Bluesky</a> (<code>.bsky.social</code>) account. 42 + </span> 43 + </div> 44 + <input type="hidden" name="return_url" value="{{ .ReturnUrl }}"> 52 45 53 - <button 54 - class="btn w-full my-2 mt-6 text-base " 55 - type="submit" 56 - id="login-button" 57 - tabindex="3"> 58 - <span>login</span> 59 - </button> 60 - </form> 61 - <p class="text-sm text-gray-500"> 62 - Don't have an account? 63 - <a href="/signup" class="underline">Create an account</a> 64 - on Tangled now! 65 - </p> 46 + <button 47 + class="btn w-full my-2 mt-6 text-base " 48 + type="submit" 49 + id="login-button" 50 + tabindex="3" 51 + > 52 + <span>login</span> 53 + </button> 54 + </form> 55 + <p class="text-sm text-gray-500"> 56 + Don't have an account? <a href="/signup" class="underline">Create an account</a> on Tangled now! 57 + </p> 66 58 67 - <p id="login-msg" class="error w-full"></p> 68 - </main> 69 - </body> 70 - </html> 59 + <p id="login-msg" class="error w-full"></p> 60 + </main> 61 + </body> 62 + </html> 71 63 {{ end }}
+66 -112
appview/pages/templates/user/profile.html
··· 1 1 {{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }}{{ end }} 2 2 3 3 {{ define "extrameta" }} 4 - <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}" /> 5 - <meta property="og:type" content="profile" /> 6 - <meta 7 - property="og:url" 8 - content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}" /> 9 - <meta 10 - property="og:description" 11 - content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 4 + <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}" /> 5 + <meta property="og:type" content="profile" /> 6 + <meta property="og:url" content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}" /> 7 + <meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 12 8 {{ end }} 13 9 14 10 {{ define "content" }} 15 - <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 11 + <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 16 12 <div class="md:col-span-3 order-1 md:order-1"> 17 13 <div class="grid grid-cols-1 gap-4"> 18 14 {{ template "user/fragments/profileCard" .Card }} 19 - {{ block "punchcard" .Punchcard }}{{ end }} 15 + {{ block "punchcard" .Punchcard }} {{ end }} 20 16 </div> 21 17 </div> 22 18 <div id="all-repos" class="md:col-span-4 order-2 md:order-2"> ··· 22 26 </div> 23 27 </div> 24 28 <div class="md:col-span-4 order-3 md:order-3"> 25 - {{ block "profileTimeline" . }}{{ end }} 29 + {{ block "profileTimeline" . }}{{ end }} 26 30 </div> 27 - </div> 31 + </div> 28 32 {{ end }} 29 33 30 34 {{ define "profileTimeline" }} ··· 33 37 {{ with .ProfileTimeline }} 34 38 {{ range $idx, $byMonth := .ByMonth }} 35 39 {{ with $byMonth }} 36 - <div 37 - class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm"> 38 - {{ if eq $idx 0 }} 40 + <div class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm"> 41 + {{ if eq $idx 0 }} 39 42 40 - {{ else }} 41 - {{ $s := "s" }} 42 - {{ if eq $idx 1 }} 43 - {{ $s = "" }} 44 - {{ end }} 45 - <p class="text-sm font-bold dark:text-white mb-2"> 46 - {{ $idx }} month{{ $s }} ago 47 - </p> 43 + {{ else }} 44 + {{ $s := "s" }} 45 + {{ if eq $idx 1 }} 46 + {{ $s = "" }} 48 47 {{ end }} 48 + <p class="text-sm font-bold dark:text-white mb-2">{{$idx}} month{{$s}} ago</p> 49 + {{ end }} 49 50 50 - {{ if .IsEmpty }} 51 - <div class="text-gray-500 dark:text-gray-400"> 52 - No activity for this month 53 - </div> 54 - {{ else }} 55 - <div class="flex flex-col gap-1"> 56 - {{ block "repoEvents" .RepoEvents }}{{ end }} 57 - {{ block "issueEvents" .IssueEvents }}{{ end }} 58 - {{ block "pullEvents" .PullEvents }}{{ end }} 59 - </div> 60 - {{ end }} 61 - </div> 51 + {{ if .IsEmpty }} 52 + <div class="text-gray-500 dark:text-gray-400"> 53 + No activity for this month 54 + </div> 55 + {{ else }} 56 + <div class="flex flex-col gap-1"> 57 + {{ block "repoEvents" .RepoEvents }} {{ end }} 58 + {{ block "issueEvents" .IssueEvents }} {{ end }} 59 + {{ block "pullEvents" .PullEvents }} {{ end }} 60 + </div> 61 + {{ end }} 62 + </div> 63 + 62 64 {{ end }} 63 65 {{ else }} 64 66 <p class="dark:text-white">This user does not have any activity yet.</p> ··· 68 74 {{ define "repoEvents" }} 69 75 {{ if gt (len .) 0 }} 70 76 <details> 71 - <summary 72 - class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 77 + <summary class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 73 78 <div class="flex flex-wrap items-center gap-2"> 74 79 {{ i "book-plus" "w-4 h-4" }} 75 - created 76 - {{ len . }} 77 - {{ if eq (len .) 1 }}repository{{ else }}repositories{{ end }} 80 + created {{ len . }} {{if eq (len .) 1 }}repository{{else}}repositories{{end}} 78 81 </div> 79 82 </summary> 80 83 <div class="py-2 text-sm flex flex-col gap-3 mb-2"> ··· 84 93 {{ i "book-plus" "w-4 h-4" }} 85 94 {{ end }} 86 95 </span> 87 - <a 88 - href="/{{ resolve .Repo.Did }}/{{ .Repo.Name }}" 89 - class="no-underline hover:underline"> 96 + <a href="/{{ resolve .Repo.Did }}/{{ .Repo.Name }}" class="no-underline hover:underline"> 90 97 {{- .Repo.Name -}} 91 98 </a> 92 99 </div> ··· 100 111 101 112 {{ if gt (len $items) 0 }} 102 113 <details> 103 - <summary 104 - class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 114 + <summary class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 105 115 <div class="flex flex-wrap items-center gap-2"> 106 116 {{ i "circle-dot" "w-4 h-4" }} 107 117 108 - 109 118 <div> 110 - created 111 - {{ len $items }} 112 - {{ if eq (len $items) 1 }}issue{{ else }}issues{{ end }} 119 + created {{ len $items }} {{if eq (len $items) 1 }}issue{{else}}issues{{end}} 113 120 </div> 114 121 115 122 {{ if gt $stats.Open 0 }} 116 - <span 117 - class="px-2 py-1/2 text-sm rounded text-white bg-green-600 dark:bg-green-700"> 118 - {{ $stats.Open }} open 123 + <span class="px-2 py-1/2 text-sm rounded text-white bg-green-600 dark:bg-green-700"> 124 + {{$stats.Open}} open 119 125 </span> 120 126 {{ end }} 121 127 122 128 {{ if gt $stats.Closed 0 }} 123 - <span 124 - class="px-2 py-1/2 text-sm rounded text-white bg-gray-800 dark:bg-gray-700"> 125 - {{ $stats.Closed }} closed 126 - </span> 129 + <span class="px-2 py-1/2 text-sm rounded text-white bg-gray-800 dark:bg-gray-700"> 130 + {{$stats.Closed}} closed 131 + </span> 127 132 {{ end }} 128 133 129 134 </div> ··· 127 144 {{ $repoOwner := resolve .Metadata.Repo.Did }} 128 145 {{ $repoName := .Metadata.Repo.Name }} 129 146 {{ $repoUrl := printf "%s/%s" $repoOwner $repoName }} 130 - 131 147 132 148 <div class="flex gap-2 text-gray-600 dark:text-gray-300"> 133 149 {{ if .Open }} ··· 139 157 </span> 140 158 {{ end }} 141 159 <div class="flex-none min-w-8 text-right"> 142 - <span class="text-gray-500 dark:text-gray-400"> 143 - #{{ .IssueId }} 144 - </span> 160 + <span class="text-gray-500 dark:text-gray-400">#{{ .IssueId }}</span> 145 161 </div> 146 162 <div class="break-words max-w-full"> 147 - <a 148 - href="/{{ $repoUrl }}/issues/{{ .IssueId }}" 149 - class="no-underline hover:underline"> 163 + <a href="/{{$repoUrl}}/issues/{{ .IssueId }}" class="no-underline hover:underline"> 150 164 {{ .Title -}} 151 165 </a> 152 166 on 153 - <a 154 - href="/{{ $repoUrl }}" 155 - class="no-underline hover:underline whitespace-nowrap"> 156 - {{ $repoUrl }} 167 + <a href="/{{$repoUrl}}" class="no-underline hover:underline whitespace-nowrap"> 168 + {{$repoUrl}} 157 169 </a> 158 170 </div> 159 171 </div> ··· 162 186 {{ $stats := .Stats }} 163 187 {{ if gt (len $items) 0 }} 164 188 <details> 165 - <summary 166 - class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 189 + <summary class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 167 190 <div class="flex flex-wrap items-center gap-2"> 168 191 {{ i "git-pull-request" "w-4 h-4" }} 169 192 170 - 171 193 <div> 172 - created 173 - {{ len $items }} 174 - {{ if eq (len $items) 1 }} 175 - pull request 176 - {{ else }} 177 - pull requests 178 - {{ end }} 194 + created {{ len $items }} {{if eq (len $items) 1 }}pull request{{else}}pull requests{{end}} 179 195 </div> 180 196 181 197 {{ if gt $stats.Open 0 }} 182 - <span 183 - class="px-2 py-1/2 text-sm rounded text-white bg-green-600 dark:bg-green-700"> 184 - {{ $stats.Open }} open 198 + <span class="px-2 py-1/2 text-sm rounded text-white bg-green-600 dark:bg-green-700"> 199 + {{$stats.Open}} open 185 200 </span> 186 201 {{ end }} 187 202 188 203 {{ if gt $stats.Merged 0 }} 189 - <span 190 - class="px-2 py-1/2 text-sm rounded text-white bg-purple-600 dark:bg-purple-700"> 191 - {{ $stats.Merged }} merged 204 + <span class="px-2 py-1/2 text-sm rounded text-white bg-purple-600 dark:bg-purple-700"> 205 + {{$stats.Merged}} merged 192 206 </span> 193 207 {{ end }} 194 208 209 + 195 210 {{ if gt $stats.Closed 0 }} 196 - <span 197 - class="px-2 py-1/2 text-sm rounded text-white bg-gray-800 dark:bg-gray-700"> 198 - {{ $stats.Closed }} closed 199 - </span> 211 + <span class="px-2 py-1/2 text-sm rounded text-white bg-gray-800 dark:bg-gray-700"> 212 + {{$stats.Closed}} closed 213 + </span> 200 214 {{ end }} 201 215 202 216 </div> ··· 196 230 {{ $repoOwner := resolve .Repo.Did }} 197 231 {{ $repoName := .Repo.Name }} 198 232 {{ $repoUrl := printf "%s/%s" $repoOwner $repoName }} 199 - 200 233 201 234 <div class="flex gap-2 text-gray-600 dark:text-gray-300"> 202 235 {{ if .State.IsOpen }} ··· 212 247 </span> 213 248 {{ end }} 214 249 <div class="flex-none min-w-8 text-right"> 215 - <span class="text-gray-500 dark:text-gray-400"> 216 - #{{ .PullId }} 217 - </span> 250 + <span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span> 218 251 </div> 219 252 <div class="break-words max-w-full"> 220 - <a 221 - href="/{{ $repoUrl }}/pulls/{{ .PullId }}" 222 - class="no-underline hover:underline"> 253 + <a href="/{{$repoUrl}}/pulls/{{ .PullId }}" class="no-underline hover:underline"> 223 254 {{ .Title -}} 224 255 </a> 225 256 on 226 - <a 227 - href="/{{ $repoUrl }}" 228 - class="no-underline hover:underline whitespace-nowrap"> 229 - {{ $repoUrl }} 257 + <a href="/{{$repoUrl}}" class="no-underline hover:underline whitespace-nowrap"> 258 + {{$repoUrl}} 230 259 </a> 231 260 </div> 232 261 </div> ··· 232 273 233 274 {{ define "ownRepos" }} 234 275 <div> 235 - <div 236 - class="text-sm font-bold p-2 pr-0 dark:text-white flex items-center justify-between gap-2"> 237 - <a 238 - href="/@{{ or $.Card.UserHandle $.Card.UserDid }}?tab=repos" 276 + <div class="text-sm font-bold p-2 pr-0 dark:text-white flex items-center justify-between gap-2"> 277 + <a href="/@{{ or $.Card.UserHandle $.Card.UserDid }}?tab=repos" 239 278 class="flex text-black dark:text-white items-center gap-2 no-underline hover:no-underline group"> 240 279 <span>PINNED REPOS</span> 241 - <span 242 - class="flex gap-1 items-center font-normal text-sm text-gray-500 dark:text-gray-400 "> 243 - view all 244 - {{ i "chevron-right" "w-4 h-4" }} 280 + <span class="flex gap-1 items-center font-normal text-sm text-gray-500 dark:text-gray-400 "> 281 + view all {{ i "chevron-right" "w-4 h-4" }} 245 282 </span> 246 283 </a> 247 284 {{ if and .LoggedInUser (eq .LoggedInUser.Did .Card.UserDid) }} 248 - <button 285 + <button 249 286 hx-get="profile/edit-pins" 250 287 hx-target="#all-repos" 251 288 class="btn py-0 font-normal text-sm flex gap-2 items-center group"> ··· 255 300 {{ range .Repos }} 256 301 {{ template "user/fragments/repoCard" (list $ . false) }} 257 302 {{ else }} 258 - <p class="px-6 dark:text-white"> 259 - This user does not have any repos yet. 260 - </p> 303 + <p class="px-6 dark:text-white">This user does not have any repos yet.</p> 261 304 {{ end }} 262 305 </div> 263 306 </div> ··· 269 316 {{ range .CollaboratingRepos }} 270 317 {{ template "user/fragments/repoCard" (list $ . true) }} 271 318 {{ else }} 272 - <p class="px-6 dark:text-white">This user is not collaborating.</p> 319 + <p class="px-6 dark:text-white">This user is not collaborating.</p> 273 320 {{ end }} 274 321 </div> 275 322 </div> ··· 308 355 <div class="w-full h-full flex justify-center items-center"> 309 356 <div 310 357 class="aspect-square rounded-full transition-all duration-300 {{ $theme }} max-w-full max-h-full" 311 - title="{{ .Date.Format "2006-01-02" }}: {{ .Count }} commits"></div> 358 + title="{{ .Date.Format "2006-01-02" }}: {{ .Count }} commits"> 359 + </div> 312 360 </div> 313 361 {{ end }} 314 362 </div>
+11 -17
appview/pages/templates/user/repos.html
··· 1 - {{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }} · repos{{ end }} 1 + {{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }} · repos {{ end }} 2 2 3 3 {{ define "extrameta" }} 4 - <meta 5 - property="og:title" 6 - content="{{ or .Card.UserHandle .Card.UserDid }}'s repos" /> 7 - <meta property="og:type" content="object" /> 8 - <meta 9 - property="og:url" 10 - content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}/repos" /> 11 - <meta 12 - property="og:description" 13 - content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 4 + <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}'s repos" /> 5 + <meta property="og:type" content="object" /> 6 + <meta property="og:url" content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}/repos" /> 7 + <meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 14 8 {{ end }} 15 9 16 10 {{ define "content" }} 17 - <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 11 + <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 18 12 <div class="md:col-span-3 order-1 md:order-1"> 19 - {{ template "user/fragments/profileCard" .Card }} 13 + {{ template "user/fragments/profileCard" .Card }} 20 14 </div> 21 15 <div id="all-repos" class="md:col-span-8 order-2 md:order-2"> 22 - {{ block "ownRepos" . }}{{ end }} 16 + {{ block "ownRepos" . }}{{ end }} 23 17 </div> 24 - </div> 18 + </div> 25 19 {{ end }} 26 20 27 21 {{ define "ownRepos" }} 28 22 <p class="text-sm font-bold p-2 dark:text-white">ALL REPOSITORIES</p> 29 23 <div id="repos" class="grid grid-cols-1 gap-4 mb-6"> 30 24 {{ range .Repos }} 31 - {{ template "user/fragments/repoCard" (list $ . false) }} 25 + {{ template "user/fragments/repoCard" (list $ . false) }} 32 26 {{ else }} 33 - <p class="px-6 dark:text-white">This user does not have any repos yet.</p> 27 + <p class="px-6 dark:text-white">This user does not have any repos yet.</p> 34 28 {{ end }} 35 29 </div> 36 30 {{ end }}
+50 -60
appview/pages/templates/user/signup.html
··· 1 1 {{ define "user/signup" }} 2 - <!doctype html> 3 - <html lang="en" class="dark:bg-gray-900"> 4 - <head> 5 - <meta charset="UTF-8" /> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <meta property="og:title" content="signup · tangled" /> 8 - <meta property="og:url" content="https://tangled.sh/signup" /> 9 - <meta property="og:description" content="sign up for tangled" /> 10 - <script src="/static/htmx.min.js"></script> 11 - <link 12 - rel="stylesheet" 13 - href="/static/tw.css?{{ cssContentHash }}" 14 - type="text/css" /> 15 - <title>sign up &middot; tangled</title> 16 - </head> 17 - <body class="flex items-center justify-center min-h-screen"> 18 - <main class="max-w-md px-6 -mt-4"> 19 - <h1 class="text-center text-2xl font-semibold italic dark:text-white"> 20 - tangled 21 - </h1> 22 - <h2 class="text-center text-xl italic dark:text-white"> 23 - tightly-knit social coding. 24 - </h2> 25 - <form 26 - class="mt-4 max-w-sm mx-auto" 27 - hx-post="/signup" 28 - hx-swap="none" 29 - hx-disabled-elt="#signup-button"> 30 - <div class="flex flex-col mt-2"> 31 - <label for="email">email</label> 32 - <input 33 - type="email" 34 - id="email" 35 - name="email" 36 - tabindex="4" 37 - required 38 - placeholder="jason@bourne.co" /> 39 - </div> 40 - <span class="text-sm text-gray-500 mt-1"> 41 - You will receive an email with an invite code. Enter your invite 42 - code, desired username, and password in the next page to complete 43 - your registration. 44 - </span> 45 - <button 46 - class="btn text-base w-full my-2 mt-6" 47 - type="submit" 48 - id="signup-button" 49 - tabindex="7"> 50 - <span>join now</span> 51 - </button> 52 - </form> 53 - <p class="text-sm text-gray-500"> 54 - Already have an ATProto account? 55 - <a href="/login" class="underline">Login to Tangled</a> 56 - . 57 - </p> 2 + <!doctype html> 3 + <html lang="en" class="dark:bg-gray-900"> 4 + <head> 5 + <meta charset="UTF-8" /> 6 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 + <meta property="og:title" content="signup · tangled" /> 8 + <meta property="og:url" content="https://tangled.sh/signup" /> 9 + <meta property="og:description" content="sign up for tangled" /> 10 + <script src="/static/htmx.min.js"></script> 11 + <link rel="stylesheet" href="/static/tw.css?{{ cssContentHash }}" type="text/css" /> 12 + <title>sign up &middot; tangled</title> 13 + </head> 14 + <body class="flex items-center justify-center min-h-screen"> 15 + <main class="max-w-md px-6 -mt-4"> 16 + <h1 class="text-center text-2xl font-semibold italic dark:text-white" >tangled</h1> 17 + <h2 class="text-center text-xl italic dark:text-white">tightly-knit social coding.</h2> 18 + <form 19 + class="mt-4 max-w-sm mx-auto" 20 + hx-post="/signup" 21 + hx-swap="none" 22 + hx-disabled-elt="#signup-button" 23 + > 24 + <div class="flex flex-col mt-2"> 25 + <label for="email">email</label> 26 + <input 27 + type="email" 28 + id="email" 29 + name="email" 30 + tabindex="4" 31 + required 32 + placeholder="jason@bourne.co" 33 + /> 34 + </div> 35 + <span class="text-sm text-gray-500 mt-1"> 36 + You will receive an email with an invite code. Enter your 37 + invite code, desired username, and password in the next 38 + page to complete your registration. 39 + </span> 40 + <button class="btn text-base w-full my-2 mt-6" type="submit" id="signup-button" tabindex="7" > 41 + <span>join now</span> 42 + </button> 43 + </form> 44 + <p class="text-sm text-gray-500"> 45 + Already have an ATProto account? <a href="/login" class="underline">Login to Tangled</a>. 46 + </p> 58 47 59 - <p id="signup-msg" class="error w-full"></p> 60 - </main> 61 - </body> 62 - </html> 48 + <p id="signup-msg" class="error w-full"></p> 49 + </main> 50 + </body> 51 + </html> 63 52 {{ end }} 53 +