1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-04 13:16:47 +00:00

Improved viewing experience for visual files

This commit is contained in:
Tw93
2025-10-08 23:27:52 +08:00
parent c0dc5203b3
commit 3fa81ffebd

View File

@@ -23,6 +23,14 @@ readonly MIN_LARGE_FILE_SIZE="1000000000" # 1GB
readonly MIN_MEDIUM_FILE_SIZE="100000000" # 100MB
readonly MIN_SMALL_FILE_SIZE="10000000" # 10MB
# Emoji badges for list displays only
readonly BADGE_DIR="🍞"
readonly BADGE_FILE="📔"
readonly BADGE_MEDIA="🌁"
readonly BADGE_BUNDLE="🥜"
readonly BADGE_LOG="📝"
readonly BADGE_APP="🐣"
# Global state
declare -a SCAN_RESULTS=()
declare -a DIR_RESULTS=()
@@ -63,13 +71,14 @@ scan_large_files() {
fi
# Scan files > 1GB
mdfind -onlyin "$target_path" "kMDItemFSSize > $MIN_LARGE_FILE_SIZE" 2>/dev/null | \
while IFS= read -r file; do
if [[ -f "$file" ]]; then
local size=$(stat -f%z "$file" 2>/dev/null || echo "0")
echo "$size|$file"
fi
done | sort -t'|' -k1 -rn > "$output_file"
local file=""
while IFS= read -r file; do
if [[ -f "$file" ]]; then
local size=$(stat -f%z "$file" 2>/dev/null || echo "0")
echo "$size|$file"
fi
done < <(mdfind -onlyin "$target_path" "kMDItemFSSize > $MIN_LARGE_FILE_SIZE" 2>/dev/null) | \
sort -t'|' -k1 -rn > "$output_file"
}
# Scan medium files (100MB - 1GB)
@@ -81,14 +90,15 @@ scan_medium_files() {
return 1
fi
mdfind -onlyin "$target_path" \
"kMDItemFSSize > $MIN_MEDIUM_FILE_SIZE && kMDItemFSSize < $MIN_LARGE_FILE_SIZE" 2>/dev/null | \
while IFS= read -r file; do
if [[ -f "$file" ]]; then
local size=$(stat -f%z "$file" 2>/dev/null || echo "0")
echo "$size|$file"
fi
done | sort -t'|' -k1 -rn > "$output_file"
local file=""
while IFS= read -r file; do
if [[ -f "$file" ]]; then
local size=$(stat -f%z "$file" 2>/dev/null || echo "0")
echo "$size|$file"
fi
done < <(mdfind -onlyin "$target_path" \
"kMDItemFSSize > $MIN_MEDIUM_FILE_SIZE && kMDItemFSSize < $MIN_LARGE_FILE_SIZE" 2>/dev/null) | \
sort -t'|' -k1 -rn > "$output_file"
}
# Scan top-level directories with du (optimized with parallel)
@@ -357,7 +367,7 @@ display_large_files_compact() {
return
fi
log_header "📊 Top Large Files"
log_header "Top Large Files"
echo ""
local count=0
@@ -379,8 +389,10 @@ display_large_files_compact() {
local filename=$(basename "$path")
local dirname=$(basename "$(dirname "$path")")
printf " ${GREEN}%-8s${NC} 📄 %-40s ${GRAY}%s${NC}\n" \
"$human_size" "${filename:0:40}" "$dirname"
local info=$(get_file_info "$path")
local badge="${info%|*}"
printf " ${GREEN}%-8s${NC} %s %-40s ${GRAY}%s${NC}\n" \
"$human_size" "$badge" "${filename:0:40}" "$dirname"
((count++))
done < "$temp_large"
@@ -396,14 +408,14 @@ display_large_files() {
local temp_large="$TEMP_PREFIX.large"
if [[ ! -f "$temp_large" ]] || [[ ! -s "$temp_large" ]]; then
log_header "📊 Large Files (>1GB)"
log_header "Large Files (>1GB)"
echo ""
echo " ${GRAY}No files larger than 1GB found${NC}"
echo ""
return
fi
log_header "📊 Large Files (>1GB)"
log_header "Large Files (>1GB)"
echo ""
local count=0
@@ -424,8 +436,10 @@ display_large_files() {
local filename=$(basename "$path")
local dirname=$(dirname "$path" | sed "s|^$HOME|~|")
local info=$(get_file_info "$path")
local badge="${info%|*}"
printf " %s [${GREEN}%s${NC}] %7s\n" "$bar" "$human_size" ""
printf " 📄 %s\n" "$filename"
printf " %s %s\n" "$badge" "$filename"
printf " ${GRAY}%s${NC}\n\n" "$dirname"
((count++))
@@ -447,7 +461,7 @@ display_directories_compact() {
return
fi
log_header "📁 Top Directories"
log_header "Top Directories"
echo ""
local count=0
@@ -485,8 +499,8 @@ display_directories_compact() {
bar="${bar}$(printf "%${empty}s" "" | tr ' ' '░')"
fi
printf " ${BLUE}%-8s${NC} %s ${GRAY}%3s%%${NC} 📁 %s\n" \
"$human_size" "$bar" "$percentage" "$dirname"
printf " ${BLUE}%-8s${NC} %s ${GRAY}%3s%%${NC} %s %s\n" \
"$human_size" "$bar" "$percentage" "$BADGE_DIR" "$dirname"
((count++))
done < "$temp_dirs"
@@ -501,7 +515,7 @@ display_directories() {
return
fi
log_header "📁 Top Directories"
log_header "Top Directories"
echo ""
local count=0
@@ -531,7 +545,7 @@ display_directories() {
local dirname=$(basename "$path")
printf " %s [${BLUE}%s${NC}] %5s%%\n" "$bar" "$human_size" "$percentage"
printf " 📁 %s\n\n" "$display_path"
printf " %s %s\n\n" "$BADGE_DIR" "$display_path"
((count++))
done < "$temp_dirs"
@@ -545,7 +559,7 @@ display_hotspots() {
return
fi
log_header "🔥 Hotspot Directories (High File Concentration)"
log_header "High-concentration Hotspot Directories"
echo ""
local count=0
@@ -557,7 +571,7 @@ display_hotspots() {
local human_size=$(bytes_to_human "$size")
local display_path=$(echo "$path" | sed "s|^$HOME|~|")
printf " 📍 %s\n" "$display_path"
printf " %s\n" "$display_path"
printf " ${GREEN}%s${NC} in ${YELLOW}%d${NC} large files\n\n" \
"$human_size" "$file_count"
@@ -635,9 +649,9 @@ display_cleanup_suggestions_compact() {
fi
if [[ $suggestions_count -gt 0 ]]; then
log_header "💡 Quick Insights"
log_header "Quick Insights"
echo ""
echo " ${YELLOW}$top_suggestion${NC}"
echo " ${YELLOW}$top_suggestion${NC}"
if [[ $suggestions_count -gt 1 ]]; then
echo " ${GRAY}... and $((suggestions_count - 1)) more insights${NC}"
fi
@@ -659,7 +673,7 @@ display_cleanup_suggestions_compact() {
# Display smart cleanup suggestions (full version)
display_cleanup_suggestions() {
log_header "💡 Smart Cleanup Suggestions"
log_header "Smart Cleanup Suggestions"
echo ""
local suggestions=()
@@ -669,7 +683,7 @@ display_cleanup_suggestions() {
local cache_size=$(du -sk "$HOME/Library/Caches" 2>/dev/null | cut -f1)
if [[ $cache_size -gt 1048576 ]]; then # > 1GB
local human=$(bytes_to_human $((cache_size * 1024)))
suggestions+=(" 🗑️ Clear application caches: $human")
suggestions+=(" Clear application caches: $human")
fi
fi
@@ -677,7 +691,7 @@ display_cleanup_suggestions() {
if [[ -d "$HOME/Downloads" ]]; then
local old_files=$(find "$HOME/Downloads" -type f -mtime +90 2>/dev/null | wc -l | tr -d ' ')
if [[ $old_files -gt 0 ]]; then
suggestions+=(" 📥 Clean old downloads: $old_files files older than 90 days")
suggestions+=(" Clean old downloads: $old_files files older than 90 days")
fi
fi
@@ -686,7 +700,7 @@ display_cleanup_suggestions() {
local dmg_count=$(mdfind -onlyin "$HOME" \
"kMDItemFSSize > 500000000 && kMDItemDisplayName == '*.dmg'" 2>/dev/null | wc -l | tr -d ' ')
if [[ $dmg_count -gt 0 ]]; then
suggestions+=(" 💿 Remove disk images: $dmg_count DMG files >500MB")
suggestions+=(" Remove disk images: $dmg_count DMG files >500MB")
fi
fi
@@ -695,7 +709,7 @@ display_cleanup_suggestions() {
local xcode_size=$(du -sk "$HOME/Library/Developer/Xcode/DerivedData" 2>/dev/null | cut -f1)
if [[ $xcode_size -gt 10485760 ]]; then # > 10GB
local human=$(bytes_to_human $((xcode_size * 1024)))
suggestions+=(" 🔨 Clear Xcode cache: $human")
suggestions+=(" Clear Xcode cache: $human")
fi
fi
@@ -716,7 +730,7 @@ display_cleanup_suggestions() {
sort | uniq -d | wc -l | tr -d ' ' > "$temp_dup" 2>/dev/null || echo "0" > "$temp_dup"
local dup_count=$(cat "$temp_dup" 2>/dev/null || echo "0")
if [[ $dup_count -gt 5 ]]; then
suggestions+=(" 📋 Possible duplicates: $dup_count size matches in large files (>10MB)")
suggestions+=(" ♻️ Possible duplicates: $dup_count size matches in large files (>10MB)")
fi
fi
@@ -724,7 +738,7 @@ display_cleanup_suggestions() {
if [[ ${#suggestions[@]} -gt 0 ]]; then
printf '%s\n' "${suggestions[@]}"
echo ""
echo " ${YELLOW}Tip:${NC} Run 'mole clean' to perform cleanup operations"
echo " Tip: Run 'mole clean' to perform cleanup operations"
else
echo " ${GREEN}${NC} No obvious cleanup opportunities found"
fi
@@ -756,7 +770,7 @@ display_disk_summary() {
done < "$temp_dirs"
fi
log_header "💾 Disk Situation"
log_header "Disk Situation"
local target_display=$(echo "$CURRENT_PATH" | sed "s|^$HOME|~|")
echo " ${BLUE}Scanning:${NC} $target_display | ${BLUE}Free:${NC} $(get_free_space)"
@@ -774,22 +788,28 @@ display_disk_summary() {
get_file_info() {
local path="$1"
local ext="${path##*.}"
local icon=""
local type=""
local badge="$BADGE_FILE"
local type="File"
case "$ext" in
dmg|iso|pkg) icon="📦" ; type="Installer" ;;
mov|mp4|avi|mkv|webm) icon="🎬" ; type="Video" ;;
zip|tar|gz|rar|7z) icon="🗜️" ; type="Archive" ;;
pdf) icon="📄" ; type="Document" ;;
jpg|jpeg|png|gif|heic) icon="🖼️" ; type="Image" ;;
key|ppt|pptx) icon="📊" ; type="Slides" ;;
log) icon="📝" ; type="Log" ;;
app) icon="⚙️" ; type="App" ;;
*) icon="📄" ; type="File" ;;
dmg|iso|pkg|zip|tar|gz|rar|7z)
badge="$BADGE_BUNDLE" ; type="Bundle"
;;
mov|mp4|avi|mkv|webm|jpg|jpeg|png|gif|heic)
badge="$BADGE_MEDIA" ; type="Media"
;;
pdf|key|ppt|pptx)
type="Document"
;;
log)
badge="$BADGE_LOG" ; type="Log"
;;
app)
badge="$BADGE_APP" ; type="App"
;;
esac
echo "$icon|$type"
echo "$badge|$type"
}
# Get file age in human readable format
@@ -828,7 +848,7 @@ display_large_files_table() {
return
fi
log_header "🎯 What's Taking Up Space"
log_header "What's Taking Up Space"
# Table header
printf " %-4s %-10s %-8s %s\n" "TYPE" "SIZE" "AGE" "FILE"
@@ -845,9 +865,9 @@ display_large_files_table() {
local ext="${filename##*.}"
local age=$(get_file_age "$path")
# Get file info
# Get file info and badge
local info=$(get_file_info "$path")
local icon="${info%|*}"
local badge="${info%|*}"
# Truncate filename if too long
if [[ ${#filename} -gt 50 ]]; then
@@ -864,7 +884,7 @@ display_large_files_table() {
esac
printf " %b%-4s %-10s %-8s %s${NC}\n" \
"$color" "$icon" "$human_size" "$age" "$filename"
"$color" "$badge" "$human_size" "$age" "$filename"
((count++))
done < "$temp_large"
@@ -948,7 +968,7 @@ display_unified_directories() {
# Display context-aware recommendations
display_recommendations() {
echo " ${YELLOW}💡 Quick Actions:${NC}"
echo " ${YELLOW}Quick Actions:${NC}"
if [[ "$CURRENT_PATH" == "$HOME/Downloads"* ]]; then
echo " → Delete ${RED}[Can Delete]${NC} items (installers/DMG)"
@@ -971,7 +991,7 @@ display_space_chart() {
return
fi
log_header "📊 Space Distribution"
log_header "Space Distribution"
echo ""
# Calculate total
@@ -1012,7 +1032,7 @@ display_space_chart() {
# Display recent large files (added in last 30 days)
display_recent_large_files() {
log_header "🆕 Recent Large Files (Last 30 Days)"
log_header "Recent Large Files (Last 30 Days)"
echo ""
if ! command -v mdfind &>/dev/null; then
@@ -1047,7 +1067,10 @@ display_recent_large_files() {
local dirname=$(dirname "$path" | sed "s|^$HOME|~|")
local days_ago=$(( ($(date +%s) - mtime) / 86400 ))
printf " 📄 %s ${GRAY}(%s)${NC}\n" "$filename" "$human_size"
local info=$(get_file_info "$path")
local badge="${info%|*}"
printf " %s %s ${GRAY}(%s)${NC}\n" "$badge" "$filename" "$human_size"
printf " ${GRAY}%s - %d days ago${NC}\n\n" "$dirname" "$days_ago"
((count++))
@@ -1154,9 +1177,9 @@ count_directories() {
display_interactive_menu() {
clear_screen
log_header "🔍 Disk Space Analyzer"
log_header "Disk Space Analyzer"
echo ""
echo "📂 Current: ${BLUE}$(echo "$CURRENT_PATH" | sed "s|^$HOME|~|")${NC}"
echo "Current: ${BLUE}$(echo "$CURRENT_PATH" | sed "s|^$HOME|~|")${NC}"
echo ""
# Show navigation hints
@@ -1166,7 +1189,7 @@ display_interactive_menu() {
# Display results based on view mode
case "$VIEW_MODE" in
"navigate")
log_header "📁 Select Directory"
log_header "Select Directory"
echo ""
display_directory_list "$CURSOR_POS"
;;
@@ -1189,7 +1212,7 @@ display_interactive_menu() {
display_file_types() {
local temp_types="$TEMP_PREFIX.types"
log_header "📊 File Types Analysis"
log_header "File Types Analysis"
echo ""
if ! command -v mdfind &>/dev/null; then
@@ -1222,7 +1245,14 @@ display_file_types() {
if [[ $total_size -gt 0 ]]; then
local human_size=$(bytes_to_human "$total_size")
printf " 📦 %-12s %8s (%d files)\n" "$type_name:" "$human_size" "$count"
local badge="$BADGE_FILE"
case "$type_name" in
"Videos"|"Images") badge="$BADGE_MEDIA" ;;
"Archives") badge="$BADGE_BUNDLE" ;;
"Documents") badge="$BADGE_FILE" ;;
"Audio") badge="🎵" ;;
esac
printf " %s %-12s %8s (%d files)\n" "$badge" "$type_name:" "$human_size" "$count"
fi
fi
done
@@ -1260,7 +1290,7 @@ scan_directory_contents_fast() {
if [[ "$show_progress" == "true" ]]; then
printf "\033[?25l\033[H\033[J" >&2
echo "" >&2
printf " ${BLUE}📊 | Scanning...${NC}\r" >&2
printf " ${BLUE} | Scanning...${NC}\r" >&2
fi
# Ultra-fast file scanning - batch stat for maximum speed
@@ -1329,7 +1359,7 @@ scan_directory_contents_fast() {
(( spin_len == 0 )) && spinner=('|' '/' '-' '\\') && spin_len=${#spinner[@]}
while ( kill -0 "$dir_pid" 2>/dev/null || kill -0 "$file_pid" 2>/dev/null ); do
printf "\r ${BLUE}📊 ${spinner[$((i % spin_len))]} Scanning... (%ds)${NC}" "$elapsed" >&2
printf "\r ${BLUE}Scanning${NC} ${spinner[$((i % spin_len))]} (%ds)" "$elapsed" >&2
((i++))
sleep 0.1 # Faster animation (100ms per frame)
((tick++))
@@ -1345,7 +1375,7 @@ scan_directory_contents_fast() {
kill -9 "$file_pid" 2>/dev/null || true
wait "$dir_pid" 2>/dev/null || true
wait "$file_pid" 2>/dev/null || true
printf "\r ${YELLOW}⚠️ Large directory - showing estimated sizes${NC}\n" >&2
printf "\r ${YELLOW}Large directory - showing estimated sizes${NC}\n" >&2
sleep 0.3
break
fi
@@ -1430,18 +1460,18 @@ show_volumes_overview() {
# Collect most useful locations (quick display, no size calculation)
{
# Priority order for display (prioritized by typical usefulness)
[[ -d "$HOME" ]] && echo "1000|$HOME|🏠 Home Directory"
[[ -d "$HOME/Downloads" ]] && echo "900|$HOME/Downloads|📥 Downloads"
[[ -d "/Applications" ]] && echo "800|/Applications|📦 Applications"
[[ -d "$HOME/Library" ]] && echo "700|$HOME/Library|📚 User Library"
[[ -d "/Library" ]] && echo "600|/Library|📚 System Library"
[[ -d "$HOME" ]] && echo "1000|$HOME|Home Directory"
[[ -d "$HOME/Downloads" ]] && echo "900|$HOME/Downloads|Downloads"
[[ -d "/Applications" ]] && echo "800|/Applications|Applications"
[[ -d "$HOME/Library" ]] && echo "700|$HOME/Library|User Library"
[[ -d "/Library" ]] && echo "600|/Library|System Library"
# External volumes (if any)
if [[ -d "/Volumes" ]]; then
local vol_priority=500
find /Volumes -mindepth 1 -maxdepth 1 -type d 2>/dev/null | while IFS= read -r vol; do
local vol_name=$(basename "$vol")
echo "$((vol_priority))|$vol|🔌 $vol_name"
echo "$((vol_priority))|$vol|Volume: $vol_name"
((vol_priority--))
done
fi
@@ -1474,7 +1504,7 @@ show_volumes_overview() {
output+="\033[?25l" # Hide cursor
output+="\033[H\033[J"
output+=$'\n'
output+="\033[0;35m💾 Select a location to explore\033[0m"$'\n'
output+="\033[0;35mSelect a location to explore\033[0m"$'\n'
output+=$'\n'
local idx=0
@@ -1707,7 +1737,7 @@ interactive_drill_down() {
output+="\033[?25l" # Hide cursor
output+="\033[H\033[J" # Clear screen
output+=$'\n'
output+="\033[0;35m📊 Disk space explorer > $(echo "$current_path" | sed "s|^$HOME|~|")\033[0m"$'\n'
output+="\033[0;35mDisk space explorer > $(echo "$current_path" | sed "s|^$HOME|~|")\033[0m"$'\n'
output+=$'\n'
local max_show=15 # Show 15 items per page
@@ -1742,37 +1772,39 @@ interactive_drill_down() {
human_size=$(bytes_to_human "$size")
fi
# Get icon and color
local icon="" color="${NC}"
# Determine label and color hints
local badge="$BADGE_FILE" color="${NC}"
if [[ "$type" == "dir" ]]; then
icon="📁" color="${BLUE}"
badge="$BADGE_DIR" color="${BLUE}"
if [[ $size -gt 10737418240 ]]; then color="${RED}"
elif [[ $size -gt 1073741824 ]]; then color="${YELLOW}"
fi
else
local ext="${name##*.}"
local info=$(get_file_info "$path")
badge="${info%|*}"
case "$ext" in
dmg|iso|pkg) icon="📦" ; color="${RED}" ;;
mov|mp4|avi|mkv|webm) icon="🎬" ; color="${YELLOW}" ;;
zip|tar|gz|rar|7z) icon="🗜️" ; color="${YELLOW}" ;;
pdf) icon="📄" ;;
jpg|jpeg|png|gif|heic) icon="🖼️" ;;
key|ppt|pptx) icon="📊" ;;
log) icon="📝" ; color="${GRAY}" ;;
*) icon="📄" ;;
dmg|iso|pkg|zip|tar|gz|rar|7z)
color="${YELLOW}"
;;
mov|mp4|avi|mkv|webm|jpg|jpeg|png|gif|heic)
color="${YELLOW}"
;;
log)
color="${GRAY}"
;;
esac
fi
# Truncate name
if [[ ${#name} -gt 50 ]]; then name="${name:0:47}..."; fi
# Build line with better spacing
# Icon (emoji) + 2 spaces + Right-aligned size + 4 spaces + filename
# Build line with emoji badge, size, and name
local line
if [[ $idx -eq $cursor ]]; then
line=$(printf " ${GREEN}${NC} ${color}%s %10s %s${NC}" "$icon" "$human_size" "$name")
line=$(printf " ${GREEN}${NC} %s%s${NC} %10s %s${NC}" "$color" "$badge" "$human_size" "$name")
else
line=$(printf " ${color}%s %10s %s${NC}" "$icon" "$human_size" "$name")
line=$(printf " %s%s${NC} %10s %s${NC}" "$color" "$badge" "$human_size" "$name")
fi
output+="$line"$'\n'
@@ -1852,7 +1884,7 @@ interactive_drill_down() {
# Clear screen and show loading message
printf "\033[H\033[J"
echo ""
echo " ${BLUE}📄 Opening: $filename${NC}"
echo " ${BLUE}Opening file:${NC} $filename"
echo ""
# Try less first (best for text viewing)
@@ -1884,7 +1916,7 @@ interactive_drill_down() {
# Show message without flashing
printf "\033[H\033[J"
echo ""
echo " ${BLUE}📦 Opening: $filename${NC}"
echo " ${BLUE}Opening file:${NC} $filename"
echo ""
echo " ${GRAY}Launching default application...${NC}"
@@ -1905,7 +1937,7 @@ interactive_drill_down() {
if [[ "$open_success" != "true" ]]; then
printf "\033[H\033[J"
echo ""
echo " ${YELLOW}⚠️ Could not open file${NC}"
echo " ${YELLOW}Warning:${NC} Could not open file"
echo ""
echo " ${GRAY}File: $selected_path${NC}"
echo " ${GRAY}Press any key to return...${NC}"
@@ -1960,26 +1992,20 @@ interactive_drill_down() {
echo ""
if [[ "$type" == "dir" ]]; then
echo " ${RED}Delete folder? ${YELLOW}⚠️ This action cannot be undone!${NC}"
echo " ${RED}Delete folder? ${YELLOW}Warning:${NC} This action cannot be undone!"
else
echo " ${RED}Delete file? ${YELLOW}⚠️ This action cannot be undone!${NC}"
echo " ${RED}Delete file? ${YELLOW}Warning:${NC} This action cannot be undone!"
fi
echo ""
# Show icon based on type
if [[ "$type" == "dir" ]]; then
echo " 📁 ${YELLOW}$selected_name${NC}"
echo " ${BADGE_DIR} ${YELLOW}$selected_name${NC}"
else
local ext="${selected_name##*.}"
local icon="📄"
case "$ext" in
dmg|iso|pkg) icon="📦" ;;
mov|mp4|avi|mkv|webm) icon="🎬" ;;
zip|tar|gz|rar|7z) icon="🗜️" ;;
jpg|jpeg|png|gif|heic) icon="🖼️" ;;
esac
echo " $icon ${YELLOW}$selected_name${NC}"
local info=$(get_file_info "$selected_path")
local badge="${info%|*}"
echo " $badge ${YELLOW}$selected_name${NC}"
fi
echo " ${GRAY}Size: $human_size${NC}"
@@ -1987,7 +2013,7 @@ interactive_drill_down() {
if [[ "$needs_sudo" == "true" ]]; then
echo ""
echo " ${YELLOW}🔐 Requires admin privileges${NC}"
echo " ${YELLOW}Warning:${NC} Requires admin privileges"
fi
echo ""
@@ -1998,10 +2024,23 @@ interactive_drill_down() {
confirm=$(read_key 2>/dev/null || echo "QUIT")
if [[ "$confirm" == "ENTER" ]]; then
# Request sudo if needed before deletion
if [[ "$needs_sudo" == "true" ]]; then
printf "\033[H\033[J"
echo ""
echo ""
if ! request_sudo_access "Admin access required to delete this item"; then
echo ""
echo " ${RED}✗ Admin access denied${NC}"
sleep 1.5
continue
fi
fi
# Show deleting message
printf "\033[H\033[J"
echo ""
echo " ${BLUE}🗑️ Deleting...${NC}"
echo " ${BLUE}Deleting...${NC}"
echo ""
# Try to delete with sudo if needed