Preserve custom chat color order in backup

This commit is contained in:
Fedor Indutny 2024-09-10 14:07:55 -07:00 committed by GitHub
parent 989659028a
commit eab5f7762a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 36 additions and 1 deletions

View file

@ -20,6 +20,7 @@ import {
import type { PageMessagesCursorType } from '../../sql/Interface'; import type { PageMessagesCursorType } from '../../sql/Interface';
import * as log from '../../logging/log'; import * as log from '../../logging/log';
import { GiftBadgeStates } from '../../components/conversation/Message'; import { GiftBadgeStates } from '../../components/conversation/Message';
import { type CustomColorType } from '../../types/Colors';
import { StorySendMode, MY_STORY_ID } from '../../types/Stories'; import { StorySendMode, MY_STORY_ID } from '../../types/Stories';
import { import {
isPniString, isPniString,
@ -37,6 +38,7 @@ import type {
QuotedMessageType, QuotedMessageType,
} from '../../model-types.d'; } from '../../model-types.d';
import { drop } from '../../util/drop'; import { drop } from '../../util/drop';
import { isNotNil } from '../../util/isNotNil';
import { explodePromise } from '../../util/explodePromise'; import { explodePromise } from '../../util/explodePromise';
import { import {
isDirectConversation, isDirectConversation,
@ -2405,8 +2407,29 @@ export class BackupExportStream extends Readable {
return []; return [];
} }
const result = new Array<Backups.ChatStyle.ICustomChatColor>(); const { order = [] } = customColors;
const map = new Map(
order
.map((id: string): [string, CustomColorType] | undefined => {
const color = customColors.colors[id];
if (color == null) {
return undefined;
}
return [id, color];
})
.filter(isNotNil)
);
// Add colors not present in the order list
for (const [uuid, color] of Object.entries(customColors.colors)) { for (const [uuid, color] of Object.entries(customColors.colors)) {
if (map.has(uuid)) {
continue;
}
map.set(uuid, color);
}
const result = new Array<Backups.ChatStyle.ICustomChatColor>();
for (const [uuid, color] of map.entries()) {
const id = Long.fromNumber(result.length); const id = Long.fromNumber(result.length);
this.customColorIdByUuid.set(uuid, id); this.customColorIdByUuid.set(uuid, id);

View file

@ -2853,15 +2853,19 @@ export class BackupImportStream extends Writable {
return; return;
} }
const order = new Array<string>();
const customColors: CustomColorsItemType = { const customColors: CustomColorsItemType = {
version: 1, version: 1,
colors: {}, colors: {},
order,
}; };
for (const color of customChatColors) { for (const color of customChatColors) {
const uuid = generateUuid(); const uuid = generateUuid();
let value: CustomColorType; let value: CustomColorType;
order.push(uuid);
if (color.solid) { if (color.solid) {
value = { value = {
start: rgbIntToHSL(color.solid), start: rgbIntToHSL(color.solid),

View file

@ -142,6 +142,7 @@ function getDefaultCustomColorData() {
return { return {
colors: {} as Record<string, CustomColorType>, colors: {} as Record<string, CustomColorType>,
version: 1, version: 1,
order: [],
}; };
} }
@ -157,12 +158,17 @@ function addCustomColor(
uuid = getGuid(); uuid = getGuid();
} }
const order = new Set(customColors.order ?? []);
order.delete(uuid);
order.add(uuid);
const nextCustomColors = { const nextCustomColors = {
...customColors, ...customColors,
colors: { colors: {
...customColors.colors, ...customColors.colors,
[uuid]: customColor, [uuid]: customColor,
}, },
order: [...order],
}; };
dispatch(putItem('customColors', nextCustomColors)); dispatch(putItem('customColors', nextCustomColors));
@ -220,6 +226,7 @@ function removeCustomColor(
const nextCustomColors = { const nextCustomColors = {
...customColors, ...customColors,
colors: omit(customColors.colors, payload), colors: omit(customColors.colors, payload),
order: customColors.order?.filter(id => id !== payload),
}; };
dispatch(putItem('customColors', nextCustomColors)); dispatch(putItem('customColors', nextCustomColors));

View file

@ -187,6 +187,7 @@ export const DEFAULT_CONVERSATION_COLOR: DefaultConversationColorType = {
export type CustomColorsItemType = { export type CustomColorsItemType = {
readonly colors: Record<string, CustomColorType>; readonly colors: Record<string, CustomColorType>;
readonly version: number; readonly version: number;
readonly order?: ReadonlyArray<string>;
}; };
export function getAvatarColor(color?: AvatarColorType): AvatarColorType { export function getAvatarColor(color?: AvatarColorType): AvatarColorType {