mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-01 05:36:19 +01:00
Merge branch 'forgejo' into ts-test
This commit is contained in:
commit
9e929bd709
142 changed files with 1221 additions and 1276 deletions
|
@ -12,8 +12,10 @@
|
|||
# whatever is in the default branch instead
|
||||
#
|
||||
# - after it is merged, double check it works by setting the
|
||||
# run-end-to-end-test on a pull request (any pull request will doe
|
||||
# run-end-to-end-test on a pull request (any pull request will do)
|
||||
#
|
||||
name: end-to-end
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
@ -33,10 +35,9 @@ jobs:
|
|||
run: |
|
||||
echo github.event.pull_request.head.repo.fork = ${{ github.event.pull_request.head.repo.fork }}
|
||||
echo github.event.action = ${{ github.event.action }}
|
||||
echo github.event.pull_request.merged = ${{ github.event.pull_request.merged }}
|
||||
echo github.event.pull_request.labels.*.name
|
||||
echo github.event.label
|
||||
cat <<'EOF'
|
||||
${{ toJSON(github.event.pull_request.labels.*.name) }}
|
||||
${{ toJSON(github.event.label) }}
|
||||
EOF
|
||||
cat <<'EOF'
|
||||
${{ toJSON(github.event) }}
|
||||
|
@ -47,7 +48,7 @@ jobs:
|
|||
!startsWith(vars.ROLE, 'forgejo-') && (
|
||||
github.event_name == 'push' ||
|
||||
(
|
||||
github.event.action == 'label_updated' && contains(github.event.pull_request.labels.*.name, 'run-end-to-end-tests')
|
||||
github.event.action == 'label_updated' && github.event.label.name == 'run-end-to-end-tests'
|
||||
)
|
||||
)
|
||||
runs-on: docker
|
||||
|
|
44
.forgejo/workflows/merge-requirements.yml
Normal file
44
.forgejo/workflows/merge-requirements.yml
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Copyright 2024 The Forgejo Authors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: requirements
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- labeled
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
merge-conditions:
|
||||
runs-on: docker
|
||||
container:
|
||||
image: 'code.forgejo.org/oci/node:20-bookworm'
|
||||
steps:
|
||||
- name: Debug output
|
||||
run: |
|
||||
cat <<'EOF'
|
||||
${{ toJSON(github.event) }}
|
||||
EOF
|
||||
- name: Missing test label
|
||||
if: >
|
||||
!(
|
||||
contains(toJSON(github.event.pull_request.labels), 'test/present')
|
||||
|| contains(toJSON(github.event.pull_request.labels), 'test/not-needed')
|
||||
|| contains(toJSON(github.event.pull_request.labels), 'test/manual')
|
||||
)
|
||||
run: |
|
||||
echo "Test label must be set to either 'present', 'not-needed' or 'manual'."
|
||||
exit 1
|
||||
- name: Missing manual test instructions
|
||||
if: >
|
||||
(
|
||||
contains(toJSON(github.event.pull_request.labels), 'test/manual')
|
||||
&& !contains(toJSON(github.event.pull_request.body), '# Test')
|
||||
)
|
||||
run: |
|
||||
echo "Manual test label is set. The PR description needs to contain test steps introduced by a heading like:"
|
||||
echo "# Testing"
|
||||
exit 1
|
|
@ -8,7 +8,9 @@ name: renovate
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'renovate/**' # self-test updates
|
||||
- renovate/** # self-test updates
|
||||
paths:
|
||||
- .forgejo/workflows/renovate.yml
|
||||
schedule:
|
||||
- cron: '0 0/2 * * *'
|
||||
workflow_dispatch:
|
||||
|
@ -21,9 +23,9 @@ jobs:
|
|||
renovate:
|
||||
if: ${{ secrets.RENOVATE_TOKEN != '' }}
|
||||
|
||||
runs-on: docker
|
||||
runs-on: docker-runner-one
|
||||
container:
|
||||
image: code.forgejo.org/forgejo-contrib/renovate:39.5.0
|
||||
image: code.forgejo.org/forgejo-contrib/renovate:39.9.1
|
||||
|
||||
steps:
|
||||
- name: Load renovate repo cache
|
||||
|
|
|
@ -82,7 +82,7 @@ jobs:
|
|||
- uses: ./.forgejo/workflows-composite/build-backend
|
||||
- run: |
|
||||
su forgejo -c 'make test-backend test-check'
|
||||
timeout-minutes: 50
|
||||
timeout-minutes: 120
|
||||
env:
|
||||
RACE_ENABLED: 'true'
|
||||
TAGS: bindata
|
||||
|
@ -116,7 +116,7 @@ jobs:
|
|||
separator: '\n'
|
||||
- run: |
|
||||
su forgejo -c 'make generate test-e2e-sqlite'
|
||||
timeout-minutes: 40
|
||||
timeout-minutes: 120
|
||||
env:
|
||||
USE_REPO_TEST_DIR: 1
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
|
||||
|
@ -156,7 +156,7 @@ jobs:
|
|||
- uses: ./.forgejo/workflows-composite/build-backend
|
||||
- run: |
|
||||
su forgejo -c 'make test-remote-cacher test-check'
|
||||
timeout-minutes: 50
|
||||
timeout-minutes: 120
|
||||
env:
|
||||
RACE_ENABLED: 'true'
|
||||
TAGS: bindata
|
||||
|
@ -187,7 +187,7 @@ jobs:
|
|||
- uses: ./.forgejo/workflows-composite/build-backend
|
||||
- run: |
|
||||
su forgejo -c 'make test-mysql-migration test-mysql'
|
||||
timeout-minutes: 50
|
||||
timeout-minutes: 120
|
||||
env:
|
||||
USE_REPO_TEST_DIR: 1
|
||||
test-pgsql:
|
||||
|
@ -219,7 +219,7 @@ jobs:
|
|||
- uses: ./.forgejo/workflows-composite/build-backend
|
||||
- run: |
|
||||
su forgejo -c 'make test-pgsql-migration test-pgsql'
|
||||
timeout-minutes: 50
|
||||
timeout-minutes: 120
|
||||
env:
|
||||
RACE_ENABLED: true
|
||||
USE_REPO_TEST_DIR: 1
|
||||
|
@ -240,7 +240,7 @@ jobs:
|
|||
- uses: ./.forgejo/workflows-composite/build-backend
|
||||
- run: |
|
||||
su forgejo -c 'make test-sqlite-migration test-sqlite'
|
||||
timeout-minutes: 50
|
||||
timeout-minutes: 120
|
||||
env:
|
||||
TAGS: sqlite sqlite_unlock_notify
|
||||
RACE_ENABLED: true
|
||||
|
|
|
@ -77,6 +77,8 @@ linters-settings:
|
|||
- name: unreachable-code
|
||||
- name: var-declaration
|
||||
- name: var-naming
|
||||
- name: redefines-builtin-id
|
||||
disabled: true
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
depguard:
|
||||
|
|
5
Makefile
5
Makefile
|
@ -39,7 +39,7 @@ XGO_VERSION := go-1.21.x
|
|||
AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.0.3 # renovate: datasource=go
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.7.0 # renovate: datasource=go
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0 # renovate: datasource=go
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 # renovate: datasource=go
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go
|
||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.6.0 # renovate: datasource=go
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 # renovate: datasource=go
|
||||
|
@ -49,7 +49,7 @@ GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasour
|
|||
DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.26.0 # renovate: datasource=go
|
||||
GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go
|
||||
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.16.2 # renovate: datasource=go
|
||||
RENOVATE_NPM_PACKAGE ?= renovate@39.5.0 # renovate: datasource=docker packageName=code.forgejo.org/forgejo-contrib/renovate
|
||||
RENOVATE_NPM_PACKAGE ?= renovate@39.9.1 # renovate: datasource=docker packageName=code.forgejo.org/forgejo-contrib/renovate
|
||||
|
||||
ifeq ($(HAS_GO), yes)
|
||||
CGO_EXTRA_CFLAGS := -DSQLITE_MAX_VARIABLE_NUMBER=32766
|
||||
|
@ -660,6 +660,7 @@ generate-ini-pgsql:
|
|||
-e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
|
||||
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
|
||||
-e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
|
||||
-e 's|{{TEST_STORAGE_TYPE}}|$(or $(TEST_STORAGE_TYPE),minio)|g' \
|
||||
tests/pgsql.ini.tmpl > tests/pgsql.ini
|
||||
|
||||
.PHONY: test-pgsql
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
{
|
||||
"go.buildTags": "sqlite,sqlite_unlock_notify",
|
||||
"go.testFlags": ["-v"]
|
||||
"go.buildTags": "sqlite,sqlite_unlock_notify",
|
||||
"go.testFlags": ["-v"],
|
||||
"go.lintTool": "golangci-lint",
|
||||
"go.lintFlags": ["--fast"]
|
||||
}
|
||||
|
|
|
@ -353,16 +353,25 @@ RUN_USER = ; git
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Database to use. Either "mysql", "postgres", "mssql" or "sqlite3".
|
||||
;; Database to use. Either "sqlite3", "mySQL" or "postgres".
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; SQLite Configuration
|
||||
;;
|
||||
DB_TYPE = sqlite3
|
||||
;PATH= ; defaults to data/forgejo.db
|
||||
;SQLITE_TIMEOUT = ; Query timeout defaults to: 500
|
||||
;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; MySQL Configuration
|
||||
;;
|
||||
DB_TYPE = mysql
|
||||
HOST = 127.0.0.1:3306 ; can use socket e.g. /var/run/mysqld/mysqld.sock
|
||||
NAME = gitea
|
||||
USER = root
|
||||
;DB_TYPE = mysql
|
||||
;HOST = 127.0.0.1:3306 ; can use socket e.g. /var/run/mysqld/mysqld.sock
|
||||
;NAME = gitea
|
||||
;USER = root
|
||||
;PASSWD = ;Use PASSWD = `your password` for quoting if you use special characters in the password.
|
||||
;SSL_MODE = false ; either "false" (default), "true", or "skip-verify"
|
||||
;CHARSET_COLLATION = ; Empty as default, Gitea will try to find a case-sensitive collation. Don't change it unless you clearly know what you need.
|
||||
|
@ -381,26 +390,6 @@ USER = root
|
|||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; SQLite Configuration
|
||||
;;
|
||||
;DB_TYPE = sqlite3
|
||||
;PATH= ; defaults to data/forgejo.db
|
||||
;SQLITE_TIMEOUT = ; Query timeout defaults to: 500
|
||||
;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; MSSQL Configuration
|
||||
;;
|
||||
;DB_TYPE = mssql
|
||||
;HOST = 172.17.0.2:1433
|
||||
;NAME = gitea
|
||||
;USER = SA
|
||||
;PASSWD = MwantsaSecurePassword1
|
||||
;CHARSET_COLLATION = ; Empty as default, Gitea will try to find a case-sensitive collation. Don't change it unless you clearly know what you need.
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Other settings
|
||||
;;
|
||||
;; For iterate buffer, default is 50
|
||||
|
|
20
go.mod
20
go.mod
|
@ -6,10 +6,10 @@ require (
|
|||
code.forgejo.org/f3/gof3/v3 v3.7.0
|
||||
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
code.forgejo.org/forgejo/reply v1.0.2
|
||||
code.forgejo.org/go-chi/binding v0.0.0-20241105210225-1f8bf5136720
|
||||
code.forgejo.org/go-chi/cache v0.0.0-20240912103640-dcb08fba860d
|
||||
code.forgejo.org/go-chi/captcha v0.0.0-20240905153133-df43b9250ed5
|
||||
code.forgejo.org/go-chi/session v0.0.0-20241017103059-2a992261fc26
|
||||
code.forgejo.org/go-chi/binding v1.0.0
|
||||
code.forgejo.org/go-chi/cache v1.0.0
|
||||
code.forgejo.org/go-chi/captcha v1.0.0
|
||||
code.forgejo.org/go-chi/session v1.0.0
|
||||
code.gitea.io/actions-proto-go v0.4.0
|
||||
code.gitea.io/gitea-vet v0.2.3
|
||||
code.gitea.io/sdk/gitea v0.17.1
|
||||
|
@ -100,12 +100,12 @@ require (
|
|||
github.com/yuin/goldmark v1.7.8
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||
go.uber.org/mock v0.4.0
|
||||
golang.org/x/crypto v0.28.0
|
||||
golang.org/x/crypto v0.29.0
|
||||
golang.org/x/image v0.21.0
|
||||
golang.org/x/net v0.30.0
|
||||
golang.org/x/net v0.31.0
|
||||
golang.org/x/oauth2 v0.23.0
|
||||
golang.org/x/sys v0.26.0
|
||||
golang.org/x/text v0.19.0
|
||||
golang.org/x/sys v0.27.0
|
||||
golang.org/x/text v0.20.0
|
||||
golang.org/x/tools v0.26.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
google.golang.org/protobuf v1.35.1
|
||||
|
@ -281,7 +281,7 @@ require (
|
|||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
|
@ -296,3 +296,5 @@ replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142
|
|||
replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.21.5
|
||||
|
||||
replace github.com/mholt/archiver/v3 => code.forgejo.org/forgejo/archiver/v3 v3.5.1
|
||||
|
||||
replace github.com/goccy/go-json => github.com/grafana/go-json v0.0.0-20241106155216-71a03f133f5c
|
||||
|
|
44
go.sum
44
go.sum
|
@ -10,14 +10,14 @@ code.forgejo.org/forgejo/archiver/v3 v3.5.1 h1:UmmbA7D5550uf71SQjarmrn6yKwOGxtEj
|
|||
code.forgejo.org/forgejo/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
code.forgejo.org/forgejo/reply v1.0.2 h1:dMhQCHV6/O3L5CLWNTol+dNzDAuyCK88z4J/lCdgFuQ=
|
||||
code.forgejo.org/forgejo/reply v1.0.2/go.mod h1:RyZUfzQLc+fuLIGjTSQWDAJWPiL4WtKXB/FifT5fM7U=
|
||||
code.forgejo.org/go-chi/binding v0.0.0-20241105210225-1f8bf5136720 h1:DDdvrdov1a6HK0xiJIUTfGh1RpKP0prkHi2guxhDKIU=
|
||||
code.forgejo.org/go-chi/binding v0.0.0-20241105210225-1f8bf5136720/go.mod h1:fWwqaHj0H1/KeCpBqdvKunflq8pYfciEHI5v3UUeE2E=
|
||||
code.forgejo.org/go-chi/cache v0.0.0-20240912103640-dcb08fba860d h1:nOu/2GX571t4intmtfvpctS148OqsBYrGUySVm93ifc=
|
||||
code.forgejo.org/go-chi/cache v0.0.0-20240912103640-dcb08fba860d/go.mod h1:OVlZ/TqDYJ+RUJ+R+J+OLxtlyjo3pbjBeK7LAWAB+Vk=
|
||||
code.forgejo.org/go-chi/captcha v0.0.0-20240905153133-df43b9250ed5 h1:A7P1liXCpJBHEJ5KIDsF0ujnQ8FQ/aX1UixTW0vGrDQ=
|
||||
code.forgejo.org/go-chi/captcha v0.0.0-20240905153133-df43b9250ed5/go.mod h1:YLOsiln/arX3egGtxG4QNp49G2CIqP9pqD2VL56obLc=
|
||||
code.forgejo.org/go-chi/session v0.0.0-20241017103059-2a992261fc26 h1:6XCLWu8A0nPM862Uh68kQmxsBsaQNfPPFwYjzG8M8QE=
|
||||
code.forgejo.org/go-chi/session v0.0.0-20241017103059-2a992261fc26/go.mod h1:lS76JFHZqGXYJTBHqwZ910UG046hIXAaYIN6J0Lf8sI=
|
||||
code.forgejo.org/go-chi/binding v1.0.0 h1:EIDJtk9brK7WsT7rvS/D4cxX8XlnhY3LMy8ex1jeHu0=
|
||||
code.forgejo.org/go-chi/binding v1.0.0/go.mod h1:fWwqaHj0H1/KeCpBqdvKunflq8pYfciEHI5v3UUeE2E=
|
||||
code.forgejo.org/go-chi/cache v1.0.0 h1:akLfGxNlHcacmtutovNtYFSTMsbdcp5MGjAEsP4pxnE=
|
||||
code.forgejo.org/go-chi/cache v1.0.0/go.mod h1:OVlZ/TqDYJ+RUJ+R+J+OLxtlyjo3pbjBeK7LAWAB+Vk=
|
||||
code.forgejo.org/go-chi/captcha v1.0.0 h1:ZKVznXrPfruc1RMavCFBEINGxB3RAYr4I+WQAK8+eP0=
|
||||
code.forgejo.org/go-chi/captcha v1.0.0/go.mod h1:YLOsiln/arX3egGtxG4QNp49G2CIqP9pqD2VL56obLc=
|
||||
code.forgejo.org/go-chi/session v1.0.0 h1:1hjLWHpXkb4vs/g9rk/unhRL4AoKEqVUPJ+opI8UO3Y=
|
||||
code.forgejo.org/go-chi/session v1.0.0/go.mod h1:lS76JFHZqGXYJTBHqwZ910UG046hIXAaYIN6J0Lf8sI=
|
||||
code.gitea.io/actions-proto-go v0.4.0 h1:OsPBPhodXuQnsspG1sQ4eRE1PeoZyofd7+i73zCwnsU=
|
||||
code.gitea.io/actions-proto-go v0.4.0/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas=
|
||||
code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI=
|
||||
|
@ -307,8 +307,6 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA
|
|||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
|
||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
|
||||
|
@ -383,6 +381,8 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX
|
|||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
|
||||
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
|
||||
github.com/grafana/go-json v0.0.0-20241106155216-71a03f133f5c h1:yKBKEC347YZpgii1KazRCfxHsTaxMqWZzoivM1OTT50=
|
||||
github.com/grafana/go-json v0.0.0-20241106155216-71a03f133f5c/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
|
||||
github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||
|
@ -733,8 +733,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
|
|||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
|
||||
|
@ -760,8 +760,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -771,8 +771,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -801,8 +801,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
|
@ -812,8 +812,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
|||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
@ -825,8 +825,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
|
|
@ -96,6 +96,6 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
|
|||
// Test JSON rendering
|
||||
jsonData, err := json.Marshal(heatmap)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.JSONResult, string(jsonData))
|
||||
assert.JSONEq(t, tc.JSONResult, string(jsonData))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
size: 7597
|
||||
is_fsck_enabled: true
|
||||
close_issues_via_commit_in_any_branch: false
|
||||
|
||||
created_unix: 1731254961
|
||||
updated_unix: 1731254961
|
||||
-
|
||||
id: 2
|
||||
owner_id: 2
|
||||
|
|
|
@ -5,7 +5,6 @@ package project
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
@ -124,5 +123,5 @@ func Test_NewColumn(t *testing.T) {
|
|||
ProjectID: project1.ID,
|
||||
})
|
||||
require.Error(t, err)
|
||||
assert.True(t, strings.Contains(err.Error(), "maximum number of columns reached"))
|
||||
assert.Contains(t, err.Error(), "maximum number of columns reached")
|
||||
}
|
||||
|
|
|
@ -4,99 +4,12 @@
|
|||
package unittest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// Copy copies file from source to target path.
|
||||
func Copy(src, dest string) error {
|
||||
// Gather file information to set back later.
|
||||
si, err := os.Lstat(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Handle symbolic link.
|
||||
if si.Mode()&os.ModeSymlink != 0 {
|
||||
target, err := os.Readlink(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// NOTE: os.Chmod and os.Chtimes don't recognize symbolic link,
|
||||
// which will lead "no such file or directory" error.
|
||||
return os.Symlink(target, dest)
|
||||
}
|
||||
|
||||
sr, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sr.Close()
|
||||
|
||||
dw, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dw.Close()
|
||||
|
||||
if _, err = io.Copy(dw, sr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set back file information.
|
||||
if err = os.Chtimes(dest, si.ModTime(), si.ModTime()); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Chmod(dest, si.Mode())
|
||||
}
|
||||
|
||||
// CopyDir copy files recursively from source to target directory.
|
||||
//
|
||||
// The filter accepts a function that process the path info.
|
||||
// and should return true for need to filter.
|
||||
//
|
||||
// It returns error when error occurs in underlying functions.
|
||||
func CopyDir(srcPath, destPath string, filters ...func(filePath string) bool) error {
|
||||
// Check if target directory exists.
|
||||
if _, err := os.Stat(destPath); !errors.Is(err, os.ErrNotExist) {
|
||||
return util.NewAlreadyExistErrorf("file or directory already exists: %s", destPath)
|
||||
}
|
||||
|
||||
err := os.MkdirAll(destPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Gather directory info.
|
||||
infos, err := util.StatDir(srcPath, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var filter func(filePath string) bool
|
||||
if len(filters) > 0 {
|
||||
filter = filters[0]
|
||||
}
|
||||
|
||||
for _, info := range infos {
|
||||
if filter != nil && filter(info) {
|
||||
continue
|
||||
}
|
||||
|
||||
curPath := path.Join(destPath, info)
|
||||
if strings.HasSuffix(info, "/") {
|
||||
err = os.MkdirAll(curPath, os.ModePerm)
|
||||
} else {
|
||||
err = Copy(path.Join(srcPath, info), curPath)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
func CopyDir(srcPath, destPath string) error {
|
||||
return os.CopyFS(destPath, os.DirFS(srcPath))
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -119,7 +118,7 @@ func TestActivityPubSignedPost(t *testing.T) {
|
|||
|
||||
expected := "BODY"
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Regexp(t, regexp.MustCompile("^"+setting.Federation.DigestAlgorithm), r.Header.Get("Digest"))
|
||||
assert.Regexp(t, "^"+setting.Federation.DigestAlgorithm, r.Header.Get("Digest"))
|
||||
assert.Contains(t, r.Header.Get("Signature"), pubID)
|
||||
assert.Equal(t, ActivityStreamsContentType, r.Header.Get("Content-Type"))
|
||||
body, err := io.ReadAll(r.Body)
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
// GetCommitGraph return a list of commit (GraphItems) from all branches
|
||||
func GetCommitGraph(r *git.Repository, page, maxAllowedColors int, hidePRRefs bool, branches, files []string) (*Graph, error) {
|
||||
format := "DATA:%D|%H|%ad|%h|%s"
|
||||
format := "DATA:%D|%H|%aD|%h|%s"
|
||||
|
||||
if page == 0 {
|
||||
page = 1
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
@ -198,6 +199,11 @@ func NewCommit(row, column int, line []byte) (*Commit, error) {
|
|||
if len(data) < 5 {
|
||||
return nil, fmt.Errorf("malformed data section on line %d with commit: %s", row, string(line))
|
||||
}
|
||||
// Format is a slight modifcation from RFC1123Z
|
||||
t, err := time.Parse("Mon, _2 Jan 2006 15:04:05 -0700", string(data[2]))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse date of commit: %w", err)
|
||||
}
|
||||
return &Commit{
|
||||
Row: row,
|
||||
Column: column,
|
||||
|
@ -205,8 +211,8 @@ func NewCommit(row, column int, line []byte) (*Commit, error) {
|
|||
Refs: newRefsFromRefNames(data[0]),
|
||||
// 1 matches git log --pretty=format:%H => commit hash
|
||||
Rev: string(data[1]),
|
||||
// 2 matches git log --pretty=format:%ad => author date (format respects --date= option)
|
||||
Date: string(data[2]),
|
||||
// 2 matches git log --pretty=format:%aD => author date, RFC2822 style
|
||||
Date: t,
|
||||
// 3 matches git log --pretty=format:%h => abbreviated commit hash
|
||||
ShortRev: string(data[3]),
|
||||
// 4 matches git log --pretty=format:%s => subject
|
||||
|
@ -245,7 +251,7 @@ type Commit struct {
|
|||
Column int
|
||||
Refs []git.Reference
|
||||
Rev string
|
||||
Date string
|
||||
Date time.Time
|
||||
ShortRev string
|
||||
Subject string
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ func TestParseGlyphs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCommitStringParsing(t *testing.T) {
|
||||
dataFirstPart := "* DATA:|4e61bacab44e9b4730e44a6615d04098dd3a8eaf|2016-12-20 21:10:41 +0100|4e61bac|"
|
||||
dataFirstPart := "* DATA:|4e61bacab44e9b4730e44a6615d04098dd3a8eaf|Tue, 20 Dec 2016 21:10:41 +0100|4e61bac|"
|
||||
tests := []struct {
|
||||
shouldPass bool
|
||||
testName string
|
||||
|
|
|
@ -19,6 +19,15 @@ func NumericEqualityQuery(value int64, field string) *query.NumericRangeQuery {
|
|||
return q
|
||||
}
|
||||
|
||||
// MatchQuery generates a match query for the given phrase, field and analyzer
|
||||
func MatchQuery(matchTerm, field, analyzer string, fuzziness int) *query.MatchQuery {
|
||||
q := bleve.NewMatchQuery(matchTerm)
|
||||
q.FieldVal = field
|
||||
q.Analyzer = analyzer
|
||||
q.Fuzziness = fuzziness
|
||||
return q
|
||||
}
|
||||
|
||||
// MatchPhraseQuery generates a match phrase query for the given phrase, field and analyzer
|
||||
func MatchPhraseQuery(matchPhrase, field, analyzer string, fuzziness int) *query.MatchPhraseQuery {
|
||||
q := bleve.NewMatchPhraseQuery(matchPhrase)
|
||||
|
|
|
@ -35,13 +35,7 @@ func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
|
|||
})
|
||||
}
|
||||
|
||||
const (
|
||||
maxBatchSize = 16
|
||||
// fuzzyDenominator determines the levenshtein distance per each character of a keyword
|
||||
fuzzyDenominator = 4
|
||||
// see https://github.com/blevesearch/bleve/issues/1563#issuecomment-786822311
|
||||
maxFuzziness = 2
|
||||
)
|
||||
const maxBatchSize = 16
|
||||
|
||||
// IndexerData an update to the issue indexer
|
||||
type IndexerData internal.IndexerData
|
||||
|
@ -162,16 +156,25 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
|
|||
var queries []query.Query
|
||||
|
||||
if options.Keyword != "" {
|
||||
fuzziness := 0
|
||||
if options.IsFuzzyKeyword {
|
||||
fuzziness = min(maxFuzziness, len(options.Keyword)/fuzzyDenominator)
|
||||
fuzziness := 1
|
||||
if kl := len(options.Keyword); kl > 3 {
|
||||
fuzziness = 2
|
||||
} else if kl < 2 {
|
||||
fuzziness = 0
|
||||
}
|
||||
queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{
|
||||
inner_bleve.MatchQuery(options.Keyword, "title", issueIndexerAnalyzer, fuzziness),
|
||||
inner_bleve.MatchQuery(options.Keyword, "content", issueIndexerAnalyzer, fuzziness),
|
||||
inner_bleve.MatchQuery(options.Keyword, "comments", issueIndexerAnalyzer, fuzziness),
|
||||
}...))
|
||||
} else {
|
||||
queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{
|
||||
inner_bleve.MatchPhraseQuery(options.Keyword, "title", issueIndexerAnalyzer, 0),
|
||||
inner_bleve.MatchPhraseQuery(options.Keyword, "content", issueIndexerAnalyzer, 0),
|
||||
inner_bleve.MatchPhraseQuery(options.Keyword, "comments", issueIndexerAnalyzer, 0),
|
||||
}...))
|
||||
}
|
||||
|
||||
queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{
|
||||
inner_bleve.MatchPhraseQuery(options.Keyword, "title", issueIndexerAnalyzer, fuzziness),
|
||||
inner_bleve.MatchPhraseQuery(options.Keyword, "content", issueIndexerAnalyzer, fuzziness),
|
||||
inner_bleve.MatchPhraseQuery(options.Keyword, "comments", issueIndexerAnalyzer, fuzziness),
|
||||
}...))
|
||||
}
|
||||
|
||||
if len(options.RepoIDs) > 0 || options.AllPublic {
|
||||
|
|
|
@ -78,7 +78,9 @@ func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOp
|
|||
searchOpt.Paginator = opts.Paginator
|
||||
|
||||
switch opts.SortType {
|
||||
case "", "latest":
|
||||
case "", "relevance":
|
||||
searchOpt.SortBy = SortByScore
|
||||
case "latest":
|
||||
searchOpt.SortBy = SortByCreatedDesc
|
||||
case "oldest":
|
||||
searchOpt.SortBy = SortByCreatedAsc
|
||||
|
|
|
@ -236,7 +236,7 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
|
|||
}
|
||||
|
||||
if options.SortBy == "" {
|
||||
options.SortBy = internal.SortByCreatedAsc
|
||||
options.SortBy = internal.SortByScore
|
||||
}
|
||||
sortBy := []elastic.Sorter{
|
||||
parseSortBy(options.SortBy),
|
||||
|
|
|
@ -269,6 +269,7 @@ func IsAvailable(ctx context.Context) bool {
|
|||
type SearchOptions = internal.SearchOptions
|
||||
|
||||
const (
|
||||
SortByScore = internal.SortByScore
|
||||
SortByCreatedDesc = internal.SortByCreatedDesc
|
||||
SortByUpdatedDesc = internal.SortByUpdatedDesc
|
||||
SortByCommentsDesc = internal.SortByCommentsDesc
|
||||
|
|
|
@ -127,6 +127,7 @@ func (o *SearchOptions) Copy(edit ...func(options *SearchOptions)) *SearchOption
|
|||
type SortBy string
|
||||
|
||||
const (
|
||||
SortByScore SortBy = "-_score"
|
||||
SortByCreatedDesc SortBy = "-created_unix"
|
||||
SortByUpdatedDesc SortBy = "-updated_unix"
|
||||
SortByCommentsDesc SortBy = "-comment_count"
|
||||
|
|
|
@ -126,6 +126,7 @@ var cases = []*testIndexerCase{
|
|||
},
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
Keyword: "hello",
|
||||
SortBy: internal.SortByCreatedDesc,
|
||||
},
|
||||
ExpectedIDs: []int64{1002, 1001, 1000},
|
||||
ExpectedTotal: 3,
|
||||
|
@ -139,6 +140,7 @@ var cases = []*testIndexerCase{
|
|||
},
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
Keyword: "hello world",
|
||||
SortBy: internal.SortByCreatedDesc,
|
||||
IsFuzzyKeyword: true,
|
||||
},
|
||||
ExpectedIDs: []int64{1002, 1001, 1000},
|
||||
|
@ -157,6 +159,7 @@ var cases = []*testIndexerCase{
|
|||
},
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
Keyword: "hello",
|
||||
SortBy: internal.SortByCreatedDesc,
|
||||
RepoIDs: []int64{1, 4},
|
||||
},
|
||||
ExpectedIDs: []int64{1006, 1002, 1001},
|
||||
|
@ -175,6 +178,7 @@ var cases = []*testIndexerCase{
|
|||
},
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
Keyword: "hello",
|
||||
SortBy: internal.SortByCreatedDesc,
|
||||
RepoIDs: []int64{1, 4},
|
||||
AllPublic: true,
|
||||
},
|
||||
|
@ -597,6 +601,22 @@ var cases = []*testIndexerCase{
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "SortByScore",
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
Paginator: &db.ListOptionsAll,
|
||||
SortBy: internal.SortByScore,
|
||||
},
|
||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
|
||||
assert.Equal(t, len(data), len(result.Hits))
|
||||
assert.Equal(t, len(data), int(result.Total))
|
||||
for i, v := range result.Hits {
|
||||
if i < len(result.Hits)-1 {
|
||||
assert.GreaterOrEqual(t, v.Score, result.Hits[i+1].Score)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "SortByCreatedAsc",
|
||||
SearchOptions: &internal.SearchOptions{
|
||||
|
|
|
@ -208,12 +208,18 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
|
|||
query.And(inner_meilisearch.NewFilterLte("updated_unix", options.UpdatedBeforeUnix.Value()))
|
||||
}
|
||||
|
||||
if options.SortBy == "" {
|
||||
options.SortBy = internal.SortByCreatedAsc
|
||||
}
|
||||
sortBy := []string{
|
||||
parseSortBy(options.SortBy),
|
||||
"id:desc",
|
||||
var sortBy []string
|
||||
switch options.SortBy {
|
||||
// sort by relevancy (no explicit sorting)
|
||||
case internal.SortByScore:
|
||||
fallthrough
|
||||
case "":
|
||||
sortBy = []string{}
|
||||
default:
|
||||
sortBy = []string{
|
||||
parseSortBy(options.SortBy),
|
||||
"id:desc",
|
||||
}
|
||||
}
|
||||
|
||||
skip, limit := indexer_internal.ParsePaginator(options.Paginator, maxTotalHits)
|
||||
|
|
|
@ -267,7 +267,7 @@ func TestHTTPClientDownload(t *testing.T) {
|
|||
return nil
|
||||
})
|
||||
if len(c.expectederror) > 0 {
|
||||
assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
} else {
|
||||
require.NoError(t, err, "case %d", n)
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ func TestHTTPClientUpload(t *testing.T) {
|
|||
return io.NopCloser(new(bytes.Buffer)), objectError
|
||||
})
|
||||
if len(c.expectederror) > 0 {
|
||||
assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
} else {
|
||||
require.NoError(t, err, "case %d", n)
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ func TestBasicTransferAdapter(t *testing.T) {
|
|||
for n, c := range cases {
|
||||
_, err := a.Download(context.Background(), c.link)
|
||||
if len(c.expectederror) > 0 {
|
||||
assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
} else {
|
||||
require.NoError(t, err, "case %d", n)
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ func TestBasicTransferAdapter(t *testing.T) {
|
|||
for n, c := range cases {
|
||||
err := a.Upload(context.Background(), c.link, p, bytes.NewBufferString("dummy"))
|
||||
if len(c.expectederror) > 0 {
|
||||
assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
} else {
|
||||
require.NoError(t, err, "case %d", n)
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ func TestBasicTransferAdapter(t *testing.T) {
|
|||
for n, c := range cases {
|
||||
err := a.Verify(context.Background(), c.link, p)
|
||||
if len(c.expectederror) > 0 {
|
||||
assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
} else {
|
||||
require.NoError(t, err, "case %d", n)
|
||||
}
|
||||
|
|
|
@ -445,7 +445,7 @@ MINIO_BASE_PATH = /lfs
|
|||
require.NoError(t, loadLFSFrom(cfg))
|
||||
assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID)
|
||||
assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey)
|
||||
assert.True(t, true, LFS.Storage.MinioConfig.UseSSL)
|
||||
assert.True(t, LFS.Storage.MinioConfig.UseSSL)
|
||||
assert.EqualValues(t, "/lfs", LFS.Storage.MinioConfig.BasePath)
|
||||
|
||||
cfg, err = NewConfigProviderFromData(`
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/svg"
|
||||
"code.gitea.io/gitea/modules/templates/eval"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
)
|
||||
|
@ -65,16 +64,18 @@ func NewFuncMap() template.FuncMap {
|
|||
|
||||
// -----------------------------------------------------------------
|
||||
// time / number / format
|
||||
"FileSize": FileSizePanic,
|
||||
"CountFmt": base.FormatNumberSI,
|
||||
"TimeSince": timeutil.TimeSince,
|
||||
"TimeSinceUnix": timeutil.TimeSinceUnix,
|
||||
"DateTime": dateTimeLegacy, // for backward compatibility only, do not use it anymore
|
||||
"Sec2Time": util.SecToTime,
|
||||
"FileSize": FileSizePanic,
|
||||
"CountFmt": base.FormatNumberSI,
|
||||
"Sec2Time": util.SecToTime,
|
||||
"LoadTimes": func(startTime time.Time) string {
|
||||
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
|
||||
},
|
||||
|
||||
// for backward compatibility only, do not use them anymore
|
||||
"TimeSince": timeSinceLegacy,
|
||||
"TimeSinceUnix": timeSinceLegacy,
|
||||
"DateTime": dateTimeLegacy,
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// setting
|
||||
"AppName": func() string {
|
||||
|
|
|
@ -4,35 +4,40 @@
|
|||
package templates
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
)
|
||||
|
||||
type DateUtils struct {
|
||||
ctx context.Context
|
||||
}
|
||||
type DateUtils struct{}
|
||||
|
||||
func NewDateUtils(ctx context.Context) *DateUtils {
|
||||
return &DateUtils{ctx}
|
||||
func NewDateUtils() *DateUtils {
|
||||
return (*DateUtils)(nil) // the util is stateless, and we do not need to create an instance
|
||||
}
|
||||
|
||||
// AbsoluteShort renders in "Jan 01, 2006" format
|
||||
func (du *DateUtils) AbsoluteShort(time any) template.HTML {
|
||||
return timeutil.DateTime("short", time)
|
||||
return dateTimeFormat("short", time)
|
||||
}
|
||||
|
||||
// AbsoluteLong renders in "January 01, 2006" format
|
||||
func (du *DateUtils) AbsoluteLong(time any) template.HTML {
|
||||
return timeutil.DateTime("long", time)
|
||||
return dateTimeFormat("long", time)
|
||||
}
|
||||
|
||||
// FullTime renders in "Jan 01, 2006 20:33:44" format
|
||||
func (du *DateUtils) FullTime(time any) template.HTML {
|
||||
return timeutil.DateTime("full", time)
|
||||
return dateTimeFormat("full", time)
|
||||
}
|
||||
|
||||
func (du *DateUtils) TimeSince(time any) template.HTML {
|
||||
return TimeSince(time)
|
||||
}
|
||||
|
||||
// ParseLegacy parses the datetime in legacy format, eg: "2016-01-02" in server's timezone.
|
||||
|
@ -56,5 +61,91 @@ func dateTimeLegacy(format string, datetime any, _ ...string) template.HTML {
|
|||
if s, ok := datetime.(string); ok {
|
||||
datetime = parseLegacy(s)
|
||||
}
|
||||
return timeutil.DateTime(format, datetime)
|
||||
return dateTimeFormat(format, datetime)
|
||||
}
|
||||
|
||||
func timeSinceLegacy(time any, _ translation.Locale) template.HTML {
|
||||
if !setting.IsProd || setting.IsInTesting {
|
||||
panic("timeSinceLegacy is for backward compatibility only, do not use it in new code")
|
||||
}
|
||||
return TimeSince(time)
|
||||
}
|
||||
|
||||
func anyToTime(any any) (t time.Time, isZero bool) {
|
||||
switch v := any.(type) {
|
||||
case nil:
|
||||
// it is zero
|
||||
case *time.Time:
|
||||
if v != nil {
|
||||
t = *v
|
||||
}
|
||||
case time.Time:
|
||||
t = v
|
||||
case timeutil.TimeStamp:
|
||||
t = v.AsTime()
|
||||
case timeutil.TimeStampNano:
|
||||
t = v.AsTime()
|
||||
case int:
|
||||
t = timeutil.TimeStamp(v).AsTime()
|
||||
case int64:
|
||||
t = timeutil.TimeStamp(v).AsTime()
|
||||
default:
|
||||
panic(fmt.Sprintf("Unsupported time type %T", any))
|
||||
}
|
||||
return t, t.IsZero() || t.Unix() == 0
|
||||
}
|
||||
|
||||
func dateTimeFormat(format string, datetime any) template.HTML {
|
||||
t, isZero := anyToTime(datetime)
|
||||
if isZero {
|
||||
return "-"
|
||||
}
|
||||
var textEscaped string
|
||||
datetimeEscaped := html.EscapeString(t.Format(time.RFC3339))
|
||||
if format == "full" {
|
||||
textEscaped = html.EscapeString(t.Format("2006-01-02 15:04:05 -07:00"))
|
||||
} else {
|
||||
textEscaped = html.EscapeString(t.Format("2006-01-02"))
|
||||
}
|
||||
|
||||
attrs := []string{`weekday=""`, `year="numeric"`}
|
||||
switch format {
|
||||
case "short", "long": // date only
|
||||
attrs = append(attrs, `month="`+format+`"`, `day="numeric"`)
|
||||
return template.HTML(fmt.Sprintf(`<absolute-date %s date="%s">%s</absolute-date>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
|
||||
case "full": // full date including time
|
||||
attrs = append(attrs, `format="datetime"`, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`, `data-tooltip-content`, `data-tooltip-interactive="true"`)
|
||||
return template.HTML(fmt.Sprintf(`<relative-time %s datetime="%s">%s</relative-time>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
|
||||
default:
|
||||
panic(fmt.Sprintf("Unsupported format %s", format))
|
||||
}
|
||||
}
|
||||
|
||||
func timeSinceTo(then any, now time.Time) template.HTML {
|
||||
thenTime, isZero := anyToTime(then)
|
||||
if isZero {
|
||||
return "-"
|
||||
}
|
||||
|
||||
friendlyText := thenTime.Format("2006-01-02 15:04:05 -07:00")
|
||||
|
||||
// document: https://github.com/github/relative-time-element
|
||||
attrs := `tense="past"`
|
||||
isFuture := now.Before(thenTime)
|
||||
if isFuture {
|
||||
attrs = `tense="future"`
|
||||
}
|
||||
|
||||
// declare data-tooltip-content attribute to switch from "title" tooltip to "tippy" tooltip
|
||||
htm := fmt.Sprintf(`<relative-time prefix="" %s datetime="%s" data-tooltip-content data-tooltip-interactive="true">%s</relative-time>`,
|
||||
attrs, thenTime.Format(time.RFC3339), friendlyText)
|
||||
return template.HTML(htm)
|
||||
}
|
||||
|
||||
// TimeSince renders relative time HTML given a time
|
||||
func TimeSince(then any) template.HTML {
|
||||
if setting.UI.PreferredTimestampTense == "absolute" {
|
||||
return dateTimeFormat("full", then)
|
||||
}
|
||||
return timeSinceTo(then, time.Now())
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func TestDateTime(t *testing.T) {
|
|||
defer test.MockVariableValue(&setting.DefaultUILocation, testTz)()
|
||||
defer test.MockVariableValue(&setting.IsInTesting, false)()
|
||||
|
||||
du := NewDateUtils(nil)
|
||||
du := NewDateUtils()
|
||||
|
||||
refTimeStr := "2018-01-01T00:00:00Z"
|
||||
refDateStr := "2018-01-01"
|
||||
|
@ -59,3 +59,24 @@ func TestDateTime(t *testing.T) {
|
|||
actual = du.FullTime(refTimeStamp)
|
||||
assert.EqualValues(t, `<relative-time weekday="" year="numeric" format="datetime" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" data-tooltip-content data-tooltip-interactive="true" datetime="2017-12-31T19:00:00-05:00">2017-12-31 19:00:00 -05:00</relative-time>`, actual)
|
||||
}
|
||||
|
||||
func TestTimeSince(t *testing.T) {
|
||||
testTz, _ := time.LoadLocation("America/New_York")
|
||||
defer test.MockVariableValue(&setting.DefaultUILocation, testTz)()
|
||||
defer test.MockVariableValue(&setting.IsInTesting, false)()
|
||||
|
||||
du := NewDateUtils()
|
||||
assert.EqualValues(t, "-", du.TimeSince(nil))
|
||||
|
||||
refTimeStr := "2018-01-01T00:00:00Z"
|
||||
refTime, _ := time.Parse(time.RFC3339, refTimeStr)
|
||||
|
||||
actual := du.TimeSince(refTime)
|
||||
assert.EqualValues(t, `<relative-time prefix="" tense="past" datetime="2018-01-01T00:00:00Z" data-tooltip-content data-tooltip-interactive="true">2018-01-01 00:00:00 +00:00</relative-time>`, actual)
|
||||
|
||||
actual = timeSinceTo(&refTime, time.Time{})
|
||||
assert.EqualValues(t, `<relative-time prefix="" tense="future" datetime="2018-01-01T00:00:00Z" data-tooltip-content data-tooltip-interactive="true">2018-01-01 00:00:00 +00:00</relative-time>`, actual)
|
||||
|
||||
actual = timeSinceLegacy(timeutil.TimeStampNano(refTime.UnixNano()), nil)
|
||||
assert.EqualValues(t, `<relative-time prefix="" tense="past" datetime="2017-12-31T19:00:00-05:00" data-tooltip-content data-tooltip-interactive="true">2017-12-31 19:00:00 -05:00</relative-time>`, actual)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,10 @@ func NewStringUtils() *StringUtils {
|
|||
return &stringUtils
|
||||
}
|
||||
|
||||
func (su *StringUtils) Make(arr ...string) []string {
|
||||
return arr
|
||||
}
|
||||
|
||||
func (su *StringUtils) HasPrefix(s any, prefix string) bool {
|
||||
switch v := s.(type) {
|
||||
case string:
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package timeutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DateTime renders an absolute time HTML element by datetime.
|
||||
func DateTime(format string, datetime any) template.HTML {
|
||||
if p, ok := datetime.(*time.Time); ok {
|
||||
datetime = *p
|
||||
}
|
||||
if p, ok := datetime.(*TimeStamp); ok {
|
||||
datetime = *p
|
||||
}
|
||||
switch v := datetime.(type) {
|
||||
case TimeStamp:
|
||||
datetime = v.AsTime()
|
||||
case int:
|
||||
datetime = TimeStamp(v).AsTime()
|
||||
case int64:
|
||||
datetime = TimeStamp(v).AsTime()
|
||||
}
|
||||
|
||||
var datetimeEscaped, textEscaped string
|
||||
switch v := datetime.(type) {
|
||||
case nil:
|
||||
return "-"
|
||||
case time.Time:
|
||||
if v.IsZero() || v.Unix() == 0 {
|
||||
return "-"
|
||||
}
|
||||
datetimeEscaped = html.EscapeString(v.Format(time.RFC3339))
|
||||
if format == "full" {
|
||||
textEscaped = html.EscapeString(v.Format("2006-01-02 15:04:05 -07:00"))
|
||||
} else {
|
||||
textEscaped = html.EscapeString(v.Format("2006-01-02"))
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("Unsupported time type %T", datetime))
|
||||
}
|
||||
|
||||
attrs := []string{`weekday=""`, `year="numeric"`}
|
||||
switch format {
|
||||
case "short", "long": // date only
|
||||
attrs = append(attrs, `month="`+format+`"`, `day="numeric"`)
|
||||
return template.HTML(fmt.Sprintf(`<absolute-date %s date="%s">%s</absolute-date>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
|
||||
case "full": // full date including time
|
||||
attrs = append(attrs, `format="datetime"`, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`, `data-tooltip-content`, `data-tooltip-interactive="true"`)
|
||||
return template.HTML(fmt.Sprintf(`<relative-time %s datetime="%s">%s</relative-time>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
|
||||
default:
|
||||
panic(fmt.Sprintf("Unsupported format %s", format))
|
||||
}
|
||||
}
|
|
@ -4,12 +4,9 @@
|
|||
package timeutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
)
|
||||
|
||||
|
@ -81,16 +78,11 @@ func computeTimeDiffFloor(diff int64, lang translation.Locale) (int64, string) {
|
|||
return diff, diffStr
|
||||
}
|
||||
|
||||
// MinutesToFriendly returns a user friendly string with number of minutes
|
||||
// MinutesToFriendly returns a user-friendly string with number of minutes
|
||||
// converted to hours and minutes.
|
||||
func MinutesToFriendly(minutes int, lang translation.Locale) string {
|
||||
duration := time.Duration(minutes) * time.Minute
|
||||
return TimeSincePro(time.Now().Add(-duration), lang)
|
||||
}
|
||||
|
||||
// TimeSincePro calculates the time interval and generate full user-friendly string.
|
||||
func TimeSincePro(then time.Time, lang translation.Locale) string {
|
||||
return timeSincePro(then, time.Now(), lang)
|
||||
return timeSincePro(time.Now().Add(-duration), time.Now(), lang)
|
||||
}
|
||||
|
||||
func timeSincePro(then, now time.Time, lang translation.Locale) string {
|
||||
|
@ -114,32 +106,3 @@ func timeSincePro(then, now time.Time, lang translation.Locale) string {
|
|||
}
|
||||
return strings.TrimPrefix(timeStr, ", ")
|
||||
}
|
||||
|
||||
func timeSinceUnix(then, now time.Time, _ translation.Locale) template.HTML {
|
||||
friendlyText := then.Format("2006-01-02 15:04:05 -07:00")
|
||||
|
||||
// document: https://github.com/github/relative-time-element
|
||||
attrs := `tense="past"`
|
||||
isFuture := now.Before(then)
|
||||
if isFuture {
|
||||
attrs = `tense="future"`
|
||||
}
|
||||
|
||||
// declare data-tooltip-content attribute to switch from "title" tooltip to "tippy" tooltip
|
||||
htm := fmt.Sprintf(`<relative-time prefix="" %s datetime="%s" data-tooltip-content data-tooltip-interactive="true">%s</relative-time>`,
|
||||
attrs, then.Format(time.RFC3339), friendlyText)
|
||||
return template.HTML(htm)
|
||||
}
|
||||
|
||||
// TimeSince renders relative time HTML given a time.Time
|
||||
func TimeSince(then time.Time, lang translation.Locale) template.HTML {
|
||||
if setting.UI.PreferredTimestampTense == "absolute" {
|
||||
return DateTime("full", then)
|
||||
}
|
||||
return timeSinceUnix(then, time.Now(), lang)
|
||||
}
|
||||
|
||||
// TimeSinceUnix renders relative time HTML given a TimeStamp
|
||||
func TimeSinceUnix(then TimeStamp, lang translation.Locale) template.HTML {
|
||||
return TimeSince(then.AsLocalTime(), lang)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -24,8 +23,8 @@ func TestKeygen(t *testing.T) {
|
|||
assert.NotEmpty(t, priv)
|
||||
assert.NotEmpty(t, pub)
|
||||
|
||||
assert.Regexp(t, regexp.MustCompile("^-----BEGIN RSA PRIVATE KEY-----.*"), priv)
|
||||
assert.Regexp(t, regexp.MustCompile("^-----BEGIN PUBLIC KEY-----.*"), pub)
|
||||
assert.Regexp(t, "^-----BEGIN RSA PRIVATE KEY-----.*", priv)
|
||||
assert.Regexp(t, "^-----BEGIN PUBLIC KEY-----.*", pub)
|
||||
}
|
||||
|
||||
func TestSignUsingKeys(t *testing.T) {
|
||||
|
|
|
@ -1586,6 +1586,7 @@ issues.filter_type.mentioning_you = Mentioning you
|
|||
issues.filter_type.review_requested = Review requested
|
||||
issues.filter_type.reviewed_by_you = Reviewed by you
|
||||
issues.filter_sort = Sort
|
||||
issues.filter_sort.relevance = Relevance
|
||||
issues.filter_sort.latest = Newest
|
||||
issues.filter_sort.oldest = Oldest
|
||||
issues.filter_sort.recentupdate = Recently updated
|
||||
|
|
18
package-lock.json
generated
18
package-lock.json
generated
|
@ -37,7 +37,7 @@
|
|||
"monaco-editor": "0.51.0",
|
||||
"monaco-editor-webpack-plugin": "7.1.0",
|
||||
"pdfobject": "2.3.0",
|
||||
"postcss": "8.4.47",
|
||||
"postcss": "8.4.48",
|
||||
"postcss-loader": "8.1.1",
|
||||
"postcss-nesting": "13.0.1",
|
||||
"pretty-ms": "9.0.0",
|
||||
|
@ -67,7 +67,7 @@
|
|||
"@stylistic/eslint-plugin-js": "2.10.1",
|
||||
"@stylistic/stylelint-plugin": "3.1.1",
|
||||
"@typescript-eslint/parser": "8.13.0",
|
||||
"@vitejs/plugin-vue": "5.1.4",
|
||||
"@vitejs/plugin-vue": "5.1.5",
|
||||
"@vitest/coverage-v8": "2.1.4",
|
||||
"@vitest/eslint-plugin": "1.1.7",
|
||||
"@vue/test-utils": "2.4.6",
|
||||
|
@ -5085,9 +5085,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@vitejs/plugin-vue": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz",
|
||||
"integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==",
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.5.tgz",
|
||||
"integrity": "sha512-dlnib73G05CDBAUR/YpuZcQQ47fpjihnnNouAAqN62z+oqSsWJ+kh52GRzIxpkgFG3q11eXK7Di7RMmoCwISZA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
@ -13083,9 +13083,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.47",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
|
||||
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||
"version": "8.4.48",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.48.tgz",
|
||||
"integrity": "sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
@ -13103,7 +13103,7 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.1.0",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"monaco-editor": "0.51.0",
|
||||
"monaco-editor-webpack-plugin": "7.1.0",
|
||||
"pdfobject": "2.3.0",
|
||||
"postcss": "8.4.47",
|
||||
"postcss": "8.4.48",
|
||||
"postcss-loader": "8.1.1",
|
||||
"postcss-nesting": "13.0.1",
|
||||
"pretty-ms": "9.0.0",
|
||||
|
@ -66,7 +66,7 @@
|
|||
"@stylistic/eslint-plugin-js": "2.10.1",
|
||||
"@stylistic/stylelint-plugin": "3.1.1",
|
||||
"@typescript-eslint/parser": "8.13.0",
|
||||
"@vitejs/plugin-vue": "5.1.4",
|
||||
"@vitejs/plugin-vue": "5.1.5",
|
||||
"@vitest/coverage-v8": "2.1.4",
|
||||
"@vitest/eslint-plugin": "1.1.7",
|
||||
"@vue/test-utils": "2.4.6",
|
||||
|
|
|
@ -83,6 +83,12 @@
|
|||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"groupName": "postcss"
|
||||
},
|
||||
{
|
||||
"description": "Group Forgejo go-chi packages",
|
||||
"matchUpdateTypes": ["minor", "patch", "digest"],
|
||||
"matchPackageNames": ["code.forgejo.org/go-chi/**"],
|
||||
"groupName": "forgejo go-chi packages"
|
||||
},
|
||||
{
|
||||
"description": "Split minor and patch updates",
|
||||
"matchPackageNames": [
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
files_service "code.gitea.io/gitea/services/repository/files"
|
||||
|
@ -254,7 +253,7 @@ func renderBlame(ctx *context.Context, blameParts []*git.BlamePart, commitNames
|
|||
commitCnt++
|
||||
|
||||
// User avatar image
|
||||
commitSince := timeutil.TimeSinceUnix(timeutil.TimeStamp(commit.Author.When.Unix()), ctx.Locale)
|
||||
commitSince := templates.TimeSince(commit.Author.When)
|
||||
|
||||
var avatar string
|
||||
if commit.User != nil {
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
|
@ -73,10 +72,10 @@ func GetContentHistoryList(ctx *context.Context) {
|
|||
class := avatars.DefaultAvatarClass + " tw-mr-2"
|
||||
name := html.EscapeString(username)
|
||||
avatarHTML := string(templates.AvatarHTML(src, 28, class, username))
|
||||
timeSinceText := string(timeutil.TimeSinceUnix(item.EditedUnix, ctx.Locale))
|
||||
timeSinceHTML := string(templates.TimeSince(item.EditedUnix))
|
||||
|
||||
results = append(results, map[string]any{
|
||||
"name": avatarHTML + "<strong>" + name + "</strong> " + actionText + " " + timeSinceText,
|
||||
"name": avatarHTML + "<strong>" + name + "</strong> " + actionText + " " + timeSinceHTML,
|
||||
"value": item.HistoryID,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -102,7 +102,6 @@ func NewTemplateContextForWeb(ctx *Context) TemplateContext {
|
|||
tmplCtx := NewTemplateContext(ctx)
|
||||
tmplCtx["Locale"] = ctx.Base.Locale
|
||||
tmplCtx["AvatarUtils"] = templates.NewAvatarUtils(ctx)
|
||||
tmplCtx["DateUtils"] = templates.NewDateUtils(ctx)
|
||||
return tmplCtx
|
||||
}
|
||||
|
||||
|
|
|
@ -51,14 +51,14 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if pr.HeadRepo.IsFork {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if err := pr.LoadBaseRepo(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if pr.BaseRepo.IsFork {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
repo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -43,7 +43,7 @@ func TestRepository_ContributorsGraph(t *testing.T) {
|
|||
dataString, isData := mockCache.Get("key2").(string)
|
||||
assert.True(t, isData)
|
||||
// Verify that JSON is actually stored in the cache.
|
||||
assert.EqualValues(t, `{"ethantkoenig@gmail.com":{"name":"Ethan Koenig","login":"","avatar_link":"https://secure.gravatar.com/avatar/b42fb195faa8c61b8d88abfefe30e9e3?d=identicon","home_link":"","total_commits":1,"weeks":{"1511654400000":{"week":1511654400000,"additions":3,"deletions":0,"commits":1}}},"jimmy.praet@telenet.be":{"name":"Jimmy Praet","login":"","avatar_link":"https://secure.gravatar.com/avatar/93c49b7c89eb156971d11161c9b52795?d=identicon","home_link":"","total_commits":1,"weeks":{"1624752000000":{"week":1624752000000,"additions":2,"deletions":0,"commits":1}}},"jon@allspice.io":{"name":"Jon","login":"","avatar_link":"https://secure.gravatar.com/avatar/00388ce725e6886f3e07c3733007289b?d=identicon","home_link":"","total_commits":1,"weeks":{"1607817600000":{"week":1607817600000,"additions":10,"deletions":0,"commits":1}}},"total":{"name":"Total","login":"","avatar_link":"","home_link":"","total_commits":3,"weeks":{"1511654400000":{"week":1511654400000,"additions":3,"deletions":0,"commits":1},"1607817600000":{"week":1607817600000,"additions":10,"deletions":0,"commits":1},"1624752000000":{"week":1624752000000,"additions":2,"deletions":0,"commits":1}}}}`, dataString)
|
||||
assert.JSONEq(t, `{"ethantkoenig@gmail.com":{"name":"Ethan Koenig","login":"","avatar_link":"https://secure.gravatar.com/avatar/b42fb195faa8c61b8d88abfefe30e9e3?d=identicon","home_link":"","total_commits":1,"weeks":{"1511654400000":{"week":1511654400000,"additions":3,"deletions":0,"commits":1}}},"jimmy.praet@telenet.be":{"name":"Jimmy Praet","login":"","avatar_link":"https://secure.gravatar.com/avatar/93c49b7c89eb156971d11161c9b52795?d=identicon","home_link":"","total_commits":1,"weeks":{"1624752000000":{"week":1624752000000,"additions":2,"deletions":0,"commits":1}}},"jon@allspice.io":{"name":"Jon","login":"","avatar_link":"https://secure.gravatar.com/avatar/00388ce725e6886f3e07c3733007289b?d=identicon","home_link":"","total_commits":1,"weeks":{"1607817600000":{"week":1607817600000,"additions":10,"deletions":0,"commits":1}}},"total":{"name":"Total","login":"","avatar_link":"","home_link":"","total_commits":3,"weeks":{"1511654400000":{"week":1511654400000,"additions":3,"deletions":0,"commits":1},"1607817600000":{"week":1607817600000,"additions":10,"deletions":0,"commits":1},"1624752000000":{"week":1624752000000,"additions":2,"deletions":0,"commits":1}}}}`, dataString)
|
||||
|
||||
var data map[string]*ContributorData
|
||||
require.NoError(t, json.Unmarshal([]byte(dataString), &data))
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{.Name}}</a></td>
|
||||
<td>{{.TypeName}}</td>
|
||||
<td>{{if .IsActive}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</td>
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .UpdatedUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{svg "octicon-pencil"}}</a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<td><button type="submit" class="ui primary button" name="op" value="{{.Name}}" title="{{ctx.Locale.Tr "admin.dashboard.operation_run"}}">{{svg "octicon-triangle-right"}}</button></td>
|
||||
<td>{{ctx.Locale.Tr (printf "admin.dashboard.%s" .Name)}}</td>
|
||||
<td>{{.Spec}}</td>
|
||||
<td>{{ctx.DateUtils.FullTime .Next}}</td>
|
||||
<td>{{if gt .Prev.Year 1}}{{ctx.DateUtils.FullTime .Prev}}{{else}}-{{end}}</td>
|
||||
<td>{{DateUtils.FullTime .Next}}</td>
|
||||
<td>{{if gt .Prev.Year 1}}{{DateUtils.FullTime .Prev}}{{else}}-{{end}}</td>
|
||||
<td>{{.ExecTimes}}</td>
|
||||
<td {{if ne .Status ""}}data-tooltip-content="{{.FormatLastMessage ctx.Locale}}"{{end}} >{{if eq .Status ""}}—{{else if eq .Status "finished"}}{{svg "octicon-check" 16}}{{else}}{{svg "octicon-x" 16}}{{end}}</td>
|
||||
</tr>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<td>{{.ID}}</td>
|
||||
<td>{{ctx.Locale.Tr .TrStr}}</td>
|
||||
<td class="view-detail auto-ellipsis tw-w-4/5"><span class="notice-description">{{.Description}}</span></td>
|
||||
<td nowrap>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td nowrap>{{DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td class="view-detail"><a href="#">{{svg "octicon-note" 16}}</a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<td>{{.NumTeams}}</td>
|
||||
<td>{{.NumMembers}}</td>
|
||||
<td>{{.NumRepos}}</td>
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td><a href="{{.OrganisationLink}}/settings" data-tooltip-content="{{ctx.Locale.Tr "edit"}}">{{svg "octicon-pencil"}}</a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
{{end}}
|
||||
</td>
|
||||
<td>{{ctx.Locale.TrSize .CalculateBlobSize}}</td>
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .Version.CreatedUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .Version.CreatedUnix}}</td>
|
||||
<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Paginater.Current}}&sort={{$.SortType}}" data-id="{{.Version.ID}}" data-name="{{.Package.Name}}" data-data-version="{{.Version.Version}}">{{svg "octicon-trash"}}</a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
|
|
@ -82,8 +82,8 @@
|
|||
<td>{{.NumIssues}}</td>
|
||||
<td>{{ctx.Locale.TrSize .GitSize}}</td>
|
||||
<td>{{ctx.Locale.TrSize .LFSSize}}</td>
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</td>
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .UpdatedUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Paginater.Current}}&sort={{$.SortType}}" data-id="{{.ID}}" data-name="{{.Name}}">{{svg "octicon-trash"}}</a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</div>
|
||||
<div class="content tw-flex-1">
|
||||
<div class="header">{{.Process.Description}}</div>
|
||||
<div class="description">{{if ne .Process.Type "none"}}{{TimeSince .Process.Start ctx.Locale}}{{end}}</div>
|
||||
<div class="description">{{if ne .Process.Type "none"}}{{DateUtils.TimeSince .Process.Start}}{{end}}</div>
|
||||
</div>
|
||||
<div>
|
||||
{{if or (eq .Process.Type "request") (eq .Process.Type "normal")}}
|
||||
|
|
|
@ -96,9 +96,9 @@
|
|||
<td>{{if .IsActive}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{if .IsRestricted}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{if index $.UsersTwoFaStatus .ID}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .CreatedUnix}}</td>
|
||||
{{if .LastLoginUnix}}
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .LastLoginUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .LastLoginUnix}}</td>
|
||||
{{else}}
|
||||
<td><span>{{ctx.Locale.Tr "admin.users.never_login"}}</span></td>
|
||||
{{end}}
|
||||
|
|
|
@ -167,13 +167,13 @@
|
|||
|
||||
<div>
|
||||
<h1>TimeSince</h1>
|
||||
<div>Now: {{TimeSince .TimeNow ctx.Locale}}</div>
|
||||
<div>5s past: {{TimeSince .TimePast5s ctx.Locale}}</div>
|
||||
<div>5s future: {{TimeSince .TimeFuture5s ctx.Locale}}</div>
|
||||
<div>2m past: {{TimeSince .TimePast2m ctx.Locale}}</div>
|
||||
<div>2m future: {{TimeSince .TimeFuture2m ctx.Locale}}</div>
|
||||
<div>1y past: {{TimeSince .TimePast1y ctx.Locale}}</div>
|
||||
<div>1y future: {{TimeSince .TimeFuture1y ctx.Locale}}</div>
|
||||
<div>Now: {{DateUtils.TimeSince .TimeNow}}</div>
|
||||
<div>5s past: {{DateUtils.TimeSince .TimePast5s}}</div>
|
||||
<div>5s future: {{DateUtils.TimeSince .TimeFuture5s}}</div>
|
||||
<div>2m past: {{DateUtils.TimeSince .TimePast2m}}</div>
|
||||
<div>2m future: {{DateUtils.TimeSince .TimeFuture2m}}</div>
|
||||
<div>1y past: {{DateUtils.TimeSince .TimePast1y}}</div>
|
||||
<div>1y future: {{DateUtils.TimeSince .TimeFuture1y}}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="flex-item-body">{{ctx.Locale.Tr "org.repo_updated" (TimeSinceUnix .UpdatedUnix ctx.Locale)}}</div>
|
||||
<div class="flex-item-body">{{ctx.Locale.Tr "org.repo_updated" (DateUtils.TimeSince .UpdatedUnix)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<a href="mailto:{{.Email}}">{{.Email}}</a>
|
||||
</span>
|
||||
{{end}}
|
||||
<span class="flex-text-inline">{{svg "octicon-calendar"}}{{ctx.Locale.Tr "user.joined_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}}</span>
|
||||
<span class="flex-text-inline">{{svg "octicon-calendar"}}{{ctx.Locale.Tr "user.joined_on" (DateUtils.AbsoluteShort .CreatedUnix)}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<td><a href="{{.VersionWebLink}}">{{.Version.Version}}</a></td>
|
||||
<td><a href="{{.Creator.HomeLink}}">{{.Creator.Name}}</a></td>
|
||||
<td>{{ctx.Locale.TrSize .CalculateBlobSize}}</td>
|
||||
<td>{{ctx.DateUtils.AbsoluteShort .Version.CreatedUnix}}</td>
|
||||
<td>{{DateUtils.AbsoluteShort .Version.CreatedUnix}}</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<span class="ui label">{{svg .Package.Type.SVGName 16}} {{.Package.Type.Name}}</span>
|
||||
</div>
|
||||
<div class="flex-item-body">
|
||||
{{$timeStr := TimeSinceUnix .Version.CreatedUnix ctx.Locale}}
|
||||
{{$timeStr := DateUtils.TimeSince .Version.CreatedUnix}}
|
||||
{{$hasRepositoryAccess := false}}
|
||||
{{if .Repository}}
|
||||
{{$hasRepositoryAccess = index $.RepositoryAccessMap .Repository.ID}}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<div class="flex-item-main">
|
||||
<a class="flex-item-title" href="{{.VersionWebLink}}">{{.Version.LowerVersion}}</a>
|
||||
<div class="flex-item-body">
|
||||
{{ctx.Locale.Tr "packages.published_by" (TimeSinceUnix .Version.CreatedUnix ctx.Locale) .Creator.HomeLink .Creator.GetDisplayName}}
|
||||
{{ctx.Locale.Tr "packages.published_by" (DateUtils.TimeSince .Version.CreatedUnix) .Creator.HomeLink .Creator.GetDisplayName}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<h1>{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</h1>
|
||||
</div>
|
||||
<div>
|
||||
{{$timeStr := TimeSinceUnix .PackageDescriptor.Version.CreatedUnix ctx.Locale}}
|
||||
{{$timeStr := DateUtils.TimeSince .PackageDescriptor.Version.CreatedUnix}}
|
||||
{{if .HasRepositoryAccess}}
|
||||
{{ctx.Locale.Tr "packages.published_by_in" $timeStr .PackageDescriptor.Creator.HomeLink .PackageDescriptor.Creator.GetDisplayName .PackageDescriptor.Repository.Link .PackageDescriptor.Repository.FullName}}
|
||||
{{else}}
|
||||
|
@ -48,7 +48,7 @@
|
|||
{{if .HasRepositoryAccess}}
|
||||
<div class="item">{{svg "octicon-repo" 16 "tw-mr-2"}} <a href="{{.PackageDescriptor.Repository.Link}}">{{.PackageDescriptor.Repository.FullName}}</a></div>
|
||||
{{end}}
|
||||
<div class="item">{{svg "octicon-calendar" 16 "tw-mr-2"}} {{TimeSinceUnix .PackageDescriptor.Version.CreatedUnix ctx.Locale}}</div>
|
||||
<div class="item">{{svg "octicon-calendar" 16 "tw-mr-2"}} {{DateUtils.TimeSince .PackageDescriptor.Version.CreatedUnix}}</div>
|
||||
<div class="item">{{svg "octicon-download" 16 "tw-mr-2"}} {{.PackageDescriptor.Version.DownloadCount}}</div>
|
||||
{{template "package/metadata/alpine" .}}
|
||||
{{template "package/metadata/arch" .}}
|
||||
|
@ -94,7 +94,7 @@
|
|||
{{range .LatestVersions}}
|
||||
<div class="item tw-flex">
|
||||
<a class="tw-flex-1 gt-ellipsis" title="{{.Version}}" href="{{$.PackageDescriptor.PackageWebLink}}/{{PathEscape .LowerVersion}}">{{.Version}}</a>
|
||||
<span class="text small">{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</span>
|
||||
<span class="text small">{{DateUtils.AbsoluteShort .CreatedUnix}}</span>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<span class="ui label run-list-ref gt-ellipsis">{{.PrettyRef}}</span>
|
||||
{{end}}
|
||||
<div class="run-list-item-right">
|
||||
<div class="run-list-meta">{{svg "octicon-calendar" 16}}{{TimeSinceUnix .Updated ctx.Locale}}</div>
|
||||
<div class="run-list-meta">{{svg "octicon-calendar" 16}}{{DateUtils.TimeSince .Updated}}</div>
|
||||
<div class="run-list-meta">{{svg "octicon-stopwatch" 16}}{{.Duration}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DefaultBranchBranch.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "copy_branch"}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}}
|
||||
</div>
|
||||
<p class="info tw-flex tw-items-center tw-my-1">{{svg "octicon-git-commit" 16 "tw-mr-1"}}<a href="{{.RepoLink}}/commit/{{PathEscape .DefaultBranchBranch.DBBranch.CommitID}}">{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated" (TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime ctx.Locale)}} {{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}</p>
|
||||
<p class="info tw-flex tw-items-center tw-my-1">{{svg "octicon-git-commit" 16 "tw-mr-1"}}<a href="{{.RepoLink}}/commit/{{PathEscape .DefaultBranchBranch.DBBranch.CommitID}}">{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated" (DateUtils.TimeSince .DefaultBranchBranch.DBBranch.CommitTime)}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}</p>
|
||||
</td>
|
||||
<td class="right aligned middle aligned overflow-visible">
|
||||
{{if and $.IsWriter (not $.Repository.IsArchived) (not .IsDeleted)}}
|
||||
|
@ -92,7 +92,7 @@
|
|||
<span class="gt-ellipsis">{{.DBBranch.Name}}</span>
|
||||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "copy_branch"}}">{{svg "octicon-copy" 14}}</button>
|
||||
</div>
|
||||
<p class="info">{{ctx.Locale.Tr "repo.branch.deleted_by" .DBBranch.DeletedBy.Name}} {{TimeSinceUnix .DBBranch.DeletedUnix ctx.Locale}}</p>
|
||||
<p class="info">{{ctx.Locale.Tr "repo.branch.deleted_by" .DBBranch.DeletedBy.Name}} {{DateUtils.TimeSince .DBBranch.DeletedUnix}}</p>
|
||||
{{else}}
|
||||
<div class="flex-text-block">
|
||||
<a class="gt-ellipsis" href="{{$.RepoLink}}/src/branch/{{PathEscapeSegments .DBBranch.Name}}">{{.DBBranch.Name}}</a>
|
||||
|
@ -102,7 +102,7 @@
|
|||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "copy_branch"}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DBBranch.CommitID)}}
|
||||
</div>
|
||||
<p class="info tw-flex tw-items-center tw-my-1">{{svg "octicon-git-commit" 16 "tw-mr-1"}}<a href="{{$.RepoLink}}/commit/{{PathEscape .DBBranch.CommitID}}">{{ShortSha .DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DBBranch.CommitMessage ($.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated" (TimeSince .DBBranch.CommitTime.AsTime ctx.Locale)}} {{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}</p>
|
||||
<p class="info tw-flex tw-items-center tw-my-1">{{svg "octicon-git-commit" 16 "tw-mr-1"}}<a href="{{$.RepoLink}}/commit/{{PathEscape .DBBranch.CommitID}}">{{ShortSha .DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DBBranch.CommitMessage ($.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated" (DateUtils.TimeSince .DBBranch.CommitTime)}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}</p>
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="two wide ui">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{range .RecentlyPushedNewBranches}}
|
||||
<div class="ui positive message tw-flex tw-items-center tw-gap-2">
|
||||
<div class="tw-flex-1 tw-break-anywhere">
|
||||
{{$timeSince := TimeSince .CommitTime.AsTime ctx.Locale}}
|
||||
{{$timeSince := DateUtils.TimeSince .CommitTime}}
|
||||
{{$repo := .GetRepo $.Context}}
|
||||
{{$name := .Name}}
|
||||
{{if ne $repo.ID $.Repository.ID}}
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
{{ctx.AvatarUtils.AvatarByEmail .Commit.Author.Email .Commit.Author.Email 28 "tw-mr-2"}}
|
||||
<strong>{{.Commit.Author.Name}}</strong>
|
||||
{{end}}
|
||||
<span class="text grey tw-ml-2" id="authored-time">{{TimeSince .Commit.Author.When ctx.Locale}}</span>
|
||||
<span class="text grey tw-ml-2" id="authored-time">{{DateUtils.TimeSince .Commit.Author.When}}</span>
|
||||
{{if or (ne .Commit.Committer.Name .Commit.Author.Name) (ne .Commit.Committer.Email .Commit.Author.Email)}}
|
||||
<span class="tw-ml-2">•</span>
|
||||
<span class="text grey tw-mx-2">{{ctx.Locale.Tr "repo.diff.committed_by"}}</span>
|
||||
|
@ -274,7 +274,7 @@
|
|||
{{else}}
|
||||
<strong>{{.NoteCommit.Author.Name}}</strong>
|
||||
{{end}}
|
||||
<span class="text grey" id="note-authored-time">{{TimeSince .NoteCommit.Author.When ctx.Locale}}</span>
|
||||
<span class="text grey" id="note-authored-time">{{DateUtils.TimeSince .NoteCommit.Author.When}}</span>
|
||||
</div>
|
||||
<div class="ui bottom attached info segment git-notes">
|
||||
<pre class="commit-body">{{.NoteRendered | SanitizeHTML}}</pre>
|
||||
|
|
|
@ -74,9 +74,9 @@
|
|||
{{end}}
|
||||
</td>
|
||||
{{if .Committer}}
|
||||
<td class="text right aligned">{{TimeSince .Committer.When ctx.Locale}}</td>
|
||||
<td class="text right aligned">{{DateUtils.TimeSince .Committer.When}}</td>
|
||||
{{else}}
|
||||
<td class="text right aligned">{{TimeSince .Author.When ctx.Locale}}</td>
|
||||
<td class="text right aligned">{{DateUtils.TimeSince .Author.When}}</td>
|
||||
{{end}}
|
||||
<td class="text right aligned tw-py-0">
|
||||
<button class="btn interact-bg tw-p-2" data-tooltip-content="{{ctx.Locale.Tr "copy_hash"}}" data-clipboard-text="{{.ID}}">{{svg "octicon-copy"}}</button>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{range .comments}}
|
||||
|
||||
{{$createdStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
|
||||
{{$createdStr:= DateUtils.TimeSince .CreatedUnix}}
|
||||
<div class="comment" id="{{.HashTag}}">
|
||||
{{if .OriginalAuthor}}
|
||||
<span class="avatar">{{ctx.AvatarUtils.Avatar nil}}</span>
|
||||
|
|
|
@ -212,7 +212,7 @@
|
|||
{{if .Repository.ArchivedUnix.IsZero}}
|
||||
{{ctx.Locale.Tr "repo.archive.title"}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.archive.title_date" (ctx.DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
|
||||
{{ctx.Locale.Tr "repo.archive.title_date" (DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{{if .Repository.ArchivedUnix.IsZero}}
|
||||
{{ctx.Locale.Tr "repo.archive.title"}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.archive.title_date" (ctx.DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
|
||||
{{ctx.Locale.Tr "repo.archive.title_date" (DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
{{$userName}}
|
||||
{{end}}
|
||||
</span>
|
||||
<span class="time tw-flex tw-items-center">{{ctx.DateUtils.FullTime $commit.Date}}</span>
|
||||
<span class="time tw-flex tw-items-center">{{DateUtils.FullTime $commit.Date}}</span>
|
||||
{{end}}
|
||||
</li>
|
||||
{{end}}
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
<div class="fork-flag">
|
||||
{{ctx.Locale.Tr "repo.mirror_from"}}
|
||||
<a target="_blank" rel="noopener noreferrer" href="{{$.PullMirror.RemoteAddress}}">{{$.PullMirror.RemoteAddress}}</a>
|
||||
{{if $.PullMirror.UpdatedUnix}}{{ctx.Locale.Tr "repo.mirror_sync"}} {{TimeSinceUnix $.PullMirror.UpdatedUnix ctx.Locale}}{{end}}
|
||||
{{if $.PullMirror.UpdatedUnix}}{{ctx.Locale.Tr "repo.mirror_sync"}} {{DateUtils.TimeSince $.PullMirror.UpdatedUnix}}{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .IsFork}}<div class="fork-flag">{{ctx.Locale.Tr "repo.forked_from"}} <a href="{{.BaseRepo.Link}}">{{.BaseRepo.FullName}}</a></div>{{end}}
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
{{if .Repository.ArchivedUnix.IsZero}}
|
||||
{{ctx.Locale.Tr "repo.archive.title"}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.archive.title_date" (ctx.DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
|
||||
{{ctx.Locale.Tr "repo.archive.title_date" (DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<div class="meta">
|
||||
<span class="text light grey muted-links">
|
||||
{{if not $.Page.Repository}}{{.Repo.FullName}}{{end}}#{{.Index}}
|
||||
{{$timeStr := TimeSinceUnix .GetLastEventTimestamp ctx.Locale}}
|
||||
{{$timeStr := DateUtils.TimeSince .GetLastEventTimestamp}}
|
||||
{{if .OriginalAuthor}}
|
||||
{{ctx.Locale.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor}}
|
||||
{{else if gt .Poster.ID 0}}
|
||||
|
|
|
@ -146,13 +146,11 @@
|
|||
</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="menu">
|
||||
<a rel="nofollow" class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=latest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a>
|
||||
<a rel="nofollow" class="{{if eq .SortType "oldest"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=oldest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a>
|
||||
<a rel="nofollow" class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a>
|
||||
<a rel="nofollow" class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a>
|
||||
<a rel="nofollow" class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a>
|
||||
<a rel="nofollow" class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a>
|
||||
<a rel="nofollow" class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a>
|
||||
<a rel="nofollow" class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=farduedate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a>
|
||||
<a rel="nofollow" class="{{if or (eq .SortType "relevance") (not .SortType)}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=relevency&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.relevance"}}</a>
|
||||
{{$o := .}}
|
||||
{{range $opt := StringUtils.Make "latest" "oldest" "recentupdate" "leastupdate" "mostcomment" "leastcomment" "nearduedate" "farduedate"}}
|
||||
{{$text := ctx.Locale.Tr (printf "repo.issues.filter_sort.%s" $opt)}}
|
||||
<a rel="nofollow" class="{{if eq $o.SortType $opt}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$opt}}&state={{$.State}}&labels={{$o.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{$text}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<progress class="milestone-progress-big" value="{{.Milestone.Completeness}}" max="100"></progress>
|
||||
<div class="tw-flex tw-gap-4">
|
||||
<div class="tw-flex tw-items-center">
|
||||
{{$closedDate:= TimeSinceUnix .Milestone.ClosedDateUnix ctx.Locale}}
|
||||
{{$closedDate:= DateUtils.TimeSince .Milestone.ClosedDateUnix}}
|
||||
{{if .IsClosed}}
|
||||
{{svg "octicon-clock"}} {{ctx.Locale.Tr "repo.milestones.closed" $closedDate}}
|
||||
{{else}}
|
||||
|
@ -38,7 +38,7 @@
|
|||
{{if .Milestone.DeadlineString}}
|
||||
<span{{if .IsOverdue}} class="text red"{{end}}>
|
||||
{{svg "octicon-calendar"}}
|
||||
{{ctx.DateUtils.AbsoluteShort (.Milestone.DeadlineString|ctx.DateUtils.ParseLegacy)}}
|
||||
{{DateUtils.AbsoluteShort (.Milestone.DeadlineString|DateUtils.ParseLegacy)}}
|
||||
</span>
|
||||
{{else}}
|
||||
{{svg "octicon-calendar"}}
|
||||
|
|
|
@ -49,19 +49,19 @@
|
|||
{{if .UpdatedUnix}}
|
||||
<div class="flex-text-block">
|
||||
{{svg "octicon-clock"}}
|
||||
{{ctx.Locale.Tr "repo.milestones.update_ago" (TimeSinceUnix .UpdatedUnix ctx.Locale)}}
|
||||
{{ctx.Locale.Tr "repo.milestones.update_ago" (DateUtils.TimeSince .UpdatedUnix)}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="flex-text-block">
|
||||
{{if .IsClosed}}
|
||||
{{$closedDate:= TimeSinceUnix .ClosedDateUnix ctx.Locale}}
|
||||
{{$closedDate:= DateUtils.TimeSince .ClosedDateUnix}}
|
||||
{{svg "octicon-clock" 14}}
|
||||
{{ctx.Locale.Tr "repo.milestones.closed" $closedDate}}
|
||||
{{else}}
|
||||
{{if .DeadlineString}}
|
||||
<span class="flex-text-inline {{if .IsOverdue}}text red{{end}}">
|
||||
{{svg "octicon-calendar" 14}}
|
||||
{{ctx.DateUtils.AbsoluteShort (.DeadlineString|ctx.DateUtils.ParseLegacy)}}
|
||||
{{DateUtils.AbsoluteShort (.DeadlineString|DateUtils.ParseLegacy)}}
|
||||
</span>
|
||||
{{else}}
|
||||
{{svg "octicon-calendar" 14}}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<input type="hidden" id="issueIndex" value="{{.Issue.Index}}">
|
||||
<input type="hidden" id="type" value="{{.IssueType}}">
|
||||
|
||||
{{$createdStr:= TimeSinceUnix .Issue.CreatedUnix ctx.Locale}}
|
||||
{{$createdStr:= DateUtils.TimeSince .Issue.CreatedUnix}}
|
||||
<div class="issue-content-left comment-list prevent-before-timeline">
|
||||
<div class="ui timeline">
|
||||
<div id="{{.Issue.HashTag}}" class="timeline-item comment first">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{template "base/alert"}}
|
||||
{{range .Issue.Comments}}
|
||||
{{if call $.ShouldShowCommentType .Type}}
|
||||
{{$createdStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
|
||||
{{$createdStr:= DateUtils.TimeSince .CreatedUnix}}
|
||||
|
||||
<!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF,
|
||||
5 = COMMENT_REF, 6 = PULL_REF, 7 = COMMENT_LABEL, 8 = MILESTONE_CHANGE,
|
||||
|
@ -137,7 +137,7 @@
|
|||
{{else if eq .RefAction 2}}
|
||||
{{$refTr = "repo.issues.ref_reopening_from"}}
|
||||
{{end}}
|
||||
{{$createdStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
|
||||
{{$createdStr:= DateUtils.TimeSince .CreatedUnix}}
|
||||
<div class="timeline-item event" id="{{.HashTag}}">
|
||||
<span class="badge">{{svg "octicon-bookmark"}}</span>
|
||||
{{template "shared/user/avatarlink" dict "user" .Poster}}
|
||||
|
@ -300,7 +300,7 @@
|
|||
{{template "shared/user/avatarlink" dict "user" .Poster}}
|
||||
<span class="text grey muted-links">
|
||||
{{template "shared/user/authorlink" .Poster}}
|
||||
{{$dueDate := ctx.DateUtils.AbsoluteLong (.Content|ctx.DateUtils.ParseLegacy)}}
|
||||
{{$dueDate := DateUtils.AbsoluteLong (.Content|DateUtils.ParseLegacy)}}
|
||||
{{ctx.Locale.Tr "repo.issues.due_date_added" $dueDate $createdStr}}
|
||||
</span>
|
||||
</div>
|
||||
|
@ -312,8 +312,8 @@
|
|||
{{template "shared/user/authorlink" .Poster}}
|
||||
{{$parsedDeadline := StringUtils.Split .Content "|"}}
|
||||
{{if eq (len $parsedDeadline) 2}}
|
||||
{{$to := ctx.DateUtils.AbsoluteLong ((index $parsedDeadline 0)|ctx.DateUtils.ParseLegacy)}}
|
||||
{{$from := ctx.DateUtils.AbsoluteLong ((index $parsedDeadline 1)|ctx.DateUtils.ParseLegacy)}}
|
||||
{{$to := DateUtils.AbsoluteLong ((index $parsedDeadline 0)|DateUtils.ParseLegacy)}}
|
||||
{{$from := DateUtils.AbsoluteLong ((index $parsedDeadline 1)|DateUtils.ParseLegacy)}}
|
||||
{{ctx.Locale.Tr "repo.issues.due_date_modified" $to $from $createdStr}}
|
||||
{{end}}
|
||||
</span>
|
||||
|
@ -324,7 +324,7 @@
|
|||
{{template "shared/user/avatarlink" dict "user" .Poster}}
|
||||
<span class="text grey muted-links">
|
||||
{{template "shared/user/authorlink" .Poster}}
|
||||
{{$dueDate := ctx.DateUtils.AbsoluteLong (.Content|ctx.DateUtils.ParseLegacy)}}
|
||||
{{$dueDate := DateUtils.AbsoluteLong (.Content|DateUtils.ParseLegacy)}}
|
||||
{{ctx.Locale.Tr "repo.issues.due_date_remove" $dueDate $createdStr}}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
<div id="code-comments-{{(index .comments 0).ID}}" class="comment-code-cloud ui segment{{if $resolved}} tw-hidden{{end}}">
|
||||
<div class="ui comments tw-mb-0">
|
||||
{{range .comments}}
|
||||
{{$createdSubStr:= TimeSinceUnix .CreatedUnix ctx.Locale}}
|
||||
{{$createdSubStr:= DateUtils.TimeSince .CreatedUnix}}
|
||||
<div class="comment code-comment tw-pb-4" id="{{.HashTag}}">
|
||||
<div class="content">
|
||||
<div class="header comment-header">
|
||||
|
|
|
@ -202,7 +202,7 @@
|
|||
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash $prUnit.PullRequestsConfig.AllowFastForwardOnly}}
|
||||
{{$hasPendingPullRequestMergeTip := ""}}
|
||||
{{if .HasPendingPullRequestMerge}}
|
||||
{{$createdPRMergeStr := TimeSinceUnix .PendingPullRequestMerge.CreatedUnix ctx.Locale}}
|
||||
{{$createdPRMergeStr := DateUtils.TimeSince .PendingPullRequestMerge.CreatedUnix}}
|
||||
{{$hasPendingPullRequestMergeTip = ctx.Locale.Tr "repo.pulls.auto_merge_has_pending_schedule" .PendingPullRequestMerge.Doer.Name $createdPRMergeStr}}
|
||||
{{end}}
|
||||
<div class="divider"></div>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<div class="tw-flex tw-justify-between tw-items-center">
|
||||
<div class="due-date {{if .Issue.IsOverdue}}text red{{end}}" {{if .Issue.IsOverdue}}data-tooltip-content="{{ctx.Locale.Tr "repo.issues.due_date_overdue"}}"{{end}}>
|
||||
{{svg "octicon-calendar" 16 "tw-mr-2"}}
|
||||
{{ctx.DateUtils.AbsoluteLong .Issue.DeadlineUnix}}
|
||||
{{DateUtils.AbsoluteLong .Issue.DeadlineUnix}}
|
||||
</div>
|
||||
<div>
|
||||
{{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
{{$baseHref = HTMLFormat `<a href="%s">%s</a>` .BaseBranchLink $baseHref}}
|
||||
{{end}}
|
||||
{{if .Issue.PullRequest.HasMerged}}
|
||||
{{$mergedStr:= TimeSinceUnix .Issue.PullRequest.MergedUnix ctx.Locale}}
|
||||
{{$mergedStr:= DateUtils.TimeSince .Issue.PullRequest.MergedUnix}}
|
||||
{{if .Issue.OriginalAuthor}}
|
||||
{{.Issue.OriginalAuthor}}
|
||||
<span class="pull-desc">{{ctx.Locale.TrN .NumCommits "repo.pulls.merged_title_desc_one" "repo.pulls.merged_title_desc_few" .NumCommits $headHref $baseHref $mergedStr}}</span>
|
||||
|
@ -126,7 +126,7 @@
|
|||
</span>
|
||||
{{end}}
|
||||
{{else}}
|
||||
{{$createdStr:= TimeSinceUnix .Issue.CreatedUnix ctx.Locale}}
|
||||
{{$createdStr:= DateUtils.TimeSince .Issue.CreatedUnix}}
|
||||
<span class="time-desc">
|
||||
{{if .Issue.OriginalAuthor}}
|
||||
{{ctx.Locale.Tr "repo.issues.opened_by_fake" $createdStr .Issue.OriginalAuthor}}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<h2 class="ui header activity-header">
|
||||
<span>{{ctx.DateUtils.AbsoluteLong .DateFrom}} - {{ctx.DateUtils.AbsoluteLong .DateUntil}}</span>
|
||||
<span>{{DateUtils.AbsoluteLong .DateFrom}} - {{DateUtils.AbsoluteLong .DateUntil}}</span>
|
||||
<!-- Period -->
|
||||
<div class="ui floating dropdown jump filter">
|
||||
<div class="ui basic compact button">
|
||||
|
@ -135,7 +135,7 @@
|
|||
{{.TagName}}
|
||||
<a class="title" href="{{$.RepoLink}}/releases/tag/{{.TagName | PathEscapeSegments}}">{{.Title | RenderEmoji $.Context | RenderCodeBlock}}</a>
|
||||
{{end}}
|
||||
{{TimeSinceUnix .CreatedUnix ctx.Locale}}
|
||||
{{DateUtils.TimeSince .CreatedUnix}}
|
||||
</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -154,7 +154,7 @@
|
|||
<p class="desc">
|
||||
<span class="ui purple label">{{ctx.Locale.Tr "repo.activity.merged_prs_label"}}</span>
|
||||
#{{.Index}} <a class="title" href="{{$.RepoLink}}/pulls/{{.Index}}">{{RenderRefIssueTitle $.Context .Issue.Title}}</a>
|
||||
{{TimeSinceUnix .MergedUnix ctx.Locale}}
|
||||
{{DateUtils.TimeSince .MergedUnix}}
|
||||
</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -173,7 +173,7 @@
|
|||
<p class="desc">
|
||||
<span class="ui green label">{{ctx.Locale.Tr "repo.activity.opened_prs_label"}}</span>
|
||||
#{{.Index}} <a class="title" href="{{$.RepoLink}}/pulls/{{.Index}}">{{RenderRefIssueTitle $.Context .Issue.Title}}</a>
|
||||
{{TimeSinceUnix .Issue.CreatedUnix ctx.Locale}}
|
||||
{{DateUtils.TimeSince .Issue.CreatedUnix}}
|
||||
</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -192,7 +192,7 @@
|
|||
<p class="desc">
|
||||
<span class="ui red label">{{ctx.Locale.Tr "repo.activity.closed_issue_label"}}</span>
|
||||
#{{.Index}} <a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{RenderRefIssueTitle $.Context .Title}}</a>
|
||||
{{TimeSinceUnix .ClosedUnix ctx.Locale}}
|
||||
{{DateUtils.TimeSince .ClosedUnix}}
|
||||
</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -211,7 +211,7 @@
|
|||
<p class="desc">
|
||||
<span class="ui green label">{{ctx.Locale.Tr "repo.activity.new_issue_label"}}</span>
|
||||
#{{.Index}} <a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{RenderRefIssueTitle $.Context .Title}}</a>
|
||||
{{TimeSinceUnix .CreatedUnix ctx.Locale}}
|
||||
{{DateUtils.TimeSince .CreatedUnix}}
|
||||
</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -232,7 +232,7 @@
|
|||
{{else}}
|
||||
<a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{RenderRefIssueTitle $.Context .Title}}</a>
|
||||
{{end}}
|
||||
{{TimeSinceUnix .UpdatedUnix ctx.Locale}}
|
||||
{{DateUtils.TimeSince .UpdatedUnix}}
|
||||
</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
{{ctx.Locale.Tr "repo.released_this"}}
|
||||
</span>
|
||||
{{if $release.CreatedUnix}}
|
||||
<span class="time">{{TimeSinceUnix $release.CreatedUnix ctx.Locale}}</span>
|
||||
<span class="time">{{DateUtils.TimeSince $release.CreatedUnix}}</span>
|
||||
{{end}}
|
||||
{{if and (not $release.IsDraft) ($.Permission.CanRead $.UnitTypeCode)}}
|
||||
| <span class="ahead"><a href="{{$.RepoLink}}/compare/{{$release.TagName | PathEscapeSegments}}...{{$release.TargetBehind | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.release.ahead.commits" $release.NumCommitsBehind}}</a> {{ctx.Locale.Tr "repo.release.ahead.target" $release.TargetBehind}}</span>
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
{{.Fingerprint}}
|
||||
</div>
|
||||
<div class="flex-item-body">
|
||||
<p>{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}} — {{svg "octicon-info"}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="text green"{{end}}>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}} - <span>{{ctx.Locale.Tr "settings.can_read_info"}}{{if not .IsReadOnly}} / {{ctx.Locale.Tr "settings.can_write_info"}} {{end}}</span></p>
|
||||
<p>{{ctx.Locale.Tr "settings.added_on" (DateUtils.AbsoluteShort .CreatedUnix)}} — {{svg "octicon-info"}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="text green"{{end}}>{{DateUtils.AbsoluteShort .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}} - <span>{{ctx.Locale.Tr "settings.can_read_info"}}{{if not .IsReadOnly}} / {{ctx.Locale.Tr "settings.can_write_info"}} {{end}}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-item-trailing">
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>{{ctx.Locale.TrSize .Size}}</td>
|
||||
<td>{{TimeSince .CreatedUnix.AsTime ctx.Locale}}</td>
|
||||
<td>{{DateUtils.TimeSince .CreatedUnix}}</td>
|
||||
<td class="right aligned">
|
||||
<a class="ui primary button" href="{{$.Link}}/find?oid={{.Oid}}&size={{.Size}}">{{ctx.Locale.Tr "repo.settings.lfs_findcommits"}}</a>
|
||||
<button class="ui basic show-modal icon button red" data-modal="#delete-{{.Oid}}">
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
{{ctx.Locale.Tr "repo.diff.commit"}}
|
||||
<a class="ui primary sha label" href="{{$.RepoLink}}/commit/{{.SHA}}">{{ShortSha .SHA}}</a>
|
||||
</td>
|
||||
<td>{{TimeSince .When ctx.Locale}}</td>
|
||||
<td>{{DateUtils.TimeSince .When}}</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
{{$lock.Owner.DisplayName}}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{TimeSince .Created ctx.Locale}}</td>
|
||||
<td>{{DateUtils.TimeSince .Created}}</td>
|
||||
<td class="right aligned">
|
||||
<form action="{{$.LFSFilesLink}}/locks/{{$lock.ID}}/unlock" method="post">
|
||||
{{$.CsrfTokenHtml}}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{{ctx.Locale.Tr "repo.settings.options"}}
|
||||
</a>
|
||||
<details class="item toggleable-item" {{if .PageIsRepoSettingsUnits}}open{{end}}>
|
||||
<summary class="item{{if .PageIsRepoSettingsUnits}} active{{end}}">{{ctx.Locale.Tr "repo.settings.units.units"}}</summary>
|
||||
<summary {{if .PageIsRepoSettingsUnits}}class="active"{{end}}>{{ctx.Locale.Tr "repo.settings.units.units"}}</summary>
|
||||
<div class="menu">
|
||||
<a class="item" href="{{.RepoLink}}/settings/units#overview">
|
||||
{{ctx.Locale.Tr "repo.settings.units.overview"}}
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
<tr>
|
||||
<td>{{.PullMirror.RemoteAddress}}</td>
|
||||
<td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}</td>
|
||||
<td>{{ctx.DateUtils.FullTime .PullMirror.UpdatedUnix}}</td>
|
||||
<td>{{DateUtils.FullTime .PullMirror.UpdatedUnix}}</td>
|
||||
<td class="right aligned">
|
||||
<form method="post" class="tw-inline-block">
|
||||
{{.CsrfTokenHtml}}
|
||||
|
@ -243,7 +243,7 @@
|
|||
<tr>
|
||||
<td class="tw-break-anywhere">{{.RemoteAddress}}</td>
|
||||
<td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.push"}}</td>
|
||||
<td>{{if .LastUpdateUnix}}{{ctx.DateUtils.FullTime .LastUpdateUnix}}{{else}}{{ctx.Locale.Tr "never"}}{{end}} {{if .LastError}}<div class="ui red label" data-tooltip-content="{{.LastError}}">{{ctx.Locale.Tr "error"}}</div>{{end}}</td>
|
||||
<td>{{if .LastUpdateUnix}}{{DateUtils.FullTime .LastUpdateUnix}}{{else}}{{ctx.Locale.Tr "never"}}{{end}} {{if .LastError}}<div class="ui red label" data-tooltip-content="{{.LastError}}">{{ctx.Locale.Tr "error"}}</div>{{end}}</td>
|
||||
<td>{{if not (eq (len .GetPublicKey) 0)}}<a data-clipboard-text="{{.GetPublicKey}}">{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.copy_public_key"}}</a>{{else}}{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.none_ssh"}}{{end}}</td>
|
||||
<td class="right aligned">
|
||||
<button
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<a class="ui primary sha label toggle button show-panel" data-panel="#info-{{.ID}}">{{.UUID}}</a>
|
||||
</div>
|
||||
<span class="text grey">
|
||||
{{TimeSince .Delivered.AsTime ctx.Locale}}
|
||||
{{DateUtils.TimeSince .Delivered}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="info tw-hidden" id="info-{{.ID}}">
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<div class="download tw-flex tw-items-center">
|
||||
{{if $.Permission.CanRead $.UnitTypeCode}}
|
||||
{{if .CreatedUnix}}
|
||||
<span class="tw-mr-2">{{svg "octicon-clock" 16 "tw-mr-1"}}{{TimeSinceUnix .CreatedUnix ctx.Locale}}</span>
|
||||
<span class="tw-mr-2">{{svg "octicon-clock" 16 "tw-mr-1"}}{{DateUtils.TimeSince .CreatedUnix}}</span>
|
||||
{{end}}
|
||||
|
||||
<a class="tw-mr-2 tw-font-mono muted" href="{{$.RepoLink}}/src/commit/{{.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .Sha1}}</a>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
{{else if .Location}}
|
||||
{{svg "octicon-location"}} {{.Location}}
|
||||
{{else}}
|
||||
{{svg "octicon-calendar"}} {{ctx.Locale.Tr "user.joined_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}}
|
||||
{{svg "octicon-calendar"}} {{ctx.Locale.Tr "user.joined_on" (DateUtils.AbsoluteShort .CreatedUnix)}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
{{if .LatestCommit}}
|
||||
{{if .LatestCommit.Committer}}
|
||||
<div class="text grey age">
|
||||
{{TimeSince .LatestCommit.Committer.When ctx.Locale}}
|
||||
{{DateUtils.TimeSince .LatestCommit.Committer.When}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Committer}}{{TimeSince .LatestCommit.Committer.When ctx.Locale}}{{end}}{{end}}</th>
|
||||
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Committer}}{{DateUtils.TimeSince .LatestCommit.Committer.When}}{{end}}{{end}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -62,7 +62,7 @@
|
|||
{{end}}
|
||||
</span>
|
||||
</td>
|
||||
<td class="text right age three wide">{{if $commit}}{{TimeSince $commit.Committer.When ctx.Locale}}{{end}}</td>
|
||||
<td class="text right age three wide">{{if $commit}}{{DateUtils.TimeSince $commit.Committer.When}}{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<a href="{{$.RepoLink}}/wiki/{{.SubURL}}">{{.Name}}</a>
|
||||
<a class="wiki-git-entry" href="{{$.RepoLink}}/wiki/{{.GitEntryName | PathEscape}}" data-tooltip-content="{{ctx.Locale.Tr "repo.wiki.original_git_entry_tooltip"}}">{{svg "octicon-chevron-right"}}</a>
|
||||
</td>
|
||||
{{$timeSince := TimeSinceUnix .UpdatedUnix ctx.Locale}}
|
||||
{{$timeSince := DateUtils.TimeSince .UpdatedUnix}}
|
||||
<td class="text right">{{ctx.Locale.Tr "repo.wiki.last_updated" $timeSince}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<a class="file-revisions-btn ui basic button" title="{{ctx.Locale.Tr "repo.wiki.back_to_wiki"}}" href="{{.RepoLink}}/wiki/{{.PageURL}}"><span>{{.revision}}</span> {{svg "octicon-home"}}</a>
|
||||
{{$title}}
|
||||
<div class="ui sub header tw-break-anywhere">
|
||||
{{$timeSince := TimeSince .Author.When ctx.Locale}}
|
||||
{{$timeSince := DateUtils.TimeSince .Author.When}}
|
||||
{{ctx.Locale.Tr "repo.wiki.last_commit_info" .Author.Name $timeSince}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<a class="file-revisions-btn ui basic button" title="{{ctx.Locale.Tr "repo.wiki.file_revision"}}" href="{{.RepoLink}}/wiki/{{.PageURL}}?action=_revision" ><span>{{.CommitCount}}</span> {{svg "octicon-history"}}</a>
|
||||
{{$title}}
|
||||
<div class="ui sub header">
|
||||
{{$timeSince := TimeSince .Author.When ctx.Locale}}
|
||||
{{$timeSince := DateUtils.TimeSince .Author.When}}
|
||||
{{ctx.Locale.Tr "repo.wiki.last_commit_info" .Author.Name $timeSince}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</div>
|
||||
<div class="field tw-inline-block tw-mr-4">
|
||||
<label>{{ctx.Locale.Tr "actions.runners.last_online"}}</label>
|
||||
<span>{{if .Runner.LastOnline}}{{TimeSinceUnix .Runner.LastOnline ctx.Locale}}{{else}}{{ctx.Locale.Tr "never"}}{{end}}</span>
|
||||
<span>{{if .Runner.LastOnline}}{{DateUtils.TimeSince .Runner.LastOnline}}{{else}}{{ctx.Locale.Tr "never"}}{{end}}</span>
|
||||
</div>
|
||||
<div class="field tw-inline-block tw-mr-4">
|
||||
<label>{{ctx.Locale.Tr "actions.runners.labels"}}</label>
|
||||
|
@ -70,7 +70,7 @@
|
|||
<strong><a href="{{.GetCommitLink}}" target="_blank">{{ShortSha .CommitSHA}}</a></strong>
|
||||
</td>
|
||||
<td>{{if .IsStopped}}
|
||||
<span>{{TimeSinceUnix .Stopped ctx.Locale}}</span>
|
||||
<span>{{DateUtils.TimeSince .Stopped}}</span>
|
||||
{{else}}-{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<td class="tw-flex tw-flex-wrap tw-gap-2 runner-tags">
|
||||
{{range .AgentLabels}}<span class="ui label">{{.}}</span>{{end}}
|
||||
</td>
|
||||
<td>{{if .LastOnline}}{{TimeSinceUnix .LastOnline ctx.Locale}}{{else}}{{ctx.Locale.Tr "never"}}{{end}}</td>
|
||||
<td>{{if .LastOnline}}{{DateUtils.TimeSince .LastOnline}}{{else}}{{ctx.Locale.Tr "never"}}{{end}}</td>
|
||||
<td class="runner-ops">
|
||||
{{if .Editable $.RunnerOwnerID $.RunnerRepoID}}
|
||||
<a href="{{$.Link}}/{{.ID}}">{{svg "octicon-pencil"}}</a>
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
#{{.Index}}
|
||||
{{end}}
|
||||
</a>
|
||||
{{$timeStr := TimeSinceUnix .GetLastEventTimestamp ctx.Locale}}
|
||||
{{$timeStr := DateUtils.TimeSince .GetLastEventTimestamp}}
|
||||
{{if .OriginalAuthor}}
|
||||
{{ctx.Locale.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor}}
|
||||
{{else if gt .Poster.ID 0}}
|
||||
|
@ -117,7 +117,7 @@
|
|||
<span class="due-date flex-text-inline" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.due_date"}}">
|
||||
<span{{if .IsOverdue}} class="text red"{{end}}>
|
||||
{{svg "octicon-calendar" 14}}
|
||||
{{ctx.DateUtils.AbsoluteShort .DeadlineUnix}}
|
||||
{{DateUtils.AbsoluteShort .DeadlineUnix}}
|
||||
</span>
|
||||
</span>
|
||||
{{end}}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue