forked from tangled.org/core
this repo has no description

improve issue styling, add comment counts

Changed files
+152 -86
appview
+29 -2
appview/db/issues.go
···
Title string
Body string
Open bool
+
Metadata *IssueMetadata
+
}
+
+
type IssueMetadata struct {
+
CommentCount int
+
// labels, assignee etc.
}
type Comment struct {
···
func GetIssues(e Execer, repoAt syntax.ATURI) ([]Issue, error) {
var issues []Issue
-
rows, err := e.Query(`select owner_did, issue_id, created, title, body, open from issues where repo_at = ? order by created desc`, repoAt)
+
rows, err := e.Query(
+
`select
+
i.owner_did,
+
i.issue_id,
+
i.created,
+
i.title,
+
i.body,
+
i.open,
+
count(c.id)
+
from
+
issues i
+
left join
+
comments c on i.repo_at = c.repo_at and i.issue_id = c.issue_id
+
where
+
i.repo_at = ?
+
group by
+
i.id, i.owner_did, i.issue_id, i.created, i.title, i.body, i.open
+
order by
+
i.created desc`,
+
repoAt)
if err != nil {
return nil, err
}
···
for rows.Next() {
var issue Issue
var createdAt string
-
err := rows.Scan(&issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open)
+
var metadata IssueMetadata
+
err := rows.Scan(&issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount)
if err != nil {
return nil, err
}
···
return nil, err
}
issue.Created = &createdTime
+
issue.Metadata = &metadata
issues = append(issues, issue)
}
+1 -1
appview/pages/templates/fragments/star.html
···
{{ define "fragments/star" }}
<button id="starBtn"
-
class="btn text-sm disabled:opacity-50 disabled:cursor-not-allowed"
+
class="text-sm disabled:opacity-50 disabled:cursor-not-allowed"
{{ if .IsStarred }}
hx-delete="/star?subject={{.RepoAt}}&countHint={{.Stats.StarCount}}"
+11 -11
appview/pages/templates/layouts/repobase.html
···
{{ define "content" }}
<section id="repo-header" class="mb-4 py-2 px-6">
-
<div class="flex gap-3">
-
<p class="text-lg">
-
<a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a>
-
<span class="select-none">/</span>
-
<a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a>
-
</p>
-
{{ template "fragments/star" .RepoInfo }}
-
</div>
+
<p class="text-lg">
+
<a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a>
+
<span class="select-none">/</span>
+
<a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a>
+
<span class="ml-3">
+
{{ template "fragments/star" .RepoInfo }}
+
</span>
+
</p>
{{ template "fragments/repoDescription" . }}
</section>
-
<section id="repo-links" class="min-h-screen flex flex-col drop-shadow-sm">
+
<section class="min-h-screen flex flex-col drop-shadow-sm">
<nav class="w-full mx-auto ml-4">
-
<div class="flex z-60">
+
<div class="flex z-60 overflow-auto">
{{ $activeTabStyles := "-mb-px bg-white" }}
{{ $tabs := .RepoInfo.GetTabs }}
{{ $tabmeta := .RepoInfo.TabMetadata }}
···
hx-boost="true"
>
<div
-
class="px-4 py-1 mr-1 text-black min-w-[80px] text-center relative rounded-t
+
class="px-4 py-1 mr-1 text-black min-w-[80px] text-center relative rounded-t whitespace-nowrap
{{ if eq $.Active $key }}
{{ $activeTabStyles }}
{{ else }}
+3 -1
appview/pages/templates/repo/index.html
···
></div>
<span>{{ timeFmt .Author.When }}</span>
{{ $tagsForCommit := index $.TagMap .Hash.String }}
-
{{ range $tagsForCommit }}
+
{{ if gt (len $tagsForCommit) 0 }}
<div
class="inline-block px-1 select-none after:content-['·']"
></div>
+
{{ end }}
+
{{ range $tagsForCommit }}
<span class="text-xs rounded bg-gray-100 font-mono px-2 mx-1/2 inline-flex items-center">
{{ . }}
</span>
+50 -36
appview/pages/templates/repo/issues/issues.html
···
<span>new issue</span>
</a>
</div>
+
{{ end }}
-
<section id="issues" class="mt-8 space-y-4">
-
{{ range .Issues }}
-
<div class="border border-gray-200 p-4 mx-4 hover:bg-gray-50">
-
<time class="float-right text-sm">
-
{{ .Created | timeFmt }}
-
</time>
-
<div class="flex items-center gap-2 py-2">
-
{{ if .Open }}
-
<i
-
data-lucide="circle-dot"
-
class="w-4 h-4 text-green-600"
-
></i>
-
{{ else }}
-
<i data-lucide="ban" class="w-4 h-4 text-red-600"></i>
-
{{ end }}
-
<a
-
href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}"
-
class="no-underline hover:underline"
-
>
-
{{ .Title }}
-
</a>
-
</div>
-
<div class="text-sm flex gap-2 text-gray-400">
-
<span>#{{ .IssueId }}</span>
-
<span class="before:content-['·']">
-
opened by
-
{{ $owner := index $.DidHandleMap .OwnerDid }}
-
<a
-
href="/{{ $owner }}"
-
class="no-underline hover:underline"
-
>{{ $owner }}</a
-
>
-
</span>
-
</div>
-
</div>
+
{{ define "repoAfter" }}
+
<div class="flex flex-col gap-2 mt-8">
+
{{ range .Issues }}
+
<div class="rounded drop-shadow-sm bg-white px-6 py-4">
+
<div class="pb-2">
+
<a
+
href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}"
+
class="no-underline hover:underline"
+
>
+
{{ .Title }}
+
<span class="text-gray-400">#{{ .IssueId }}</span>
+
</a>
+
</div>
+
<p class="text-sm text-gray-400">
+
{{ $bgColor := "bg-gray-800" }}
+
{{ $icon := "ban" }}
+
{{ $state := "closed" }}
+
{{ if .Open }}
+
{{ $bgColor = "bg-green-600" }}
+
{{ $icon = "circle-dot" }}
+
{{ $state = "open" }}
+
{{ end }}
+
+
<span class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm">
+
<i data-lucide="{{ $icon }}" class="w-3 h-3 mr-1.5 text-white"></i>
+
<span class="text-white">{{ $state }}</span>
+
</span>
+
+
<span>
+
{{ $owner := index $.DidHandleMap .OwnerDid }}
+
<a href="/{{ $owner }}">{{ $owner }}</a>
+
</span>
+
+
<span class="before:content-['·']">
+
<time>
+
{{ .Created | timeFmt }}
+
</time>
+
</span>
+
+
<span class="before:content-['·']">
+
{{ $s := "s" }}
+
{{ if eq .Metadata.CommentCount 1 }}
+
{{ $s = "" }}
{{ end }}
-
</section>
+
<a href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" class="text-gray-400">{{ .Metadata.CommentCount }} comment{{$s}}</a>
+
</span>
+
</p>
+
</div>
+
{{ end }}
+
</div>
{{ end }}
+1 -1
appview/pages/templates/repo/log.html
···
{{ range $commits }}
<div class="flex flex-row justify-between items-center">
<div
-
class="relative w-full px-4 py-4 mt-5 hover:bg-gray-50 rounded-sm bg-white"
+
class="relative w-full px-4 py-4 mt-4 rounded-sm bg-white"
>
<div id="commit-message">
{{ $messageParts := splitN .Message "\n\n" 2 }}
+2 -2
appview/pages/templates/settings.html
···
{{ define "profile" }}
<header class="text-sm font-bold py-2 px-6 uppercase">profile</header>
-
<section class="rounded bg-white drop-shadow-sm px-6 py-4 mb-6 w-fit">
+
<section class="rounded bg-white drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit">
<dl class="grid grid-cols-[auto_1fr] gap-x-4">
{{ if .LoggedInUser.Handle }}
<dt class="font-bold">handle</dt>
···
{{ define "keys" }}
<header class="text-sm font-bold py-2 px-6 uppercase">ssh keys</header>
-
<section class="rounded bg-white drop-shadow-sm px-6 py-4 mb-6 w-fit">
+
<section class="rounded bg-white drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit">
<div id="key-list" class="flex flex-col gap-6 mb-8">
{{ range .PubKeys }}
<div>
+3 -3
appview/pages/templates/timeline.html
···
<a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a>
created
<a href="/{{ $userHandle }}/{{ .Repo.Name }}" class="no-underline hover:underline">{{ .Repo.Name }}</a>
-
<time class="text-gray-700">{{ .Repo.Created | timeFmt }}</time>
+
<time class="text-gray-700 text-xs">{{ .Repo.Created | timeFmt }}</time>
</p>
</div>
{{ else if .Follow }}
···
<a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a>
followed
<a href="/{{ $subjectHandle }}" class="no-underline hover:underline">{{ $subjectHandle }}</a>
-
<time class="text-gray-700">{{ .Follow.FollowedAt | timeFmt }}</time>
+
<time class="text-gray-700 text-xs">{{ .Follow.FollowedAt | timeFmt }}</time>
</p>
</div>
{{ else if .Star }}
···
<a href="/{{ $starrerHandle }}" class="no-underline hover:underline">{{ $starrerHandle }}</a>
starred
<a href="/{{ $repoOwnerHandle }}/{{ .Star.Repo.Name }}" class="no-underline hover:underline">{{ $repoOwnerHandle }}/{{ .Star.Repo.Name }}</a>
-
<time class="text-gray-700">{{ .Star.Created | timeFmt }}</time>
+
<time class="text-gray-700 text-xs">{{ .Star.Created | timeFmt }}</time>
</p>
</div>
{{ end }}
+4 -4
appview/pages/templates/user/profile.html
···
{{ define "title" }}{{ or .UserHandle .UserDid }}{{ end }}
{{ define "content" }}
-
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
-
<div class="lg:col-span-1">
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-6">
+
<div class="md:col-span-1">
{{ block "profileCard" . }} {{ end }}
</div>
-
<div class="lg:col-span-3">
+
<div class="md:col-span-3">
{{ block "ownRepos" . }} {{ end }}
{{ block "collaboratingRepos" . }} {{ end }}
</div>
···
<div class="bg-white px-6 py-4 rounded drop-shadow-sm max-h-fit">
<div class="flex justify-center items-center">
{{ if .AvatarUri }}
-
<img class="w-1/2 lg:w-full rounded-full p-2" src="{{ .AvatarUri }}" />
+
<img class="w-1/2 rounded-full p-2" src="{{ .AvatarUri }}" />
{{ end }}
</div>
<p class="text-xl font-bold text-center">
+31 -14
flake.nix
···
pname = "knotserver";
version = "0.1.0";
src = gitignoreSource ./.;
-
nativeBuildInputs = [ final.makeWrapper ];
+
nativeBuildInputs = [final.makeWrapper];
subPackages = ["cmd/knotserver"];
vendorHash = goModHash;
installPhase = ''
-
runHook preInstall
+
runHook preInstall
-
mkdir -p $out/bin
-
cp $GOPATH/bin/knotserver $out/bin/knotserver
+
mkdir -p $out/bin
+
cp $GOPATH/bin/knotserver $out/bin/knotserver
-
wrapProgram $out/bin/knotserver \
-
--prefix PATH : ${pkgs.git}/bin
+
wrapProgram $out/bin/knotserver \
+
--prefix PATH : ${pkgs.git}/bin
-
runHook postInstall
+
runHook postInstall
'';
env.CGO_ENABLED = 1;
};
+
knotserver-unwrapped = with final;
+
final.pkgsStatic.buildGoModule {
+
pname = "knotserver";
+
version = "0.1.0";
+
src = gitignoreSource ./.;
+
subPackages = ["cmd/knotserver"];
+
vendorHash = goModHash;
+
env.CGO_ENABLED = 1;
+
};
repoguard = buildCmdPackage "repoguard";
keyfetch = buildCmdPackage "keyfetch";
};
packages = forAllSystems (system: {
-
inherit (nixpkgsFor."${system}") indigo-lexgen appview knotserver repoguard keyfetch;
+
inherit
+
(nixpkgsFor."${system}")
+
indigo-lexgen
+
appview
+
knotserver
+
knotserver-unwrapped
+
repoguard
+
keyfetch
+
;
});
defaultPackage = forAllSystems (system: nixpkgsFor.${system}.appview);
formatter = forAllSystems (system: nixpkgsFor."${system}".alejandra);
···
config = mkIf config.services.tangled-knotserver.enable {
nixpkgs.overlays = [self.overlays.default];
-
environment.systemPackages = with pkgs; [ git ];
+
environment.systemPackages = with pkgs; [git];
users.users.git = {
isNormalUser = true;
···
};
environment.etc."ssh/keyfetch_wrapper" = {
-
mode = "0555";
-
text = ''
-
#!${pkgs.stdenv.shell}
-
${pkgs.keyfetch}/bin/keyfetch -repoguard-path ${pkgs.repoguard}/bin/repoguard -log-path /tmp/repoguard.log
-
'';
+
mode = "0555";
+
text = ''
+
#!${pkgs.stdenv.shell}
+
${pkgs.keyfetch}/bin/keyfetch -repoguard-path ${pkgs.repoguard}/bin/repoguard -log-path /tmp/repoguard.log
+
'';
};
systemd.services.knotserver = {
+5 -5
input.css
···
@apply bg-opacity-30;
}
-
html {
-
letter-spacing: -0.01em;
-
word-spacing: -0.07em;
-
}
-
@layer base {
+
html {
+
letter-spacing: -0.01em;
+
word-spacing: -0.07em;
+
font-size: 14px;
+
}
a {
@apply no-underline text-black hover:underline hover:text-gray-800;
}
+12 -6
tailwind.config.js
···
/** @type {import('tailwindcss').Config} */
+
const colors = require('tailwindcss/colors')
+
module.exports = {
content: ["./appview/pages/templates/**/*.html"],
theme: {
···
padding: "2rem",
center: true,
screens: {
-
sm: "540px",
-
md: "650px",
-
lg: "900px",
-
xl: "1100px",
-
"2xl": "1300px"
+
sm: "500px",
+
md: "600px",
+
lg: "800px",
+
xl: "1000px",
+
"2xl": "1200px"
},
},
extend: {
···
DEFAULT: {
css: {
maxWidth: 'none',
-
}
+
pre: {
+
backgroundColor: colors.gray[100],
+
color: colors.black,
+
},
+
},
},
},
},