Merge branch 'master' into newads

This commit is contained in:
Miodec 2023-03-08 15:49:49 +01:00
commit dea501b7ec
9 changed files with 159 additions and 67 deletions

View file

@ -15,6 +15,7 @@
"chartjs-adapter-date-fns": "2.0.0",
"chartjs-plugin-annotation": "1.4.0",
"chartjs-plugin-trendline": "1.0.2",
"color-blend": "4.0.0",
"crypto-browserify": "3.12.0",
"damerau-levenshtein": "1.0.8",
"date-fns": "2.28.0",
@ -5027,6 +5028,14 @@
"node": ">=0.10.0"
}
},
"node_modules/color-blend": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/color-blend/-/color-blend-4.0.0.tgz",
"integrity": "sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@ -21733,6 +21742,11 @@
"object-visit": "^1.0.0"
}
},
"color-blend": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/color-blend/-/color-blend-4.0.0.tgz",
"integrity": "sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw=="
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",

View file

@ -64,6 +64,7 @@
"chartjs-adapter-date-fns": "2.0.0",
"chartjs-plugin-annotation": "1.4.0",
"chartjs-plugin-trendline": "1.0.2",
"color-blend": "4.0.0",
"crypto-browserify": "3.12.0",
"damerau-levenshtein": "1.0.8",
"date-fns": "2.28.0",

View file

@ -504,22 +504,9 @@
place-content: center center;
}
.box:nth-child(1) {
background: var(--colorful-error-color);
border-radius: var(--roundness) 0 0 var(--roundness);
}
.box:nth-child(2) {
background: var(--colorful-error-color);
filter: opacity(0.6);
}
.box:nth-child(3) {
background: var(--sub-color);
}
.box:nth-child(4) {
background: var(--main-color);
filter: opacity(0.6);
}
.box:nth-child(5) {
background: var(--main-color);
border-radius: 0 var(--roundness) var(--roundness) 0;
}
}
@ -546,25 +533,8 @@
letter.incorrect.extra {
color: var(--error-extra-color);
}
&.unreached letter {
filter: opacity(0.2);
}
&.heatmap0 letter {
color: var(--colorful-error-color);
}
&.heatmap1 letter {
color: var(--colorful-error-color);
filter: opacity(0.6);
}
&.heatmap2 letter {
color: var(--sub-color);
}
&.heatmap3 letter {
color: var(--main-color);
filter: opacity(0.6);
}
&.heatmap4 letter {
color: var(--main-color);
&.heatmapInherit letter {
color: inherit;
}
}
&.rightToLeftTest {

View file

@ -241,4 +241,11 @@ $("#resultEditTagsPanelWrapper .confirmButton").on("click", async () => {
}
});
$(document).on("keydown", (event) => {
if (event.key === "Escape" && isPopupVisible(wrapperId)) {
hide();
event.preventDefault();
}
});
Skeleton.save(wrapperId);

View file

