From 99b3ca6db796130f99ad45524815585621cad8d0 Mon Sep 17 00:00:00 2001 From: Ben Weeks Date: Tue, 23 Dec 2025 02:24:58 +0000 Subject: [PATCH] feat: update extension icon with shop storefront design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add generate_logo.py script to create icon programmatically - New shop icon with striped awning and display windows - Consistent purple color scheme with Nostr Proxy extension - Update config.json to reference new icon Closes #150 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- config.json | 2 +- static/images/generate_logo.py | 123 +++++++++++++++++++++++++++++++++ static/images/nostr-market.png | Bin 0 -> 4432 bytes 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 static/images/generate_logo.py create mode 100644 static/images/nostr-market.png diff --git a/config.json b/config.json index a02b0b0..1aa34a8 100644 --- a/config.json +++ b/config.json @@ -2,7 +2,7 @@ "name": "Nostr Market", "version": "1.1.0", "short_description": "Nostr Webshop/market on LNbits", - "tile": "/nostrmarket/static/images/bitcoin-shop.png", + "tile": "/nostrmarket/static/images/nostr-market.png", "min_lnbits_version": "1.4.0", "contributors": [ { diff --git a/static/images/generate_logo.py b/static/images/generate_logo.py new file mode 100644 index 0000000..cb66c59 --- /dev/null +++ b/static/images/generate_logo.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +""" +Generate the Nostr Market logo. +Requires: pip install Pillow +""" + +from PIL import Image, ImageDraw # type: ignore[import-not-found] + +# Render at 4x size for antialiasing +scale = 4 +size = 128 * scale +final_size = 128 + +# Consistent color scheme with Nostr Proxy +dark_purple = (80, 40, 120) +light_purple = (140, 100, 180) +white = (255, 255, 255) + +margin = 4 * scale + +swoosh_center = ((128 + 100) * scale, -90 * scale) +swoosh_radius = 220 * scale + +# Create rounded rectangle mask +mask = Image.new("L", (size, size), 0) +mask_draw = ImageDraw.Draw(mask) +corner_radius = 20 * scale +mask_draw.rounded_rectangle( + [margin, margin, size - margin, size - margin], + radius=corner_radius, + fill=255, +) + +# Create background with swoosh +bg = Image.new("RGBA", (size, size), (0, 0, 0, 0)) +bg_draw = ImageDraw.Draw(bg) +bg_draw.rounded_rectangle( + [margin, margin, size - margin, size - margin], + radius=corner_radius, + fill=dark_purple, +) +bg_draw.ellipse( + [ + swoosh_center[0] - swoosh_radius, + swoosh_center[1] - swoosh_radius, + swoosh_center[0] + swoosh_radius, + swoosh_center[1] + swoosh_radius, + ], + fill=light_purple, +) + +# Apply rounded rectangle mask +final = Image.new("RGBA", (size, size), (0, 0, 0, 0)) +final.paste(bg, mask=mask) +draw = ImageDraw.Draw(final) + +center_x, center_y = size // 2, size // 2 + +# Shop/storefront - wider and shorter for shop look +shop_width = 80 * scale +awning_height = 18 * scale +body_height = 45 * scale +total_height = awning_height + body_height + +shop_left = center_x - shop_width // 2 +shop_right = center_x + shop_width // 2 + +# Center vertically +awning_top = center_y - total_height // 2 +awning_bottom = awning_top + awning_height +shop_bottom = awning_bottom + body_height +awning_extend = 5 * scale + +# Draw awning background (white base) +draw.rectangle( + [shop_left - awning_extend, awning_top, shop_right + awning_extend, awning_bottom], + fill=white, +) + +# Vertical stripes on awning (alternating dark purple) +stripe_count = 8 +stripe_width = (shop_width + 2 * awning_extend) // stripe_count +for i in range(1, stripe_count, 2): + x_left = shop_left - awning_extend + i * stripe_width + draw.rectangle( + [x_left, awning_top, x_left + stripe_width, awning_bottom], + fill=dark_purple, + ) + +# Shop body (below awning) +draw.rectangle( + [shop_left, awning_bottom, shop_right, shop_bottom], + fill=white, +) + +# Large display window (shop style) +window_margin = 8 * scale +window_top = awning_bottom + 6 * scale +window_bottom = shop_bottom - 6 * scale +# Left display window +draw.rectangle( + [shop_left + window_margin, window_top, center_x - 10 * scale, window_bottom], + fill=dark_purple, +) +# Right display window +draw.rectangle( + [center_x + 10 * scale, window_top, shop_right - window_margin, window_bottom], + fill=dark_purple, +) + +# Door (center, dark purple cutout) +door_width = 14 * scale +door_left = center_x - door_width // 2 +draw.rectangle( + [door_left, window_top, door_left + door_width, shop_bottom], + fill=dark_purple, +) + +# Downscale with LANCZOS for antialiasing +final = final.resize((final_size, final_size), Image.LANCZOS) + +final.save("nostr-market.png") +print("Logo saved to nostr-market.png") diff --git a/static/images/nostr-market.png b/static/images/nostr-market.png new file mode 100644 index 0000000000000000000000000000000000000000..3e924b594eea5da5ad7f935755f07f07799969d8 GIT binary patch literal 4432 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 ZZ)o4>-mvYNJ_7>-gQu&X%Q~loCIF$JKV<*_ literal 0 HcmV?d00001