Removing Focalboard from the catalogue left its icon still being served: the sync only ever ADDS, so every app ever dropped leaves a file behind that the portal keeps offering for something that is gone. Same shape as the task queue that only ever appended. webuiPruneAppIcons runs at the end of the sync and removes only icons it can match to a missing template — anything else in the directory is left alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
85 lines
3.3 KiB
Bash
Executable File
85 lines
3.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Sync app icons from container template dirs to the LibrePortal frontend.
|
|
#
|
|
# apps.json references /core/icons/apps/<app>.<ext> 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="${containers_dir}libreportal/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="${containers_dir}libreportal/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
|
|
}
|