Compare commits

..

3 Commits

Author SHA1 Message Date
jolheiser 9030c27f00
fix: minor correction for non-chroma pre/code blocks
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2024-05-24 22:29:44 -05:00
jolheiser f93238ae57
feat: move search to topbar and no result indicator
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2024-05-24 21:31:35 -05:00
jolheiser fdbe918ef4
docs: update email
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2024-05-24 21:08:39 -05:00
9 changed files with 60 additions and 48 deletions

View File

@ -10,7 +10,7 @@ Minimal git server
ugit allows cloning via HTTPS/SSH, but can only be pushed to via SSH.
There are no plans to directly support issues or PR workflows, although webhooks are planned and auxillary software may be created to facilitate these things.
For now, if you wish to collaborate, please send me patches at [john+ugit@jolheiser.com](mailto:john+ugit@jolheiser.com).
For now, if you wish to collaborate, please send me patches at [ugit@jolheiser.com](mailto:git@jolheiser.com).
Currently all HTML is allowed in markdown, ugit is intended to be run by/for a trusted user.

View File

@ -1,7 +1,7 @@
package html
type BaseContext struct {
Title string
Title string
Description string
}
@ -23,4 +23,3 @@ templ base(bc BaseContext) {
</body>
</html>
}

View File

@ -3,6 +3,11 @@
color: rgb(var(--ctp-text));
}
.markdown code,
.markdown pre {
background-color: rgb(var(--ctp-base));
}
.markdown a {
color: rgb(var(--ctp-blue));
text-decoration-line: underline;

View File

@ -3,10 +3,10 @@ package html
import "fmt"
type RepoHeaderComponentContext struct {
Name string
Ref string
Description string
CloneURL string
Name string
Ref string
Description string
CloneURL string
}
templ repoHeaderComponent(rhcc RepoHeaderComponentContext) {
@ -21,10 +21,9 @@ templ repoHeaderComponent(rhcc RepoHeaderComponentContext) {
{ " - " }
<a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ templ.SafeURL(fmt.Sprintf("/%s/log/%s", rhcc.Name, rhcc.Ref)) }>log</a>
{ " - " }
<a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ templ.SafeURL(fmt.Sprintf("/%s/search", rhcc.Name)) }>search</a>
<form class="inline-block" action={ templ.SafeURL(fmt.Sprintf("/%s/search", rhcc.Name)) } method="get"><input class="rounded p-1 bg-mantle focus:border-lavender focus:outline-none focus:ring-0" id="search" type="text" name="q" placeholder="search"/></form>
{ " - " }
<pre class="text-text inline select-all bg-base dark:bg-base/50 p-1 rounded">{ fmt.Sprintf("%s/%s.git", rhcc.CloneURL, rhcc.Name) }</pre>
</div>
<div class="text-text/80 mb-1">{ rhcc.Description }</div>
}

View File

@ -4,7 +4,7 @@ import "fmt"
import "go.jolheiser.com/ugit/internal/git"
type SearchContext struct {
BaseContext
BaseContext
RepoHeaderComponentContext
Results []git.GrepResult
}
@ -33,10 +33,12 @@ func (s SearchContext) DedupeResults() [][]git.GrepResult {
templ RepoSearch(sc SearchContext) {
@base(sc.BaseContext) {
@repoHeaderComponent(sc.RepoHeaderComponentContext)
<form method="get"><label class="text-text">Search <input class="rounded p-1 mt-2 bg-mantle focus:border-lavender focus:outline-none focus:ring-0" id="search" type="text" name="q" placeholder="search"/></label></form>
for _, results := range sc.DedupeResults() {
@repoSearchResult(sc.RepoHeaderComponentContext.Name, sc.RepoHeaderComponentContext.Ref, results)
}
if len(sc.DedupeResults()) == 0 {
<p class="text-text mt-5 text-lg">No results</p>
}
}
<script>
const search = new URLSearchParams(window.location.search).get("q");
@ -46,15 +48,18 @@ templ RepoSearch(sc SearchContext) {
templ repoSearchResult(repo, ref string, results []git.GrepResult) {
<div class="text-text mt-5"><a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s#L%d", repo, ref, results[0].File, results[0].Line)) }>{ results[0].File }</a></div>
<div class="code">@templ.Raw(results[0].Content)</div>
<div class="code">
@templ.Raw(results[0].Content)
</div>
if len(results) > 1 {
<details class="text-text cursor-pointer">
<summary>{ fmt.Sprintf("%d ", len(results[1:])) }more</summary>
for _, result := range results[1:] {
<div class="text-text mt-5 ml-5"><a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s#L%d", repo, ref, result.File, result.Line)) }>{ results[0].File }</a></div>
<div class="code ml-5">@templ.Raw(result.Content)</div>
<div class="code ml-5">
@templ.Raw(result.Content)
</div>
}
</details>
}
}

View File

@ -63,16 +63,7 @@ func RepoSearch(sc SearchContext) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <form method=\"get\"><label class=\"text-text\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var3 := `Search `
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<input class=\"rounded p-1 mt-2 bg-mantle focus:border-lavender focus:outline-none focus:ring-0\" id=\"search\" type=\"text\" name=\"q\" placeholder=\"search\"></label></form>")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -82,6 +73,25 @@ func RepoSearch(sc SearchContext) templ.Component {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if len(sc.DedupeResults()) == 0 {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-text mt-5 text-lg\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var3 := `No results`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
}
@ -143,7 +153,7 @@ func repoSearchResult(repo, ref string, results []git.GrepResult) templ.Componen
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(results[0].File)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 47, Col: 230}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 49, Col: 230}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@ -169,7 +179,7 @@ func repoSearchResult(repo, ref string, results []git.GrepResult) templ.Componen
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d ", len(results[1:])))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 51, Col: 50}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 55, Col: 50}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
@ -201,7 +211,7 @@ func repoSearchResult(repo, ref string, results []git.GrepResult) templ.Componen
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(results[0].File)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 53, Col: 230}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 57, Col: 230}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {

View File

@ -166,7 +166,7 @@ func repoHeaderComponent(rhcc RepoHeaderComponentContext) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form class=\"inline-block\" action=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -175,25 +175,16 @@ func repoHeaderComponent(rhcc RepoHeaderComponentContext) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" method=\"get\"><input class=\"rounded p-1 bg-mantle focus:border-lavender focus:outline-none focus:ring-0\" id=\"search\" type=\"text\" name=\"q\" placeholder=\"search\"></form>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var15 := `search`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var15)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(" - ")
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(" - ")
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo.templ`, Line: 24, Col: 9}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -201,12 +192,12 @@ func repoHeaderComponent(rhcc RepoHeaderComponentContext) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s/%s.git", rhcc.CloneURL, rhcc.Name))
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s/%s.git", rhcc.CloneURL, rhcc.Name))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo.templ`, Line: 25, Col: 131}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -214,12 +205,12 @@ func repoHeaderComponent(rhcc RepoHeaderComponentContext) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(rhcc.Description)
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(rhcc.Description)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo.templ`, Line: 27, Col: 50}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

File diff suppressed because one or more lines are too long

View File

@ -71,6 +71,9 @@ func (rh repoHandler) repoTree(ref, path string) http.HandlerFunc {
func (rh repoHandler) repoFile(w http.ResponseWriter, r *http.Request, repo *git.Repo, ref, path string) error {
content, err := repo.FileContent(ref, path)
if err != nil {
if errors.Is(err, object.ErrFileNotFound) {
return httperr.Status(err, http.StatusNotFound)
}
return httperr.Error(err)
}