#!/bin/bash set -e # Colors for output GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color echo -e "${GREEN}Generating app icons...${NC}\n" # Check for inkscape (preferred) or rsvg-convert as fallback if command -v inkscape &> /dev/null; then SVG_RENDERER="inkscape" elif command -v rsvg-convert &> /dev/null; then SVG_RENDERER="rsvg" else echo -e "${YELLOW}Warning: neither inkscape nor rsvg-convert found. Install one to render SVG icons.${NC}" echo "On Fedora/RHEL: sudo dnf install inkscape" echo "On Ubuntu/Debian: sudo apt-get install inkscape" exit 1 fi # Check if ImageMagick is installed (needed for compositing). # ImageMagick 7+ uses `magick`; ImageMagick 6 (Ubuntu/Debian) uses `convert`. if command -v magick &> /dev/null; then MAGICK="magick" elif command -v convert &> /dev/null; then MAGICK="convert" else echo -e "${YELLOW}Warning: ImageMagick not found. Please install it to generate icons.${NC}" echo "On Fedora/RHEL: sudo dnf install ImageMagick" echo "On Ubuntu/Debian: sudo apt-get install imagemagick" exit 1 fi # Source SVG logo SOURCE_SVG="public/logo.svg" if [ ! -f "$SOURCE_SVG" ]; then echo -e "${YELLOW}Error: Source logo not found at $SOURCE_SVG${NC}" exit 1 fi # Brand colors BG_COLOR="#e9673f" # Agora orange (hsl(14 79% 58%)) TMPDIR=$(mktemp -d) LOGO_WHITE_SVG="$TMPDIR/logo_white.svg" LOGO_WHITE="$TMPDIR/logo_white.png" # Recolor the SVG fill to white before rasterizing. The phoenix logo.svg # declares fill="#fcd414"; older sources used black/purple, kept for safety. sed -e 's/fill="black"/fill="#ffffff"/g' \ -e 's/#000000/#ffffff/g' \ -e 's/#7c52e0/#ffffff/g' \ -e 's/#fcd414/#ffffff/g' "$SOURCE_SVG" > "$LOGO_WHITE_SVG" echo "Rendering white SVG (preserving aspect ratio)..." # Render at 1024px tall and let the renderer derive the width from the SVG # viewBox, so the non-square logo (720x880) is NOT stretched into a square. # The composite steps below use -resize WxH which fits-inside (aspect- # preserving), keeping the glyph's true proportions. if [ "$SVG_RENDERER" = "inkscape" ]; then inkscape --export-type=png --export-filename="$LOGO_WHITE" -h 1024 "$LOGO_WHITE_SVG" 2>/dev/null else rsvg-convert -h 1024 "$LOGO_WHITE_SVG" -o "$LOGO_WHITE" fi # Orange-fill render, for marks placed on a white/light background (iOS splash). LOGO_ORANGE_SVG="$TMPDIR/logo_orange.svg" LOGO_ORANGE="$TMPDIR/logo_orange.png" sed -e 's/fill="black"/fill="'"$BG_COLOR"'"/g' \ -e 's/#000000/'"$BG_COLOR"'/g' \ -e 's/#7c52e0/'"$BG_COLOR"'/g' \ -e 's/#fcd414/'"$BG_COLOR"'/g' "$SOURCE_SVG" > "$LOGO_ORANGE_SVG" if [ "$SVG_RENDERER" = "inkscape" ]; then inkscape --export-type=png --export-filename="$LOGO_ORANGE" -h 1024 "$LOGO_ORANGE_SVG" 2>/dev/null else rsvg-convert -h 1024 "$LOGO_ORANGE_SVG" -o "$LOGO_ORANGE" fi # ── Adaptive icon foreground PNGs (transparent bg, white logo, safe-zone padding) ── # Content at 47% of canvas to fit within Android's adaptive icon safe zone. echo "Generating adaptive foreground PNGs..." make_foreground() { local size=$1 local content_size=$(echo "$size * 47 / 100" | bc) local dest=$2 $MAGICK -size "${size}x${size}" "xc:none" \ \( "$LOGO_WHITE" -resize "${content_size}x${content_size}" \) \ -gravity center -compose over -composite \ "$dest" } make_foreground 48 android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png make_foreground 72 android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png make_foreground 96 android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png make_foreground 144 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png make_foreground 192 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png # ── Legacy launcher icons (ic_launcher.png and ic_launcher_round.png) ── # These are used on pre-API-26 devices and as fallback on some launchers. # Both are the white logo composited onto an orange circle (brand mark). echo "Generating legacy launcher icons (ic_launcher.png and ic_launcher_round.png)..." # make_legacy_square: white logo on an orange circle (transparent corners) make_legacy_square() { local size=$1 local content_size=$(echo "$size * 60 / 100" | bc) local dest=$2 local mask="$TMPDIR/circle_mask_sq_${size}.png" $MAGICK -size "${size}x${size}" "xc:none" \ -fill white -draw "circle $((size/2)),$((size/2)) $((size/2)),0" \ "$mask" $MAGICK -size "${size}x${size}" "xc:${BG_COLOR}" \ "$mask" -compose dst-in -composite \ \( "$LOGO_WHITE" -resize "${content_size}x${content_size}" \) \ -gravity center -compose over -composite \ "$dest" } # make_legacy_round: white logo on circular orange background (alpha-masked circle) make_legacy_round() { local size=$1 local content_size=$(echo "$size * 60 / 100" | bc) local dest=$2 local mask="$TMPDIR/circle_mask_${size}.png" # Create a white circle mask $MAGICK -size "${size}x${size}" "xc:none" \ -fill white -draw "circle $((size/2)),$((size/2)) $((size/2)),0" \ "$mask" # Fill orange, apply circle mask, composite logo $MAGICK -size "${size}x${size}" "xc:${BG_COLOR}" \ "$mask" -compose dst-in -composite \ \( "$LOGO_WHITE" -resize "${content_size}x${content_size}" \) \ -gravity center -compose over -composite \ "$dest" } make_legacy_square 48 android/app/src/main/res/mipmap-mdpi/ic_launcher.png make_legacy_square 72 android/app/src/main/res/mipmap-hdpi/ic_launcher.png make_legacy_square 96 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png make_legacy_square 144 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png make_legacy_square 192 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png # Web logo.png (AppDownloadNudge) uses the same round brand-mark style. make_legacy_round 512 public/logo.png # PWA install icons (manifest.webmanifest "any" + "maskable" purposes). make_legacy_round 192 public/icon-192.png make_legacy_round 512 public/icon-512.png make_legacy_round 48 android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png make_legacy_round 72 android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png make_legacy_round 96 android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png make_legacy_round 144 android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png make_legacy_round 192 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png # ── Android push-notification status-bar icon (ic_stat_ditto) ── # Must be a flat white silhouette on transparent — the OS tints it, any # color/gradient gets ignored or looks wrong. Referenced directly by # NostrPoller.java / NotificationRelayService.java via R.drawable.ic_stat_ditto. echo "Generating notification status-bar icon (ic_stat_ditto)..." make_notification_icon() { local size=$1 local content_size=$(echo "$size * 80 / 100" | bc) local dest=$2 $MAGICK -size "${size}x${size}" "xc:none" \ \( "$LOGO_WHITE" -resize "${content_size}x${content_size}" \) \ -gravity center -compose over -composite \ "$dest" } for dir in drawable mipmap; do make_notification_icon 24 android/app/src/main/res/${dir}-mdpi/ic_stat_ditto.png make_notification_icon 48 android/app/src/main/res/${dir}-xhdpi/ic_stat_ditto.png make_notification_icon 72 android/app/src/main/res/${dir}-xxhdpi/ic_stat_ditto.png make_notification_icon 96 android/app/src/main/res/${dir}-xxxhdpi/ic_stat_ditto.png done make_notification_icon 36 android/app/src/main/res/drawable-hdpi/ic_stat_ditto.png # Update background color BACKGROUND_COLOR_FILE="android/app/src/main/res/values/ic_launcher_background.xml" mkdir -p android/app/src/main/res/values cat > "$BACKGROUND_COLOR_FILE" << 'EOF' #e9673f EOF # ── iOS App Icon (1024x1024, white logo on orange background) ── echo "Generating iOS app icon..." IOS_ICON_DIR="ios/App/App/Assets.xcassets/AppIcon.appiconset" if [ -d "$IOS_ICON_DIR" ]; then IOS_ICON="$IOS_ICON_DIR/AppIcon-512@2x.png" # Logo at ~60% of canvas, centered on orange background (matches Android style) $MAGICK -size "1024x1024" "xc:${BG_COLOR}" \ \( "$LOGO_WHITE" -resize "614x614" \) \ -gravity center -compose over -composite \ "$IOS_ICON" echo -e " ${GREEN}✓${NC} $IOS_ICON" else echo -e " ${YELLOW}Skipped: $IOS_ICON_DIR not found${NC}" fi # ── iOS launch screen (Splash.imageset, 2732x2732, white bg + small mark) ── # Referenced by LaunchScreen.storyboard. Ships one image for all 3 scale # slots (1x/2x/3x), matching how the project already had it set up. echo "Generating iOS launch screen..." IOS_SPLASH_DIR="ios/App/App/Assets.xcassets/Splash.imageset" if [ -d "$IOS_SPLASH_DIR" ]; then $MAGICK -size "2732x2732" "xc:white" \ \( "$LOGO_ORANGE" -resize "160x160" \) \ -gravity center -compose over -composite \ "$IOS_SPLASH_DIR/splash-2732x2732.png" cp "$IOS_SPLASH_DIR/splash-2732x2732.png" "$IOS_SPLASH_DIR/splash-2732x2732-1.png" cp "$IOS_SPLASH_DIR/splash-2732x2732.png" "$IOS_SPLASH_DIR/splash-2732x2732-2.png" echo -e " ${GREEN}✓${NC} $IOS_SPLASH_DIR (3 files)" else echo -e " ${YELLOW}Skipped: $IOS_SPLASH_DIR not found${NC}" fi # Cleanup temp files rm -rf "$TMPDIR" echo -e "\n${GREEN}App icons generated successfully!${NC}" echo -e "Icon: white Agora logo on ${GREEN}${BG_COLOR}${NC} (Agora orange)" echo -e "Generated:" echo -e " Android:" echo -e " - ic_launcher_foreground.png (adaptive, all densities)" echo -e " - ic_launcher.png (legacy square, all densities)" echo -e " - ic_launcher_round.png (legacy round, all densities)" echo -e " iOS:" echo -e " - AppIcon-512@2x.png (1024x1024)"