This commit is contained in:
Lysec
2026-01-18 16:24:57 +01:00
parent 385b2d57f2
commit 1410269dfd
52 changed files with 51 additions and 67 deletions
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
# Generate a registry.json from all color schemes in Assets/ColorScheme
# Output format matches ~/Development/misc/noctalia/noctalia-colorschemes/registry.json
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
COLORSCHEME_DIR="$PROJECT_ROOT/Assets/ColorScheme"
# Start JSON output
echo '{'
echo ' "version": 1,'
echo ' "themes": ['
first=true
for dir in "$COLORSCHEME_DIR"/*/; do
[ -d "$dir" ] || continue
name=$(basename "$dir")
json_file="$dir/$name.json"
[ -f "$json_file" ] || continue
# Read the JSON file content
content=$(cat "$json_file")
# Extract dark and light objects using jq
dark=$(echo "$content" | jq -c '.dark')
light=$(echo "$content" | jq -c '.light')
# Skip if missing dark or light
[ "$dark" = "null" ] || [ "$light" = "null" ] && continue
# Add comma before all but first entry
if [ "$first" = true ]; then
first=false
else
echo ','
fi
# Output theme entry
printf ' {\n'
printf ' "name": "%s",\n' "$name"
printf ' "path": "%s",\n' "$name"
printf ' "dark": %s,\n' "$dark"
printf ' "light": %s\n' "$light"
printf ' }'
done
echo ''
echo ' ]'
echo '}'
+73
View File
@@ -0,0 +1,73 @@
#!/bin/bash
# Pull translations from Noctalia Translate API
# Usage: ./i18n-pull.sh <project-slug> <output-dir>
# Example: ./i18n-pull.sh noctalia-shell ./Assets/Translations
set -e
# Configuration
API_BASE="${I18N_API_BASE:-https://i18n.noctalia.dev}"
PROJECT_SLUG="${1:-noctalia-shell}"
OUTPUT_DIR="${2:-./Assets/Translations}"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${YELLOW}Pulling translations for project: ${PROJECT_SLUG}${NC}"
echo "API: ${API_BASE}"
echo "Output: ${OUTPUT_DIR}"
echo ""
# Confirmation
read -p "Pull translations and overwrite local files? [y/N] " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 0
fi
echo ""
# Create output directory if it doesn't exist
mkdir -p "$OUTPUT_DIR"
# Pull all translations
RESPONSE=$(curl -s -w "\n%{http_code}" "${API_BASE}/api/projects/${PROJECT_SLUG}/pull")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" != "200" ]; then
echo -e "${RED}Error: HTTP ${HTTP_CODE}${NC}"
echo "$BODY"
exit 1
fi
# Check if jq is available
if ! command -v jq &> /dev/null; then
echo -e "${RED}Error: jq is required but not installed${NC}"
echo "Install with: apt install jq (Linux) or brew install jq (macOS)"
exit 1
fi
# Get list of locales
LOCALES=$(echo "$BODY" | jq -r 'keys[]')
if [ -z "$LOCALES" ]; then
echo -e "${RED}Error: No translations found${NC}"
exit 1
fi
# Save each locale to a separate file
COUNT=0
for LOCALE in $LOCALES; do
OUTPUT_FILE="${OUTPUT_DIR}/${LOCALE}.json"
echo "$BODY" | jq ".[\"${LOCALE}\"]" > "$OUTPUT_FILE"
echo -e "${GREEN}Saved: ${OUTPUT_FILE}${NC}"
COUNT=$((COUNT + 1))
done
echo ""
echo -e "${GREEN}Successfully pulled ${COUNT} language(s)${NC}"
+116
View File
@@ -0,0 +1,116 @@
#!/bin/bash
# Push translations to Noctalia Translate API
# Usage: TRANSLATION_PUSH_SECRET=your_secret ./push-translations.sh [--overwrite] [/path/to/Assets/Translations]
# Or set the secret in environment and pass the path as argument
set -e
# Parse arguments
OVERWRITE=false
TRANSLATIONS_DIR="Assets/Translations"
for arg in "$@"; do
case $arg in
--overwrite)
OVERWRITE=true
;;
*)
TRANSLATIONS_DIR="$arg"
;;
esac
done
# Configuration
API_URL="${TRANSLATION_API_URL:-https://i18n.noctalia.dev}"
PROJECT_SLUG="${TRANSLATION_PROJECT:-noctalia-shell}"
# Check for secret
if [ -z "$NOCTALIA_SHELL_TRANSLATION_PUSH_SECRET" ]; then
echo "Error: NOCTALIA_SHELL_TRANSLATION_PUSH_SECRET environment variable is required"
exit 1
fi
# Check if directory exists
if [ ! -d "$TRANSLATIONS_DIR" ]; then
echo "Error: Directory not found: $TRANSLATIONS_DIR"
exit 1
fi
# Check for jq
if ! command -v jq &> /dev/null; then
echo "Error: jq is required but not installed"
echo "Install with: apt install jq"
exit 1
fi
echo "Pushing translations from: $TRANSLATIONS_DIR"
echo "Target: $API_URL/api/projects/$PROJECT_SLUG/push"
# Build combined JSON object
COMBINED_JSON="{}"
for file in "$TRANSLATIONS_DIR"/*.json; do
if [ -f "$file" ]; then
# Extract locale from filename (e.g., en.json -> en)
filename=$(basename "$file")
locale="${filename%.json}"
echo " Loading: $locale ($filename)"
# Add this locale's translations to the combined object
COMBINED_JSON=$(echo "$COMBINED_JSON" | jq --arg locale "$locale" --slurpfile content "$file" '. + {($locale): $content[0]}')
fi
done
# Count locales
LOCALE_COUNT=$(echo "$COMBINED_JSON" | jq 'keys | length')
echo "Found $LOCALE_COUNT locale(s)"
if [ "$LOCALE_COUNT" -eq 0 ]; then
echo "Error: No JSON files found in $TRANSLATIONS_DIR"
exit 1
fi
# Check if English exists
if ! echo "$COMBINED_JSON" | jq -e '.en' > /dev/null 2>&1; then
echo "Error: English (en.json) is required"
exit 1
fi
# Confirmation
echo ""
read -p "Push $LOCALE_COUNT locale(s) to $API_URL? [y/N] " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 0
fi
# Build URL with optional overwrite parameter
PUSH_URL="$API_URL/api/projects/$PROJECT_SLUG/push"
if [ "$OVERWRITE" = true ]; then
PUSH_URL="$PUSH_URL?overwrite=true"
echo "Overwrite mode enabled"
fi
# Push to API
echo "Pushing to API..."
RESPONSE=$(echo "$COMBINED_JSON" | curl -s -w "\n%{http_code}" -X POST \
"$PUSH_URL" \
-H "Authorization: Bearer $NOCTALIA_SHELL_TRANSLATION_PUSH_SECRET" \
-H "Content-Type: application/json" \
-d @-)
# Extract HTTP status code (last line) and body (everything else)
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" -eq 200 ]; then
echo "Success!"
echo "$BODY" | jq .
else
echo "Error: HTTP $HTTP_CODE"
echo "$BODY" | jq . 2>/dev/null || echo "$BODY"
exit 1
fi
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Test script for notification replacement functionality
echo "Testing notification replacement..."
echo ""
# Send initial notification and capture the ID
echo "Step 1: Sending initial notification 'asdf'..."
NOTIF_ID=$(notify-send -p "asdf")
echo "Notification ID: $NOTIF_ID"
echo ""
# Wait a moment for the notification to appear
sleep 1
# Replace the notification
echo "Step 2: Replacing notification $NOTIF_ID with 'test'..."
notify-send -r "$NOTIF_ID" -p "test"
echo ""
echo "The notification should now show 'test' instead of 'asdf'."
echo "If it still shows 'asdf', the replacement is not working."
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env -S bash
echo "Sending test notifications..."
# Send a bunch of notifications with numbers
for i in {1..4}; do
notify-send "Notification $i" "This is test notification number $i with a very long text that will probably break the layout or maybe not? Who knows? Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
sleep 1
done
echo "All notifications sent!"
# Additional tests for icon/image handling
if command -v notify-send >/dev/null 2>&1; then
echo "Sending icon/image tests..."
# 1) Themed icon name
notify-send -i dialog-information "Icon name test" "Should resolve from theme (dialog-information)"
sleep 1
# 2) Absolute path if a sample image exists
SAMPLE_IMG="/usr/share/pixmaps/steam.png"
if [ -f "$SAMPLE_IMG" ]; then
notify-send -i "$SAMPLE_IMG" "Absolute path test" "Should show the provided image path"
fi
sleep 1
# 3) file:// URL form
if [ -f "$SAMPLE_IMG" ]; then
notify-send -i "file://$SAMPLE_IMG" "file:// URL test" "Should display after stripping scheme"
fi
sleep 1
echo "Icon/image tests sent!"
fi
# A test notification with actions
gdbus call --session \
--dest org.freedesktop.Notifications \
--object-path /org/freedesktop/Notifications \
--method org.freedesktop.Notifications.Notify \
"my-app" \
0 \
"dialog-question" \
"Confirmation Required" \
"Do you want to proceed with the action?" \
"['default', 'OK', 'cancel', 'Cancel', 'maybe', 'Maybe', 'undecided', 'Undecided']" \
"{}" \
5000
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env -S bash
set -euo pipefail
# QML Formatter Script
# Suppress Qt debug logging from qmlformat
export QT_LOGGING_RULES="qt.qmldom.*=false"
# Find qmlformat binary
QMLFORMAT=""
for path in "/usr/lib64/qt6/bin/qmlformat" "/usr/lib/qt6/bin/qmlformat"; do
if [ -x "$path" ]; then
QMLFORMAT="$path"
break
fi
done
# Fallback to PATH
if [ -z "$QMLFORMAT" ] && command -v qmlformat &>/dev/null; then
QMLFORMAT="qmlformat"
fi
if [ -z "$QMLFORMAT" ]; then
echo "No 'qmlformat' found in standard locations or PATH." >&2
echo "To proceed, install it via 'qt6-tools', 'qt6-declarative-tools' or 'qt6-qtdeclarative-devel'" >&2
exit 1
fi
format_file() {
"${QMLFORMAT}" -w 2 -W 360 -S --semicolon-rule always -i "$1" || { echo "Failed: $1" >&2; return 1; }
}
export -f format_file
export QMLFORMAT
# Find all .qml files
mapfile -t all_files < <(find "${1:-.}" -name "*.qml" -type f)
[ ${#all_files[@]} -eq 0 ] && { echo "No QML files found"; exit 0; }
echo "Formatting ${#all_files[@]} files..."
printf '%s\0' "${all_files[@]}" | \
xargs -0 -P "${QMLFMT_JOBS:-$(nproc)}" -I {} bash -c 'format_file "$@"' _ {} \
&& echo "Done" || { echo "Errors occurred" >&2; exit 1; }
+92
View File
@@ -0,0 +1,92 @@
#!/bin/bash
# Find qsb binary in common locations.
QSB_PATHS=(
"/usr/lib/qt6/bin/qsb"
"/usr/lib64/qt6/bin/qsb"
)
QSB_BIN=""
for path in "${QSB_PATHS[@]}"; do
if [ -x "$path" ]; then
QSB_BIN="$path"
break
fi
done
if [ -z "$QSB_BIN" ]; then
echo "Error: qsb binary not found in any of: ${QSB_PATHS[*]}"
exit 1
fi
# Directory containing the source shaders.
SOURCE_DIR="Shaders/frag/"
# Directory where the compiled shaders will be saved.
DEST_DIR="Shaders/qsb/"
# Check if the source directory exists.
if [ ! -d "$SOURCE_DIR" ]; then
echo "Source directory $SOURCE_DIR not found!"
exit 1
fi
# Create the destination directory if it doesn't exist.
mkdir -p "$DEST_DIR"
# Array to hold the list of full paths to the shaders.
SHADERS_TO_COMPILE=()
# Specific files mode.
if [ "$#" -gt 0 ]; then
# Loop through all command-line arguments ($@ holds all arguments).
for SINGLE_FILE in "$@"; do
# Construct the full path to the source file.
FULL_PATH="$SOURCE_DIR$SINGLE_FILE"
# Check if the specified file exists in the SOURCE_DIR.
if [ ! -f "$FULL_PATH" ]; then
echo "Error: Specified file '$SINGLE_FILE' not found in $SOURCE_DIR! Skipping."
continue
fi
# Add the valid file to the compilation list.
SHADERS_TO_COMPILE+=("$FULL_PATH")
done
# Check if any valid files were found to compile.
if [ ${#SHADERS_TO_COMPILE[@]} -eq 0 ]; then
echo "No valid shaders found to compile."
exit 1
fi
# Whole directory mode (no argument provided).
else
# Use find to generate the list of files and assign it to the array.
while IFS= read -r shader_path; do
if [ -n "$shader_path" ]; then
SHADERS_TO_COMPILE+=("$shader_path")
fi
done < <(find "$SOURCE_DIR" -maxdepth 1 -name "*.frag")
fi
# Loop through the list of shaders to compile.
for shader in "${SHADERS_TO_COMPILE[@]}"; do
# Get the base name of the file (e.g., wp_fade).
shader_name=$(basename "$shader" .frag)
# Construct the output path for the compiled shader.
output_path="$DEST_DIR$shader_name.frag.qsb"
# Construct and run the qsb command.
"$QSB_BIN" --qt6 -o "$output_path" "$shader"
# Print a message to confirm compilation.
echo "Compiled $(basename "$shader") to $output_path"
done
echo "Shader compilation complete."