ProxmoxVED/misc/msg.func
2025-05-05 15:58:10 +02:00

99 lines
2.1 KiB
Bash

#!/usr/bin/env bash
# Spinner state
declare -A SPINNER_PIDS
declare -A SPINNER_MSGS
declare -A MSG_SHOWN
# Color definitions (adjust as needed)
RD='\033[0;31m'
GN='\033[0;32m'
YW='\033[0;33m'
CL='\033[0m'
CM='✔'
CROSS='✘'
# Trap cleanup
trap cleanup_spinners EXIT INT TERM HUP
# Hash function for message ID
msg_hash() {
local input="$1"
echo -n "$input" | sha1sum | awk '{print $1}'
}
# Start a spinner for a specific message
start_spinner_for_msg() {
local msg="$1"
local id
id=$(msg_hash "$msg")
[[ -n "${MSG_SHOWN["$id"]+x}" ]] && return
MSG_SHOWN["$id"]=1
SPINNER_MSGS["$id"]="$msg"
local frames=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏)
local interval=0.1
local spin_i=0
{
while true; do
printf "\r\e[2K%s %b" "${frames[spin_i]}" "${YW}${msg}${CL}" >&2
spin_i=$(((spin_i + 1) % ${#frames[@]}))
sleep "$interval"
done
} &
SPINNER_PIDS["$id"]=$!
disown "${SPINNER_PIDS["$id"]}"
}
# Stop the spinner for a specific message
stop_spinner_for_msg() {
local msg="$1"
local id
id=$(msg_hash "$msg")
if [[ -n "${SPINNER_PIDS["$id"]+x}" ]] && ps -p "${SPINNER_PIDS["$id"]}" >/dev/null 2>&1; then
kill "${SPINNER_PIDS["$id"]}" 2>/dev/null
wait "${SPINNER_PIDS["$id"]}" 2>/dev/null || true
fi
unset SPINNER_PIDS["$id"]
unset SPINNER_MSGS["$id"]
unset MSG_SHOWN["$id"]
}
# Cleanup all active spinners
cleanup_spinners() {
for id in "${!SPINNER_PIDS[@]}"; do
if ps -p "${SPINNER_PIDS[$id]}" >/dev/null 2>&1; then
kill "${SPINNER_PIDS[$id]}" 2>/dev/null
wait "${SPINNER_PIDS[$id]}" 2>/dev/null || true
fi
unset SPINNER_PIDS["$id"]
unset SPINNER_MSGS["$id"]
unset MSG_SHOWN["$id"]
done
}
# Show info message with spinner
msg_info() {
local msg="$1"
start_spinner_for_msg "$msg"
}
# End spinner and show success message
msg_ok() {
local msg="$1"
stop_spinner_for_msg "$msg"
printf "\r\e[2K%s %b\n" "${CM}" "${GN}${msg}${CL}" >&2
}
# End spinner and show error message
msg_error() {
local msg="$1"
stop_spinner_for_msg "$msg"
printf "\r\e[2K%s %b\n" "${CROSS}" "${RD}${msg}${CL}" >&2
}