@ -51,6 +51,7 @@ ConfigEvent.subscribe((eventKey, eventValue, nosave) => {
}
if (eventKey === "fontSize" && !nosave) {
updateWordsHeight(true);
updateWordsInputPosition(true);
}
if (eventValue === undefined || typeof eventValue !== "boolean") return;
@ -137,8 +138,8 @@ export function updateActiveElement(
});
}
} catch (e) {}
if (initial || shouldUpdateWordsInputPosition()) {
updateWordsInputPosition(initial);
if (!initial && shouldUpdateWordsInputPosition()) {
updateWordsInputPosition();
}
}
@ -220,8 +221,21 @@ export function updateWordsInputPosition(initial = false): void {
return;
}
const computed = window.getComputedStyle(activeWord);
const activeWordMargin =
parseInt(computed.marginTop) + parseInt(computed.marginBottom);
const wordsWrapperTop =
(document.querySelector("#wordsWrapper") as HTMLElement | null)
?.offsetTop || 0;
if (Config.tapeMode !== "off") {
el.style.top = activeWord.offsetTop + "px";
el.style.top =
wordsWrapperTop +
activeWord.offsetHeight +
activeWordMargin * 0.25 +
-el.offsetHeight +
"px";
el.style.left = activeWord.offsetLeft + "px";
return;
}
@ -231,10 +245,22 @@ export function updateWordsInputPosition(initial = false): void {
!posUpdateLangList.some((l) => Config.language.startsWith(l))
) {
el.style.left = "0px";
el.style.top = activeWord.offsetHeight * 2 + "px";
el.style.top =
wordsWrapperTop +
activeWord.offsetHeight * 2 +
activeWordMargin * 1.5 +
-el.offsetHeight +
"px";
} else {
el.style.top = activeWord.offsetTop + "px";
el.style.left = activeWord.offsetLeft + "px";
el.style.top =
activeWord.offsetTop -
activeWordMargin +
wordsWrapperTop +
activeWord.offsetHeight +
activeWordMargin +
-el.offsetHeight +
"px";
}
}
@ -985,7 +1011,7 @@ export function toggleResultWords(): void {
}
}
export function applyBurstHeatmap(): void {
export async function applyBurstHeatmap(): Promise<void> {
if (Config.burstHeatmap) {
$("#resultWordsHistory .heatmapLegend").removeClass("hidden");
@ -1007,26 +1033,39 @@ export function applyBurstHeatmap(): void {
adatm.push(Math.abs(median - burst));
});
const step = Misc.mean(adatm);
const themeColors = await ThemeColors.getAll();
const colors = [
themeColors.colorfulError,
Misc.blendTwoHexColors(themeColors.colorfulError, themeColors.text),
themeColors.text,
Misc.blendTwoHexColors(themeColors.main, themeColors.text),
themeColors.main,
];
const unreachedColor = themeColors.sub;
const steps = [
{
val: 0,
class: "heatmap0",
colorId: 0,
},
{
val: median - step * 1.5,
class: "heatmap1",
colorId: 1,
},
{
val: median - step * 0.5,
class: "heatmap2",
colorId: 2,
},
{
val: median + step * 0.5,
class: "heatmap3",
colorId: 3,
},
{
val: median + step * 1.5,
class: "heatmap4",
colorId: 4,
},
];
@ -1048,26 +1087,29 @@ export function applyBurstHeatmap(): void {
});
$("#resultWordsHistory .words .word").each((_, word) => {
let cls = "";
const wordBurstAttr = $(word).attr("burst");
if (wordBurstAttr === undefined) {
cls = "unreached";
$(word).css("color", unreachedColor);
} else {
const wordBurstVal = parseInt(<string>wordBurstAttr);
steps.forEach((step) => {
if (wordBurstVal >= step.val) cls = step.class;
if (wordBurstVal >= step.val) {
$(word).addClass("heatmapInherit");
$(word).css("color", colors[step.colorId]);
}
});
}
$(word).addClass(cls);
});
$("#resultWordsHistory .heatmapLegend .boxes .box").each((index, box) => {
$(box).css("background", colors[index]);
});
} else {
$("#resultWordsHistory .heatmapLegend").addClass("hidden");
$("#resultWordsHistory .words .word").removeClass("heatmap0");
$("#resultWordsHistory .words .word").removeClass("heatmap1");
$("#resultWordsHistory .words .word").removeClass("heatmap2");
$("#resultWordsHistory .words .word").removeClass("heatmap3");
$("#resultWordsHistory .words .word").removeClass("heatmap4");
$("#resultWordsHistory .words .word").removeClass("unreached");
$("#resultWordsHistory .words .word").removeClass("heatmapInherit");
$("#resultWordsHistory .words .word").css("color", "");
$("#resultWordsHistory .heatmapLegend .boxes .box").css("color", "");
}
}

View file

