diff --git a/commands/list.command.sh b/commands/list.command.sh index a7c95a1..956ad91 100644 --- a/commands/list.command.sh +++ b/commands/list.command.sh @@ -283,13 +283,19 @@ function cmd::list::_collect_all_rows() { local status="${state%%|*}" # Resolve last seen - local last_seen="—" + local last_seen="-" if [[ "$is_blocked" == "true" && -n "$last_ts" && "$last_ts" != "0" ]]; then local attempt_ts attempt_ts=$(json::iso_to_ts "$last_ts") - last_seen=$(fmt::datetime_short "$attempt_ts") + last_seen="$(fmt::datetime_short "$attempt_ts") (dropped)" elif [[ -n "$handshake_ts" && "$handshake_ts" != "0" ]]; then - last_seen=$(fmt::datetime_short "$handshake_ts") + local ts_display + ts_display=$(fmt::datetime_short "$handshake_ts") + if [[ "$status" == "online" ]]; then + last_seen="${ts_display} (handshake)" + else + last_seen="$ts_display" + fi fi printf "%s|%s|%s|%s|%s|%s|%s|%s|%s\n" \ @@ -413,7 +419,11 @@ function cmd::list::_render_detailed() { while IFS='|' read -r name ip type rule group status last_seen is_blocked is_restricted; do [[ -z "$name" ]] && continue local subnet - subnet=$(peers::get_meta "$name" "subnet" 2>/dev/null) || subnet="-" + subnet=$(peers::get_meta "$name" "subnet" 2>/dev/null) + if [[ -z "$subnet" ]]; then + local peer_type="${p_types[$name]:-}" + [[ -n "$peer_type" ]] && subnet="$peer_type" + fi [[ -z "$subnet" ]] && subnet="-" ui::peer::list_row_detailed \ "$w_name" "$w_ip" "$w_type" "$w_rule" "$w_group" "$w_subnet" \ @@ -431,8 +441,12 @@ function cmd::list::_render_detailed() { while IFS='|' read -r name ip type rule group status last_seen is_blocked is_restricted; do [[ -z "$name" ]] && continue local subnet - subnet=$(peers::get_meta "$name" "subnet" 2>/dev/null) || subnet="—" - [[ -z "$subnet" ]] && subnet="—" + subnet=$(peers::get_meta "$name" "subnet" 2>/dev/null) + if [[ -z "$subnet" ]]; then + local peer_type="${p_types[$name]:-}" + [[ -n "$peer_type" ]] && subnet="$peer_type" + fi + [[ -z "$subnet" ]] && subnet="-" ui::peer::list_row_detailed \ "$w_name" "$w_ip" "$w_type" "$w_rule" "$w_group" "$w_subnet" \ "$name" "$ip" "$type" "$rule" "$group" "$subnet" \ diff --git a/modules/ui/peer.module.sh b/modules/ui/peer.module.sh index 2772b4f..c16dae2 100644 --- a/modules/ui/peer.module.sh +++ b/modules/ui/peer.module.sh @@ -19,7 +19,7 @@ function ui::peer::list_row_compact() { local name="${1:-}" ip="${2:-}" type="${3:-}" rule="${4:-}" \ group="${5:-}" status="${6:-}" last_seen="${7:-}" \ is_blocked="${8:-false}" is_restricted="${9:-false}" - + local status_color="\033[0;37m" if [[ "$is_blocked" == "true" ]]; then status_color="\033[1;31m" @@ -28,28 +28,25 @@ function ui::peer::list_row_compact() { elif [[ "$status" == "online" ]]; then status_color="\033[1;32m" fi - - local ls_color="\033[0;37m" - [[ "$status" == "online" ]] && ls_color="\033[1;32m" - + + # Last seen mirrors status color + local ls_color="$status_color" + local rule_val="${rule:--}" local group_val="${group:--}" - - # Pad name, ip, type — pure ASCII, safe for printf + local name_pad ip_pad type_pad status_pad name_pad=$(printf "%-${w_name}s" "$name") ip_pad=$(printf "%-${w_ip}s" "$ip") type_pad=$(printf "%-${w_type}s" "$type") status_pad=$(printf "%-8s" "$status") - - # Padding for label+value fields — compute trailing spaces manually - # so ANSI codes in labels don't confuse printf width calculation + local rule_pad_n group_pad_n rule_pad_n=$(( w_rule - ${#rule_val} )) group_pad_n=$(( w_group - ${#group_val} )) [[ $rule_pad_n -lt 0 ]] && rule_pad_n=0 [[ $group_pad_n -lt 0 ]] && group_pad_n=0 - + printf " %s %s %s \033[2mrule:\033[0m %s%*s \033[2mgroup:\033[0m %s%*s %b%s\033[0m %b%s\033[0m\n" \ "$name_pad" "$ip_pad" "$type_pad" \ "$rule_val" "$rule_pad_n" "" \ @@ -120,7 +117,7 @@ function ui::peer::list_row_detailed() { local name="${1:-}" ip="${2:-}" type="${3:-}" rule="${4:-}" \ group="${5:-}" subnet="${6:-}" status="${7:-}" last_seen="${8:-}" \ is_blocked="${9:-false}" is_restricted="${10:-false}" - + local status_color="\033[0;37m" if [[ "$is_blocked" == "true" ]]; then status_color="\033[1;31m" @@ -129,20 +126,20 @@ function ui::peer::list_row_detailed() { elif [[ "$status" == "online" ]]; then status_color="\033[1;32m" fi - - local ls_color="\033[0;37m" - [[ "$status" == "online" ]] && ls_color="\033[1;32m" - - local rule_val="${rule:-—}" - local group_val="${group:-—}" - local subnet_val="${subnet:-—}" - + + # Last seen mirrors status color + local ls_color="$status_color" + + local rule_val="${rule:--}" + local group_val="${group:--}" + local subnet_val="${subnet:--}" + local name_pad ip_pad type_pad status_pad name_pad=$(printf "%-${w_name}s" "$name") ip_pad=$(printf "%-${w_ip}s" "$ip") type_pad=$(printf "%-${w_type}s" "$type") status_pad=$(printf "%-8s" "$status") - + local rule_pad_n group_pad_n subnet_pad_n rule_pad_n=$(( w_rule - ${#rule_val} )) group_pad_n=$(( w_group - ${#group_val} )) @@ -150,7 +147,7 @@ function ui::peer::list_row_detailed() { [[ $rule_pad_n -lt 0 ]] && rule_pad_n=0 [[ $group_pad_n -lt 0 ]] && group_pad_n=0 [[ $subnet_pad_n -lt 0 ]] && subnet_pad_n=0 - + printf " · %s %s %s \033[2mrule:\033[0m %s%*s \033[2mgroup:\033[0m %s%*s \033[2msubnet:\033[0m %s%*s %b%s\033[0m %b%s\033[0m\n" \ "$name_pad" "$ip_pad" "$type_pad" \ "$rule_val" "$rule_pad_n" "" \