diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index 0f464ad07..809a5009b 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -258,7 +258,7 @@ func renderBlame(ctx *context.Context, blameParts []*git.BlamePart, commitNames var avatar string if commit.User != nil { - avatar = string(avatarUtils.Avatar(commit.User, 18, "gt-mr-3")) + avatar = string(avatarUtils.Avatar(commit.User, 18)) } else { avatar = string(avatarUtils.AvatarByEmail(commit.Author.Email, commit.Author.Name, 18, "gt-mr-3")) } diff --git a/templates/devtest/gitea-ui.tmpl b/templates/devtest/gitea-ui.tmpl index 9ef0aa675..26eaddae6 100644 --- a/templates/devtest/gitea-ui.tmpl +++ b/templates/devtest/gitea-ui.tmpl @@ -2,6 +2,13 @@
+

Link

+
+ normal + muted + suppressed + silenced +

Button

Style: diff --git a/templates/repo/blame.tmpl b/templates/repo/blame.tmpl index 67046b814..9eb98f75f 100644 --- a/templates/repo/blame.tmpl +++ b/templates/repo/blame.tmpl @@ -50,11 +50,11 @@ {{$row.Avatar}}
-
+
{{$row.CommitSince}}
@@ -62,7 +62,7 @@ {{if $row.PreviousSha}} - + {{svg "octicon-versions"}} {{end}} @@ -84,6 +84,12 @@ {{end}} +
+ {{if $.Permission.CanRead $.UnitTypeIssues}} + {{ctx.Locale.Tr "repo.issues.context.reference_issue"}} + {{end}} + {{ctx.Locale.Tr "repo.file_copy_permalink"}} +
{{end}}
diff --git a/web_src/css/base.css b/web_src/css/base.css index e61311abd..ac451c4bc 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -226,10 +226,14 @@ h1.error-code { a { color: var(--color-primary); cursor: pointer; - text-decoration: none; + text-decoration-line: none; text-decoration-skip-ink: all; } +a:hover { + text-decoration-line: underline; +} + /* a = always colored, underlined on hover */ /* a.muted = colored on hover, underlined on hover */ /* a.suppressed = never colored, underlined on hover */ @@ -256,7 +260,7 @@ a.suppressed:hover { } a.silenced:hover { - text-decoration: none; + text-decoration-line: none; } a.label, @@ -264,7 +268,7 @@ a.label, .ui .menu a, .ui.cards a.card, .issue-keyword a { - text-decoration: none !important; + text-decoration-line: none !important; } .ui.search > .results { @@ -1433,18 +1437,15 @@ a.ui.active.label:hover { } .lines-blame-btn { - padding-left: 10px; - padding-right: 10px; - text-align: right !important; - background-color: var(--color-code-sidebar-bg); - width: 2%; + padding: 0 0 0 5px; + display: flex; + justify-content: center; } .lines-num { - padding-left: 10px; - padding-right: 10px; + padding: 0 8px; text-align: right !important; - color: var(--color-text-light-1); + color: var(--color-text-light-2); width: 1%; font-family: var(--fonts-monospace); } @@ -1498,22 +1499,34 @@ a.ui.active.label:hover { } .lines-code { - background-color: var(--color-code-bg); padding-left: 5px; } -.lines-code.active, -.lines-code .active { - background: var(--color-active-line) !important; +.file-view tr.active { + color: inherit !important; + background: inherit !important; } -.blame .lines-num { - padding: 0 !important; - background-color: var(--color-code-sidebar-bg); +.file-view tr.active .lines-num, +.file-view tr.active .lines-code { + background: var(--color-highlight-bg) !important; } -.blame .lines-code { - padding: 0 !important; +.file-view tr.active:last-of-type .lines-code { + border-bottom-right-radius: var(--border-radius); +} + +.file-view tr.active .lines-num { + position: relative; +} + +.file-view tr.active .lines-num::before { + content: ""; + position: absolute; + left: 0; + width: 2px; + height: 100%; + background: var(--color-highlight-fg); } .code-inner { @@ -1524,24 +1537,21 @@ a.ui.active.label:hover { } .blame .code-inner { - white-space: pre; - word-break: normal; - word-wrap: normal; /* not using overflow-wrap because safari does not treat is an an alias */ + white-space: pre-wrap; + overflow-wrap: anywhere; } .lines-commit { vertical-align: top; - color: var(--color-text-light-2); + color: var(--color-text-light-1); padding: 0 !important; - background: var(--color-code-sidebar-bg); width: 1%; } .lines-commit .blame-info { - width: 350px; - max-width: 350px; + width: min(26vw, 300px); display: block; - padding: 0 0 0 10px; + padding: 0 0 0 6px; line-height: 20px; box-sizing: content-box; } @@ -1563,11 +1573,10 @@ a.ui.active.label:hover { flex-shrink: 0; } -.lines-commit .ui.avatar { - height: 18px; - width: 18px; - display: block; - margin-top: 1px; +.blame-avatar { + display: flex; + align-items: center; + margin-right: 4px; } .top-line-blame { @@ -1583,6 +1592,11 @@ a.ui.active.label:hover { border-bottom: 1px solid var(--color-secondary); } +.code-view { + background: var(--color-code-bg); + border-radius: var(--border-radius); +} + .code-view table { width: 100%; } diff --git a/web_src/css/chroma/base.css b/web_src/css/chroma/base.css index 26d128775..bce13332f 100644 --- a/web_src/css/chroma/base.css +++ b/web_src/css/chroma/base.css @@ -1,7 +1,3 @@ -.chroma { - background-color: var(--color-code-bg); -} - /* LineTableTD */ .chroma .lntd { vertical-align: top; diff --git a/web_src/css/modules/button.css b/web_src/css/modules/button.css index a06cab446..452791cf0 100644 --- a/web_src/css/modules/button.css +++ b/web_src/css/modules/button.css @@ -11,6 +11,7 @@ .ui.button:focus { background: var(--color-hover); color: var(--color-text); + border-color: var(--color-secondary-dark-2); } .page-content .ui.button { @@ -63,11 +64,17 @@ It needs some tricks to tweak the left/right borders with active state */ border-right: none; } -.ui.buttons .button:first-child { +.ui.buttons .button:hover + .button { + border-left: 1px solid var(--color-secondary-dark-2); +} + +.ui.buttons .button:first-child, +.ui.buttons .button.gt-hidden:first-child + .button { border-left: 1px solid var(--color-light-border); } -.ui.buttons .button:last-child { +.ui.buttons .button:last-child, +.ui.buttons .button:nth-last-child(2):has(+ .button.gt-hidden) { border-right: 1px solid var(--color-light-border); } @@ -107,6 +114,7 @@ It needs some tricks to tweak the left/right borders with active state */ .ui.basic.button:focus { color: var(--color-text); background: var(--color-hover); + border-color: var(--color-secondary-dark-2); } .ui.basic.buttons .button:active, diff --git a/web_src/css/modules/message.css b/web_src/css/modules/message.css index a29603cd9..c62dbddd2 100644 --- a/web_src/css/modules/message.css +++ b/web_src/css/modules/message.css @@ -100,3 +100,15 @@ color: var(--color-warning-text); border-color: var(--color-warning-border); } + +.ui.message > .close.icon { + cursor: pointer; + position: absolute; + top: 9px; + right: 9px; + opacity: .7; +} + +.ui.message > .close.icon:hover { + opacity: 1; +} diff --git a/web_src/css/repo.css b/web_src/css/repo.css index 6ccbbb49d..c1a798040 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1601,7 +1601,6 @@ .repository .diff-file-box .file-body.file-code .lines-num { text-align: right; - color: var(--color-text-light); width: 1%; min-width: 50px; } diff --git a/web_src/css/repo/linebutton.css b/web_src/css/repo/linebutton.css index 79be5a7a9..e99d0399d 100644 --- a/web_src/css/repo/linebutton.css +++ b/web_src/css/repo/linebutton.css @@ -3,18 +3,16 @@ } .code-line-button { - background-color: var(--color-menu); - color: var(--color-text-light); border: 1px solid var(--color-secondary); border-radius: var(--border-radius); - padding: 1px 10px; + padding: 1px 4px !important; position: absolute; font-family: var(--fonts-regular); left: 0; - transform: translateX(-50%); + transform: translateX(calc(-50% + 6px)); cursor: pointer; } .code-line-button:hover { - color: var(--color-primary); + background: var(--color-secondary) !important; } diff --git a/web_src/css/themes/theme-gitea-dark.css b/web_src/css/themes/theme-gitea-dark.css index c769c51cd..626590ca5 100644 --- a/web_src/css/themes/theme-gitea-dark.css +++ b/web_src/css/themes/theme-gitea-dark.css @@ -183,7 +183,7 @@ --color-body: #1c1f25; --color-box-header: #1a1d1f; --color-box-body: #14171a; - --color-box-body-highlight: #121517; + --color-box-body-highlight: #1c2227; --color-text-dark: #f8f8f9; --color-text: #d1d5d8; --color-text-light: #bdc3c7; @@ -207,11 +207,10 @@ --color-markup-table-row: #e8e8ff06; --color-markup-code-block: #e8e8ff16; --color-button: #151a1e; - --color-code-bg: #191d20; - --color-code-sidebar-bg: #1b1f22; + --color-code-bg: #14171a; --color-shadow: #00001758; - --color-secondary-bg: #2f3135; - --color-expand-button: #414348; + --color-secondary-bg: #2f3138; + --color-expand-button: #2b353e; --color-placeholder-text: var(--color-text-light-3); --color-editor-line-highlight: var(--color-primary-light-5); --color-project-board-bg: var(--color-secondary-light-2); @@ -233,7 +232,8 @@ --color-label-active-bg: #73828eff; --color-accent: var(--color-primary-light-1); --color-small-accent: var(--color-primary-light-5); - --color-active-line: #534d1b; + --color-highlight-fg: #87651e; + --color-highlight-bg: #352c1c; --color-overlay-backdrop: #080808c0; accent-color: var(--color-accent); color-scheme: dark; diff --git a/web_src/css/themes/theme-gitea-light.css b/web_src/css/themes/theme-gitea-light.css index 2d9ab8e72..f6913fbe2 100644 --- a/web_src/css/themes/theme-gitea-light.css +++ b/web_src/css/themes/theme-gitea-light.css @@ -183,7 +183,7 @@ --color-body: #ffffff; --color-box-header: #f1f3f5; --color-box-body: #ffffff; - --color-box-body-highlight: #f4faff; + --color-box-body-highlight: #ecf5fd; --color-text-dark: #01050a; --color-text: #181c21; --color-text-light: #30363b; @@ -208,10 +208,9 @@ --color-markup-code-block: #00001710; --color-button: #f8f9fb; --color-code-bg: #fafdff; - --color-code-sidebar-bg: #f2f5f8; --color-shadow: #00001726; --color-secondary-bg: #f2f5f8; - --color-expand-button: #d8efff; + --color-expand-button: #cfe8fa; --color-placeholder-text: var(--color-text-light-3); --color-editor-line-highlight: var(--color-primary-light-6); --color-project-board-bg: var(--color-secondary-light-4); @@ -233,7 +232,8 @@ --color-label-active-bg: #949da6ff; --color-accent: var(--color-primary-light-1); --color-small-accent: var(--color-primary-light-6); - --color-active-line: #fffbdd; + --color-highlight-fg: #eed200; + --color-highlight-bg: #fffbdd; --color-overlay-backdrop: #080808c0; accent-color: var(--color-accent); color-scheme: light; diff --git a/web_src/js/features/repo-code.js b/web_src/js/features/repo-code.js index 08fae763b..befa09000 100644 --- a/web_src/js/features/repo-code.js +++ b/web_src/js/features/repo-code.js @@ -16,8 +16,16 @@ function changeHash(hash) { } } -function selectRange($list, $select, $from) { - $list.removeClass('active'); +function isBlame() { + return Boolean(document.querySelector('div.blame')); +} + +function getLineEls() { + return document.querySelectorAll(`.code-view td.lines-code${isBlame() ? '.blame-code' : ''}`); +} + +function selectRange($linesEls, $selectionEndEl, $selectionStartEls) { + $linesEls.closest('tr').removeClass('active'); // add hashchange to permalink const $refInNewIssue = $('a.ref-in-new-issue'); @@ -25,7 +33,7 @@ function selectRange($list, $select, $from) { const $viewGitBlame = $('a.view_git_blame'); const updateIssueHref = function (anchor) { - if ($refInNewIssue.length === 0) { + if (!$refInNewIssue.length) { return; } const urlIssueNew = $refInNewIssue.attr('data-url-issue-new'); @@ -35,9 +43,7 @@ function selectRange($list, $select, $from) { }; const updateViewGitBlameFragment = function (anchor) { - if ($viewGitBlame.length === 0) { - return; - } + if (!$viewGitBlame.length) return; let href = $viewGitBlame.attr('href'); href = `${href.replace(/#L\d+$|#L\d+-L\d+$/, '')}`; if (anchor.length !== 0) { @@ -47,17 +53,15 @@ function selectRange($list, $select, $from) { }; const updateCopyPermalinkUrl = function(anchor) { - if ($copyPermalink.length === 0) { - return; - } + if (!$copyPermalink.length) return; let link = $copyPermalink.attr('data-url'); link = `${link.replace(/#L\d+$|#L\d+-L\d+$/, '')}#${anchor}`; $copyPermalink.attr('data-url', link); }; - if ($from) { - let a = parseInt($select.attr('rel').slice(1)); - let b = parseInt($from.attr('rel').slice(1)); + if ($selectionStartEls) { + let a = parseInt($selectionEndEl.attr('rel').slice(1)); + let b = parseInt($selectionStartEls.attr('rel').slice(1)); let c; if (a !== b) { if (a > b) { @@ -69,7 +73,9 @@ function selectRange($list, $select, $from) { for (let i = a; i <= b; i++) { classes.push(`[rel=L${i}]`); } - $list.filter(classes.join(',')).addClass('active'); + $linesEls.filter(classes.join(',')).each(function () { + $(this).closest('tr').addClass('active'); + }); changeHash(`#L${a}-L${b}`); updateIssueHref(`L${a}-L${b}`); @@ -78,12 +84,12 @@ function selectRange($list, $select, $from) { return; } } - $select.addClass('active'); - changeHash(`#${$select.attr('rel')}`); + $selectionEndEl.closest('tr').addClass('active'); + changeHash(`#${$selectionEndEl.attr('rel')}`); - updateIssueHref($select.attr('rel')); - updateViewGitBlameFragment($select.attr('rel')); - updateCopyPermalinkUrl($select.attr('rel')); + updateIssueHref($selectionEndEl.attr('rel')); + updateViewGitBlameFragment($selectionEndEl.attr('rel')); + updateCopyPermalinkUrl($selectionEndEl.attr('rel')); } function showLineButton() { @@ -96,10 +102,10 @@ function showLineButton() { } // find active row and add button - const tr = document.querySelector('.code-view td.lines-code.active').closest('tr'); - const td = tr.querySelector('td'); + const tr = document.querySelector('.code-view tr.active'); + const td = tr.querySelector('td.lines-num'); const btn = document.createElement('button'); - btn.classList.add('code-line-button'); + btn.classList.add('code-line-button', 'ui', 'basic', 'button'); btn.innerHTML = svg('octicon-kebab-horizontal'); td.prepend(btn); @@ -123,14 +129,18 @@ function showLineButton() { export function initRepoCodeView() { if ($('.code-view .lines-num').length > 0) { $(document).on('click', '.lines-num span', function (e) { - const $select = $(this); - let $list; - if ($('div.blame').length) { - $list = $('.code-view td.lines-code.blame-code'); - } else { - $list = $('.code-view td.lines-code'); + const linesEls = getLineEls(); + const selectedEls = Array.from(linesEls).filter((el) => { + return el.matches(`[rel=${this.getAttribute('id')}]`); + }); + + let from; + if (e.shiftKey) { + from = Array.from(linesEls).filter((el) => { + return el.closest('tr').classList.contains('active'); + }); } - selectRange($list, $list.filter(`[rel=${$select.attr('id')}]`), (e.shiftKey ? $list.filter('.active').eq(0) : null)); + selectRange($(linesEls), $(selectedEls), from ? $(from) : null); if (window.getSelection) { window.getSelection().removeAllRanges(); @@ -138,28 +148,20 @@ export function initRepoCodeView() { document.selection.empty(); } - // show code view menu marker (don't show in blame page) - if ($('div.blame').length === 0) { - showLineButton(); - } + showLineButton(); }); $(window).on('hashchange', () => { let m = window.location.hash.match(rangeAnchorRegex); - let $list; - if ($('div.blame').length) { - $list = $('.code-view td.lines-code.blame-code'); - } else { - $list = $('.code-view td.lines-code'); - } + const $linesEls = $(getLineEls()); let $first; if (m) { - $first = $list.filter(`[rel=${m[1]}]`); + $first = $linesEls.filter(`[rel=${m[1]}]`); if ($first.length) { - selectRange($list, $first, $list.filter(`[rel=${m[2]}]`)); + selectRange($linesEls, $first, $linesEls.filter(`[rel=${m[2]}]`)); // show code view menu marker (don't show in blame page) - if ($('div.blame').length === 0) { + if (!isBlame()) { showLineButton(); } @@ -169,12 +171,12 @@ export function initRepoCodeView() { } m = window.location.hash.match(singleAnchorRegex); if (m) { - $first = $list.filter(`[rel=L${m[2]}]`); + $first = $linesEls.filter(`[rel=L${m[2]}]`); if ($first.length) { - selectRange($list, $first); + selectRange($linesEls, $first); // show code view menu marker (don't show in blame page) - if ($('div.blame').length === 0) { + if (!isBlame()) { showLineButton(); }