@ -1,4 +1,5 @@
import * as Loader from "../elements/loader";
import { normal as normalBlend } from "color-blend";
async function fetchJson<T>(url: string): Promise<T> {
try {
@ -235,6 +236,62 @@ export async function getContributorsList(): Promise<string[]> {
}
}
export function blendTwoHexColors(color1: string, color2: string): string {
const rgb1 = hexToRgb(color1);
const rgb2 = hexToRgb(color2);
if (rgb1 && rgb2) {
const rgba1 = {
r: rgb1.r,
g: rgb1.g,
b: rgb1.b,
a: 1,
};
const rgba2 = {
r: rgb2.r,
g: rgb2.g,
b: rgb2.b,
a: 0.5,
};
const blended = normalBlend(rgba1, rgba2);
console.log(blended);
return rgbToHex(blended.r, blended.g, blended.b);
} else {
return "#000000";
}
}
function hexToRgb(hex: string):
| {
r: number;
g: number;
b: number;
}
| undefined {
if (hex.length != 4 && hex.length != 7 && !hex.startsWith("#")) {
return undefined;
}
let r: number;
let g: number;
let b: number;
if (hex.length == 4) {
r = ("0x" + hex[1] + hex[1]) as unknown as number;
g = ("0x" + hex[2] + hex[2]) as unknown as number;
b = ("0x" + hex[3] + hex[3]) as unknown as number;
} else if (hex.length == 7) {
r = ("0x" + hex[1] + hex[2]) as unknown as number;
g = ("0x" + hex[3] + hex[4]) as unknown as number;
b = ("0x" + hex[5] + hex[6]) as unknown as number;
} else {
return undefined;
}
return { r, g, b };
}
function rgbToHex(r: number, g: number, b: number): string {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
function hexToHSL(hex: string): {
hue: number;
sat: number;

View file

@ -113,20 +113,20 @@
<i class="fas fa-mouse-pointer"></i>
Click here or start typing to focus
</div>
<input
id="wordsInput"
class=""
tabindex="0"
type="text"
autocomplete="off"
autocapitalize="off"
autocorrect="off"
data-gramm="false"
data-gramm_editor="false"
data-enable-grammarly="false"
list="autocompleteOff"
/>
<div id="wordsWrapper" translate="no">
<input
id="wordsInput"
class=""
tabindex="0"
type="text"
autocomplete="off"
autocapitalize="off"
autocorrect="off"
data-gramm="false"
data-gramm_editor="false"
data-enable-grammarly="false"
list="autocompleteOff"
/>
<div id="paceCaret" class="default hidden"></div>
<div id="caret" class="default"></div>
<div id="words"></div>

View file

@ -46,6 +46,7 @@
"rawset",
"require",
"select",
"self",
"setfenv",
"setmetatable",
"tonumber",

View file

@ -1660,7 +1660,7 @@
{
"id": 279,
"source": "Кундера Милан - Неспешность",
"text": "Дружба необходима человеку для того, чтобы у него как следует работала память. Помнить о своём прошлом, вечно хранить его в душe - таково необходимое условие, позволяющее нам, как говорится, сберечь цельность нашего \"я\". Чтобы это \"я\" не съёживалось, не утрачивало своей полноты, его нужно орошать воспоминаниями, как горшок с цветами, а такая поливка невозможна без постоянного общения со свидетелями прошлого, то есть с друзьями. Они - наше зеркало, наша память; от них требуется лишь одно - хотя бы время от времени протирать это зеркало, чтобы мы могли в него смотреться.",
"text": "Дружба необходима человеку для того, чтобы у него как следует работала память. Помнить о своём прошлом, вечно хранить его в душе - таково необходимое условие, позволяющее нам, как говорится, сберечь цельность нашего \"я\". Чтобы это \"я\" не съёживалось, не утрачивало своей полноты, его нужно орошать воспоминаниями, как горшок с цветами, а такая поливка невозможна без постоянного общения со свидетелями прошлого, то есть с друзьями. Они - наше зеркало, наша память; от них требуется лишь одно - хотя бы время от времени протирать это зеркало, чтобы мы могли в него смотреться.",
"length": 575
},
{