mirror of https://git.jolheiser.com/ugit.git
permalink
parent
68992f0807
commit
ea40aa746e
|
@ -127,6 +127,21 @@ func (r Repo) Dir(ref, path string) ([]FileInfo, error) {
|
||||||
return fis, nil
|
return fis, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCommitFromRef returns the commit object for a given ref
|
||||||
|
func (r Repo) GetCommitFromRef(ref string) (*object.Commit, error) {
|
||||||
|
g, err := r.Git()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := g.ResolveRevision(plumbing.Revision(ref))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return g.CommitObject(*hash)
|
||||||
|
}
|
||||||
|
|
||||||
// FileContent returns the content of a file in the git tree at a given ref/rev
|
// FileContent returns the content of a file in the git tree at a given ref/rev
|
||||||
func (r Repo) FileContent(ref, file string) (string, error) {
|
func (r Repo) FileContent(ref, file string) (string, error) {
|
||||||
t, err := r.Tree(ref)
|
t, err := r.Tree(ref)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package html
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
. "maragu.dev/gomponents"
|
. "maragu.dev/gomponents"
|
||||||
. "maragu.dev/gomponents/html"
|
. "maragu.dev/gomponents/html"
|
||||||
|
@ -12,18 +13,23 @@ type RepoFileContext struct {
|
||||||
RepoHeaderComponentContext
|
RepoHeaderComponentContext
|
||||||
RepoBreadcrumbComponentContext
|
RepoBreadcrumbComponentContext
|
||||||
Code string
|
Code string
|
||||||
|
Commit string
|
||||||
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:embed repo_file.js
|
//go:embed repo_file.js
|
||||||
var repoFileJS string
|
var repoFileJS string
|
||||||
|
|
||||||
func RepoFileTemplate(rfc RepoFileContext) Node {
|
func RepoFileTemplate(rfc RepoFileContext) Node {
|
||||||
|
permalink := fmt.Sprintf("/%s/tree/%s/%s", rfc.RepoBreadcrumbComponentContext.Repo, rfc.Commit, rfc.Path)
|
||||||
return base(rfc.BaseContext, []Node{
|
return base(rfc.BaseContext, []Node{
|
||||||
repoHeaderComponent(rfc.RepoHeaderComponentContext),
|
repoHeaderComponent(rfc.RepoHeaderComponentContext),
|
||||||
Div(Class("mt-2 text-text"),
|
Div(Class("mt-2 text-text"),
|
||||||
repoBreadcrumbComponent(rfc.RepoBreadcrumbComponentContext),
|
repoBreadcrumbComponent(rfc.RepoBreadcrumbComponentContext),
|
||||||
Text(" - "),
|
Text(" - "),
|
||||||
A(Class("text-text underline decoration-text/50 decoration-dashed hover:decoration-solid"), Href("?raw"), Text("raw")),
|
A(Class("text-text underline decoration-text/50 decoration-dashed hover:decoration-solid"), Href("?raw"), Text("raw")),
|
||||||
|
Text(" - "),
|
||||||
|
A(Class("text-text underline decoration-text/50 decoration-dashed hover:decoration-solid"), ID("permalink"), Data("permalink", permalink), Href(permalink), Text("permalink")),
|
||||||
Div(Class("code relative"),
|
Div(Class("code relative"),
|
||||||
Raw(rfc.Code),
|
Raw(rfc.Code),
|
||||||
Button(ID("copy"), Class("absolute top-0 right-0 rounded bg-base hover:bg-surface0")),
|
Button(ID("copy"), Class("absolute top-0 right-0 rounded bg-base hover:bg-surface0")),
|
||||||
|
|
|
@ -2,6 +2,7 @@ const lineRe = /#L(\d+)(?:-L(\d+))?/g
|
||||||
const $lineLines = document.querySelectorAll(".chroma .lntable .lnt");
|
const $lineLines = document.querySelectorAll(".chroma .lntable .lnt");
|
||||||
const $codeLines = document.querySelectorAll(".chroma .lntable .line");
|
const $codeLines = document.querySelectorAll(".chroma .lntable .line");
|
||||||
const $copyButton = document.getElementById('copy');
|
const $copyButton = document.getElementById('copy');
|
||||||
|
const $permalink = document.getElementById('permalink');
|
||||||
const $copyIcon = "📋";
|
const $copyIcon = "📋";
|
||||||
const $copiedIcon = "✅";
|
const $copiedIcon = "✅";
|
||||||
let $code = ""
|
let $code = ""
|
||||||
|
@ -13,9 +14,12 @@ if (0 in results) {
|
||||||
start = results[0][1] !== undefined ? parseInt(results[0][1]) : 0;
|
start = results[0][1] !== undefined ? parseInt(results[0][1]) : 0;
|
||||||
end = results[0][2] !== undefined ? parseInt(results[0][2]) : 0;
|
end = results[0][2] !== undefined ? parseInt(results[0][2]) : 0;
|
||||||
}
|
}
|
||||||
if (start != 0) {
|
if (start !== 0) {
|
||||||
deactivateLines();
|
deactivateLines();
|
||||||
activateLines(start, end);
|
activateLines(start, end);
|
||||||
|
let anchor = `#${start}`;
|
||||||
|
if (end !== 0) anchor += `-${end}`;
|
||||||
|
if (anchor !== "") $permalink.href = $permalink.dataset.permalink + anchor;
|
||||||
$lineLines[start - 1].scrollIntoView(true);
|
$lineLines[start - 1].scrollIntoView(true);
|
||||||
}
|
}
|
||||||
for (let line of $lineLines) {
|
for (let line of $lineLines) {
|
||||||
|
@ -27,13 +31,17 @@ for (let line of $lineLines) {
|
||||||
if (event.shiftKey) {
|
if (event.shiftKey) {
|
||||||
end = n;
|
end = n;
|
||||||
anchor = `#L${start}-L${end}`;
|
anchor = `#L${start}-L${end}`;
|
||||||
|
} else if (start === n) {
|
||||||
|
start = 0;
|
||||||
|
end = 0;
|
||||||
} else {
|
} else {
|
||||||
start = n;
|
start = n;
|
||||||
end = 0;
|
end = 0;
|
||||||
anchor = `#L${start}`;
|
anchor = `#L${start}`;
|
||||||
}
|
}
|
||||||
history.replaceState(null, null, anchor);
|
history.replaceState(null, null, window.location.pathname + anchor);
|
||||||
activateLines(start, end);
|
$permalink.href = $permalink.dataset.permalink + anchor;
|
||||||
|
if (start !== 0) activateLines(start, end);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||||
|
|
|
@ -92,11 +92,21 @@ func (rh repoHandler) repoFile(w http.ResponseWriter, r *http.Request, repo *git
|
||||||
return httperr.Error(err)
|
return httperr.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commit := ref
|
||||||
|
if len(ref) < 40 {
|
||||||
|
commitObj, err := repo.GetCommitFromRef(ref)
|
||||||
|
if err == nil {
|
||||||
|
commit = commitObj.Hash.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := html.RepoFileTemplate(html.RepoFileContext{
|
if err := html.RepoFileTemplate(html.RepoFileContext{
|
||||||
BaseContext: rh.baseContext(),
|
BaseContext: rh.baseContext(),
|
||||||
RepoHeaderComponentContext: rh.repoHeaderContext(repo, r),
|
RepoHeaderComponentContext: rh.repoHeaderContext(repo, r),
|
||||||
RepoBreadcrumbComponentContext: rh.repoBreadcrumbContext(repo, r, path),
|
RepoBreadcrumbComponentContext: rh.repoBreadcrumbContext(repo, r, path),
|
||||||
Code: buf.String(),
|
Code: buf.String(),
|
||||||
|
Commit: commit,
|
||||||
|
Path: path,
|
||||||
}).Render(w); err != nil {
|
}).Render(w); err != nil {
|
||||||
return httperr.Error(err)
|
return httperr.Error(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue