database schema adjustments to server/realm/scene
20
stock/avatar/angry.svg
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - narrowed -->
|
||||
<ellipse cx="16" cy="20" rx="3" ry="2.5" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="15" cy="19" rx="1" ry="1" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Left eyebrow - angled inward/down -->
|
||||
<path d="M 10 14 L 20 17" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round"/>
|
||||
|
||||
<!-- Right eye - narrowed -->
|
||||
<ellipse cx="32" cy="20" rx="3" ry="2.5" fill="#000000"/>
|
||||
<!-- Right eye highlight -->
|
||||
<ellipse cx="31" cy="19" rx="1" ry="1" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Right eyebrow - angled inward/down -->
|
||||
<path d="M 28 17 L 38 14" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round"/>
|
||||
|
||||
<!-- Angry mouth - tight frown -->
|
||||
<path d="M 16 32 Q 24 28 32 32" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 982 B |
23
stock/avatar/confused.svg
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - normal -->
|
||||
<ellipse cx="16" cy="19" rx="3" ry="4" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="15" cy="17" rx="1" ry="1.5" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Left eyebrow - flat/slightly down -->
|
||||
<path d="M 10 14 Q 16 14 22 15" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Right eye - slightly squinted -->
|
||||
<ellipse cx="32" cy="20" rx="3" ry="3" fill="#000000"/>
|
||||
<!-- Right eye highlight -->
|
||||
<ellipse cx="31" cy="18" rx="1" ry="1.2" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Right eyebrow - raised/quirked -->
|
||||
<path d="M 26 12 Q 32 9 38 13" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Confused mouth - wavy/uncertain -->
|
||||
<path d="M 14 32 Q 18 30 22 33 Q 26 30 30 33 Q 34 30 34 32" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Question mark thought -->
|
||||
<text x="40" y="12" font-family="Arial, sans-serif" font-size="10" fill="#000000" opacity="0.6">?</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
30
stock/avatar/crying.svg
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - squinting/crying -->
|
||||
<ellipse cx="16" cy="20" rx="2.5" ry="2" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="15" cy="19" rx="0.8" ry="0.6" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Left eyebrow - angled down sharply -->
|
||||
<path d="M 10 14 Q 16 12 21 15" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Right eye - squinting/crying -->
|
||||
<ellipse cx="32" cy="20" rx="2.5" ry="2" fill="#000000"/>
|
||||
<!-- Right eye highlight -->
|
||||
<ellipse cx="31" cy="19" rx="0.8" ry="0.6" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Right eyebrow - angled down sharply -->
|
||||
<path d="M 27 15 Q 32 12 38 14" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Crying frown - wavy/trembling -->
|
||||
<path d="M 14 34 Q 19 28 24 31 Q 29 28 34 34" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Left tear stream -->
|
||||
<ellipse cx="18" cy="26" rx="2" ry="2.5" fill="#6BC5E8" opacity="0.8"/>
|
||||
<ellipse cx="17" cy="31" rx="1.5" ry="2" fill="#6BC5E8" opacity="0.7"/>
|
||||
<ellipse cx="16" cy="36" rx="1" ry="1.5" fill="#6BC5E8" opacity="0.6"/>
|
||||
|
||||
<!-- Right tear stream -->
|
||||
<ellipse cx="30" cy="26" rx="2" ry="2.5" fill="#6BC5E8" opacity="0.8"/>
|
||||
<ellipse cx="31" cy="31" rx="1.5" ry="2" fill="#6BC5E8" opacity="0.7"/>
|
||||
<ellipse cx="32" cy="36" rx="1" ry="1.5" fill="#6BC5E8" opacity="0.6"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
45
stock/avatar/face.svg
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<style>
|
||||
:root {
|
||||
--face-primary: #FFCC00;
|
||||
--face-highlight: #FFE566;
|
||||
--face-shadow: #CC9900;
|
||||
}
|
||||
.face-primary { stop-color: var(--face-primary); }
|
||||
.face-highlight { stop-color: var(--face-highlight); }
|
||||
.face-shadow { stop-color: var(--face-shadow); }
|
||||
.face-stroke { stroke: var(--face-shadow); }
|
||||
.bevel-fill { fill: var(--face-primary); }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<!-- Radial gradient for 3D sphere effect -->
|
||||
<radialGradient id="faceGradient" cx="35%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="50%" class="face-highlight"/>
|
||||
<stop offset="100%" class="face-primary"/>
|
||||
</radialGradient>
|
||||
|
||||
<!-- Darker gradient for bottom edge (bevel effect) -->
|
||||
<radialGradient id="shadowGradient" cx="50%" cy="0%" r="100%">
|
||||
<stop offset="60%" class="face-primary"/>
|
||||
<stop offset="100%" class="face-shadow"/>
|
||||
</radialGradient>
|
||||
|
||||
<!-- Drop shadow filter -->
|
||||
<filter id="dropShadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="1" dy="2" stdDeviation="2" flood-color="#000000" flood-opacity="0.3"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<!-- Main face with gradient and shadow -->
|
||||
<circle cx="24" cy="24" r="20" fill="url(#faceGradient)" class="face-stroke" stroke-width="1.5" filter="url(#dropShadow)"/>
|
||||
|
||||
<!-- Subtle bottom bevel overlay -->
|
||||
<ellipse cx="24" cy="32" rx="18" ry="12" fill="url(#shadowGradient)" opacity="0.3"/>
|
||||
|
||||
<!-- Specular highlight (top-left light reflection) -->
|
||||
<ellipse cx="16" cy="14" rx="6" ry="4" fill="#FFFFFF" opacity="0.6"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
18
stock/avatar/laughing.svg
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - closed/squinting (happy arc) -->
|
||||
<path d="M 12 18 Q 16 14 20 18" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Right eye - closed/squinting (happy arc) -->
|
||||
<path d="M 28 18 Q 32 14 36 18" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Big open laughing mouth -->
|
||||
<path d="M 12 28 Q 24 44 36 28" fill="#000000" stroke="#000000" stroke-width="2" stroke-linecap="round"/>
|
||||
<!-- Tongue/inner mouth -->
|
||||
<ellipse cx="24" cy="34" rx="6" ry="4" fill="#CC4444"/>
|
||||
|
||||
<!-- Laugh lines / tears of joy -->
|
||||
<path d="M 8 20 Q 10 22 8 24" fill="none" stroke="#6BC5E8" stroke-width="1" stroke-linecap="round" opacity="0.7"/>
|
||||
<path d="M 40 20 Q 38 22 40 24" fill="none" stroke="#6BC5E8" stroke-width="1" stroke-linecap="round" opacity="0.7"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 978 B |
22
stock/avatar/love.svg
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left heart eye -->
|
||||
<path d="M 16 16 C 13 13 9 16 9 19 C 9 23 16 27 16 27 C 16 27 23 23 23 19 C 23 16 19 13 16 16" fill="#FF1493"/>
|
||||
<!-- Left heart highlight -->
|
||||
<ellipse cx="12" cy="17" rx="1.5" ry="1" fill="#FFFFFF" opacity="0.5"/>
|
||||
|
||||
<!-- Right heart eye -->
|
||||
<path d="M 32 16 C 29 13 25 16 25 19 C 25 23 32 27 32 27 C 32 27 39 23 39 19 C 39 16 35 13 32 16" fill="#FF1493"/>
|
||||
<!-- Right heart highlight -->
|
||||
<ellipse cx="28" cy="17" rx="1.5" ry="1" fill="#FFFFFF" opacity="0.5"/>
|
||||
|
||||
<!-- Happy/dreamy smile -->
|
||||
<path d="M 12 30 Q 24 42 36 30" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<!-- Inner smile shadow for depth -->
|
||||
<path d="M 14 31 Q 24 40 34 31" fill="none" stroke="#996600" stroke-width="1" stroke-linecap="round" opacity="0.4"/>
|
||||
|
||||
<!-- Blush marks -->
|
||||
<ellipse cx="10" cy="28" rx="3" ry="2" fill="#FF6B6B" opacity="0.4"/>
|
||||
<ellipse cx="38" cy="28" rx="3" ry="2" fill="#FF6B6B" opacity="0.4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
16
stock/avatar/neutral.svg
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye -->
|
||||
<ellipse cx="16" cy="19" rx="3" ry="4" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="15" cy="17" rx="1" ry="1.5" fill="#FFFFFF" opacity="0.8"/>
|
||||
|
||||
<!-- Right eye -->
|
||||
<ellipse cx="32" cy="19" rx="3" ry="4" fill="#000000"/>
|
||||
<!-- Right eye highlight -->
|
||||
<ellipse cx="31" cy="17" rx="1" ry="1.5" fill="#FFFFFF" opacity="0.8"/>
|
||||
|
||||
<!-- Neutral straight mouth -->
|
||||
<path d="M 14 30 L 34 30" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 654 B |
23
stock/avatar/sad.svg
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - droopy -->
|
||||
<ellipse cx="16" cy="20" rx="3" ry="3.5" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="15" cy="18.5" rx="1" ry="1.2" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Left eyebrow - angled down -->
|
||||
<path d="M 11 14 Q 16 13 20 15" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Right eye - droopy -->
|
||||
<ellipse cx="32" cy="20" rx="3" ry="3.5" fill="#000000"/>
|
||||
<!-- Right eye highlight -->
|
||||
<ellipse cx="31" cy="18.5" rx="1" ry="1.2" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Right eyebrow - angled down -->
|
||||
<path d="M 28 15 Q 32 13 37 14" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Sad frown - inverted curve -->
|
||||
<path d="M 14 33 Q 24 26 34 33" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Optional tear drop -->
|
||||
<ellipse cx="20" cy="26" rx="1.5" ry="2" fill="#6BC5E8" opacity="0.7"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
21
stock/avatar/sleeping.svg
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - closed (sleeping arc, curves down) -->
|
||||
<path d="M 12 20 Q 16 23 20 20" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Right eye - closed (sleeping arc, curves down) -->
|
||||
<path d="M 28 20 Q 32 23 36 20" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Sleeping mouth - small open snore -->
|
||||
<ellipse cx="24" cy="32" rx="3" ry="2" fill="#000000"/>
|
||||
|
||||
<!-- Z's for sleeping -->
|
||||
<text x="38" y="12" font-family="sans-serif" font-size="8" font-weight="bold" fill="#000000">Z</text>
|
||||
<text x="42" y="8" font-family="sans-serif" font-size="6" font-weight="bold" fill="#000000" opacity="0.7">z</text>
|
||||
<text x="45" y="5" font-family="sans-serif" font-size="4" font-weight="bold" fill="#000000" opacity="0.5">z</text>
|
||||
|
||||
<!-- Blush/rosy cheeks -->
|
||||
<ellipse cx="10" cy="26" rx="3" ry="2" fill="#FF9999" opacity="0.3"/>
|
||||
<ellipse cx="38" cy="26" rx="3" ry="2" fill="#FF9999" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
18
stock/avatar/smile.svg
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye -->
|
||||
<ellipse cx="16" cy="19" rx="3" ry="4" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="15" cy="17" rx="1" ry="1.5" fill="#FFFFFF" opacity="0.8"/>
|
||||
|
||||
<!-- Right eye -->
|
||||
<ellipse cx="32" cy="19" rx="3" ry="4" fill="#000000"/>
|
||||
<!-- Right eye highlight -->
|
||||
<ellipse cx="31" cy="17" rx="1" ry="1.5" fill="#FFFFFF" opacity="0.8"/>
|
||||
|
||||
<!-- Smile with slight depth -->
|
||||
<path d="M 12 28 Q 24 40 36 28" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<!-- Inner smile shadow for depth -->
|
||||
<path d="M 14 29 Q 24 38 34 29" fill="none" stroke="#996600" stroke-width="1" stroke-linecap="round" opacity="0.4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 824 B |
22
stock/avatar/surprised.svg
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - wide open -->
|
||||
<ellipse cx="16" cy="18" rx="4" ry="5" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="14.5" cy="16" rx="1.5" ry="2" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Left eyebrow - raised -->
|
||||
<path d="M 10 11 Q 16 9 22 11" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Right eye - wide open -->
|
||||
<ellipse cx="32" cy="18" rx="4" ry="5" fill="#000000"/>
|
||||
<!-- Right eye highlight -->
|
||||
<ellipse cx="30.5" cy="16" rx="1.5" ry="2" fill="#FFFFFF" opacity="0.8"/>
|
||||
<!-- Right eyebrow - raised -->
|
||||
<path d="M 26 11 Q 32 9 38 11" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Surprised open mouth - oval -->
|
||||
<ellipse cx="24" cy="32" rx="5" ry="6" fill="#000000"/>
|
||||
<!-- Inner mouth -->
|
||||
<ellipse cx="24" cy="33" rx="3" ry="4" fill="#8B0000"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1,016 B |
19
stock/avatar/thinking.svg
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - looking up/side -->
|
||||
<ellipse cx="15" cy="18" rx="3" ry="4" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="13.5" cy="16" rx="1" ry="1.5" fill="#FFFFFF" opacity="0.8"/>
|
||||
|
||||
<!-- Right eye - looking up/side -->
|
||||
<ellipse cx="31" cy="18" rx="3" ry="4" fill="#000000"/>
|
||||
<!-- Right eye highlight -->
|
||||
<ellipse cx="29.5" cy="16" rx="1" ry="1.5" fill="#FFFFFF" opacity="0.8"/>
|
||||
|
||||
<!-- One raised eyebrow -->
|
||||
<path d="M 26 12 Q 32 10 38 13" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Thinking mouth - slight sideways purse -->
|
||||
<path d="M 18 31 Q 22 30 26 32 Q 30 34 32 32" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 872 B |
218
stock/avatar/upload-stockavatars.sh
Executable file
|
|
@ -0,0 +1,218 @@
|
|||
#!/bin/bash
|
||||
# Upload all stock avatar props to the server.
|
||||
#
|
||||
# Usage: ./stockavatar/upload-stockavatars.sh [--force|-f] [HOST]
|
||||
#
|
||||
# Options:
|
||||
# --force, -f Update existing props instead of failing with 409 Conflict
|
||||
#
|
||||
# HOST defaults to http://localhost:3001 (owner admin port)
|
||||
#
|
||||
# Prerequisites:
|
||||
# 1. Run the dev server: ./run-dev.sh -f
|
||||
# 2. Wait for it to finish building: ./run-dev.sh -s
|
||||
#
|
||||
# The owner admin server (port 3001) uses the chattyness_owner DB role
|
||||
# which bypasses RLS, so no authentication is required.
|
||||
|
||||
set -e
|
||||
|
||||
# Parse arguments
|
||||
FORCE=""
|
||||
HOST="http://localhost:3001"
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--force|-f)
|
||||
FORCE="?force=true"
|
||||
;;
|
||||
http://*)
|
||||
HOST="$arg"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Script directory is the stockavatar directory
|
||||
STOCKAVATAR_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
echo "Uploading stock avatars to $HOST/api/admin/props"
|
||||
echo "Source directory: $STOCKAVATAR_DIR"
|
||||
echo ""
|
||||
|
||||
# Check if server is running
|
||||
echo "Checking server health..."
|
||||
health_response=$(curl -s -o /dev/null -w "%{http_code}" "$HOST/api/admin/health" 2>/dev/null || echo "000")
|
||||
if [ "$health_response" != "200" ]; then
|
||||
echo "ERROR: Server is not responding at $HOST (HTTP $health_response)"
|
||||
echo ""
|
||||
echo "Make sure the server is running:"
|
||||
echo " ./run-dev.sh -f"
|
||||
echo " ./run-dev.sh -s # Check status"
|
||||
exit 1
|
||||
fi
|
||||
echo "Server is healthy!"
|
||||
echo ""
|
||||
|
||||
# Function to capitalize first letter
|
||||
capitalize() {
|
||||
echo "$1" | sed 's/.*/\u&/'
|
||||
}
|
||||
|
||||
# Function to determine tags based on filename
|
||||
# Tags complement default_layer/default_emotion - avoid redundant info
|
||||
get_tags() {
|
||||
local filename="$1"
|
||||
case "$filename" in
|
||||
face.svg)
|
||||
# Content layer prop - "skin" is already in default_layer
|
||||
echo '["base", "face"]'
|
||||
;;
|
||||
smile.svg | happy.svg | neutral.svg | sad.svg | angry.svg | surprised.svg | thinking.svg | laughing.svg | crying.svg | love.svg | confused.svg)
|
||||
# Emotion props - emotion is already in default_emotion
|
||||
echo '["face"]'
|
||||
;;
|
||||
sleeping.svg)
|
||||
# Emotion prop for sleeping
|
||||
echo '["face"]'
|
||||
;;
|
||||
wink.svg)
|
||||
# Emotion prop for wink
|
||||
echo '["face"]'
|
||||
;;
|
||||
*)
|
||||
echo '["prop"]'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Function to get positioning fields based on filename
|
||||
# Returns: "layer:<value>" for content layer props, "emotion:<value>" for emotion props, "none" for generic props
|
||||
get_positioning() {
|
||||
local filename="$1"
|
||||
case "$filename" in
|
||||
face.svg)
|
||||
# Base face is a content layer prop (skin layer)
|
||||
echo "layer:skin"
|
||||
;;
|
||||
neutral.svg)
|
||||
echo "emotion:neutral"
|
||||
;;
|
||||
smile.svg)
|
||||
echo "emotion:happy"
|
||||
;;
|
||||
sad.svg)
|
||||
echo "emotion:sad"
|
||||
;;
|
||||
angry.svg)
|
||||
echo "emotion:angry"
|
||||
;;
|
||||
surprised.svg)
|
||||
echo "emotion:surprised"
|
||||
;;
|
||||
thinking.svg)
|
||||
echo "emotion:thinking"
|
||||
;;
|
||||
laughing.svg)
|
||||
echo "emotion:laughing"
|
||||
;;
|
||||
crying.svg)
|
||||
echo "emotion:crying"
|
||||
;;
|
||||
love.svg)
|
||||
echo "emotion:love"
|
||||
;;
|
||||
confused.svg)
|
||||
echo "emotion:confused"
|
||||
;;
|
||||
sleeping.svg)
|
||||
echo "emotion:sleeping"
|
||||
;;
|
||||
wink.svg)
|
||||
echo "emotion:wink"
|
||||
;;
|
||||
*)
|
||||
echo "none"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Track success/failure counts
|
||||
success_count=0
|
||||
fail_count=0
|
||||
|
||||
# Upload each SVG file
|
||||
for file in "$STOCKAVATAR_DIR"/*.svg; do
|
||||
if [ ! -f "$file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
filename=$(basename "$file")
|
||||
name_without_ext="${filename%.svg}"
|
||||
display_name=$(capitalize "$name_without_ext")
|
||||
tags=$(get_tags "$filename")
|
||||
positioning=$(get_positioning "$filename")
|
||||
|
||||
echo "Uploading: $filename -> $display_name (positioning: $positioning)"
|
||||
|
||||
# Build positioning fields based on type
|
||||
positioning_type="${positioning%%:*}"
|
||||
positioning_value="${positioning#*:}"
|
||||
|
||||
case "$positioning_type" in
|
||||
layer)
|
||||
# Content layer prop
|
||||
positioning_json="\"default_layer\": \"$positioning_value\", \"default_position\": 4"
|
||||
;;
|
||||
emotion)
|
||||
# Emotion layer prop
|
||||
positioning_json="\"default_emotion\": \"$positioning_value\", \"default_position\": 4"
|
||||
;;
|
||||
*)
|
||||
# Generic prop (no default positioning)
|
||||
positioning_json=""
|
||||
;;
|
||||
esac
|
||||
|
||||
# Create metadata JSON
|
||||
if [ -n "$positioning_json" ]; then
|
||||
metadata=$(
|
||||
cat <<EOF
|
||||
{
|
||||
"name": "$display_name",
|
||||
"tags": $tags,
|
||||
$positioning_json
|
||||
}
|
||||
EOF
|
||||
)
|
||||
else
|
||||
metadata=$(
|
||||
cat <<EOF
|
||||
{
|
||||
"name": "$display_name",
|
||||
"tags": $tags
|
||||
}
|
||||
EOF
|
||||
)
|
||||
fi
|
||||
|
||||
# Upload via curl
|
||||
response=$(curl -s -w "\n%{http_code}" -X POST "$HOST/api/admin/props$FORCE" \
|
||||
-F "metadata=$metadata" \
|
||||
-F "file=@$file")
|
||||
|
||||
# Extract HTTP status code (last line)
|
||||
http_code=$(echo "$response" | tail -n1)
|
||||
body=$(echo "$response" | sed '$d')
|
||||
|
||||
if [ "$http_code" = "200" ] || [ "$http_code" = "201" ]; then
|
||||
echo " ✓ Success: $body"
|
||||
((++success_count))
|
||||
else
|
||||
echo " ✗ Failed (HTTP $http_code): $body"
|
||||
((++fail_count))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "=========================================="
|
||||
echo "Upload complete: $success_count succeeded, $fail_count failed"
|
||||
19
stock/avatar/wink.svg
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
||||
<g transform="scale(2.5)">
|
||||
<!-- Left eye - open -->
|
||||
<ellipse cx="16" cy="19" rx="3" ry="4" fill="#000000"/>
|
||||
<!-- Left eye highlight -->
|
||||
<ellipse cx="15" cy="17" rx="1" ry="1.5" fill="#FFFFFF" opacity="0.8"/>
|
||||
|
||||
<!-- Right eye - winking (closed arc) -->
|
||||
<path d="M 28 19 Q 32 16 36 19" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Cheeky smile -->
|
||||
<path d="M 12 28 Q 24 40 36 28" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<!-- Inner smile shadow -->
|
||||
<path d="M 14 29 Q 24 38 34 29" fill="none" stroke="#996600" stroke-width="1" stroke-linecap="round" opacity="0.4"/>
|
||||
|
||||
<!-- Dimple/blush on wink side -->
|
||||
<ellipse cx="38" cy="24" rx="3" ry="2" fill="#FF9999" opacity="0.4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 887 B |