1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-14 14:37:20 +00:00

Fix and rewrite contrast color calculation, fix project-related bugs (#30326)

Backport https://github.com/go-gitea/gitea/pull/30237 to 1.22. Also
includes https://github.com/go-gitea/gitea/pull/30183. Both were clean
cherry-picks.

Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
silverwind
2024-04-09 11:45:29 +02:00
committed by GitHub
parent 82992cf32d
commit b8e9d3c553
14 changed files with 148 additions and 203 deletions

View File

@ -1,8 +1,8 @@
import $ from 'jquery';
import {useLightTextOnBackground} from '../utils/color.js';
import tinycolor from 'tinycolor2';
import {contrastColor} from '../utils/color.js';
import {createSortable} from '../modules/sortable.js';
import {POST, DELETE, PUT} from '../modules/fetch.js';
import tinycolor from 'tinycolor2';
function updateIssueCount(cards) {
const parent = cards.parentElement;
@ -65,14 +65,11 @@ async function initRepoProjectSortable() {
boardColumns = mainBoard.getElementsByClassName('project-column');
for (let i = 0; i < boardColumns.length; i++) {
const column = boardColumns[i];
if (parseInt($(column).data('sorting')) !== i) {
if (parseInt(column.getAttribute('data-sorting')) !== i) {
try {
await PUT($(column).data('url'), {
data: {
sorting: i,
color: rgbToHex(window.getComputedStyle($(column)[0]).backgroundColor),
},
});
const bgColor = column.style.backgroundColor; // will be rgb() string
const color = bgColor ? tinycolor(bgColor).toHexString() : '';
await PUT(column.getAttribute('data-url'), {data: {sorting: i, color}});
} catch (error) {
console.error(error);
}
@ -94,47 +91,51 @@ async function initRepoProjectSortable() {
}
export function initRepoProject() {
if (!$('.repository.projects').length) {
if (!document.querySelector('.repository.projects')) {
return;
}
const _promise = initRepoProjectSortable();
$('.edit-project-column-modal').each(function () {
const $projectHeader = $(this).closest('.project-column-header');
const $projectTitleLabel = $projectHeader.find('.project-column-title');
const $projectTitleInput = $(this).find('.project-column-title-input');
const $projectColorInput = $(this).find('#new_project_column_color');
const $boardColumn = $(this).closest('.project-column');
const bgColor = $boardColumn[0].style.backgroundColor;
if (bgColor) {
setLabelColor($projectHeader, rgbToHex(bgColor));
}
$(this).find('.edit-project-column-button').on('click', async function (e) {
for (const modal of document.getElementsByClassName('edit-project-column-modal')) {
const projectHeader = modal.closest('.project-column-header');
const projectTitleLabel = projectHeader?.querySelector('.project-column-title-label');
const projectTitleInput = modal.querySelector('.project-column-title-input');
const projectColorInput = modal.querySelector('#new_project_column_color');
const boardColumn = modal.closest('.project-column');
modal.querySelector('.edit-project-column-button')?.addEventListener('click', async function (e) {
e.preventDefault();
try {
await PUT($(this).data('url'), {
await PUT(this.getAttribute('data-url'), {
data: {
title: $projectTitleInput.val(),
color: $projectColorInput.val(),
title: projectTitleInput?.value,
color: projectColorInput?.value,
},
});
} catch (error) {
console.error(error);
} finally {
$projectTitleLabel.text($projectTitleInput.val());
$projectTitleInput.closest('form').removeClass('dirty');
if ($projectColorInput.val()) {
setLabelColor($projectHeader, $projectColorInput.val());
projectTitleLabel.textContent = projectTitleInput?.value;
projectTitleInput.closest('form')?.classList.remove('dirty');
const dividers = boardColumn.querySelectorAll(':scope > .divider');
if (projectColorInput.value) {
const color = contrastColor(projectColorInput.value);
boardColumn.style.setProperty('background', projectColorInput.value, 'important');
boardColumn.style.setProperty('color', color, 'important');
for (const divider of dividers) {
divider.style.setProperty('color', color);
}
} else {
boardColumn.style.removeProperty('background');
boardColumn.style.removeProperty('color');
for (const divider of dividers) {
divider.style.removeProperty('color');
}
}
$boardColumn[0].style = `background: ${$projectColorInput.val()} !important`;
$('.ui.modal').modal('hide');
}
});
});
}
$('.default-project-column-modal').each(function () {
const $boardColumn = $(this).closest('.project-column');
@ -183,22 +184,3 @@ export function initRepoProject() {
createNewColumn(url, $columnTitle, $projectColorInput);
});
}
function setLabelColor(label, color) {
const {r, g, b} = tinycolor(color).toRgb();
if (useLightTextOnBackground(r, g, b)) {
label.removeClass('dark-label').addClass('light-label');
} else {
label.removeClass('light-label').addClass('dark-label');
}
}
function rgbToHex(rgb) {
rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+).*\)$/);
return `#${hex(rgb[1])}${hex(rgb[2])}${hex(rgb[3])}`;
}
function hex(x) {
const hexDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
return Number.isNaN(x) ? '00' : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
}