#!/bin/bash # Sync app icons from container template dirs to the LibrePortal frontend. # # apps.json references /core/icons/apps/. unconditionally (see # webui_config.sh), so the icon file must physically exist in the frontend # icons dir or the apps page falls back to the default icon. # Copy a single app's icon into the frontend icons dir. Returns 0 if an # icon was copied, 1 if the app has no icon (or no app name given). # Idempotent — cheap enough to call on every install/uninstall. webuiSyncAppIcon() { local app_name="$1" [[ -z "$app_name" ]] && return 1 local icons_dir="$(webuiDir)/frontend/core/icons/apps" runFileOp mkdir -p "$icons_dir" # Icons live in the install template dir — copy_build_context.sh # excludes *.svg from the install→deployed copy, so the deployed # container dir can't be relied on as the source. local src_dir="${install_containers_dir}/${app_name}" local ext for ext in svg png; do local src="${src_dir}/${app_name}.${ext}" if [[ -f "$src" ]]; then # cp to a temp name then mv so the webserver never serves a # half-written file. local dest="${icons_dir}/${app_name}.${ext}" if runFileWrite "${dest}.tmp.$$" < "$src" 2>/dev/null; then runFileOp mv "${dest}.tmp.$$" "$dest" 2>/dev/null fi return 0 fi done return 1 } # Sync every app's icon. Used by the full WebUI update pass. webuiSyncAppIcons() { echo "Syncing app icons from installed containers to LibrePortal frontend..." if [ -d "$install_containers_dir" ]; then find "$install_containers_dir" -maxdepth 1 -type d -not -path "$install_containers_dir" | while read -r dir; do local app_name app_name=$(basename "$dir") if webuiSyncAppIcon "$app_name"; then echo "✅ Copied icon for $app_name" else echo "⚠️ No icon found for $app_name" fi done else echo "❌ Install containers directory not found: $install_containers_dir" fi webuiPruneAppIcons echo "Icon sync completed!" } # Drop icons whose app template no longer exists. The sync above only ever # ADDS, so removing an app from the catalogue left its icon being served # forever — harmless-looking, but it is a file the portal keeps offering for # something that is gone, and they accumulate release after release. # Only ever removes icons it can match to a missing template, never anything # else in the directory. webuiPruneAppIcons() { local icons_dir="$(webuiDir)/frontend/core/icons/apps" [[ -d "$icons_dir" ]] || return 0 [[ -d "$install_containers_dir" ]] || return 0 local f base app removed=0 while IFS= read -r f; do [[ -n "$f" ]] || continue base="$(basename "$f")" app="${base%.*}" # Keep anything whose template is still present. [[ -d "${install_containers_dir}/${app}" ]] && continue runFileOp rm -f "$f" 2>/dev/null && removed=$((removed + 1)) echo "🧹 Removed orphaned icon for $app" done < <(runFileOp find "$icons_dir" -maxdepth 1 -type f \( -name '*.svg' -o -name '*.png' \) 2>/dev/null) (( removed > 0 )) && echo "Pruned $removed orphaned icon(s)." return 0 }