mirror of
https://github.com/tw93/Mole.git
synced 2026-02-15 11:05:09 +00:00
The results are more uniform
This commit is contained in:
94
bin/clean.sh
94
bin/clean.sh
@@ -363,7 +363,7 @@ start_cleanup() {
|
|||||||
|
|
||||||
if [[ -t 0 ]]; then
|
if [[ -t 0 ]]; then
|
||||||
echo ""
|
echo ""
|
||||||
echo -ne "${ICON_SETTINGS} ${BLUE}System cleanup?${NC} ${GRAY}Enter to continue, any key to skip${NC} "
|
echo -ne "${BLUE}${ICON_SETTINGS}${NC} ${BLUE}System cleanup?${NC} ${GRAY}Enter to continue, any key to skip${NC} "
|
||||||
|
|
||||||
# Use IFS= and read without -n to allow Ctrl+C to work properly
|
# Use IFS= and read without -n to allow Ctrl+C to work properly
|
||||||
IFS= read -r -s -n 1 choice
|
IFS= read -r -s -n 1 choice
|
||||||
@@ -406,7 +406,7 @@ start_cleanup() {
|
|||||||
else
|
else
|
||||||
# Any other key = no system cleanup
|
# Any other key = no system cleanup
|
||||||
SYSTEM_CLEAN=false
|
SYSTEM_CLEAN=false
|
||||||
echo -e "Skipped system cleanup, user-level only"
|
echo -e "${BLUE}${ICON_EMPTY}${NC} Skipped system cleanup, user-level only"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
SYSTEM_CLEAN=false
|
SYSTEM_CLEAN=false
|
||||||
@@ -1346,68 +1346,80 @@ perform_cleanup() {
|
|||||||
space_freed_kb=$((space_after - space_before))
|
space_freed_kb=$((space_after - space_before))
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "===================================================================="
|
|
||||||
|
local summary_heading=""
|
||||||
|
local summary_status="success"
|
||||||
if [[ "$DRY_RUN" == "true" ]]; then
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
echo "DRY RUN COMPLETE!"
|
summary_heading="Dry run complete"
|
||||||
else
|
else
|
||||||
echo "CLEANUP COMPLETE!"
|
summary_heading="Cleanup complete"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local -a summary_details=()
|
||||||
|
|
||||||
if [[ $total_size_cleaned -gt 0 ]]; then
|
if [[ $total_size_cleaned -gt 0 ]]; then
|
||||||
local freed_gb=$(echo "$total_size_cleaned" | awk '{printf "%.2f", $1/1024/1024}')
|
local freed_gb
|
||||||
|
freed_gb=$(echo "$total_size_cleaned" | awk '{printf "%.2f", $1/1024/1024}')
|
||||||
|
|
||||||
if [[ "$DRY_RUN" == "true" ]]; then
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
echo "Potential reclaimable space: ${GREEN}${freed_gb}GB${NC} (no changes made) | Free space now: $(get_free_space)"
|
summary_details+=("Potential reclaimable space: ${GREEN}${freed_gb}GB${NC}")
|
||||||
|
summary_details+=("No changes were made in this mode.")
|
||||||
# Show file/category stats for dry run
|
|
||||||
if [[ $files_cleaned -gt 0 && $total_items -gt 0 ]]; then
|
|
||||||
printf "Files to clean: %s | Categories: %s" "$files_cleaned" "$total_items"
|
|
||||||
[[ $whitelist_skipped_count -gt 0 ]] && printf " | Protected: %s" "$whitelist_skipped_count"
|
|
||||||
printf "\n"
|
|
||||||
elif [[ $files_cleaned -gt 0 ]]; then
|
|
||||||
printf "Files to clean: %s" "$files_cleaned"
|
|
||||||
[[ $whitelist_skipped_count -gt 0 ]] && printf " | Protected: %s" "$whitelist_skipped_count"
|
|
||||||
printf "\n"
|
|
||||||
elif [[ $total_items -gt 0 ]]; then
|
|
||||||
printf "Categories: %s" "$total_items"
|
|
||||||
[[ $whitelist_skipped_count -gt 0 ]] && printf " | Protected: %s" "$whitelist_skipped_count"
|
|
||||||
printf "\n"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "To protect specific cache files from deletion, run: mo clean --whitelist"
|
|
||||||
else
|
else
|
||||||
echo "Space freed: ${GREEN}${freed_gb}GB${NC} | Free space now: $(get_free_space)"
|
summary_details+=("Space freed: ${GREEN}${freed_gb}GB${NC}")
|
||||||
|
fi
|
||||||
|
summary_details+=("Free space now: $(get_free_space)")
|
||||||
|
|
||||||
# Show file/category stats for actual cleanup
|
|
||||||
if [[ $files_cleaned -gt 0 && $total_items -gt 0 ]]; then
|
if [[ $files_cleaned -gt 0 && $total_items -gt 0 ]]; then
|
||||||
printf "Files cleaned: %s | Categories: %s" "$files_cleaned" "$total_items"
|
local stats
|
||||||
[[ $whitelist_skipped_count -gt 0 ]] && printf " | Protected: %s" "$whitelist_skipped_count"
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
printf "\n"
|
stats="Files to clean: $files_cleaned | Categories: $total_items"
|
||||||
|
else
|
||||||
|
stats="Files cleaned: $files_cleaned | Categories: $total_items"
|
||||||
|
fi
|
||||||
|
[[ $whitelist_skipped_count -gt 0 ]] && stats+=" | Protected: $whitelist_skipped_count"
|
||||||
|
summary_details+=("$stats")
|
||||||
elif [[ $files_cleaned -gt 0 ]]; then
|
elif [[ $files_cleaned -gt 0 ]]; then
|
||||||
printf "Files cleaned: %s" "$files_cleaned"
|
local stats
|
||||||
[[ $whitelist_skipped_count -gt 0 ]] && printf " | Protected: %s" "$whitelist_skipped_count"
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
printf "\n"
|
stats="Files to clean: $files_cleaned"
|
||||||
|
else
|
||||||
|
stats="Files cleaned: $files_cleaned"
|
||||||
|
fi
|
||||||
|
[[ $whitelist_skipped_count -gt 0 ]] && stats+=" | Protected: $whitelist_skipped_count"
|
||||||
|
summary_details+=("$stats")
|
||||||
elif [[ $total_items -gt 0 ]]; then
|
elif [[ $total_items -gt 0 ]]; then
|
||||||
printf "Categories: %s" "$total_items"
|
local stats
|
||||||
[[ $whitelist_skipped_count -gt 0 ]] && printf " | Protected: %s" "$whitelist_skipped_count"
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
printf "\n"
|
stats="Categories to review: $total_items"
|
||||||
|
else
|
||||||
|
stats="Categories: $total_items"
|
||||||
|
fi
|
||||||
|
[[ $whitelist_skipped_count -gt 0 ]] && stats+=" | Protected: $whitelist_skipped_count"
|
||||||
|
summary_details+=("$stats")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
summary_details+=("Protect specific caches anytime with: mo clean --whitelist")
|
||||||
|
else
|
||||||
if [[ $(echo "$freed_gb" | awk '{print ($1 >= 1) ? 1 : 0}') -eq 1 ]]; then
|
if [[ $(echo "$freed_gb" | awk '{print ($1 >= 1) ? 1 : 0}') -eq 1 ]]; then
|
||||||
local movies=$(echo "$freed_gb" | awk '{printf "%.0f", $1/4.5}')
|
local movies
|
||||||
|
movies=$(echo "$freed_gb" | awk '{printf "%.0f", $1/4.5}')
|
||||||
if [[ $movies -gt 0 ]]; then
|
if [[ $movies -gt 0 ]]; then
|
||||||
echo "That's like ~$movies 4K movies worth of space!"
|
summary_details+=("Equivalent to ~$movies 4K movies of storage.")
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
summary_status="info"
|
||||||
if [[ "$DRY_RUN" == "true" ]]; then
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
echo "No significant reclaimable space detected (already clean) | Free space: $(get_free_space)"
|
summary_details+=("No significant reclaimable space detected (system already clean).")
|
||||||
else
|
else
|
||||||
echo "No significant space was freed (system was already clean) | Free space: $(get_free_space)"
|
summary_details+=("System was already clean; no additional space freed.")
|
||||||
fi
|
fi
|
||||||
|
summary_details+=("Free space now: $(get_free_space)")
|
||||||
fi
|
fi
|
||||||
printf "====================================================================\n"
|
|
||||||
|
print_summary_block "$summary_status" "$summary_heading" "${summary_details[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -175,37 +175,47 @@ batch_uninstall_applications() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Summary
|
# Summary
|
||||||
local freed_display=$(bytes_to_human "$((total_size_freed * 1024))")
|
local freed_display
|
||||||
local bar="================================================================================"
|
freed_display=$(bytes_to_human "$((total_size_freed * 1024))")
|
||||||
echo "$bar"
|
|
||||||
|
local summary_status="success"
|
||||||
|
local -a summary_details=()
|
||||||
|
|
||||||
if [[ $success_count -gt 0 ]]; then
|
if [[ $success_count -gt 0 ]]; then
|
||||||
local success_list="${success_items[*]}"
|
local success_list="${success_items[*]}"
|
||||||
echo -e "Removed: ${GREEN}${success_list}${NC} | Freed: ${GREEN}${freed_display}${NC}"
|
summary_details+=("Removed: ${GREEN}${success_list}${NC}")
|
||||||
|
summary_details+=("Freed space: ${GREEN}${freed_display}${NC}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $failed_count -gt 0 ]]; then
|
if [[ $failed_count -gt 0 ]]; then
|
||||||
|
summary_status="warn"
|
||||||
|
|
||||||
local failed_names=()
|
local failed_names=()
|
||||||
local reason_summary=""
|
|
||||||
for item in "${failed_items[@]}"; do
|
for item in "${failed_items[@]}"; do
|
||||||
local name=${item%%:*}
|
local name=${item%%:*}
|
||||||
failed_names+=("$name")
|
failed_names+=("$name")
|
||||||
done
|
done
|
||||||
local failed_list="${failed_names[*]}"
|
local failed_list="${failed_names[*]}"
|
||||||
|
|
||||||
# Determine primary reason
|
local reason_summary="could not be removed"
|
||||||
if [[ $failed_count -eq 1 ]]; then
|
if [[ $failed_count -eq 1 ]]; then
|
||||||
local first_reason=${failed_items[0]#*:}
|
local first_reason=${failed_items[0]#*:}
|
||||||
case "$first_reason" in
|
case "$first_reason" in
|
||||||
still*running*) reason_summary="still running" ;;
|
still*running*) reason_summary="is still running" ;;
|
||||||
remove*failed*) reason_summary="could not be removed" ;;
|
remove*failed*) reason_summary="could not be removed" ;;
|
||||||
permission*) reason_summary="permission denied" ;;
|
permission*) reason_summary="permission denied" ;;
|
||||||
*) reason_summary="$first_reason" ;;
|
*) reason_summary="$first_reason" ;;
|
||||||
esac
|
esac
|
||||||
echo -e "Failed: ${RED}${failed_list}${NC} ${reason_summary}"
|
|
||||||
else
|
|
||||||
echo -e "Failed: ${RED}${failed_list}${NC} could not be removed"
|
|
||||||
fi
|
fi
|
||||||
|
summary_details+=("Failed: ${RED}${failed_list}${NC} ${reason_summary}")
|
||||||
fi
|
fi
|
||||||
echo "$bar"
|
|
||||||
|
if [[ $success_count -eq 0 && $failed_count -eq 0 ]]; then
|
||||||
|
summary_status="info"
|
||||||
|
summary_details+=("No applications were uninstalled.")
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_summary_block "$summary_status" "Uninstall complete" "${summary_details[@]}"
|
||||||
|
|
||||||
if [[ ${#dock_cleanup_paths[@]} -gt 0 ]]; then
|
if [[ ${#dock_cleanup_paths[@]} -gt 0 ]]; then
|
||||||
remove_apps_from_dock "${dock_cleanup_paths[@]}"
|
remove_apps_from_dock "${dock_cleanup_paths[@]}"
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ readonly NC="${ESC}[0m"
|
|||||||
|
|
||||||
# Icon definitions
|
# Icon definitions
|
||||||
readonly ICON_CONFIRM="◎" # Confirm operation
|
readonly ICON_CONFIRM="◎" # Confirm operation
|
||||||
readonly ICON_ADMIN="●" # Admin permission
|
readonly ICON_ADMIN="⚙" # Admin permission
|
||||||
readonly ICON_SUCCESS="✓" # Success
|
readonly ICON_SUCCESS="✓" # Success
|
||||||
readonly ICON_ERROR="✗" # Error
|
readonly ICON_ERROR="✗" # Error
|
||||||
readonly ICON_EMPTY="○" # Empty state
|
readonly ICON_EMPTY="○" # Empty state
|
||||||
@@ -116,6 +116,39 @@ icon_menu() {
|
|||||||
echo -e "${BLUE}${ICON_MENU} ${num}. ${text}${NC}"
|
echo -e "${BLUE}${ICON_MENU} ${num}. ${text}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Consistent summary blocks for command results
|
||||||
|
print_summary_block() {
|
||||||
|
local status="info"
|
||||||
|
local heading=""
|
||||||
|
|
||||||
|
if [[ $# -gt 0 ]]; then
|
||||||
|
status="$1"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $# -gt 0 ]]; then
|
||||||
|
heading="$1"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -a details=("$@")
|
||||||
|
local divider="======================================================================"
|
||||||
|
|
||||||
|
local color="$BLUE"
|
||||||
|
|
||||||
|
local indent=" "
|
||||||
|
|
||||||
|
echo "$divider"
|
||||||
|
if [[ -n "$heading" ]]; then
|
||||||
|
echo -e "${BLUE}${heading}${NC}"
|
||||||
|
fi
|
||||||
|
for detail in "${details[@]}"; do
|
||||||
|
[[ -z "$detail" ]] && continue
|
||||||
|
echo -e "${detail}"
|
||||||
|
done
|
||||||
|
echo "$divider"
|
||||||
|
}
|
||||||
|
|
||||||
# System detection
|
# System detection
|
||||||
detect_architecture() {
|
detect_architecture() {
|
||||||
if [[ "$(uname -m)" == "arm64" ]]; then
|
if [[ "$(uname -m)" == "arm64" ]]; then
|
||||||
@@ -343,7 +376,7 @@ request_sudo_access() {
|
|||||||
|
|
||||||
# If Touch ID is supported and not forced to use password
|
# If Touch ID is supported and not forced to use password
|
||||||
if [[ "$force_password" != "true" ]] && check_touchid_support; then
|
if [[ "$force_password" != "true" ]] && check_touchid_support; then
|
||||||
echo -e "${BLUE}${ICON_ADMIN}${NC} ${prompt_msg} ${GRAY}(Touch ID or password)${NC}"
|
echo -e "${GRAY}${ICON_ADMIN}${NC} ${GRAY}${prompt_msg} (Touch ID or password)${NC}"
|
||||||
if sudo -v 2>/dev/null; then
|
if sudo -v 2>/dev/null; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
@@ -351,8 +384,8 @@ request_sudo_access() {
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Traditional password method
|
# Traditional password method
|
||||||
echo -e "${BLUE}${ICON_ADMIN}${NC} ${prompt_msg}"
|
echo -e "${GRAY}${ICON_ADMIN}${NC} ${GRAY}${prompt_msg}${NC}"
|
||||||
echo -ne "${BLUE}${ICON_MENU}${NC} Password: "
|
echo -ne "${GRAY}${ICON_MENU}${NC} Password: "
|
||||||
read -s password
|
read -s password
|
||||||
echo ""
|
echo ""
|
||||||
if [[ -n "$password" ]] && echo "$password" | sudo -S true 2>/dev/null; then
|
if [[ -n "$password" ]] && echo "$password" | sudo -S true 2>/dev/null; then
|
||||||
|
|||||||
@@ -25,9 +25,8 @@ paginated_multi_select() {
|
|||||||
|
|
||||||
local total_items=${#items[@]}
|
local total_items=${#items[@]}
|
||||||
local items_per_page=15
|
local items_per_page=15
|
||||||
local total_pages=$(( (total_items + items_per_page - 1) / items_per_page ))
|
|
||||||
local current_page=0
|
|
||||||
local cursor_pos=0
|
local cursor_pos=0
|
||||||
|
local top_index=0
|
||||||
local -a selected=()
|
local -a selected=()
|
||||||
|
|
||||||
# Initialize selection array
|
# Initialize selection array
|
||||||
@@ -113,30 +112,48 @@ paginated_multi_select() {
|
|||||||
# Clear each line as we go instead of clearing entire screen
|
# Clear each line as we go instead of clearing entire screen
|
||||||
local clear_line="\r\033[2K"
|
local clear_line="\r\033[2K"
|
||||||
|
|
||||||
# Header - compute underline length without external seq dependency
|
# Count selections for header display
|
||||||
local title_clean="${title//[^[:print:]]/}"
|
|
||||||
local underline_len=${#title_clean}
|
|
||||||
[[ $underline_len -lt 10 ]] && underline_len=10
|
|
||||||
# Build underline robustly (no seq); printf width then translate spaces to '='
|
|
||||||
local underline
|
|
||||||
underline=$(printf '%*s' "$underline_len" '' | tr ' ' '=')
|
|
||||||
printf "${clear_line}${PURPLE}%s${NC}\n" "$title" >&2
|
|
||||||
printf "${clear_line}%s\n" "$underline" >&2
|
|
||||||
|
|
||||||
# Status
|
|
||||||
local selected_count=0
|
local selected_count=0
|
||||||
for ((i = 0; i < total_items; i++)); do
|
for ((i = 0; i < total_items; i++)); do
|
||||||
[[ ${selected[i]} == true ]] && ((selected_count++))
|
[[ ${selected[i]} == true ]] && ((selected_count++))
|
||||||
done
|
done
|
||||||
printf "${clear_line}Page %d/%d │ Total: %d │ Selected: %d\n\n" \
|
|
||||||
$((current_page + 1)) $total_pages $total_items $selected_count >&2
|
|
||||||
|
|
||||||
# Items for current page
|
# Header
|
||||||
local start_idx=$((current_page * items_per_page))
|
printf "${clear_line}${PURPLE}%s${NC} ${GRAY}%d/%d selected${NC}\n" "${title}" "$selected_count" "$total_items" >&2
|
||||||
local end_idx=$((start_idx + items_per_page - 1))
|
|
||||||
|
if [[ $total_items -eq 0 ]]; then
|
||||||
|
printf "${clear_line}${GRAY}No items available${NC}\n" >&2
|
||||||
|
printf "${clear_line}\n" >&2
|
||||||
|
printf "${clear_line}${GRAY}Q/ESC${NC} Quit\n" >&2
|
||||||
|
printf "${clear_line}" >&2
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $top_index -gt $((total_items - 1)) ]]; then
|
||||||
|
if [[ $total_items -gt $items_per_page ]]; then
|
||||||
|
top_index=$((total_items - items_per_page))
|
||||||
|
else
|
||||||
|
top_index=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local visible_count=$((total_items - top_index))
|
||||||
|
[[ $visible_count -gt $items_per_page ]] && visible_count=$items_per_page
|
||||||
|
[[ $visible_count -le 0 ]] && visible_count=1
|
||||||
|
if [[ $cursor_pos -ge $visible_count ]]; then
|
||||||
|
cursor_pos=$((visible_count - 1))
|
||||||
|
[[ $cursor_pos -lt 0 ]] && cursor_pos=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "${clear_line}\n" >&2
|
||||||
|
|
||||||
|
# Items for current window
|
||||||
|
local start_idx=$top_index
|
||||||
|
local end_idx=$((top_index + items_per_page - 1))
|
||||||
[[ $end_idx -ge $total_items ]] && end_idx=$((total_items - 1))
|
[[ $end_idx -ge $total_items ]] && end_idx=$((total_items - 1))
|
||||||
|
|
||||||
for ((i = start_idx; i <= end_idx; i++)); do
|
for ((i = start_idx; i <= end_idx; i++)); do
|
||||||
|
[[ $i -lt 0 ]] && continue
|
||||||
local is_current=false
|
local is_current=false
|
||||||
[[ $((i - start_idx)) -eq $cursor_pos ]] && is_current=true
|
[[ $((i - start_idx)) -eq $cursor_pos ]] && is_current=true
|
||||||
render_item $i $is_current
|
render_item $i $is_current
|
||||||
@@ -144,13 +161,14 @@ paginated_multi_select() {
|
|||||||
|
|
||||||
# Fill empty slots to clear previous content
|
# Fill empty slots to clear previous content
|
||||||
local items_shown=$((end_idx - start_idx + 1))
|
local items_shown=$((end_idx - start_idx + 1))
|
||||||
|
[[ $items_shown -lt 0 ]] && items_shown=0
|
||||||
for ((i = items_shown; i < items_per_page; i++)); do
|
for ((i = items_shown; i < items_per_page; i++)); do
|
||||||
printf "${clear_line}\n" >&2
|
printf "${clear_line}\n" >&2
|
||||||
done
|
done
|
||||||
|
|
||||||
# Clear any remaining lines at bottom
|
# Clear any remaining lines at bottom
|
||||||
printf "${clear_line}\n" >&2
|
printf "${clear_line}\n" >&2
|
||||||
printf "${clear_line}${GRAY}↑/↓${NC} Navigate ${GRAY}|${NC} ${GRAY}Space${NC} Select ${GRAY}|${NC} ${GRAY}Enter${NC} Confirm ${GRAY}|${NC} ${GRAY}Q/ESC${NC} Quit ${GRAY}|${NC} ○ off ● on\n" >&2
|
printf "${clear_line}${GRAY}↑/↓${NC} Navigate ${GRAY}|${NC} ${GRAY}Space${NC} Select ${GRAY}|${NC} ${GRAY}Enter${NC} Confirm ${GRAY}|${NC} ${GRAY}Q/ESC${NC} Quit\n" >&2
|
||||||
|
|
||||||
# Clear one more line to ensure no artifacts
|
# Clear one more line to ensure no artifacts
|
||||||
printf "${clear_line}" >&2
|
printf "${clear_line}" >&2
|
||||||
@@ -184,31 +202,38 @@ EOF
|
|||||||
return 1
|
return 1
|
||||||
;;
|
;;
|
||||||
"UP")
|
"UP")
|
||||||
if [[ $cursor_pos -gt 0 ]]; then
|
if [[ $total_items -eq 0 ]]; then
|
||||||
|
:
|
||||||
|
elif [[ $cursor_pos -gt 0 ]]; then
|
||||||
((cursor_pos--))
|
((cursor_pos--))
|
||||||
elif [[ $current_page -gt 0 ]]; then
|
elif [[ $top_index -gt 0 ]]; then
|
||||||
((current_page--))
|
((top_index--))
|
||||||
# Calculate cursor position for new page
|
|
||||||
local start_idx=$((current_page * items_per_page))
|
|
||||||
local items_on_page=$((total_items - start_idx))
|
|
||||||
[[ $items_on_page -gt $items_per_page ]] && items_on_page=$items_per_page
|
|
||||||
cursor_pos=$((items_on_page - 1))
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"DOWN")
|
"DOWN")
|
||||||
local start_idx=$((current_page * items_per_page))
|
if [[ $total_items -eq 0 ]]; then
|
||||||
local items_on_page=$((total_items - start_idx))
|
:
|
||||||
[[ $items_on_page -gt $items_per_page ]] && items_on_page=$items_per_page
|
else
|
||||||
|
local absolute_index=$((top_index + cursor_pos))
|
||||||
|
if [[ $absolute_index -lt $((total_items - 1)) ]]; then
|
||||||
|
local visible_count=$((total_items - top_index))
|
||||||
|
[[ $visible_count -gt $items_per_page ]] && visible_count=$items_per_page
|
||||||
|
|
||||||
if [[ $cursor_pos -lt $((items_on_page - 1)) ]]; then
|
if [[ $cursor_pos -lt $((visible_count - 1)) ]]; then
|
||||||
((cursor_pos++))
|
((cursor_pos++))
|
||||||
elif [[ $current_page -lt $((total_pages - 1)) ]]; then
|
elif [[ $((top_index + visible_count)) -lt $total_items ]]; then
|
||||||
((current_page++))
|
((top_index++))
|
||||||
cursor_pos=0
|
visible_count=$((total_items - top_index))
|
||||||
|
[[ $visible_count -gt $items_per_page ]] && visible_count=$items_per_page
|
||||||
|
if [[ $cursor_pos -ge $visible_count ]]; then
|
||||||
|
cursor_pos=$((visible_count - 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"SPACE")
|
"SPACE")
|
||||||
local idx=$((current_page * items_per_page + cursor_pos))
|
local idx=$((top_index + cursor_pos))
|
||||||
if [[ $idx -lt $total_items ]]; then
|
if [[ $idx -lt $total_items ]]; then
|
||||||
if [[ ${selected[idx]} == true ]]; then
|
if [[ ${selected[idx]} == true ]]; then
|
||||||
selected[idx]=false
|
selected[idx]=false
|
||||||
|
|||||||
@@ -280,9 +280,9 @@ manage_whitelist_categories() {
|
|||||||
save_whitelist_patterns
|
save_whitelist_patterns
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
print_summary_block "success" \
|
||||||
echo -e "${GREEN}✓${NC} Protected ${#selected_patterns[@]} cache(s)"
|
"Protected ${#selected_patterns[@]} cache(s)" \
|
||||||
echo -e "${GRAY}Config: ${WHITELIST_CONFIG}${NC}"
|
"Saved to ${WHITELIST_CONFIG}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
6
mole
6
mole
@@ -22,7 +22,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
source "$SCRIPT_DIR/lib/common.sh"
|
source "$SCRIPT_DIR/lib/common.sh"
|
||||||
|
|
||||||
# Version info
|
# Version info
|
||||||
VERSION="1.7.4"
|
VERSION="1.7.5"
|
||||||
MOLE_TAGLINE="can dig deep to clean your Mac."
|
MOLE_TAGLINE="can dig deep to clean your Mac."
|
||||||
|
|
||||||
# Get latest version from remote repository
|
# Get latest version from remote repository
|
||||||
@@ -38,10 +38,10 @@ check_for_updates() {
|
|||||||
local msg_cache="$HOME/.cache/mole/update_message"
|
local msg_cache="$HOME/.cache/mole/update_message"
|
||||||
mkdir -p "$(dirname "$cache")" 2>/dev/null
|
mkdir -p "$(dirname "$cache")" 2>/dev/null
|
||||||
|
|
||||||
# Skip if checked within 24 hours
|
# Skip if checked within 3 hours
|
||||||
if [[ -f "$cache" ]]; then
|
if [[ -f "$cache" ]]; then
|
||||||
local age=$(($(date +%s) - $(stat -f%m "$cache" 2>/dev/null || echo 0)))
|
local age=$(($(date +%s) - $(stat -f%m "$cache" 2>/dev/null || echo 0)))
|
||||||
[[ $age -lt 86400 ]] && return
|
[[ $age -lt 10800 ]] && return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Background version check (save to file, don't output)
|
# Background version check (save to file, don't output)
|
||||||
|
|||||||
Reference in New Issue
Block a user