maybe a fork of sparrowhe's "bluesky circle" webapp, to frontend only?

:hammer: chore: better workflow / fix: allow hyphen in handle

Changed files
+43 -25
frontend
static
avatars
templates
+2 -2
.dockerignore
··· 4 4 bin/ 5 5 share/ 6 6 pyvenv.cfg 7 - static/avatars/ 8 7 test.py 9 8 *.png 10 - frontend/ 9 + frontend/ 10 + !frontend/dist
-1
.gitignore
··· 173 173 bin/ 174 174 share/ 175 175 pyvenv.cfg 176 - static/ 177 176 test.py 178 177 *.png
+6 -2
app.py
··· 1 1 from flask import Flask 2 2 from flask_cors import CORS 3 + 3 4 from avatar.routes import avatar_bp 4 5 from config import Config 5 6 from at_client import at_client_extension 6 7 7 - app = Flask(__name__) 8 - cors = CORS(app, resources={r"/*": {"origins": "*"}}) 8 + app = Flask(__name__, 9 + static_folder='./frontend/dist/static', 10 + template_folder='./frontend/dist' 11 + ) 9 12 app.config.from_object(Config) 13 + cors = CORS(app, resources={r"/*": {"origins": "*"}}) 10 14 11 15 # Register blueprints 12 16 app.register_blueprint(avatar_bp)
+1
config.py
··· 4 4 """Configuration class for the Flask app.""" 5 5 BASE_DIR = os.path.abspath(os.path.dirname(__file__)) 6 6 UPLOAD_FOLDER = os.path.join(BASE_DIR, 'static/avatars') 7 + VITE_FOLDER_PATH = os.path.join(BASE_DIR, 'frontend') 7 8 8 9 # BlueSky login credentials 9 10 BLUESKY_HANDLE = os.getenv('BLUESKY_HANDLE', 'sparrow.0x0e.top')
+19 -5
frontend/src/App.tsx
··· 8 8 import { Label } from "@/components/ui/label" 9 9 import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" 10 10 import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" 11 - import { AlertCircle } from "lucide-react" 11 + import { AlertCircle, Github, ExternalLink } from "lucide-react" 12 12 13 13 import "./App.css" 14 14 ··· 25 25 export default function Component() { 26 26 // const turnstile = useTurnstile() 27 27 const [handle, setHandle] = useState('') 28 - const [captchaKey, ] = useState('') 28 + const [captchaKey,] = useState('') 29 29 const [imageData, setImageData] = useState<string | null>(null) 30 30 const [backgroundColor, setBackgroundColor] = useState('#0085ff') 31 31 const [isLoading, setIsLoading] = useState(false) ··· 119 119 // remove @ from handle 120 120 setHandle(e.target.value.replace('@', '')) 121 121 // remove invalid characters 122 - setHandle(e.target.value.replace(/[^a-zA-Z0-9_.]/g, '')) 122 + setHandle(e.target.value.replace(/[^a-zA-Z0-9_\-.]/g, '')) 123 123 }} 124 - pattern='@{0,1}[a-zA-Z0-9_.]*' 124 + pattern='@{0,1}[a-zA-Z0-9_\-.]*' 125 125 placeholder="Enter BlueSky Handle" 126 126 required 127 127 /> ··· 170 170 </div> 171 171 </CardFooter> 172 172 )} 173 + <footer className="mt-8 text-sm text-gray-500 space-y-1"> 174 + <div className="flex items-center justify-center space-x-4"> 175 + <a href="https://github.com/sparrowhe/bluesky-circle" className="flex items-center text-primary hover:text-primary/60 transition-colors"> 176 + <Github className="w-4 h-4 mr-1" /> 177 + Source Code 178 + </a> 179 + <a href="https://github.com/users/sparrowhe/projects/1" className="flex items-center text-primary hover:text-primary/60 transition-colors"> 180 + <ExternalLink className="w-4 h-4 mr-1" /> 181 + Roadmap 182 + </a> 183 + </div> 184 + <p className="text-center pb-2"> 185 + Designed and developed by <a href="https://bsky.app/profile/sparrow.0x0e.top">SparrowHe</a> with ❤️ 186 + </p> 187 + </footer> 173 188 </Card> 174 - <Label>Powered by SparrowCloud</Label> 175 189 </div> 176 190 ) 177 191 }
+15
frontend/vite.config.ts
··· 9 9 "@": path.resolve(__dirname, "./src"), 10 10 }, 11 11 }, 12 + base: "./", 13 + build: { 14 + assetsDir: 'static', 15 + }, 16 + server: { 17 + port: 3000, 18 + cors: true, 19 + proxy: { 20 + "/generate": { 21 + target: "https://circle.sparrowhe.top/", 22 + changeOrigin: true, 23 + secure: false, 24 + }, 25 + }, 26 + }, 12 27 })
static/avatars/.gitkeep

This is a binary file and will not be displayed.

-14
templates/index.html
··· 1 - <!doctype html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="UTF-8" /> 5 - <link rel="icon" type="image/svg+xml" href="/vite.svg" /> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <title>Bluesky Circle</title> 8 - <script type="module" crossorigin src="/static/index-B2_p4wCz.js"></script> 9 - <link rel="stylesheet" crossorigin href="/static/index-C1gmdyUs.css"> 10 - </head> 11 - <body> 12 - <div id="root"></div> 13 - </body> 14 - </html>
-1
templates/vite.svg
··· 1 - <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>