Fix custom color backup import/export
This commit is contained in:
parent
734929f74f
commit
c7dc4279a1
8 changed files with 96 additions and 31 deletions
|
@ -110,7 +110,7 @@ import {
|
||||||
AdhocCallStatus,
|
AdhocCallStatus,
|
||||||
} from '../../types/CallDisposition';
|
} from '../../types/CallDisposition';
|
||||||
import { isAciString } from '../../util/isAciString';
|
import { isAciString } from '../../util/isAciString';
|
||||||
import { hslToRGB } from '../../util/hslToRGB';
|
import { hslToRGBInt } from '../../util/hslToRGB';
|
||||||
import type { AboutMe, LocalChatStyle } from './types';
|
import type { AboutMe, LocalChatStyle } from './types';
|
||||||
import { BackupType } from './types';
|
import { BackupType } from './types';
|
||||||
import { messageHasPaymentEvent } from '../../messages/helpers';
|
import { messageHasPaymentEvent } from '../../messages/helpers';
|
||||||
|
@ -2588,10 +2588,10 @@ export class BackupExportStream extends Readable {
|
||||||
const id = Long.fromNumber(result.length + 1);
|
const id = Long.fromNumber(result.length + 1);
|
||||||
this.customColorIdByUuid.set(uuid, id);
|
this.customColorIdByUuid.set(uuid, id);
|
||||||
|
|
||||||
const start = hslToRGBInt(
|
const start = desktopHslToRgbInt(
|
||||||
color.start.hue,
|
color.start.hue,
|
||||||
color.start.saturation,
|
color.start.saturation,
|
||||||
color.start.luminance
|
color.start.lightness
|
||||||
);
|
);
|
||||||
|
|
||||||
if (color.end == null) {
|
if (color.end == null) {
|
||||||
|
@ -2600,10 +2600,10 @@ export class BackupExportStream extends Readable {
|
||||||
solid: start,
|
solid: start,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const end = hslToRGBInt(
|
const end = desktopHslToRgbInt(
|
||||||
color.end.hue,
|
color.end.hue,
|
||||||
color.end.saturation,
|
color.end.saturation,
|
||||||
color.end.luminance
|
color.end.lightness
|
||||||
);
|
);
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
|
@ -2776,10 +2776,13 @@ function checkServiceIdEquivalence(
|
||||||
return leftConvo && rightConvo && leftConvo === rightConvo;
|
return leftConvo && rightConvo && leftConvo === rightConvo;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hslToRGBInt(hue: number, saturation: number, luminance = 1): number {
|
function desktopHslToRgbInt(
|
||||||
const { r, g, b } = hslToRGB(hue, saturation, luminance);
|
hue: number,
|
||||||
// eslint-disable-next-line no-bitwise
|
saturation: number,
|
||||||
return ((0xff << 24) | (r << 16) | (g << 8) | b) >>> 0;
|
lightness = 1
|
||||||
|
): number {
|
||||||
|
// Desktop stores saturation not as 0.123 (0 to 1.0) but 12.3 (percentage)
|
||||||
|
return hslToRGBInt(hue, saturation / 100, lightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toGroupCallStateProto(state: CallStatus): Backups.GroupCall.State {
|
function toGroupCallStateProto(state: CallStatus): Backups.GroupCall.State {
|
||||||
|
|
|
@ -89,7 +89,7 @@ import type { GroupV2ChangeDetailType } from '../../groups';
|
||||||
import { queueAttachmentDownloads } from '../../util/queueAttachmentDownloads';
|
import { queueAttachmentDownloads } from '../../util/queueAttachmentDownloads';
|
||||||
import { isNotNil } from '../../util/isNotNil';
|
import { isNotNil } from '../../util/isNotNil';
|
||||||
import { isGroup } from '../../util/whatTypeOfConversation';
|
import { isGroup } from '../../util/whatTypeOfConversation';
|
||||||
import { rgbToHSL } from '../../util/rgbToHSL';
|
import { rgbIntToHSL } from '../../util/rgbToHSL';
|
||||||
import {
|
import {
|
||||||
convertBackupMessageAttachmentToAttachment,
|
convertBackupMessageAttachmentToAttachment,
|
||||||
convertFilePointerToAttachment,
|
convertFilePointerToAttachment,
|
||||||
|
@ -3061,7 +3061,7 @@ export class BackupImportStream extends Writable {
|
||||||
|
|
||||||
if (color.solid) {
|
if (color.solid) {
|
||||||
value = {
|
value = {
|
||||||
start: rgbIntToHSL(color.solid),
|
start: rgbIntToDesktopHSL(color.solid),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
strictAssert(color.gradient != null, 'Either solid or gradient');
|
strictAssert(color.gradient != null, 'Either solid or gradient');
|
||||||
|
@ -3076,8 +3076,8 @@ export class BackupImportStream extends Writable {
|
||||||
strictAssert(deg != null, 'Missing angle');
|
strictAssert(deg != null, 'Missing angle');
|
||||||
|
|
||||||
value = {
|
value = {
|
||||||
start: rgbIntToHSL(start),
|
start: rgbIntToDesktopHSL(start),
|
||||||
end: rgbIntToHSL(end),
|
end: rgbIntToDesktopHSL(end),
|
||||||
deg,
|
deg,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3226,20 +3226,15 @@ export class BackupImportStream extends Writable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function rgbIntToHSL(intValue: number): {
|
function rgbIntToDesktopHSL(intValue: number): {
|
||||||
hue: number;
|
hue: number;
|
||||||
saturation: number;
|
saturation: number;
|
||||||
luminance: number;
|
lightness: number;
|
||||||
} {
|
} {
|
||||||
// eslint-disable-next-line no-bitwise
|
const { h: hue, s: saturation, l: lightness } = rgbIntToHSL(intValue);
|
||||||
const r = (intValue >>> 16) & 0xff;
|
|
||||||
// eslint-disable-next-line no-bitwise
|
|
||||||
const g = (intValue >>> 8) & 0xff;
|
|
||||||
// eslint-disable-next-line no-bitwise
|
|
||||||
const b = intValue & 0xff;
|
|
||||||
const { h: hue, s: saturation, l: luminance } = rgbToHSL(r, g, b);
|
|
||||||
|
|
||||||
return { hue, saturation, luminance };
|
// Desktop stores saturation not as 0.123 (0 to 1.0) but 12.3 (percentage)
|
||||||
|
return { hue, saturation: saturation * 100, lightness };
|
||||||
}
|
}
|
||||||
|
|
||||||
function fromGroupCallStateProto(
|
function fromGroupCallStateProto(
|
||||||
|
|
35
ts/test-node/util/hslToRGB_test.ts
Normal file
35
ts/test-node/util/hslToRGB_test.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2024 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { assert } from 'chai';
|
||||||
|
|
||||||
|
import { hslToRGB, hslToRGBInt } from '../../util/hslToRGB';
|
||||||
|
|
||||||
|
describe('hslToRGB', () => {
|
||||||
|
it('converts pure rgb colors', () => {
|
||||||
|
assert.deepStrictEqual(hslToRGB(0, 1, 0.5), { r: 255, g: 0, b: 0 });
|
||||||
|
assert.deepStrictEqual(hslToRGB(120, 1, 0.5), { r: 0, g: 255, b: 0 });
|
||||||
|
assert.deepStrictEqual(hslToRGB(240, 1, 0.5), { r: 0, g: 0, b: 255 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts random sampled hsl colors', () => {
|
||||||
|
assert.deepStrictEqual(hslToRGB(50, 0.233333, 0.41), {
|
||||||
|
r: 129,
|
||||||
|
g: 121,
|
||||||
|
b: 80,
|
||||||
|
});
|
||||||
|
assert.deepStrictEqual(hslToRGB(170, 0.97, 0.1), {
|
||||||
|
r: 1,
|
||||||
|
g: 50,
|
||||||
|
b: 42,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hslToRGBInt', () => {
|
||||||
|
it('converts pure rgb colors', () => {
|
||||||
|
assert.equal(hslToRGBInt(0, 1, 0.5), 4294901760);
|
||||||
|
assert.equal(hslToRGBInt(120, 1, 0.5), 4278255360);
|
||||||
|
assert.equal(hslToRGBInt(240, 1, 0.5), 4278190335);
|
||||||
|
});
|
||||||
|
});
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
import { rgbToHSL } from '../../util/rgbToHSL';
|
import { rgbIntToHSL, rgbToHSL } from '../../util/rgbToHSL';
|
||||||
|
|
||||||
describe('rgbToHSL', () => {
|
describe('rgbToHSL', () => {
|
||||||
it('converts pure rgb colors', () => {
|
it('converts pure rgb colors', () => {
|
||||||
|
@ -40,3 +40,11 @@ describe('rgbToHSL', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('rgbIntToHSL', () => {
|
||||||
|
it('converts pure rgb colors', () => {
|
||||||
|
assert.deepStrictEqual(rgbIntToHSL(4294901760), { h: 0, s: 1, l: 0.5 });
|
||||||
|
assert.deepStrictEqual(rgbIntToHSL(4278255360), { h: 120, s: 1, l: 0.5 });
|
||||||
|
assert.deepStrictEqual(rgbIntToHSL(4278190335), { h: 240, s: 1, l: 0.5 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -159,8 +159,8 @@ export const ContactNameColors = [
|
||||||
export type ContactNameColorType = (typeof ContactNameColors)[number];
|
export type ContactNameColorType = (typeof ContactNameColors)[number];
|
||||||
|
|
||||||
export type CustomColorType = {
|
export type CustomColorType = {
|
||||||
start: { hue: number; saturation: number; luminance?: number };
|
start: { hue: number; saturation: number; lightness?: number };
|
||||||
end?: { hue: number; saturation: number; luminance?: number };
|
end?: { hue: number; saturation: number; lightness?: number };
|
||||||
deg?: number;
|
deg?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,17 +46,17 @@ export function getHSL(
|
||||||
{
|
{
|
||||||
hue,
|
hue,
|
||||||
saturation,
|
saturation,
|
||||||
luminance,
|
lightness,
|
||||||
}: {
|
}: {
|
||||||
hue: number;
|
hue: number;
|
||||||
saturation: number;
|
saturation: number;
|
||||||
luminance?: number;
|
lightness?: number;
|
||||||
},
|
},
|
||||||
adjustedLightness = 0
|
adjustedLightness = 0
|
||||||
): string {
|
): string {
|
||||||
return `hsl(${hue}, ${saturation}%, ${
|
return `hsl(${hue}, ${saturation}%, ${
|
||||||
luminance == null
|
lightness == null
|
||||||
? adjustLightnessValue(calculateLightness(hue), adjustedLightness)
|
? adjustLightnessValue(calculateLightness(hue), adjustedLightness)
|
||||||
: luminance * 100
|
: lightness * 100
|
||||||
}%)`;
|
}%)`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,3 +24,13 @@ export function hslToRGB(
|
||||||
b: Math.round(255 * f(4)),
|
b: Math.round(255 * f(4)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function hslToRGBInt(
|
||||||
|
hue: number,
|
||||||
|
saturation: number,
|
||||||
|
lightness: number
|
||||||
|
): number {
|
||||||
|
const { r, g, b } = hslToRGB(hue, saturation, lightness);
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
return ((0xff << 24) | (r << 16) | (g << 8) | b) >>> 0;
|
||||||
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ export function rgbToHSL(
|
||||||
if (c === 0) {
|
if (c === 0) {
|
||||||
h = 0;
|
h = 0;
|
||||||
} else if (v === rn) {
|
} else if (v === rn) {
|
||||||
h = 60 * (((gn - bn) / c) % 6);
|
h = 60 * (((gn - bn) / c + 6) % 6);
|
||||||
} else if (v === gn) {
|
} else if (v === gn) {
|
||||||
h = 60 * ((bn - rn) / c + 2);
|
h = 60 * ((bn - rn) / c + 2);
|
||||||
} else {
|
} else {
|
||||||
|
@ -43,3 +43,17 @@ export function rgbToHSL(
|
||||||
|
|
||||||
return { h, s, l };
|
return { h, s, l };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function rgbIntToHSL(intValue: number): {
|
||||||
|
h: number;
|
||||||
|
s: number;
|
||||||
|
l: number;
|
||||||
|
} {
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
const r = (intValue >>> 16) & 0xff;
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
const g = (intValue >>> 8) & 0xff;
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
const b = intValue & 0xff;
|
||||||
|
return rgbToHSL(r, g, b);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue