{ lib, pkgs, cfg, models }: let # Collect unique (desktopSize, thumbnailSize) pairs from provisioned phone models sizeConfigs = lib.unique (lib.filter (s: s.desktop != null) (lib.mapAttrsToList (_: phone: let m = models.${phone.model}; in { desktop = m.desktopSize; thumbnail = m.thumbnailSize; } ) cfg.phones)); # Parse "WxH" or "WxHxD" into width and height parseDimensions = size: let parts = lib.splitString "x" size; in { w = lib.elemAt parts 0; h = lib.elemAt parts 1; }; # Build a resized image derivation resizeImage = { src, width, height, name }: pkgs.runCommand name { nativeBuildInputs = [ pkgs.imagemagick ]; } '' convert "${src}" -resize ${width}x${height}! -strip PNG24:$out ''; in lib.concatMap (sc: let size = sc.desktop; dim = parseDimensions size; tn = parseDimensions sc.thumbnail; listXml = '' '' + lib.concatStringsSep "\n" (lib.imap1 (i: name: '' '') (lib.attrNames cfg.backgroundImages)) + '' ''; listFile = pkgs.writeText "List.xml" listXml; in [{ name = "Desktops/${size}/List.xml"; path = listFile; }] ++ lib.concatLists (lib.imap1 (i: name: let src = cfg.backgroundImages.${name}; in [ { name = "Desktops/${size}/bg-${toString i}.png"; path = resizeImage { inherit src; width = dim.w; height = dim.h; name = "bg-${toString i}.png"; }; } { name = "Desktops/${size}/tn-${toString i}.png"; path = resizeImage { inherit src; width = tn.w; height = tn.h; name = "tn-${toString i}.png"; }; } ] ) (lib.attrNames cfg.backgroundImages)) ) sizeConfigs