mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-05-12 22:10:25 +00:00
feat(ui): responsive releases list (#11080)
## Changes I've made releases list more usable on narrow viewports while trying keep the layout unchanged for desktop viewports. To support these changes large amount of Tailwind classes were converted to regular CSS to be applied conditionally via `@media`. While it was possible to just adjust the Tailwind classes to achieve the same behavior, there's a positive effect which is that the repeating HTML of releases generated by template's range is much less verbose and contains fewer long duplicated lines of Tailwind classes. ## Preview ### Desktop Not much changed, but the dot between tag and release name is no more. |Before|After| |-|-| ||| ### Mobile |Before|After| |-|-| ||| Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11080 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Reviewed-by: Beowulf <beowulf@beocode.eu>
This commit is contained in:
parent
f24a97f719
commit
7e4619df83
7 changed files with 243 additions and 141 deletions
|
|
@ -7,35 +7,38 @@
|
|||
<ul id="release-list">
|
||||
{{range $idx, $info := .Releases}}
|
||||
{{$release := $info.Release}}
|
||||
<li class="ui grid">
|
||||
<div class="ui four wide column meta">
|
||||
{{if ne $idx 0}}
|
||||
<div class="divider only-mobile"></div>
|
||||
{{end}}
|
||||
<li>
|
||||
<div class="meta">
|
||||
<a class="muted" href="{{if not (and $release.Sha1 ($.Permission.CanRead $.UnitTypeCode))}}#{{else}}{{$.RepoLink}}/src/tag/{{$release.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "tw-mr-1"}}{{$release.TagName}}</a>
|
||||
{{if and $release.Sha1 ($.Permission.CanRead $.UnitTypeCode)}}
|
||||
<a class="muted tw-font-mono" href="{{$.RepoLink}}/src/commit/{{$release.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha $release.Sha1}}</a>
|
||||
{{template "repo/branch_dropdown" dict "root" $ "release" $release}}
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="ui twelve wide column detail">
|
||||
<div class="tw-flex tw-items-center tw-justify-between tw-flex-wrap tw-mb-2">
|
||||
<h4 class="release-list-title tw-break-anywhere">
|
||||
<a href="{{$.RepoLink}}/releases/tag/{{$release.TagName | PathEscapeSegments}}">{{$release.Title}}</a>
|
||||
{{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "tw-flex"}}
|
||||
{{if $release.IsDraft}}
|
||||
<span class="ui yellow label">{{ctx.Locale.Tr "repo.release.draft"}}</span>
|
||||
{{else if $release.IsPrerelease}}
|
||||
<span class="ui orange label">{{ctx.Locale.Tr "repo.release.prerelease"}}</span>
|
||||
{{else if (not $release.IsTag)}}
|
||||
<span class="ui green label">{{ctx.Locale.Tr "repo.release.stable"}}</span>
|
||||
{{end}}
|
||||
</h4>
|
||||
<div>
|
||||
{{if and $.CanCreateRelease (not $release.IsTag)}}
|
||||
<a class="muted" data-tooltip-content="{{ctx.Locale.Tr "repo.release.edit"}}" href="{{$.RepoLink}}/releases/edit/{{$release.TagName | PathEscapeSegments}}" rel="nofollow">
|
||||
{{svg "octicon-pencil"}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="release-title-wrap">
|
||||
<h4>
|
||||
<a href="{{$.RepoLink}}/releases/tag/{{$release.TagName | PathEscapeSegments}}">{{$release.Title}}</a>
|
||||
{{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "tw-flex"}}
|
||||
{{if $release.IsDraft}}
|
||||
<span class="ui yellow label">{{ctx.Locale.Tr "repo.release.draft"}}</span>
|
||||
{{else if $release.IsPrerelease}}
|
||||
<span class="ui orange label">{{ctx.Locale.Tr "repo.release.prerelease"}}</span>
|
||||
{{else if (not $release.IsTag)}}
|
||||
<span class="ui green label">{{ctx.Locale.Tr "repo.release.stable"}}</span>
|
||||
{{end}}
|
||||
</h4>
|
||||
<div>
|
||||
{{if and $.CanCreateRelease (not $release.IsTag)}}
|
||||
<a class="muted" data-tooltip-content="{{ctx.Locale.Tr "repo.release.edit"}}" href="{{$.RepoLink}}/releases/edit/{{$release.TagName | PathEscapeSegments}}" rel="nofollow">
|
||||
{{svg "octicon-pencil"}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<p class="text grey">
|
||||
<span class="author">
|
||||
{{if $release.OriginalAuthor}}
|
||||
|
|
@ -59,15 +62,17 @@
|
|||
{{end}}
|
||||
</p>
|
||||
{{template "repo/tag/verification_line" (dict "ctxData" $ "release" $release)}}
|
||||
<div class="markup desc">
|
||||
{{$release.RenderedNote}}
|
||||
</div>
|
||||
{{if $release.RenderedNote}}
|
||||
<div class="markup desc">
|
||||
{{$release.RenderedNote}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{$hasReleaseAttachment := gt (len $release.Attachments) 0}}
|
||||
{{$hasArchiveLinks := and (not $.DisableDownloadSourceArchives) (not $release.IsDraft) (not $release.HideArchiveLinks) ($.Permission.CanRead $.UnitTypeCode)}}
|
||||
{{if or $hasArchiveLinks $hasReleaseAttachment}}
|
||||
<div class="divider"></div>
|
||||
<div class="divider not-mobile"></div>
|
||||
<details class="download" {{if eq $idx 0}}open{{end}}>
|
||||
<summary class="tw-my-4">
|
||||
<summary>
|
||||
{{ctx.Locale.Tr "repo.release.downloads"}}
|
||||
</summary>
|
||||
<ul class="list">
|
||||
|
|
@ -76,7 +81,7 @@
|
|||
<a class="archive-link tw-flex-1 flex-text-inline tw-font-bold" href="{{$.RepoLink}}/archive/{{$release.TagName | PathEscapeSegments}}.zip" rel="nofollow" type="application/zip">
|
||||
{{svg "octicon-file-zip" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.release.source_code"}} (ZIP)
|
||||
</a>
|
||||
<div class="tw-mr-1">
|
||||
<div class="tw-mr-2">
|
||||
<span class="text grey">{{ctx.Locale.TrPluralString .Release.ArchiveDownloadCount.Zip "release.n_downloads" (ctx.Locale.PrettyNumber .Release.ArchiveDownloadCount.Zip)}}</span>
|
||||
</div>
|
||||
<span data-tooltip-content="{{ctx.Locale.Tr "repo.release.system_generated"}}">
|
||||
|
|
@ -87,7 +92,7 @@
|
|||
<a class="archive-link tw-flex-1 flex-text-inline tw-font-bold" href="{{$.RepoLink}}/archive/{{$release.TagName | PathEscapeSegments}}.tar.gz" rel="nofollow" type="application/gzip">
|
||||
{{svg "octicon-file-zip" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.release.source_code"}} (TAR.GZ)
|
||||
</a>
|
||||
<div class="tw-mr-1">
|
||||
<div class="tw-mr-2">
|
||||
<span class="text grey">{{ctx.Locale.TrPluralString .Release.ArchiveDownloadCount.TarGz "release.n_downloads" (ctx.Locale.PrettyNumber .Release.ArchiveDownloadCount.TarGz)}}</span>
|
||||
</div>
|
||||
<span data-tooltip-content="{{ctx.Locale.Tr "repo.release.system_generated"}}">
|
||||
|
|
@ -104,7 +109,7 @@
|
|||
</a>
|
||||
</li>
|
||||
{{else}}
|
||||
<li class="max-sm:tw-flex-col max-sm:tw-gap-2">
|
||||
<li class="attachment">
|
||||
<a class="tw-flex-1 flex-text-inline tw-font-bold" target="_blank" rel="nofollow" href="{{.DownloadURL}}" download>
|
||||
{{svg "octicon-package" 16 "tw-mr-1"}}{{.Name}}
|
||||
</a>
|
||||
|
|
@ -117,7 +122,6 @@
|
|||
</ul>
|
||||
</details>
|
||||
{{end}}
|
||||
<div class="dot"></div>
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
|
|
|
|||
|
|
@ -14,15 +14,15 @@
|
|||
{{template "shared/search/combo" dict "Value" .Keyword}}
|
||||
</form>
|
||||
{{end}}
|
||||
<div class="button-sequence release-list-buttons">
|
||||
<div class="small button-sequence release-list-buttons">
|
||||
{{if .EnableFeed}}
|
||||
<a class="ui small button" href="{{.RepoLink}}/{{if .PageIsTagList}}tags{{else}}releases{{end}}.rss">
|
||||
<a class="secondary button" href="{{.RepoLink}}/{{if .PageIsTagList}}tags{{else}}releases{{end}}.rss">
|
||||
{{svg "octicon-rss" 16}}
|
||||
<label class="not-mobile">{{ctx.Locale.Tr "rss_feed"}}</label>
|
||||
</a>
|
||||
{{end}}
|
||||
{{if and (not .PageIsTagList) .CanCreateRelease}}
|
||||
<a class="ui small primary button" href="{{$.RepoLink}}/releases/new">
|
||||
<a class="primary button" href="{{$.RepoLink}}/releases/new">
|
||||
{{ctx.Locale.Tr "repo.release.new_release"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// Copyright 2024-2026 The Forgejo Authors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// @watch start
|
||||
// models/repo/attachment.go
|
||||
// modules/structs/attachment.go
|
||||
|
|
@ -16,7 +19,7 @@ import {validate_form} from './shared/forms.ts';
|
|||
test.use({user: 'user2'});
|
||||
|
||||
test.describe('Releases', () => {
|
||||
test('External Release Attachments', async ({page, isMobile}) => {
|
||||
test('External release attachments', async ({page, isMobile}) => {
|
||||
test.skip(isMobile);
|
||||
|
||||
// Click "New release"
|
||||
|
|
@ -102,6 +105,44 @@ test.describe('Releases', () => {
|
|||
await expect(page.locator('input[name=title]')).toHaveValue('v2.0');
|
||||
});
|
||||
|
||||
test('UI reaction to lengthy UGC', async ({page, viewport, isMobile}) => {
|
||||
await page.goto('/user2/repo2/releases/new');
|
||||
|
||||
await page.locator('input[name=tag_name]').pressSequentially('2.0');
|
||||
await page.locator('input[name=title]').pressSequentially('v'.repeat(200));
|
||||
await page.locator('textarea[name=content]').pressSequentially('v'.repeat(200)); // Description
|
||||
|
||||
// Submit form. Mobile Chrome can't press the button in Playwright (not a Forgejo
|
||||
// bug). Work around this by pressing Enter on submit button
|
||||
await page.getByRole('button', {name: 'Publish release'}).press('Enter');
|
||||
|
||||
// Check widths of UI elements
|
||||
await page.goto('/user2/repo2/releases');
|
||||
const release = page.locator('#release-list > li:has(a[href$="/tag/2.0"])');
|
||||
// Release entry should be less than viewport
|
||||
expect((await release.boundingBox()).width).toBeLessThan(viewport.width);
|
||||
if (isMobile) {
|
||||
const metaWidth = (await release.locator('.meta').boundingBox()).width;
|
||||
const titleWidth = (await release.locator('.release-title-wrap').boundingBox()).width;
|
||||
const detailsWidth = (await release.locator('.detail').boundingBox()).width;
|
||||
// In row layout they all should be similar to the viewport length, accounting
|
||||
// for 8px margins on each side
|
||||
expect(metaWidth).toBeCloseTo(viewport.width - 16, 0);
|
||||
expect(titleWidth).toBeCloseTo(viewport.width - 16, 0);
|
||||
expect(detailsWidth).toBeCloseTo(viewport.width - 16, 0);
|
||||
// They also should all be all same width
|
||||
expect(metaWidth).toBe(titleWidth);
|
||||
expect(titleWidth).toBe(detailsWidth);
|
||||
} else {
|
||||
// Left and right columns should be less than 25% and 75% of viewport width
|
||||
// But on wide screens there's a lot of additional emptiness, so we can't
|
||||
// match columns' width against the viewport, only make sure they fit
|
||||
expect((await release.locator('.meta').boundingBox()).width).toBeLessThan(viewport.width * 0.75);
|
||||
expect((await release.locator('.release-title-wrap').boundingBox()).width).toBeLessThan(viewport.width * 0.75);
|
||||
expect((await release.locator('.detail').boundingBox()).width).toBeLessThan(viewport.width * 0.75);
|
||||
}
|
||||
});
|
||||
|
||||
test.afterEach(async ({page}) => {
|
||||
// Delete release
|
||||
const response = await page.goto('/user2/repo2/releases/edit/2.0');
|
||||
|
|
|
|||
|
|
@ -72,9 +72,9 @@ func checkLatestReleaseAndCount(t *testing.T, session *TestSession, repoURL, ver
|
|||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
labelText := htmlDoc.doc.Find("#release-list > li .detail .label").First().Text()
|
||||
labelText := htmlDoc.doc.Find("#release-list > li > .release-title-wrap .label").First().Text()
|
||||
assert.Equal(t, label, labelText)
|
||||
titleText := htmlDoc.doc.Find("#release-list > li .detail h4 a").First().Text()
|
||||
titleText := htmlDoc.doc.Find("#release-list > li > .release-title-wrap h4 a").First().Text()
|
||||
assert.Equal(t, version, titleText)
|
||||
|
||||
// Check release count in the counter on the Release/Tag switch, as well as that the tab is highlighted
|
||||
|
|
@ -255,13 +255,13 @@ func TestViewReleaseListNoLogin(t *testing.T) {
|
|||
rsp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
htmlDoc := NewHTMLParser(t, rsp.Body)
|
||||
releases := htmlDoc.Find("#release-list li.ui.grid")
|
||||
releases := htmlDoc.Find("ul#release-list > li")
|
||||
assert.Equal(t, 5, releases.Length())
|
||||
|
||||
links := make([]string, 0, 5)
|
||||
commitsToMain := make([]string, 0, 5)
|
||||
releases.Each(func(i int, s *goquery.Selection) {
|
||||
link, exist := s.Find(".release-list-title a").Attr("href")
|
||||
link, exist := s.Find(".release-title-wrap h4 a").Attr("href")
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
|
|
@ -311,12 +311,12 @@ func TestViewReleaseListLogin(t *testing.T) {
|
|||
rsp := session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
htmlDoc := NewHTMLParser(t, rsp.Body)
|
||||
releases := htmlDoc.Find("#release-list li.ui.grid")
|
||||
releases := htmlDoc.Find("ul#release-list > li")
|
||||
assert.Equal(t, 3, releases.Length())
|
||||
|
||||
links := make([]string, 0, 5)
|
||||
releases.Each(func(i int, s *goquery.Selection) {
|
||||
link, exist := s.Find(".release-list-title a").Attr("href")
|
||||
link, exist := s.Find(".release-title-wrap h4 a").Attr("href")
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
|
|
@ -342,12 +342,12 @@ func TestViewReleaseListKeyword(t *testing.T) {
|
|||
rsp := session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
htmlDoc := NewHTMLParser(t, rsp.Body)
|
||||
releases := htmlDoc.Find("#release-list li.ui.grid")
|
||||
releases := htmlDoc.Find("ul#release-list > li")
|
||||
assert.Equal(t, 1, releases.Length())
|
||||
|
||||
links := make([]string, 0, 5)
|
||||
releases.Each(func(i int, s *goquery.Selection) {
|
||||
link, exist := s.Find(".release-list-title a").Attr("href")
|
||||
link, exist := s.Find(".release-title-wrap h4 a").Attr("href")
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
|
|
@ -370,7 +370,7 @@ func TestViewReleaseListKeywordNoPagination(t *testing.T) {
|
|||
rsp := session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
htmlDoc := NewHTMLParser(t, rsp.Body)
|
||||
releases := htmlDoc.Find("#release-list li.ui.grid")
|
||||
releases := htmlDoc.Find("ul#release-list > li")
|
||||
assert.Equal(t, 1, releases.Length())
|
||||
|
||||
pagination := htmlDoc.Find("div.pagination")
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ func TestTagViewWithoutRelease(t *testing.T) {
|
|||
assert.False(t, releaseLink.HasClass("active"))
|
||||
|
||||
// Test that the title is displayed
|
||||
releaseTitle := strings.TrimSpace(htmlDoc.Find("h4.release-list-title > a").Text())
|
||||
releaseTitle := strings.TrimSpace(htmlDoc.Find(".release-title-wrap h4 > a").Text())
|
||||
assert.Equal(t, "no-release", releaseTitle)
|
||||
|
||||
// Test that there is no "Stable" link
|
||||
htmlDoc.AssertElement(t, "h4.release-list-title > span.ui.green.label", false)
|
||||
htmlDoc.AssertElement(t, ".release-title-wrap h4 > span.ui.green.label", false)
|
||||
|
||||
// Ensure that there is no "Edit" button
|
||||
htmlDoc.AssertElement(t, ".detail a.muted > svg.octicon-pencil", false)
|
||||
|
|
@ -148,7 +148,7 @@ func TestCreateNewTagProtected(t *testing.T) {
|
|||
req := NewRequestf(t, "GET", "/%s/releases/tag/v-1.1", repo.FullName())
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
tagsTab := htmlDoc.Find(".release-list-title")
|
||||
tagsTab := htmlDoc.Find(".release-title-wrap h4")
|
||||
assert.Contains(t, tagsTab.Text(), "force update v2")
|
||||
})
|
||||
})
|
||||
|
|
@ -180,7 +180,7 @@ func TestSyncRepoTags(t *testing.T) {
|
|||
req := NewRequestf(t, "GET", "/%s/releases/tag/v2", repo.FullName())
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
tagsTab := htmlDoc.Find(".release-list-title")
|
||||
tagsTab := htmlDoc.Find(".release-title-wrap h4")
|
||||
assert.Contains(t, tagsTab.Text(), "this is an annotated tag")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1750,31 +1750,6 @@ details.repo-search-result summary::marker {
|
|||
border-bottom: 1px solid var(--color-warning-border);
|
||||
}
|
||||
|
||||
.repository .release-tag-name .ui.label.isSigned,
|
||||
.repository .release-list-title .ui.label.isSigned {
|
||||
padding: 0 0.5em;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.repository .release-tag-name .ui.label.isSigned .avatar,
|
||||
.repository .release-list-title .ui.label.isSigned .avatar {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
.repository .release-tag-name .ui.label.isSigned.isVerified,
|
||||
.repository .release-list-title .ui.label.isSigned.isVerified {
|
||||
border: 1px solid var(--color-success-border);
|
||||
background-color: var(--color-success-bg);
|
||||
color: var(--color-success-text);
|
||||
}
|
||||
|
||||
.repository .release-tag-name .ui.label.isSigned.isWarning,
|
||||
.repository .release-list-title .ui.label.isSigned.isWarning {
|
||||
border: 1px solid var(--color-warning-border);
|
||||
background-color: var(--color-warning-bg);
|
||||
color: var(--color-warning-text);
|
||||
}
|
||||
|
||||
.repository .segment.reactions.dropdown .menu,
|
||||
.repository .select-reaction.dropdown .menu {
|
||||
right: 0 !important;
|
||||
|
|
|
|||
|
|
@ -1,75 +1,145 @@
|
|||
.repository.releases #release-list {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
padding-left: 0;
|
||||
#release-list {
|
||||
margin-top: 10px; /* Overriding browser default for <ul>, same value as divider */
|
||||
padding-left: 0; /* Unset browser default */
|
||||
}
|
||||
|
||||
.repository.releases #release-list .release-list-title {
|
||||
#release-list > li {
|
||||
.meta {
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
}
|
||||
.detail .desc {
|
||||
margin-block-start: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Column layout (desktop) */
|
||||
@media (min-width: 768px) {
|
||||
#release-list > li {
|
||||
display: grid;
|
||||
grid-template-columns: 25% 75%;
|
||||
justify-content: end;
|
||||
|
||||
.meta {
|
||||
grid-column: 1;
|
||||
grid-row: 1 / span 2;
|
||||
flex-direction: column;
|
||||
text-align: right;
|
||||
|
||||
/* Align contents of meta column with release name */
|
||||
padding-top: 11px;
|
||||
}
|
||||
|
||||
.detail {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
padding-block-end: 1.5rem;
|
||||
}
|
||||
:is(.detail, .release-title-wrap) {
|
||||
/* Line separating columns on wide screen */
|
||||
border-left: 1px solid var(--color-secondary);
|
||||
padding-inline-start: 1rem;
|
||||
margin-inline-start: 1rem;
|
||||
}
|
||||
.detail .download summary {
|
||||
margin-block: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Row layout (mobile) */
|
||||
@media (max-width: 767.98px) {
|
||||
#release-list > li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.meta {
|
||||
order: 1;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-block-end: 0.75rem;
|
||||
}
|
||||
.detail {
|
||||
order: 2;
|
||||
}
|
||||
.detail .text {
|
||||
/* Same as `summary` */
|
||||
margin-block-end: 0.75rem;
|
||||
}
|
||||
.detail .download summary {
|
||||
margin-block: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.release-list-search {
|
||||
order: 2 !important;
|
||||
}
|
||||
.release-list-buttons {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
#release-list .release-title-wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-block-end: 0.5rem;
|
||||
}
|
||||
|
||||
#release-list .release-title-wrap h4 {
|
||||
font-size: 2rem;
|
||||
font-weight: var(--font-weight-normal);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .meta {
|
||||
padding-top: 25px;
|
||||
position: relative;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .detail {
|
||||
padding-bottom: 20px;
|
||||
border-left: 1px solid var(--color-secondary);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .detail .author img {
|
||||
margin-bottom: 2px; /* the legacy trick to align the avatar vertically, no better solution at the moment */
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .detail .download .list {
|
||||
/* List of downloads */
|
||||
#release-list > li .detail .download .list {
|
||||
/* Override <ul> default */
|
||||
padding-left: 0;
|
||||
/* Compensate emptiness that opener provides when <details> is closed */
|
||||
padding-block-end: 1rem;
|
||||
|
||||
hr {
|
||||
height: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
background: var(--color-light);
|
||||
border: 1px solid var(--color-secondary);
|
||||
border-top: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
:is(li:first-child, .start-gap + hr + li) {
|
||||
border-top: 1px solid var(--color-secondary);
|
||||
border-top-left-radius: var(--border-radius);
|
||||
border-top-right-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
:is(li:last-child, .start-gap) {
|
||||
border-bottom: 1px solid var(--color-secondary);
|
||||
border-bottom-left-radius: var(--border-radius);
|
||||
border-bottom-right-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .detail .download .list li {
|
||||
background: var(--color-light);
|
||||
border: 1px solid var(--color-secondary);
|
||||
border-top: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .detail .download .list :is(li:first-child, .start-gap + hr + li) {
|
||||
border-top: 1px solid var(--color-secondary);
|
||||
border-top-left-radius: var(--border-radius);
|
||||
border-top-right-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .detail .download .list :is(li:last-child, .start-gap) {
|
||||
border-bottom: 1px solid var(--color-secondary);
|
||||
border-bottom-left-radius: var(--border-radius);
|
||||
border-bottom-right-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .detail .download .list hr {
|
||||
height: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.repository.releases #release-list > li .detail .dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: var(--color-secondary-dark-3);
|
||||
position: absolute;
|
||||
left: -5.5px;
|
||||
top: 30px;
|
||||
border-radius: var(--border-radius-full);
|
||||
border: 2.5px solid var(--color-body);
|
||||
@media (max-width: 640px) {
|
||||
#release-list > li .detail .download .list .attachment {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.repository.tags #tags-table .tag {
|
||||
|
|
@ -85,10 +155,6 @@
|
|||
min-width: 500px;
|
||||
}
|
||||
|
||||
.repository.new.release .target #tag-name {
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
.repository.new.release .target .at {
|
||||
margin-left: -5px;
|
||||
margin-right: 5px;
|
||||
|
|
@ -99,15 +165,6 @@
|
|||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.release-list-search {
|
||||
order: 2 !important;
|
||||
}
|
||||
.release-list-buttons {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.repository.new.release .field .attachment_edit {
|
||||
max-width: 48em;
|
||||
}
|
||||
|
|
@ -128,3 +185,28 @@
|
|||
.ui.ui.ui.tag-label.IsRelease:hover {
|
||||
border-color: var(--color-primary-dark-1);
|
||||
}
|
||||
|
||||
.repository .release-tag-name .ui.label.isSigned,
|
||||
.repository .release-title-wrap .ui.label.isSigned {
|
||||
padding: 0 0.5em;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.repository .release-tag-name .ui.label.isSigned .avatar,
|
||||
.repository .release-title-wrap .ui.label.isSigned .avatar {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
.repository .release-tag-name .ui.label.isSigned.isVerified,
|
||||
.repository .release-title-wrap .ui.label.isSigned.isVerified {
|
||||
border: 1px solid var(--color-success-border);
|
||||
background-color: var(--color-success-bg);
|
||||
color: var(--color-success-text);
|
||||
}
|
||||
|
||||
.repository .release-tag-name .ui.label.isSigned.isWarning,
|
||||
.repository .release-title-wrap .ui.label.isSigned.isWarning {
|
||||
border: 1px solid var(--color-warning-border);
|
||||
background-color: var(--color-warning-bg);
|
||||
color: var(--color-warning-text);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue