141 lines
4.6 KiB
Bash
Executable File
141 lines
4.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Compact Flatpak TUI launcher
|
|
|
|
# Get installed apps: use only application ID, then extract readable name
|
|
readarray -t app_ids < <(flatpak list --app --columns=application 2>/dev/null | tail -n +1 | sort)
|
|
|
|
# Check if flatpak is available
|
|
if ! command -v flatpak &> /dev/null; then
|
|
echo "flatpak not found. Please install flatpak."
|
|
exit 1
|
|
fi
|
|
|
|
# Check for installed apps
|
|
if [ ${#app_ids[@]} -eq 0 ]; then
|
|
echo "No Flatpak apps installed."
|
|
exit 0
|
|
fi
|
|
|
|
show_menu() {
|
|
local input="" selection=0 max_display=8
|
|
|
|
while true; do
|
|
# Clear screen
|
|
printf "\033[2J\033[H"
|
|
|
|
# Header
|
|
echo "+----------------------------------+"
|
|
echo "| Flatpak App Launcher |"
|
|
echo "+----------------------------------+"
|
|
|
|
# Search bar
|
|
if [ -z "$input" ]; then
|
|
echo "| Search: (type to filter) |"
|
|
else
|
|
printf "| Search: %-28s |\n" "$input"
|
|
fi
|
|
|
|
# Filter apps
|
|
local filtered=() results_count=0
|
|
for app_id in "${app_ids[@]}"; do
|
|
# Extract a readable name from the app ID (e.g. org.gimp.GIMP -> GIMP)
|
|
local readable_name="${app_id##*.}"
|
|
if [[ "${readable_name,,}" == *"${input,,}"* ]] || [[ "${app_id,,}" == *"${input,,}"* ]]; then
|
|
filtered+=("$app_id")
|
|
fi
|
|
done
|
|
|
|
results_count=${#filtered[@]}
|
|
|
|
# Results header
|
|
if [ $results_count -eq 0 ]; then
|
|
echo "+----------------------------------+"
|
|
echo "| No matches. Press ESC to clear. |"
|
|
else
|
|
echo "+----------------------------------+"
|
|
printf "| %d app(s) found |\n" "$results_count"
|
|
|
|
# Calculate display range
|
|
local start=$selection
|
|
local end=$((start + max_display))
|
|
[ $end -gt $results_count ] && end=$results_count
|
|
|
|
# Show apps (compact list)
|
|
for i in "${!filtered[@]}"; do
|
|
if [ $i -ge $start ] && [ $i -lt $end ]; then
|
|
local app_id="${filtered[i]}"
|
|
# Extract readable name from app ID (last segment)
|
|
local app_name="${app_id##*.}"
|
|
local display_name=$(echo "$app_name" | cut -c1-30)
|
|
|
|
if [ $i -eq $selection ]; then
|
|
printf "| > %-30s |\n" "$display_name"
|
|
else
|
|
printf "| %-30s |\n" "$display_name"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Fill empty space
|
|
while [ $((end - start)) -lt $max_display ]; do
|
|
echo "| |"
|
|
end=$((end + 1))
|
|
done
|
|
|
|
# Scroll indicator
|
|
if [ $results_count -gt $max_display ]; then
|
|
local percent=$((selection * 100 / (results_count - max_display + 1)))
|
|
printf "| Scroll: %3d%% (%d-%d of %d) |\n" "$percent" "$((start+1))" "$end" "$results_count"
|
|
fi
|
|
fi
|
|
|
|
# Footer
|
|
echo "+----------------------------------+"
|
|
echo "| Enter:Launch ESC:Quit |"
|
|
echo "+----------------------------------+"
|
|
|
|
# Handle input
|
|
local key=""
|
|
read -rn1 key 2>/dev/null || break
|
|
|
|
case "$key" in
|
|
"") # Enter - launch
|
|
if [ $results_count -gt 0 ] && [ $selection -lt $results_count ]; then
|
|
local app_id="${filtered[selection]}"
|
|
printf "\033[2J\033[H"
|
|
echo "Launching ${app_id##*.}..."
|
|
flatpak run "$app_id" &
|
|
disown
|
|
break
|
|
fi
|
|
;;
|
|
$'\x7f') # Backspace
|
|
input="${input%?}"
|
|
selection=0
|
|
;;
|
|
$'\x1b') # Escape sequence
|
|
local seq=""
|
|
read -rn1 -t 0.1 seq 2>/dev/null || { break; } # ESC pressed
|
|
if [ "$seq" = "[" ]; then
|
|
read -rn1 -t 0.1 seq 2>/dev/null || continue
|
|
case "$seq" in
|
|
"A") # Up
|
|
[ $selection -gt 0 ] && selection=$((selection-1))
|
|
;;
|
|
"B") # Down
|
|
[ $selection -lt $((results_count - 1)) ] && selection=$((selection+1))
|
|
;;
|
|
esac
|
|
fi
|
|
;;
|
|
*) # Regular input
|
|
input+="$key"
|
|
selection=0
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
show_menu
|