Compare commits

...

93 Commits

Author SHA1 Message Date
Illya Marchenko eca8c7d4b1
Merge 0a8fd353ef into dcc3c17e5c 2024-04-27 15:23:22 +08:00
silverwind dcc3c17e5c
Suppress browserslist warning in webpack target (#30571)
1. Set
[`BROWSERSLIST_IGNORE_OLD_DATA`](c6ddf7b387/node.js (L400))
to avoid warning on outdated browserslist data which the end user can
likely not do anything about and which is currently visible in the v1.21
branch.
2. Suppress all command echoing and add a "Running webpack..." message
in place.

Warning in question was this:

```
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
```
2024-04-27 07:21:07 +00:00
GiteaBot 27861d711b [skip ci] Updated translations via Crowdin 2024-04-27 00:24:31 +00:00
silverwind c93eefb42b
Diff color enhancements, add line number background (#30670)
1. Bring back the background on line numbers. This feature was lost a
long time ago.

<img width="457" alt="Screenshot 2024-04-24 at 01 36 09"
src="https://github.com/go-gitea/gitea/assets/115237/76a7f5a9-c22a-4c72-9f0a-ebf16a66513e">
<img width="473" alt="Screenshot 2024-04-24 at 01 22 47"
src="https://github.com/go-gitea/gitea/assets/115237/eef06cf2-f1b9-40e3-947d-dd5852ec12a3">
<img width="457" alt="Screenshot 2024-04-24 at 02 13 18"
src="https://github.com/go-gitea/gitea/assets/115237/59e317d4-76a7-468c-8a19-10d88c675cc3">
<img width="459" alt="Screenshot 2024-04-24 at 01 23 21"
src="https://github.com/go-gitea/gitea/assets/115237/f1a46f8d-8846-4d78-a9d7-8b7dc18ac6e4">

2. Expanded lines background is now full-line, including line numbers:

<img width="1303" alt="Screenshot 2024-04-24 at 01 37 12"
src="https://github.com/go-gitea/gitea/assets/115237/271eefe2-0869-424e-93fb-ccd8adc87806">

3. Sort affected colors alphabetically in the CSS

Fixes #14603
2024-04-26 19:37:21 +00:00
stuzer05 0a8fd353ef
Merge branch 'main' into add-issue-planned-time 2024-04-25 21:51:46 +03:00
stuzer05 12553d7dc2
Merge branch 'main' into add-issue-planned-time 2024-04-22 12:16:56 +03:00
stuzer05 b97139b232
Merge branch 'main' into add-issue-planned-time 2024-04-15 09:28:34 +03:00
stuzer05 b452e13f35
Commit 2024-04-13 15:38:12 +03:00
stuzer05 e92bedc81d
Commit 2024-04-13 15:04:15 +03:00
stuzer05 1e22cc242f
Merge branch 'main' into add-issue-planned-time 2024-04-13 14:17:17 +03:00
stuzer05 93d09fa8fc
Merge branch 'main' into add-issue-planned-time 2024-03-29 10:38:46 +02:00
stuzer05 0820db04ed
Merge branch 'main' into add-issue-planned-time 2024-03-28 11:18:38 +02:00
stuzer05 09723c5e0b
Merge branch 'main' into add-issue-planned-time 2024-03-17 15:52:06 +02:00
stuzer05 c272512d9a
Merge branch 'main' into add-issue-planned-time 2024-03-04 12:07:39 +02:00
stuzer05 0c4b2dfa8f
Commit 2024-03-04 11:59:57 +02:00
stuzer05 805af19ef1
Merge branch 'main' into add-issue-planned-time 2024-03-04 11:59:19 +02:00
stuzer05 bb5ca4c40b
Merge branch 'main' into add-issue-planned-time 2024-02-28 13:50:55 +02:00
stuzer05 a737a8c10b
Merge branch 'main' into add-issue-planned-time 2024-02-19 09:52:21 +02:00
stuzer05 92dc2cd22c
Merge branch 'main' into add-issue-planned-time 2024-02-11 12:12:41 +02:00
stuzer05 39b8b1929d
Merge branch 'main' into add-issue-planned-time 2024-01-22 09:31:58 +02:00
stuzer05 a999055954
Merge branch 'main' into add-issue-planned-time 2024-01-17 10:37:05 +02:00
stuzer05 a6fa4c3d04
Merge branch 'main' into add-issue-planned-time 2024-01-15 11:47:48 +02:00
stuzer05 2a9009fb02
Merge branch 'main' into add-issue-planned-time 2023-10-16 12:02:04 +03:00
stuzer05 3037d6cdde
Merge branch 'main' into add-issue-planned-time 2023-10-08 20:48:33 +03:00
stuzer05 349b959022
Merge branch 'main' into add-issue-planned-time 2023-10-07 15:34:04 +03:00
stuzer05 64de74d540
Merge branch 'main' into add-issue-planned-time 2023-09-11 10:55:43 +03:00
stuzer05 fa662ec087
Merge branch 'main' into add-issue-planned-time 2023-07-10 10:07:08 +03:00
stuzer05 62094d8cf3
Merge branch 'main' into add-issue-planned-time 2023-06-26 16:12:25 +03:00
スツゼル e933a89bd9
Delete serviceworker.js 2023-06-24 09:36:32 +03:00
stuzer05 db49783fa8
Commit 2023-06-24 09:35:31 +03:00
stuzer05 a45c1e9c86
Merge branch 'main' into add-issue-planned-time 2023-06-24 09:24:08 +03:00
stuzer05 721069d766
Merge branch 'main' into add-issue-planned-time 2023-06-23 10:49:56 +03:00
stuzer05 3310440ed1
Hide time tracking 2023-06-23 10:34:52 +03:00
スツゼル 598e2d5bed
Merge branch 'main' into add-issue-planned-time 2023-06-19 16:34:14 +03:00
silverwind b211b9e66d
Merge branch 'main' into add-issue-planned-time 2023-06-18 20:43:42 +02:00
stuzer05 ffaa4babcb
Format 2023-06-18 19:35:49 +03:00
stuzer05 cef496af2a
Remove unused code 2023-06-18 19:34:22 +03:00
stuzer05 015ad01513
Merge branch 'main' into add-issue-planned-time 2023-06-18 17:27:33 +03:00
stuzer05 748bd67814
Fix displaying issue estimation 2023-06-14 11:31:49 +03:00
スツゼル 3924cb0062
Merge branch 'go-gitea:main' into add-issue-planned-time 2023-06-11 20:02:21 +03:00
stuzer05 e9afd60d6b
Refactor helper functions 2023-06-11 20:01:28 +03:00
stuzer05 40e1373dce
Merge branch 'main' into add-issue-planned-time 2023-06-06 11:12:26 +03:00
stuzer05 bf4fa112d0
Merge branch 'main' into add-issue-planned-time 2023-06-03 19:28:20 +03:00
stuzer05 fc93006f50
Merge branch 'main' into add-issue-planned-time 2023-04-18 07:16:00 +03:00
スツゼル 879d96f077
Merge branch 'main' into add-issue-planned-time 2023-03-04 23:04:29 +02:00
スツゼル fd5adc55f3
Merge branch 'main' into add-issue-planned-time 2023-02-28 18:10:11 +02:00
stuzer05 57a3664eb2
Commit 2023-02-28 18:06:04 +02:00
stuzer05 bf323cf26c
Commit 2023-02-28 16:07:09 +02:00
スツゼル fb8126035a
Update models/issues/issue.go
Co-authored-by: Yarden Shoham <hrsi88@gmail.com>
2023-02-28 16:04:21 +02:00
stuzer05 deddce59cf
Commit 2023-02-28 15:17:00 +02:00
stuzer05 79e18c6711
Commit 2023-02-28 10:11:49 +02:00
stuzer05 49a176d37c
Commit 2023-02-28 10:02:08 +02:00
stuzer05 8ef3a478aa
Commit 2023-02-27 17:40:07 +02:00
stuzer05 37e8e8ddaf
Commit 2023-02-27 16:49:29 +02:00
stuzer05 e20e23b60a
Commit 2023-02-27 16:17:58 +02:00
スツゼル 8c0bf885b2
Merge branch 'main' into add-issue-planned-time 2023-02-27 13:51:04 +02:00
stuzer05 b9cdc7c670 Commit 2023-02-26 11:51:37 +02:00
stuzer05 7be748f63b Commit 2023-02-24 23:54:01 +02:00
stuzer05 29dd61722b Commit 2023-02-24 23:33:27 +02:00
stuzer05 875087061f Commit 2023-02-24 23:28:13 +02:00
スツゼル 775c663805
Merge branch 'main' into add-issue-planned-time 2023-02-24 23:08:56 +02:00
stuzer05 db3c697178 Commit 2023-02-24 23:07:48 +02:00
stuzer05 5eea230714 Commit 2023-02-24 23:06:41 +02:00
stuzer05 0ab85af1ce Commit 2023-02-24 22:26:42 +02:00
stuzer05 5c4dc8739c Commit 2023-02-24 20:13:46 +02:00
stuzer05 79f507b81f Commit 2023-02-24 20:07:44 +02:00
stuzer05 7a570440f1 Commit 2023-02-24 19:44:24 +02:00
stuzer05 f463765fec Commit 2023-02-24 19:31:40 +02:00
stuzer05 e15549501d Commit 2023-02-24 19:29:51 +02:00
stuzer05 1cff1a9e05 Commit 2023-02-24 19:06:43 +02:00
stuzer05 f7427d8b50 Commit 2023-02-24 17:22:59 +02:00
stuzer05 1b7ba4189b Commit 2023-02-24 14:14:13 +02:00
stuzer05 11b9719b5f Commit 2023-02-24 14:13:27 +02:00
stuzer05 0f5b609f9d Commit 2023-02-24 14:13:03 +02:00
stuzer05 09c05e8b76 Commit 2023-02-24 14:12:12 +02:00
stuzer05 d247b0ffd1 Commit 2023-02-24 14:08:38 +02:00
stuzer05 870bb922cc Commit 2023-02-24 14:05:26 +02:00
stuzer05 b062fc9849 Commit 2023-02-24 14:03:03 +02:00
stuzer05 2fc2f63c6c Commit 2023-02-24 14:02:36 +02:00
スツゼル 4e1aed8a61
Merge branch 'main' into add-issue-planned-time 2023-02-24 13:58:30 +02:00
stuzer05 f33b0a0773 Commit 2023-02-24 13:57:46 +02:00
stuzer05 e187364d7a Commit 2023-02-24 13:53:53 +02:00
スツゼル f7a4c9e0aa
Update services/issue/issue.go
Co-authored-by: Yarden Shoham <hrsi88@gmail.com>
2023-02-24 13:39:32 +02:00
スツゼル 5f3edad64f
Update services/issue/issue.go
Co-authored-by: Yarden Shoham <hrsi88@gmail.com>
2023-02-24 13:38:35 +02:00
stuzer05 4be8c50a6f Commit 2023-02-24 13:38:05 +02:00
stuzer05 d75b7acac6 Commit 2023-02-24 13:36:53 +02:00
stuzer05 c248042c8e Commit 2023-02-24 13:35:16 +02:00
stuzer05 7ed86ff00a Commit 2023-02-24 12:41:38 +02:00
stuzer05 d9446629c3 Commit 2023-02-24 12:37:12 +02:00
stuzer05 a8778f4db7 Commit 2023-02-24 12:15:43 +02:00
stuzer05 c783692f6c Commit 2023-02-24 12:13:12 +02:00
stuzer05 d11ba9f46c Commit 2023-02-24 12:10:52 +02:00
stuzer05 1363205f29 Commit 2023-02-24 12:06:12 +02:00
29 changed files with 394 additions and 139 deletions

View File

@ -908,8 +908,9 @@ webpack: $(WEBPACK_DEST)
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json
@$(MAKE) -s node-check node_modules
rm -rf $(WEBPACK_DEST_ENTRIES)
npx webpack
@rm -rf $(WEBPACK_DEST_ENTRIES)
@echo "Running webpack..."
@BROWSERSLIST_IGNORE_OLD_DATA=true npx webpack
@touch $(WEBPACK_DEST)
.PHONY: svg

View File

@ -112,6 +112,8 @@ const (
CommentTypePin // 36 pin Issue
CommentTypeUnpin // 37 unpin Issue
CommentTypeChangeTimeEstimate // 38 Change time estimate
)
var commentStrings = []string{
@ -151,6 +153,7 @@ var commentStrings = []string{
"change_issue_ref",
"pull_scheduled_merge",
"pull_cancel_scheduled_merge",
"change_time_estimate",
"pin",
"unpin",
}

View File

@ -140,6 +140,9 @@ type Issue struct {
// For view issue page.
ShowRole RoleDescriptor `xorm:"-"`
// Time estimate
TimeEstimate int64 `xorm:"NOT NULL DEFAULT 0"`
}
var (
@ -909,3 +912,33 @@ func insertIssue(ctx context.Context, issue *Issue) error {
return nil
}
// ChangeIssueTimeEstimate changes the plan time of this issue, as the given user.
func ChangeIssueTimeEstimate(issue *Issue, doer *user_model.User, timeEstimate int64) (err error) {
ctx, committer, err := db.TxContext(db.DefaultContext)
if err != nil {
return err
}
defer committer.Close()
if err = UpdateIssueCols(ctx, &Issue{ID: issue.ID, TimeEstimate: timeEstimate}, "time_estimate"); err != nil {
return fmt.Errorf("updateIssueCols: %w", err)
}
if err = issue.LoadRepo(ctx); err != nil {
return fmt.Errorf("loadRepo: %w", err)
}
opts := &CreateCommentOptions{
Type: CommentTypeChangeTimeEstimate,
Doer: doer,
Repo: issue.Repo,
Issue: issue,
Content: fmt.Sprintf("%d", timeEstimate),
}
if _, err = CreateComment(ctx, opts); err != nil {
return fmt.Errorf("createComment: %w", err)
}
return committer.Commit()
}

View File

@ -586,6 +586,8 @@ var migrations = []Migration{
NewMigration("Add everyone_access_mode for repo_unit", v1_23.AddRepoUnitEveryoneAccessMode),
// v298 -> v299
NewMigration("Drop wrongly created table o_auth2_application", v1_23.DropWronglyCreatedTable),
// v300 -> v301
NewMigration("Add TimeEstimate to issue table", v1_23.AddTimeEstimateColumnToIssueTable),
}
// GetCurrentDBVersion returns the current db version

View File

@ -0,0 +1,16 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_23 //nolint
import (
"xorm.io/xorm"
)
func AddTimeEstimateColumnToIssueTable(x *xorm.Engine) error {
type Issue struct {
TimeEstimate int64 `xorm:"NOT NULL DEFAULT 0"`
}
return x.Sync(new(Issue))
}

View File

@ -65,12 +65,14 @@ func NewFuncMap() template.FuncMap {
// -----------------------------------------------------------------
// time / number / format
"FileSize": base.FileSize,
"CountFmt": base.FormatNumberSI,
"TimeSince": timeutil.TimeSince,
"TimeSinceUnix": timeutil.TimeSinceUnix,
"DateTime": timeutil.DateTime,
"Sec2Time": util.SecToTime,
"FileSize": base.FileSize,
"CountFmt": base.FormatNumberSI,
"TimeSince": timeutil.TimeSince,
"TimeSinceUnix": timeutil.TimeSinceUnix,
"DateTime": timeutil.DateTime,
"Sec2Time": util.SecToTime,
"SecToTimeExact": util.SecToTimeExact,
"TimeEstimateToStr": util.TimeEstimateToStr,
"LoadTimes": func(startTime time.Time) string {
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
},

View File

@ -66,6 +66,43 @@ func SecToTime(durationVal any) string {
return strings.TrimRight(formattedTime, " ")
}
func SecToTimeExact(duration int64, withSeconds bool) string {
formattedTime := ""
// The following four variables are calculated by taking
// into account the previously calculated variables, this avoids
// pitfalls when using remainders. As that could lead to incorrect
// results when the calculated number equals the quotient number.
remainingDays := duration / (60 * 60 * 24)
years := remainingDays / 365
remainingDays -= years * 365
months := remainingDays * 12 / 365
remainingDays -= months * 365 / 12
weeks := remainingDays / 7
remainingDays -= weeks * 7
days := remainingDays
// The following three variables are calculated without depending
// on the previous calculated variables.
hours := (duration / 3600) % 24
minutes := (duration / 60) % 60
seconds := duration % 60
// Show exact time information
formattedTime = formatTime(years, "year", formattedTime)
formattedTime = formatTime(months, "month", formattedTime)
formattedTime = formatTime(weeks, "week", formattedTime)
formattedTime = formatTime(days, "day", formattedTime)
formattedTime = formatTime(hours, "hour", formattedTime)
formattedTime = formatTime(minutes, "minute", formattedTime)
if withSeconds {
formattedTime = formatTime(seconds, "second", formattedTime)
}
// The formatTime() function always appends a space at the end. This will be trimmed
return strings.TrimRight(formattedTime, " ")
}
// formatTime appends the given value to the existing forammattedTime. E.g:
// formattedTime = "1 year"
// input: value = 3, name = "month"

99
modules/util/time_str.go Normal file
View File

@ -0,0 +1,99 @@
// Copyright 2022 Gitea. All rights reserved.
// SPDX-License-Identifier: MIT
package util
import (
"fmt"
"math"
"regexp"
"strconv"
"strings"
)
var (
// Time estimate match regex
rTimeEstimateOnlyHours = regexp.MustCompile(`^([\d]+)$`)
rTimeEstimateWeeks = regexp.MustCompile(`([\d]+)w`)
rTimeEstimateDays = regexp.MustCompile(`([\d]+)d`)
rTimeEstimateHours = regexp.MustCompile(`([\d]+)h`)
rTimeEstimateMinutes = regexp.MustCompile(`([\d]+)m`)
)
// TimeEstimateFromStr returns time estimate in seconds from formatted string
func TimeEstimateFromStr(timeStr string) int64 {
timeTotal := 0
// If single number entered, assume hours
timeStrMatches := rTimeEstimateOnlyHours.FindStringSubmatch(timeStr)
if len(timeStrMatches) > 0 {
raw, _ := strconv.Atoi(timeStrMatches[1])
timeTotal += raw * (60 * 60)
} else {
// Find time weeks
timeStrMatches = rTimeEstimateWeeks.FindStringSubmatch(timeStr)
if len(timeStrMatches) > 0 {
raw, _ := strconv.Atoi(timeStrMatches[1])
timeTotal += raw * (60 * 60 * 24 * 7)
}
// Find time days
timeStrMatches = rTimeEstimateDays.FindStringSubmatch(timeStr)
if len(timeStrMatches) > 0 {
raw, _ := strconv.Atoi(timeStrMatches[1])
timeTotal += raw * (60 * 60 * 24)
}
// Find time hours
timeStrMatches = rTimeEstimateHours.FindStringSubmatch(timeStr)
if len(timeStrMatches) > 0 {
raw, _ := strconv.Atoi(timeStrMatches[1])
timeTotal += raw * (60 * 60)
}
// Find time minutes
timeStrMatches = rTimeEstimateMinutes.FindStringSubmatch(timeStr)
if len(timeStrMatches) > 0 {
raw, _ := strconv.Atoi(timeStrMatches[1])
timeTotal += raw * (60)
}
}
return int64(timeTotal)
}
// TimeEstimateStr returns formatted time estimate string from seconds (e.g. "2w 4d 12h 5m")
func TimeEstimateToStr(amount int64) string {
var timeParts []string
timeSeconds := float64(amount)
// Format weeks
weeks := math.Floor(timeSeconds / (60 * 60 * 24 * 7))
if weeks > 0 {
timeParts = append(timeParts, fmt.Sprintf("%dw", int64(weeks)))
}
timeSeconds -= weeks * (60 * 60 * 24 * 7)
// Format days
days := math.Floor(timeSeconds / (60 * 60 * 24))
if days > 0 {
timeParts = append(timeParts, fmt.Sprintf("%dd", int64(days)))
}
timeSeconds -= days * (60 * 60 * 24)
// Format hours
hours := math.Floor(timeSeconds / (60 * 60))
if hours > 0 {
timeParts = append(timeParts, fmt.Sprintf("%dh", int64(hours)))
}
timeSeconds -= hours * (60 * 60)
// Format minutes
minutes := math.Floor(timeSeconds / (60))
if minutes > 0 {
timeParts = append(timeParts, fmt.Sprintf("%dm", int64(minutes)))
}
return strings.Join(timeParts, " ")
}

View File

@ -1480,6 +1480,11 @@ issues.add_assignee_at = `was assigned by <b>%s</b> %s`
issues.remove_assignee_at = `was unassigned by <b>%s</b> %s`
issues.remove_self_assignment = `removed their assignment %s`
issues.change_title_at = `changed title from <b><strike>%s</strike></b> to <b>%s</b> %s`
issues.time_estimate = `Time Estimate`
issues.add_time_estimate = `3w 4d 12h`
issues.change_time_estimate_at = `changed time estimate to <b>%s</b> %s`
issues.remove_time_estimate = `removed time estimate %s`
issues.time_estimate_invalid = `Time estimate format is invalid`
issues.change_ref_at = `changed reference from <b><strike>%s</strike></b> to <b>%s</b> %s`
issues.remove_ref_at = `removed reference <b>%s</b> %s`
issues.add_ref_at = `added reference <b>%s</b> %s`
@ -1650,20 +1655,20 @@ issues.start_tracking_history = `started working %s`
issues.tracker_auto_close = Timer will be stopped automatically when this issue gets closed
issues.tracking_already_started = `You have already started time tracking on <a href="%s">another issue</a>!`
issues.stop_tracking = Stop Timer
issues.stop_tracking_history = `stopped working %s`
issues.stop_tracking_history = `worked for <b>%s</b> %s`
issues.cancel_tracking = Discard
issues.cancel_tracking_history = `canceled time tracking %s`
issues.add_time = Manually Add Time
issues.del_time = Delete this time log
issues.add_time_short = Add Time
issues.add_time_cancel = Cancel
issues.add_time_history = `added spent time %s`
issues.del_time_history= `deleted spent time %s`
issues.add_time_history = `added spent time <b>%s</b> %s`
issues.del_time_history= `deleted spent time <b>%s</b> %s`
issues.add_time_hours = Hours
issues.add_time_minutes = Minutes
issues.add_time_sum_to_small = No time was entered.
issues.time_spent_total = Total Time Spent
issues.time_spent_from_all_authors = `Total Time Spent: %s`
issues.time_spent_from_all_authors = `Total Time Spent:`
issues.due_date = Due Date
issues.invalid_due_date_format = "Due date format must be 'yyyy-mm-dd'."
issues.error_modifying_due_date = "Failed to modify the due date."

View File

@ -436,6 +436,7 @@ oauth_signin_submit=Vincular conta
oauth.signin.error=Ocorreu um erro durante o processamento do pedido de autorização. Se este erro persistir, contacte o administrador.
oauth.signin.error.access_denied=O pedido de autorização foi negado.
oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponível. Tente mais tarde.
oauth_callback_unable_auto_reg=O registo automático está habilitado, mas o fornecedor OAuth2 %[1]s sinalizou campos em falta: %[2]s, por isso não foi possível criar uma conta automaticamente. Crie ou vincule uma conta ou contacte o administrador do sítio.
openid_connect_submit=Estabelecer ligação
openid_connect_title=Estabelecer ligação a uma conta existente
openid_connect_desc=O URI do OpenID escolhido é desconhecido. Associe-o a uma nova conta aqui.

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -13,6 +13,7 @@ import (
"math/big"
"net/http"
"net/url"
"regexp"
"slices"
"sort"
"strconv"
@ -1771,6 +1772,9 @@ func ViewIssue(ctx *context.Context) {
comment.Content = comment.Content[1:]
}
}
} else if comment.Type == issues_model.CommentTypeChangeTimeEstimate {
timeSec, _ := util.ToInt64(comment.Content)
comment.Content = util.SecToTimeExact(timeSec, timeSec < 60)
}
if comment.Type == issues_model.CommentTypeClose || comment.Type == issues_model.CommentTypeMergePull {
@ -2208,6 +2212,57 @@ func UpdateIssueTitle(ctx *context.Context) {
})
}
// UpdateIssueTimeEstimate change issue's planned time
var (
rTimeEstimateStr = regexp.MustCompile(`^([\d]+w)?\s?([\d]+d)?\s?([\d]+h)?\s?([\d]+m)?$`)
rTimeEstimateStrHoursOnly = regexp.MustCompile(`^([\d]+)$`)
)
func UpdateIssueTimeEstimate(ctx *context.Context) {
issue := GetActionIssue(ctx)
if ctx.Written() {
return
}
if !ctx.IsSigned || (!issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) {
ctx.Error(http.StatusForbidden)
return
}
url := issue.Link()
timeStr := ctx.FormString("time_estimate")
// Validate input
if !rTimeEstimateStr.MatchString(timeStr) && !rTimeEstimateStrHoursOnly.MatchString(timeStr) {
ctx.Flash.Error(ctx.Tr("repo.issues.time_estimate_invalid"))
ctx.Redirect(url, http.StatusSeeOther)
return
}
total := util.TimeEstimateFromStr(timeStr)
// User entered something wrong
if total == 0 && len(timeStr) != 0 {
ctx.Flash.Error(ctx.Tr("repo.issues.time_estimate_invalid"))
ctx.Redirect(url, http.StatusSeeOther)
return
}
// No time changed
if issue.TimeEstimate == total {
ctx.Redirect(url, http.StatusSeeOther)
return
}
if err := issue_service.ChangeTimeEstimate(issue, ctx.Doer, total); err != nil {
ctx.ServerError("ChangeTimeEstimate", err)
return
}
ctx.Redirect(url, http.StatusSeeOther)
}
// UpdateIssueRef change issue's ref (branch)
func UpdateIssueRef(ctx *context.Context) {
issue := GetActionIssue(ctx)

View File

@ -34,7 +34,7 @@ func AddTimeManually(c *context.Context) {
return
}
total := time.Duration(form.Hours)*time.Hour + time.Duration(form.Minutes)*time.Minute
total := util.TimeEstimateFromStr(form.TimeString)
if total <= 0 {
c.Flash.Error(c.Tr("repo.issues.add_time_sum_to_small"))
@ -42,7 +42,7 @@ func AddTimeManually(c *context.Context) {
return
}
if _, err := issues_model.AddTime(c, c.Doer, issue, int64(total.Seconds()), time.Now()); err != nil {
if _, err := issues_model.AddTime(c, c.Doer, issue, total, time.Now()); err != nil {
c.ServerError("AddTime", err)
return
}

View File

@ -1202,6 +1202,7 @@ func registerRoutes(m *web.Route) {
m.Post("/cancel", repo.CancelStopwatch)
})
})
m.Post("/time_estimate", repo.UpdateIssueTimeEstimate)
m.Post("/reactions/{action}", web.Bind(forms.ReactionForm{}), repo.ChangeIssueReaction)
m.Post("/lock", reqRepoIssuesOrPullsWriter, web.Bind(forms.IssueLockForm{}), repo.LockIssue)
m.Post("/unlock", reqRepoIssuesOrPullsWriter, repo.UnlockIssue)

View File

@ -76,6 +76,11 @@ func ToTimelineComment(ctx context.Context, repo *repo_model.Repository, c *issu
// so we check for the "|" delimeter and convert new to legacy format on demand
c.Content = util.SecToTime(c.Content[1:])
}
if c.Type == issues_model.CommentTypeChangeTimeEstimate {
timeSec, _ := util.ToInt64(c.Content)
c.Content = util.SecToTimeExact(timeSec, timeSec < 60)
}
}
comment := &api.TimelineComment{

View File

@ -877,8 +877,7 @@ func (f *DeleteRepoFileForm) Validate(req *http.Request, errs binding.Errors) bi
// AddTimeManuallyForm form that adds spent time manually.
type AddTimeManuallyForm struct {
Hours int `binding:"Range(0,1000)"`
Minutes int `binding:"Range(0,1000)"`
TimeString string
}
// Validate validates the fields

View File

@ -43,6 +43,7 @@ var hiddenCommentTypeGroups = hiddenCommentTypeGroupsType{
/*14*/ issues_model.CommentTypeAddTimeManual,
/*15*/ issues_model.CommentTypeCancelTracking,
/*26*/ issues_model.CommentTypeDeleteTimeManual,
/*38*/ issues_model.CommentTypeChangeTimeEstimate,
},
"deadline": {
/*16*/ issues_model.CommentTypeAddedDeadline,

View File

@ -9,8 +9,6 @@ import (
"fmt"
"html"
"net/url"
"regexp"
"strconv"
"strings"
"time"
@ -23,64 +21,11 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/references"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/util"
)
const (
secondsByMinute = float64(time.Minute / time.Second) // seconds in a minute
secondsByHour = 60 * secondsByMinute // seconds in an hour
secondsByDay = 8 * secondsByHour // seconds in a day
secondsByWeek = 5 * secondsByDay // seconds in a week
secondsByMonth = 4 * secondsByWeek // seconds in a month
)
var reDuration = regexp.MustCompile(`(?i)^(?:(\d+([\.,]\d+)?)(?:mo))?(?:(\d+([\.,]\d+)?)(?:w))?(?:(\d+([\.,]\d+)?)(?:d))?(?:(\d+([\.,]\d+)?)(?:h))?(?:(\d+([\.,]\d+)?)(?:m))?$`)
// timeLogToAmount parses time log string and returns amount in seconds
func timeLogToAmount(str string) int64 {
matches := reDuration.FindAllStringSubmatch(str, -1)
if len(matches) == 0 {
return 0
}
match := matches[0]
var a int64
// months
if len(match[1]) > 0 {
mo, _ := strconv.ParseFloat(strings.Replace(match[1], ",", ".", 1), 64)
a += int64(mo * secondsByMonth)
}
// weeks
if len(match[3]) > 0 {
w, _ := strconv.ParseFloat(strings.Replace(match[3], ",", ".", 1), 64)
a += int64(w * secondsByWeek)
}
// days
if len(match[5]) > 0 {
d, _ := strconv.ParseFloat(strings.Replace(match[5], ",", ".", 1), 64)
a += int64(d * secondsByDay)
}
// hours
if len(match[7]) > 0 {
h, _ := strconv.ParseFloat(strings.Replace(match[7], ",", ".", 1), 64)
a += int64(h * secondsByHour)
}
// minutes
if len(match[9]) > 0 {
d, _ := strconv.ParseFloat(strings.Replace(match[9], ",", ".", 1), 64)
a += int64(d * secondsByMinute)
}
return a
}
func issueAddTime(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, time time.Time, timeLog string) error {
amount := timeLogToAmount(timeLog)
amount := util.TimeEstimateFromStr(timeLog)
if amount == 0 {
return nil
}

View File

@ -105,6 +105,13 @@ func ChangeTitle(ctx context.Context, issue *issues_model.Issue, doer *user_mode
return nil
}
// ChangeTimeEstimate changes the time estimate of this issue, as the given user.
func ChangeTimeEstimate(issue *issues_model.Issue, doer *user_model.User, timeEstimate int64) (err error) {
issue.TimeEstimate = timeEstimate
return issues_model.ChangeIssueTimeEstimate(issue, doer, timeEstimate)
}
// ChangeIssueRef changes the branch of this issue, as the given user.
func ChangeIssueRef(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, ref string) error {
oldRef := issue.Ref

View File

@ -62,7 +62,7 @@
{{end -}}
{{- range .ReviewComments}}
<hr>
{{$.locale.Tr "mail.issue.in_tree_path" .TreePath}}
{{ctx.Locale.Tr "mail.issue.in_tree_path" .TreePath}}
<div class="review">
<pre>{{.Patch}}</pre>
<div>{{.RenderedContent}}</div>

View File

@ -1,6 +1,6 @@
{{if $.IsSplitStyle}}
{{range $k, $line := $.section.Lines}}
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}">
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}} line-expanded">
{{if eq .GetType 4}}
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}">
<div class="tw-flex">
@ -26,17 +26,17 @@
{{else}}
{{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}}
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{$.FileNameHash}}L{{$line.LeftIdx}}{{end}}"></span></td>
<td class="blob-excerpt lines-escape lines-escape-old">{{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
<td class="blob-excerpt lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
<td class="blob-excerpt lines-code lines-code-old">{{/*
<td class="lines-escape lines-escape-old">{{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
<td class="lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
<td class="lines-code lines-code-old">{{/*
*/}}{{if $line.LeftIdx}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{else}}{{/*
*/}}<code class="code-inner"></code>{{/*
*/}}{{end}}{{/*
*/}}</td>
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{$.FileNameHash}}R{{$line.RightIdx}}{{end}}"></span></td>
<td class="blob-excerpt lines-escape lines-escape-new">{{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
<td class="blob-excerpt lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
<td class="blob-excerpt lines-code lines-code-new">{{/*
<td class="lines-escape lines-escape-new">{{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
<td class="lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="tw-font-mono" data-type-marker=""></span>{{end}}</td>
<td class="lines-code lines-code-new">{{/*
*/}}{{if $line.RightIdx}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{else}}{{/*
*/}}<code class="code-inner"></code>{{/*
*/}}{{end}}{{/*
@ -46,7 +46,7 @@
{{end}}
{{else}}
{{range $k, $line := $.section.Lines}}
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}">
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}} line-expanded">
{{if eq .GetType 4}}
<td colspan="2" class="lines-num">
<div class="tw-flex">
@ -72,9 +72,9 @@
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{$.FileNameHash}}R{{$line.RightIdx}}{{end}}"></span></td>
{{end}}
{{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}}
<td class="blob-excerpt lines-escape">{{if $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
<td class="blob-excerpt lines-type-marker"><span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
<td class="blob-excerpt lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}"><code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
<td class="lines-escape">{{if $inlineDiff.EscapeStatus.Escaped}}<button class="toggle-escape-button btn interact-bg" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"></button>{{end}}</td>
<td class="lines-type-marker"><span class="tw-font-mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
<td class="lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}"><code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{template "repo/diff/escape_title" dict "diff" $inlineDiff}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
</tr>
{{end}}
{{end}}

View File

@ -12,7 +12,8 @@
26 = DELETE_TIME_MANUAL, 27 = REVIEW_REQUEST, 28 = MERGE_PULL_REQUEST,
29 = PULL_PUSH_EVENT, 30 = PROJECT_CHANGED, 31 = PROJECT_BOARD_CHANGED
32 = DISMISSED_REVIEW, 33 = COMMENT_TYPE_CHANGE_ISSUE_REF, 34 = PR_SCHEDULE_TO_AUTO_MERGE,
35 = CANCEL_SCHEDULED_AUTO_MERGE_PR, 36 = PIN_ISSUE, 37 = UNPIN_ISSUE -->
35 = CANCEL_SCHEDULED_AUTO_MERGE_PR, 36 = PIN_ISSUE, 37 = UNPIN_ISSUE,
38 = COMMENT_TYPE_CHANGE_TIME_ESTIMATE -->
{{if eq .Type 0}}
<div class="timeline-item comment" id="{{.HashTag}}">
{{if .OriginalAuthor}}
@ -249,18 +250,18 @@
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="text grey muted-links">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.stop_tracking_history" $createdStr}}
</span>
{{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
<div class="detail flex-text-block">
{{svg "octicon-clock"}}
{{$timeStr := ""}}
{{if .RenderedContent}}
{{/* compatibility with time comments made before v1.21 */}}
<span class="text grey muted-links">{{.RenderedContent}}</span>
{{$timeStr = .RenderedContent}}
{{else}}
<span class="text grey muted-links">{{.Content|Sec2Time}}</span>
{{$timeStr = .Content|Sec2Time}}
{{end}}
</div>
{{ctx.Locale.Tr "repo.issues.stop_tracking_history" $timeStr $createdStr | SafeHTML}}
</span>
{{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
</div>
{{else if eq .Type 14}}
<div class="timeline-item event" id="{{.HashTag}}">
@ -268,18 +269,18 @@
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="text grey muted-links">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.add_time_history" $createdStr}}
</span>
{{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
<div class="detail flex-text-block">
{{svg "octicon-clock"}}
{{$timeStr := ""}}
{{if .RenderedContent}}
{{/* compatibility with time comments made before v1.21 */}}
<span class="text grey muted-links">{{.RenderedContent}}</span>
{{$timeStr = .RenderedContent}}
{{else}}
<span class="text grey muted-links">{{.Content|Sec2Time}}</span>
{{$timeStr = .Content|Sec2Time}}
{{end}}
</div>
{{ctx.Locale.Tr "repo.issues.add_time_history" $timeStr $createdStr | SafeHTML}}
</span>
{{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
</div>
{{else if eq .Type 15}}
<div class="timeline-item event" id="{{.HashTag}}">
@ -680,6 +681,15 @@
{{else}}{{ctx.Locale.Tr "repo.issues.unpin_comment" $createdStr}}{{end}}
</span>
</div>
{{else if eq .Type 38}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}}
<span class="text grey muted-links">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.change_time_estimate_at" .Content $createdStr | SafeHTML}}
</span>
</div>
{{end}}
{{end}}
{{end}}

View File

@ -278,8 +278,22 @@
{{end}}
{{if .Repository.IsTimetrackerEnabled $.Context}}
{{if and .CanUseTimetracker (not .Repository.IsArchived)}}
<div class="divider"></div>
<div class="ui timetrack">
<div class="ui divider"></div>
<div>
<span class="text"><strong>{{ctx.Locale.Tr "repo.issues.time_estimate"}}</strong></span>
<form method="post" id="set_time_estimate_form" class="gt-mt-3" action="{{.Issue.Link}}/time_estimate">
{{$.CsrfTokenHtml}}
<div class="ui input fluid">
<input name="time_estimate" placeholder='{{ctx.Locale.Tr "repo.issues.add_time_estimate"}}' value="{{TimeEstimateToStr .Issue.TimeEstimate}}" data-value="{{$.Issue.TimeEstimate}}" type="text" >
</div>
<button class="ui fluid button green tooltip tw-mt-1">
{{ctx.Locale.Tr "repo.issues.save"}}
</button>
</form>
</div>
<div class="divider"></div>
<div class="ui timetrack">
<span class="text"><strong>{{ctx.Locale.Tr "repo.issues.tracker"}}</strong></span>
<div class="tw-mt-2">
<form method="post" action="{{.Issue.Link}}/times/stopwatch/toggle" id="toggle_stopwatch_form">
@ -311,9 +325,8 @@
<div class="header">{{ctx.Locale.Tr "repo.issues.add_time"}}</div>
<div class="content">
<form method="post" id="add_time_manual_form" action="{{.Issue.Link}}/times/add" class="ui input fluid tw-gap-2">
{{$.CsrfTokenHtml}}
<input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_hours"}}' type="number" name="hours">
<input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_minutes"}}' type="number" name="minutes" class="ui compact">
{{$.CsrfTokenHtml}}
<input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_estimate"}}' type="text" name="time_string">
</form>
</div>
<div class="actions">
@ -332,8 +345,9 @@
{{if .WorkingUsers}}
<div class="divider"></div>
<div class="ui comments">
<span class="text"><strong>{{ctx.Locale.Tr "repo.issues.time_spent_from_all_authors" ($.Issue.TotalTrackedTime | Sec2Time)}}</strong></span>
<div>
<div class="text"><strong>{{ctx.Locale.Tr "repo.issues.time_spent_from_all_authors" | SafeHTML}}</strong></div>
<div>{{SecToTimeExact .Issue.TotalTrackedTime false}}</div>
<div class="gt-mt-3">
{{range $user, $trackedtime := .WorkingUsers}}
<div class="comment tw-mt-2">
<a class="avatar">

View File

@ -73,8 +73,7 @@ func testViewTimetrackingControls(t *testing.T, session *TestSession, user, repo
htmlDoc = NewHTMLParser(t, resp.Body)
events = htmlDoc.doc.Find(".event > span.text")
assert.Contains(t, events.Last().Text(), "stopped working")
htmlDoc.AssertElement(t, ".event .detail .octicon-clock", true)
assert.Contains(t, events.Last().Text(), "worked for ")
} else {
session.MakeRequest(t, req, http.StatusNotFound)
}

View File

@ -2377,7 +2377,7 @@ tbody.commit-list {
.tag-code,
.tag-code td,
.tag-code .blob-excerpt {
.tag-code.line-expanded {
background-color: var(--color-box-body-highlight);
vertical-align: middle;
}
@ -2393,8 +2393,8 @@ tbody.commit-list {
padding-top: 0 !important;
}
.blob-excerpt {
background-color: var(--color-secondary-alpha-30);
.line-expanded {
background-color: var(--color-secondary-alpha-20);
}
.issue-keyword {
@ -2553,11 +2553,9 @@ tbody.commit-list {
.code-diff-unified .add-code,
.code-diff-unified .add-code td,
.code-diff-split .add-code .lines-num-new,
.code-diff-split .add-code .lines-type-marker-new,
.code-diff-split .add-code .lines-escape-new,
.code-diff-split .add-code .lines-code-new,
.code-diff-split .del-code .add-code.lines-num-new,
.code-diff-split .del-code .add-code.lines-type-marker-new,
.code-diff-split .del-code .add-code.lines-escape-new,
.code-diff-split .del-code .add-code.lines-code-new {
@ -2565,17 +2563,33 @@ tbody.commit-list {
border-color: var(--color-diff-added-row-border);
}
.code-diff-split .del-code .lines-num-new,
.code-diff-split .del-code .lines-type-marker-new,
.code-diff-split .del-code .lines-code-new,
.code-diff-split .del-code .lines-escape-new,
.code-diff-split .add-code .lines-num-old,
.code-diff-split .add-code .lines-escape-old,
.code-diff-split .add-code .lines-type-marker-old,
.code-diff-split .add-code .lines-code-old {
background: var(--color-diff-inactive);
}
.code-diff-split .add-code .lines-num.lines-num-old,
.code-diff-split .del-code .lines-num.lines-num-new {
background: var(--color-diff-inactive);
}
.code-diff-unified .del-code .lines-num,
.code-diff-split .del-code .lines-num {
background: var(--color-diff-removed-linenum-bg);
color: var(--color-text);
}
.code-diff-unified .add-code .lines-num,
.code-diff-split .add-code .lines-num,
.code-diff-split .del-code .add-code.lines-num {
background: var(--color-diff-added-linenum-bg);
color: var(--color-text);
}
.code-diff-split tbody tr td:nth-child(5),
.code-diff-split tbody tr td.add-comment-right {
border-left: 1px solid var(--color-secondary);

View File

@ -3,9 +3,10 @@
/* red/green colorblind-friendly colors */
/* from GitHub: --diffBlob-addition-*, --diffBlob-deletion-*, etc */
:root {
--color-diff-added-word-bg: #388bfd66;
--color-diff-added-row-bg: #388bfd26;
--color-diff-removed-word-bg: #db6d2866;
--color-diff-removed-row-bg: #db6d2826;
--color-diff-added-linenum-bg: #1979fd46;
--color-diff-added-row-bg: #1979fd20;
--color-diff-added-word-bg: #1979fd66;
--color-diff-removed-linenum-bg: #c8622146;
--color-diff-removed-row-bg: #c8622120;
--color-diff-removed-word-bg: #c8622166;
}

View File

@ -143,14 +143,16 @@
--color-grey-light: #818f9e;
--color-gold: #b1983b;
--color-white: #ffffff;
--color-diff-removed-word-bg: #6f3333;
--color-diff-added-word-bg: #3c653c;
--color-diff-removed-row-bg: #3c2626;
--color-diff-moved-row-bg: #818044;
--color-diff-added-row-bg: #283e2d;
--color-diff-removed-row-border: #634343;
--color-diff-moved-row-border: #bcca6f;
--color-diff-added-linenum-bg: #274227;
--color-diff-added-row-bg: #203224;
--color-diff-added-row-border: #314a37;
--color-diff-added-word-bg: #3c653c;
--color-diff-moved-row-bg: #818044;
--color-diff-moved-row-border: #bcca6f;
--color-diff-removed-linenum-bg: #482121;
--color-diff-removed-row-bg: #301e1e;
--color-diff-removed-row-border: #634343;
--color-diff-removed-word-bg: #6f3333;
--color-diff-inactive: #22282d;
--color-error-border: #a04141;
--color-error-bg: #522;

View File

@ -3,9 +3,10 @@
/* red/green colorblind-friendly colors */
/* from GitHub: --diffBlob-addition-*, --diffBlob-deletion-*, etc */
:root {
--color-diff-added-word-bg: #54aeff66;
--color-diff-added-linenum-bg: #54aeff4d;
--color-diff-added-row-bg: #ddf4ff80;
--color-diff-removed-word-bg: #ffb77c80;
--color-diff-added-word-bg: #54aeff66;
--color-diff-removed-linenum-bg: #ffb77c4d;
--color-diff-removed-row-bg: #fff1e580;
--color-diff-removed-word-bg: #ffb77c80;
}

View File

@ -143,14 +143,16 @@
--color-grey-light: #7c838a;
--color-gold: #a1882b;
--color-white: #ffffff;
--color-diff-removed-word-bg: #fdb8c0;
--color-diff-added-word-bg: #acf2bd;
--color-diff-removed-row-bg: #ffeef0;
--color-diff-moved-row-bg: #f1f8d1;
--color-diff-added-linenum-bg: #d1f8d9;
--color-diff-added-row-bg: #e6ffed;
--color-diff-removed-row-border: #f1c0c0;
--color-diff-moved-row-border: #d0e27f;
--color-diff-added-row-border: #e6ffed;
--color-diff-added-word-bg: #acf2bd;
--color-diff-moved-row-bg: #f1f8d1;
--color-diff-moved-row-border: #d0e27f;
--color-diff-removed-linenum-bg: #ffcecb;
--color-diff-removed-row-bg: #ffeef0;
--color-diff-removed-row-border: #f1c0c0;
--color-diff-removed-word-bg: #fdb8c0;
--color-diff-inactive: #f0f2f4;
--color-error-border: #e0b4b4;
--color-error-bg: #fff6f6;