#!/bin/bash appInstallMenu() { while true; do isHeader "App Categories" echo "" isNotice "Loading application categories..." echo "" local menu_categories=() declare -A category_app_data for category_app_dir in "$install_containers_dir"/*/; do if [ -d "$category_app_dir" ]; then local category_config_file="$category_app_dir/$(basename "$category_app_dir").config" if [ -f "$category_config_file" ]; then source "$category_config_file" local category_app_name=$(basename "$category_app_dir") local category_app_category=$(grep -Po "CFG_${category_app_name^^}_CATEGORY=\"[^\"]*\"" "$category_config_file" 2>/dev/null | sed "s/.*CATEGORY=\"\([^\"]*\)\".*/\1/") local category_app_title=$(grep -Po "CFG_${category_app_name^^}_TITLE=\"[^\"]*\"" "$category_config_file" 2>/dev/null | sed "s/.*TITLE=\"\([^\"]*\)\".*/\1/") local category_app_description=$(grep -Po "CFG_${category_app_name^^}_DESCRIPTION=\"[^\"]*\"" "$category_config_file" 2>/dev/null | sed "s/.*DESCRIPTION=\"\([^\"]*\)\".*/\1/") if [ -n "$category_app_name" ] && [ -n "$category_app_category" ]; then if [[ ! " ${menu_categories[@]} " =~ " ${category_app_category} " ]]; then menu_categories+=("$category_app_category") fi local actions_var="CFG_${category_app_name^^}_ACTIONS" local available_actions="${!actions_var}" category_app_data["$category_app_name"]="$category_app_category|$category_app_title|$category_app_description|$available_actions" fi fi fi done IFS=$'\n' sorted_menu_categories=($(sort <<<"${menu_categories[*]}")) unset IFS for i in "${!sorted_menu_categories[@]}"; do local capitalized_category=$(echo "${sorted_menu_categories[$i]}" | awk '{print toupper(substr($0, 1, 1)) tolower(substr($0, 2))}') isOption "$((i + 1)). ${capitalized_category}" done echo "" isOption "x. Exit" echo "" isQuestion "Please select an option (1-${#sorted_menu_categories[@]} or 'x' to exit): " read -p "" choice if [[ "$choice" =~ ^[1-9][0-9]*$ ]] && [ "$choice" -le "${#sorted_menu_categories[@]}" ]; then local selected_category="${sorted_menu_categories[$((choice - 1))]}" local capitalized_category=$(echo "${selected_category}" | awk '{print toupper(substr($0, 1, 1)) tolower(substr($0, 2))}') showInstructions; isHeader "${capitalized_category}" local app_list=() local user_actions=() # Store user inputs for each app # Build app list from stored app_data (no file reading!) for category_app_name in "${!category_app_data[@]}"; do local stored_data="${category_app_data[$category_app_name]}" IFS='|' read -r category_app_category category_app_title category_app_description actions <<< "$stored_data" if [[ "$category_app_category" == "$selected_category" ]]; then app_list+=("$category_app_name:$category_app_title:$category_app_description:$actions") fi done if [ ${#app_list[@]} -eq 0 ]; then isNotice "No applications found in category '$selected_category'!" continue fi # Show each app on single line and collect input for app_entry in "${app_list[@]}"; do IFS=':' read -r app_name title description actions <<< "$app_entry" # Extract first letters from actions and format with commas actions_display=$(echo "$actions" | tr '|' '\n' | cut -c1 | paste -sd, - | sed 's/,$//') isQuestion "$title - $description [$actions_display] : " read -p "" app_input if [ -n "$app_input" ]; then user_actions+=("$app_name:$app_input") fi done if [ ${#user_actions[@]} -gt 0 ]; then echo "" isNotice "Processing actions..." for action_pair in "${user_actions[@]}"; do IFS=':' read -r app_name user_input <<< "$action_pair" if [ -z "$app_name" ] || [ -z "$user_input" ]; then continue fi isNotice "Processing app: $app_name with actions: $user_input" # Set app variable with complete user input declare -g "${app_name}=${user_input}" # Call install function once with all actions local install_func="install${app_name^}" if declare -f "$install_func" > /dev/null; then "$install_func" else isNotice "Warning: Function '$install_func' not found." fi # Clean up after execution unset "${app_name}" done endStart else isNotice "No actions entered." fi elif [[ "$choice" == "x" ]]; then isNotice "Exiting..." else isNotice "Invalid selection. Please choose a valid category or 'x' to exit." fi done }