atagen

malice

public
Star0
Watch0
e99ada4450ecaa8f2bbfb50cf78be269cefa8752
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git

Blame: web/src/lib/pack-preferences-model.ts

132eeceeb362atagen2026-10-25 03:34 UTC1
import type { ImagePack, QuickReaction } from './types';
132eeceeb362atagen2026-10-25 03:34 UTC2
132eeceeb362atagen2026-10-25 03:34 UTC3
export type DisabledPackImages = Record<string, string[]>;
132eeceeb362atagen2026-10-25 03:34 UTC4
132eeceeb362atagen2026-10-25 03:34 UTC5
function isRecord(value: unknown): value is Record<string, unknown> {
132eeceeb362atagen2026-10-25 03:34 UTC6
  return typeof value === 'object' && value !== null && !Array.isArray(value);
132eeceeb362atagen2026-10-25 03:34 UTC7
}
132eeceeb362atagen2026-10-25 03:34 UTC8
132eeceeb362atagen2026-10-25 03:34 UTC9
function setOwn<T>(record: Record<string, T>, key: string, value: T): void {
132eeceeb362atagen2026-10-25 03:34 UTC10
  Object.defineProperty(record, key, {
132eeceeb362atagen2026-10-25 03:34 UTC11
    configurable: true,
132eeceeb362atagen2026-10-25 03:34 UTC12
    enumerable: true,
132eeceeb362atagen2026-10-25 03:34 UTC13
    value,
132eeceeb362atagen2026-10-25 03:34 UTC14
    writable: true
132eeceeb362atagen2026-10-25 03:34 UTC15
  });
132eeceeb362atagen2026-10-25 03:34 UTC16
}
132eeceeb362atagen2026-10-25 03:34 UTC17
132eeceeb362atagen2026-10-25 03:34 UTC18
function hasOwn(record: object, key: string): boolean {
132eeceeb362atagen2026-10-25 03:34 UTC19
  return Object.prototype.hasOwnProperty.call(record, key);
132eeceeb362atagen2026-10-25 03:34 UTC20
}
132eeceeb362atagen2026-10-25 03:34 UTC21
132eeceeb362atagen2026-10-25 03:34 UTC22
export function parseDisabledPackImages(raw: unknown): DisabledPackImages {
132eeceeb362atagen2026-10-25 03:34 UTC23
  if (!isRecord(raw) || !isRecord(raw['disabled'])) return {};
132eeceeb362atagen2026-10-25 03:34 UTC24
  const disabled: DisabledPackImages = {};
132eeceeb362atagen2026-10-25 03:34 UTC25
  for (const [packId, rawShortcodes] of Object.entries(raw['disabled'])) {
132eeceeb362atagen2026-10-25 03:34 UTC26
    if (!Array.isArray(rawShortcodes)) continue;
132eeceeb362atagen2026-10-25 03:34 UTC27
    const seen = new Set<string>();
132eeceeb362atagen2026-10-25 03:34 UTC28
    const shortcodes = rawShortcodes.filter((value): value is string => {
132eeceeb362atagen2026-10-25 03:34 UTC29
      if (typeof value !== 'string' || value.length === 0 || seen.has(value)) return false;
132eeceeb362atagen2026-10-25 03:34 UTC30
      seen.add(value);
132eeceeb362atagen2026-10-25 03:34 UTC31
      return true;
132eeceeb362atagen2026-10-25 03:34 UTC32
    });
132eeceeb362atagen2026-10-25 03:34 UTC33
    if (shortcodes.length > 0) setOwn(disabled, packId, shortcodes);
132eeceeb362atagen2026-10-25 03:34 UTC34
  }
132eeceeb362atagen2026-10-25 03:34 UTC35
  return disabled;
132eeceeb362atagen2026-10-25 03:34 UTC36
}
132eeceeb362atagen2026-10-25 03:34 UTC37
132eeceeb362atagen2026-10-25 03:34 UTC38
export function imageEnabled(disabled: DisabledPackImages, packId: string, shortcode: string): boolean {
132eeceeb362atagen2026-10-25 03:34 UTC39
  return !hasOwn(disabled, packId) || !disabled[packId].includes(shortcode);
132eeceeb362atagen2026-10-25 03:34 UTC40
}
132eeceeb362atagen2026-10-25 03:34 UTC41
132eeceeb362atagen2026-10-25 03:34 UTC42
export function withImageEnabled(
132eeceeb362atagen2026-10-25 03:34 UTC43
  disabled: DisabledPackImages,
132eeceeb362atagen2026-10-25 03:34 UTC44
  packId: string,
132eeceeb362atagen2026-10-25 03:34 UTC45
  shortcode: string,
132eeceeb362atagen2026-10-25 03:34 UTC46
  enabled: boolean
132eeceeb362atagen2026-10-25 03:34 UTC47
): DisabledPackImages {
132eeceeb362atagen2026-10-25 03:34 UTC48
  const current = hasOwn(disabled, packId) ? disabled[packId] : [];
132eeceeb362atagen2026-10-25 03:34 UTC49
  const nextShortcodes = enabled
132eeceeb362atagen2026-10-25 03:34 UTC50
    ? current.filter((item) => item !== shortcode)
132eeceeb362atagen2026-10-25 03:34 UTC51
    : current.includes(shortcode) ? [...current] : [...current, shortcode];
132eeceeb362atagen2026-10-25 03:34 UTC52
  if (nextShortcodes.length === current.length && nextShortcodes.every((item, index) => item === current[index])) {
132eeceeb362atagen2026-10-25 03:34 UTC53
    return disabled;
132eeceeb362atagen2026-10-25 03:34 UTC54
  }
132eeceeb362atagen2026-10-25 03:34 UTC55
  const next = { ...disabled };
132eeceeb362atagen2026-10-25 03:34 UTC56
  if (nextShortcodes.length === 0) delete next[packId];
132eeceeb362atagen2026-10-25 03:34 UTC57
  else setOwn(next, packId, nextShortcodes);
132eeceeb362atagen2026-10-25 03:34 UTC58
  return next;
132eeceeb362atagen2026-10-25 03:34 UTC59
}
132eeceeb362atagen2026-10-25 03:34 UTC60
132eeceeb362atagen2026-10-25 03:34 UTC61
export function enabledPacks(packs: ImagePack[], disabled: DisabledPackImages): ImagePack[] {
132eeceeb362atagen2026-10-25 03:34 UTC62
  return packs.map((pack) => ({
132eeceeb362atagen2026-10-25 03:34 UTC63
    ...pack,
132eeceeb362atagen2026-10-25 03:34 UTC64
    images: pack.images.filter((image) => imageEnabled(disabled, pack.id, image.shortcode))
132eeceeb362atagen2026-10-25 03:34 UTC65
  }));
132eeceeb362atagen2026-10-25 03:34 UTC66
}
132eeceeb362atagen2026-10-25 03:34 UTC67
132eeceeb362atagen2026-10-25 03:34 UTC68
export function enabledQuickReactions(
132eeceeb362atagen2026-10-25 03:34 UTC69
  quick: QuickReaction[],
132eeceeb362atagen2026-10-25 03:34 UTC70
  packs: ImagePack[],
132eeceeb362atagen2026-10-25 03:34 UTC71
  disabled: DisabledPackImages
132eeceeb362atagen2026-10-25 03:34 UTC72
): QuickReaction[] {
132eeceeb362atagen2026-10-25 03:34 UTC73
  const hidden = new Set<string>();
132eeceeb362atagen2026-10-25 03:34 UTC74
  const enabled = new Set<string>();
132eeceeb362atagen2026-10-25 03:34 UTC75
  for (const pack of packs) {
132eeceeb362atagen2026-10-25 03:34 UTC76
    for (const image of pack.images) {
132eeceeb362atagen2026-10-25 03:34 UTC77
      (imageEnabled(disabled, pack.id, image.shortcode) ? enabled : hidden).add(image.reaction_key);
132eeceeb362atagen2026-10-25 03:34 UTC78
    }
132eeceeb362atagen2026-10-25 03:34 UTC79
  }
132eeceeb362atagen2026-10-25 03:34 UTC80
  return quick.filter((reaction) => !hidden.has(reaction.key) || enabled.has(reaction.key));
132eeceeb362atagen2026-10-25 03:34 UTC81
}