moses132 commited on
Commit
8a74931
·
verified ·
1 Parent(s): b817ad6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +294 -429
app.py CHANGED
@@ -5,461 +5,326 @@ import json
5
  import hashlib
6
  import uuid
7
  from datetime import datetime
8
- import numpy as np
9
 
10
- # ============================================
11
- # STORAGE
12
- # ============================================
13
 
14
  USERS_FILE = "users.json"
15
  POSTS_FILE = "posts.json"
16
 
 
 
17
  def load_json(file):
18
  if os.path.exists(file):
19
- with open(file, 'r') as f:
20
- return json.load(f)
 
 
 
21
  return {}
22
 
23
- def save_json(file, data):
24
- with open(file, 'w') as f:
25
- json.dump(data, f, indent=2)
26
 
27
  users = load_json(USERS_FILE)
28
  posts = load_json(POSTS_FILE)
29
- os.makedirs("posts", exist_ok=True)
30
 
31
- # ============================================
32
- # AUTH FUNCTIONS
33
- # ============================================
34
 
35
- def hash_password(password):
36
- return hashlib.sha256(password.encode()).hexdigest()
 
 
37
 
38
- def signup(username, password, display_name):
39
- if not username or not password:
40
- return "❌ Username and password required"
41
-
42
  if username in users:
43
- return "❌ Username already exists"
44
-
45
  users[username] = {
46
  "password": hash_password(password),
47
- "display_name": display_name if display_name else username,
48
- "bio": "✨ New to Vibes! Share your first post ✨",
49
- "followers": [],
50
- "following": [],
51
- "created_at": datetime.now().isoformat()
52
  }
53
- save_json(USERS_FILE, users)
54
- return "✅ Account created! Please login."
55
 
56
- def login(username, password):
 
 
 
 
57
  if username not in users:
58
- return "❌ User not found", None
59
-
60
  if users[username]["password"] != hash_password(password):
61
- return "❌ Wrong password", None
62
-
63
- return f"✅ Welcome back, {users[username]['display_name']}!", username
64
-
65
- # ============================================
66
- # POST FUNCTIONS - NO PASSWORD NEEDED
67
- # ============================================
68
-
69
- def create_post(username, image, caption, hashtags):
70
- if not username:
71
- return "❌ Please login first"
72
-
 
73
  if image is None:
74
- return "❌ Please select an image to upload"
75
-
76
- try:
77
- post_id = str(uuid.uuid4())
78
-
79
- # Handle image (supports both filepath and numpy array)
80
- if isinstance(image, str):
81
- img = Image.open(image)
82
- else:
83
- # Convert numpy array to PIL Image
84
- if image.dtype == np.float32:
85
- image = (image * 255).astype(np.uint8)
86
- img = Image.fromarray(image)
87
-
88
- # Convert RGBA to RGB if needed
89
- if img.mode in ('RGBA', 'LA'):
90
- img = img.convert('RGB')
91
-
92
- # Resize if too large
93
- max_size = 1200
94
- if max(img.size) > max_size:
95
- ratio = max_size / max(img.size)
96
- new_size = (int(img.size[0] * ratio), int(img.size[1] * ratio))
97
- img = img.resize(new_size, Image.Resampling.LANCZOS)
98
-
99
- # Save image
100
- img.save(f"posts/{post_id}.jpg", "JPEG", quality=85)
101
-
102
- # Save post data
103
- posts[post_id] = {
104
- "id": post_id,
105
- "username": username,
106
- "display_name": users[username]["display_name"],
107
- "caption": caption if caption else "",
108
- "hashtags": hashtags if hashtags else "",
109
- "image": f"posts/{post_id}.jpg",
110
- "likes": [],
111
- "comments": [],
112
- "timestamp": datetime.now().isoformat()
113
- }
114
- save_json(POSTS_FILE, posts)
115
-
116
- return "✅ Post shared successfully!"
117
- except Exception as e:
118
- return f"❌ Error: {str(e)}"
119
-
120
- def get_feed():
121
- feed_items = []
122
- for pid, post in list(posts.items())[-30:]:
123
- feed_items.append({
124
- "id": pid,
125
- "username": post["username"],
126
- "display_name": post.get("display_name", post["username"]),
127
- "image": post["image"],
128
- "caption": post["caption"],
129
- "likes": len(post["likes"]),
130
- "timestamp": post["timestamp"]
131
- })
132
- return feed_items[::-1]
133
-
134
- def get_user_posts(username):
135
- user_posts = []
136
- for pid, post in posts.items():
137
- if post["username"] == username:
138
- user_posts.append(post["image"])
139
- return user_posts[-9:]
140
-
141
- def get_user_stats(username):
142
- if username not in users:
143
- return {"display_name": "", "bio": "", "followers": 0, "following": 0, "posts": 0}
144
-
145
- user = users[username]
146
- user_posts = [p for p in posts.values() if p["username"] == username]
147
-
148
- return {
149
- "display_name": user["display_name"],
150
- "bio": user.get("bio", "✨ New to Vibes! ✨"),
151
- "followers": len(user["followers"]),
152
- "following": len(user["following"]),
153
- "posts": len(user_posts)
154
  }
155
 
156
- def update_bio(username, new_bio):
157
- if username in users and new_bio:
158
- users[username]["bio"] = new_bio
159
- save_json(USERS_FILE, users)
160
- return "✅ Bio updated!"
161
- return "❌ Failed to update bio"
 
162
 
163
- def search_users(query):
164
- if len(query) < 2:
 
165
  return []
166
- results = []
167
- for username, data in users.items():
168
- if query.lower() in username.lower() or query.lower() in data["display_name"].lower():
169
- results.append({
170
- "username": username,
171
- "display_name": data["display_name"],
172
- "followers": len(data["followers"])
173
- })
174
- return results[:10]
175
-
176
- # ============================================
177
- # ORANGE THEME CSS
178
- # ============================================
179
-
180
- custom_css = """
181
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
182
-
183
- * {
184
- font-family: 'Inter', sans-serif !important;
185
- }
186
-
187
- .gradio-container {
188
- max-width: 1300px !important;
189
- margin: 0 auto !important;
190
- background: #1a1a1a !important;
191
- }
192
-
193
- .gr-box, .gr-form, .gr-panel {
194
- border-radius: 16px !important;
195
- border: none !important;
196
- background: #2d2d2d !important;
197
- }
198
-
199
- button, .gr-button {
200
- border-radius: 40px !important;
201
- font-weight: 600 !important;
202
- padding: 10px 28px !important;
203
- transition: all 0.2s ease !important;
204
- font-size: 14px !important;
205
- border: none !important;
206
- }
207
-
208
- button:hover, .gr-button:hover {
209
- transform: translateY(-2px) !important;
210
- filter: brightness(0.9) !important;
211
- cursor: pointer !important;
212
- }
213
-
214
- .gr-button-primary {
215
- background: linear-gradient(135deg, #FF6B35 0%, #F7931E 100%) !important;
216
- color: white !important;
217
- }
218
-
219
- .gr-button-secondary {
220
- background: #3d3d3d !important;
221
- color: #FF6B35 !important;
222
- }
223
-
224
- input, textarea, .gr-textbox {
225
- border-radius: 40px !important;
226
- border: 1px solid #3d3d3d !important;
227
- background: #2d2d2d !important;
228
- padding: 12px 20px !important;
229
- font-size: 14px !important;
230
- color: #ffffff !important;
231
- }
232
-
233
- input:focus, textarea:focus {
234
- border-color: #FF6B35 !important;
235
- outline: none !important;
236
- background: #3d3d3d !important;
237
- }
238
-
239
- label, .gr-form-label {
240
- color: #ffffff !important;
241
- }
242
-
243
- .gallery {
244
- border-radius: 16px !important;
245
- background: transparent !important;
246
- gap: 16px !important;
247
- }
248
-
249
- .tab-nav {
250
- background: transparent !important;
251
- border-bottom: 1px solid #3d3d3d !important;
252
- margin-bottom: 20px !important;
253
- }
254
-
255
- .tab-nav button {
256
- font-size: 16px !important;
257
- padding: 12px 24px !important;
258
- border-radius: 0 !important;
259
- background: transparent !important;
260
- color: #888888 !important;
261
- border-bottom: 2px solid transparent !important;
262
- }
263
-
264
- .tab-nav button.selected {
265
- color: #FF6B35 !important;
266
- border-bottom: 2px solid #FF6B35 !important;
267
- }
268
-
269
- .profile-card {
270
- background: linear-gradient(135deg, #FF6B35 0%, #F7931E 100%);
271
- border-radius: 20px;
272
- padding: 24px;
273
- color: white;
274
- text-align: center;
275
- }
276
-
277
- h1, h2, h3, .gr-markdown {
278
- color: #ffffff !important;
279
- }
280
-
281
- .gr-markdown p {
282
- color: #cccccc !important;
283
- }
284
  """
285
 
286
- # ============================================
287
- # BUILD UI
288
- # ============================================
289
-
290
- with gr.Blocks(theme=gr.themes.Soft(), title="Vibes", css=custom_css) as demo:
291
-
292
- current_user = gr.State(None)
293
-
294
- # Header
295
- gr.HTML("""
296
- <div style="text-align: center; padding: 20px 0 10px 0;">
297
- <div style="font-size: 48px; margin-bottom: 5px;">📸</div>
298
- <h1 style="font-size: 32px; background: linear-gradient(135deg, #FF6B35 0%, #F7931E 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin: 0;">Vibes</h1>
299
- <p style="color: #888888; margin-top: 5px; font-size: 14px;">Share moments. Connect with creators.</p>
300
- </div>
301
- """)
302
-
303
- # ===== LOGIN PANEL =====
304
- with gr.Column(visible=True, elem_id="login_panel") as login_panel:
305
- with gr.Row():
306
- with gr.Column(scale=1):
307
- pass
308
- with gr.Column(scale=2):
309
- with gr.Group():
310
- gr.Markdown("### ✨ Welcome to Vibes")
311
-
312
- with gr.Tabs():
313
- with gr.TabItem("🔐 Login"):
314
- login_user = gr.Textbox(label="Username", placeholder="Enter your username")
315
- login_pass = gr.Textbox(label="Password", type="password", placeholder="Enter your password")
316
- login_btn = gr.Button("Login", variant="primary")
317
- login_msg = gr.Markdown("")
318
-
319
- with gr.TabItem("📝 Sign Up"):
320
- signup_user = gr.Textbox(label="Username", placeholder="Choose a username")
321
- signup_pass = gr.Textbox(label="Password", type="password", placeholder="Choose a password")
322
- signup_display = gr.Textbox(label="Display Name", placeholder="What should we call you?")
323
- signup_btn = gr.Button("Create Account", variant="primary")
324
- signup_msg = gr.Markdown("")
325
- with gr.Column(scale=1):
326
- pass
327
-
328
- # ===== MAIN APP =====
329
- with gr.Column(visible=False, elem_id="main_app") as main_panel:
330
-
331
- # Top bar
332
- with gr.Row():
333
- with gr.Column(scale=3):
334
- gr.Markdown("")
335
- with gr.Column(scale=1):
336
- user_display = gr.Markdown("")
337
- logout_btn = gr.Button("🚪 Logout", variant="secondary")
338
-
339
- with gr.Tabs():
340
-
341
- # Feed Tab
342
- with gr.TabItem("🏠 Feed"):
343
- feed_gallery = gr.Gallery(
344
- label="",
345
- columns=3,
346
- rows=3,
347
- height=600,
348
- object_fit="contain",
349
- preview=True
350
- )
351
- with gr.Row():
352
- refresh_btn = gr.Button("🔄 Refresh", variant="secondary")
353
- feed_info = gr.Markdown("")
354
-
355
- # Create Tab - NO PASSWORD REQUIRED
356
- with gr.TabItem("✨ Create"):
357
- gr.Markdown("### Share Your Moment")
358
- post_image = gr.Image(label="Upload Image", type="numpy", height=350)
359
- post_caption = gr.Textbox(label="Caption", placeholder="What's on your mind?", lines=2)
360
- post_hashtags = gr.Textbox(label="Hashtags", placeholder="#inspo #art #photography")
361
- post_btn = gr.Button("✨ Share", variant="primary")
362
- post_msg = gr.Markdown("")
363
-
364
- # Profile Tab
365
- with gr.TabItem("👤 Profile"):
366
- with gr.Row():
367
- with gr.Column(scale=1):
368
- profile_stats = gr.Markdown("")
369
- update_bio_text = gr.Textbox(label="Update Bio", placeholder="Write something about yourself...", lines=3)
370
- update_bio_btn = gr.Button("Update Bio", variant="secondary")
371
- bio_status = gr.Markdown("")
372
- with gr.Column(scale=2):
373
- gr.Markdown("### My Posts")
374
- my_posts_gallery = gr.Gallery(columns=3, rows=2, height=400, object_fit="contain")
375
- refresh_profile_btn = gr.Button("🔄 Refresh", variant="secondary")
376
-
377
- # Discover Tab
378
- with gr.TabItem("🔍 Discover"):
379
- gr.Markdown("### Find New Creators")
380
- search_input = gr.Textbox(label="Search", placeholder="Enter username...")
381
- search_results = gr.Dataframe(
382
- headers=["Username", "Display Name", "Followers"],
383
- datatype=["str", "str", "number"],
384
- interactive=False,
385
- height=300
386
- )
387
-
388
- # ============================================
389
- # EVENT HANDLERS
390
- # ============================================
391
-
392
- def handle_signup(user, pwd, display):
393
- msg = signup(user, pwd, display)
394
- return msg, "", "", ""
395
-
396
- def handle_login(user, pwd):
397
- msg, logged_user = login(user, pwd)
398
- if logged_user:
399
- stats = get_user_stats(logged_user)
400
- return msg, gr.update(visible=False), gr.update(visible=True), logged_user, f"**{stats['display_name']}**\n@{logged_user}"
401
- return msg, gr.update(), gr.update(), None, ""
402
-
403
- def handle_logout():
404
- return gr.update(visible=True), gr.update(visible=False), None, ""
405
-
406
- def handle_create_post(user, img, caption, hashtags):
407
- if not user:
408
- return "❌ Please login first"
409
- msg = create_post(user, img, caption, hashtags)
410
- return msg
411
-
412
- def load_feed():
413
- feed = get_feed()
414
- if not feed:
415
- return [], "✨ No posts yet. Be the first!"
416
- images = [f["image"] for f in feed]
417
- captions = [f"**{f['display_name']}**\n{f['caption']}\n❤️ {f['likes']} likes" for f in feed]
418
- return images, f"📱 {len(feed)} posts"
419
-
420
- def load_profile(user):
421
- if not user:
422
- return "Not logged in", []
423
- stats = get_user_stats(user)
424
- profile_html = f"""
425
- <div class="profile-card">
426
- <div style="font-size: 48px;">👤</div>
427
- <h2>{stats['display_name']}</h2>
428
- <p>@{user}</p>
429
- <p>{stats['bio']}</p>
430
- <div style="display: flex; justify-content: space-around; margin-top: 20px;">
431
- <div><strong>{stats['posts']}</strong><br>Posts</div>
432
- <div><strong>{stats['followers']}</strong><br>Followers</div>
433
- <div><strong>{stats['following']}</strong><br>Following</div>
434
- </div>
435
- </div>
436
- """
437
- return profile_html, get_user_posts(user)
438
-
439
- def handle_update_bio(user, new_bio):
440
- if user:
441
- return update_bio(user, new_bio)
442
- return "Please login"
443
-
444
- # Wire events
445
- signup_btn.click(handle_signup, [signup_user, signup_pass, signup_display], [signup_msg, signup_user, signup_pass, signup_display])
446
- login_btn.click(handle_login, [login_user, login_pass], [login_msg, login_panel, main_panel, current_user, user_display])
447
- login_btn.click(lambda: load_feed(), None, [feed_gallery, feed_info])
448
- login_btn.click(lambda u: load_profile(u), [current_user], [profile_stats, my_posts_gallery])
449
-
450
- logout_btn.click(handle_logout, None, [login_panel, main_panel, current_user, user_display])
451
-
452
- post_btn.click(handle_create_post, [current_user, post_image, post_caption, post_hashtags], [post_msg])
453
- post_btn.click(lambda: None, None, [post_image, post_caption, post_hashtags])
454
- post_btn.click(lambda: load_feed(), None, [feed_gallery, feed_info])
455
- post_btn.click(lambda u: load_profile(u), [current_user], [profile_stats, my_posts_gallery])
456
-
457
- refresh_btn.click(lambda: load_feed(), None, [feed_gallery, feed_info])
458
- refresh_profile_btn.click(lambda u: load_profile(u), [current_user], [profile_stats, my_posts_gallery])
459
-
460
- update_bio_btn.click(handle_update_bio, [current_user, update_bio_text], [bio_status])
461
- update_bio_btn.click(lambda u: load_profile(u), [current_user], [profile_stats, my_posts_gallery])
462
-
463
- search_input.change(search_users, [search_input], [search_results])
464
-
465
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
5
  import hashlib
6
  import uuid
7
  from datetime import datetime
 
8
 
9
+ # ==============================
10
+ # FILE STORAGE
11
+ # ==============================
12
 
13
  USERS_FILE = "users.json"
14
  POSTS_FILE = "posts.json"
15
 
16
+ os.makedirs("posts", exist_ok=True)
17
+
18
  def load_json(file):
19
  if os.path.exists(file):
20
+ try:
21
+ with open(file) as f:
22
+ return json.load(f)
23
+ except:
24
+ return {}
25
  return {}
26
 
27
+ def save_json(file,data):
28
+ with open(file,"w") as f:
29
+ json.dump(data,f,indent=2)
30
 
31
  users = load_json(USERS_FILE)
32
  posts = load_json(POSTS_FILE)
 
33
 
34
+ # ==============================
35
+ # AUTH
36
+ # ==============================
37
 
38
+ def hash_password(p):
39
+ return hashlib.sha256(p.encode()).hexdigest()
40
+
41
+ def signup(username,password,display):
42
 
 
 
 
 
43
  if username in users:
44
+ return "Username already exists"
45
+
46
  users[username] = {
47
  "password": hash_password(password),
48
+ "display_name": display or username,
49
+ "bio":"New to Vibes ✨",
50
+ "followers":[],
51
+ "following":[]
 
52
  }
 
 
53
 
54
+ save_json(USERS_FILE,users)
55
+ return "Account created! Login now."
56
+
57
+ def login(username,password):
58
+
59
  if username not in users:
60
+ return "User not found",None
61
+
62
  if users[username]["password"] != hash_password(password):
63
+ return "Wrong password",None
64
+
65
+ return "Login successful",username
66
+
67
+ # ==============================
68
+ # POSTS
69
+ # ==============================
70
+
71
+ def create_post(user,image,caption):
72
+
73
+ if user is None:
74
+ return "Login required"
75
+
76
  if image is None:
77
+ return "Upload image"
78
+
79
+ post_id=str(uuid.uuid4())
80
+
81
+ img = Image.fromarray(image)
82
+ img = img.convert("RGB")
83
+
84
+ path=f"posts/{post_id}.jpg"
85
+
86
+ img.save(path,quality=90)
87
+
88
+ posts[post_id]={
89
+ "id":post_id,
90
+ "username":user,
91
+ "display":users[user]["display_name"],
92
+ "caption":caption,
93
+ "image":path,
94
+ "likes":[],
95
+ "comments":[],
96
+ "time":datetime.now().isoformat()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  }
98
 
99
+ save_json(POSTS_FILE,posts)
100
+
101
+ return "Post uploaded"
102
+
103
+ # ==============================
104
+ # FEED
105
+ # ==============================
106
 
107
+ def load_feed():
108
+
109
+ if len(posts)==0:
110
  return []
111
+
112
+ ordered=sorted(posts.values(),
113
+ key=lambda x:x["time"],
114
+ reverse=True)
115
+
116
+ gallery=[]
117
+
118
+ for p in ordered:
119
+
120
+ caption=f"""
121
+ {p['display']} (@{p['username']})
122
+
123
+ {p['caption']}
124
+
125
+ ❤️ {len(p['likes'])} likes
126
+ """
127
+
128
+ gallery.append((p["image"],caption))
129
+
130
+ return gallery
131
+
132
+ # ==============================
133
+ # LIKE
134
+ # ==============================
135
+
136
+ def like_latest(user):
137
+
138
+ if not posts:
139
+ return "No posts"
140
+
141
+ latest=list(posts.keys())[-1]
142
+
143
+ if user not in posts[latest]["likes"]:
144
+ posts[latest]["likes"].append(user)
145
+
146
+ save_json(POSTS_FILE,posts)
147
+
148
+ return "Liked ❤️"
149
+
150
+ # ==============================
151
+ # PROFILE
152
+ # ==============================
153
+
154
+ def load_profile(user):
155
+
156
+ if user is None:
157
+ return "Not logged",[]
158
+
159
+ user_posts=[p["image"] for p in posts.values() if p["username"]==user]
160
+
161
+ stats=f"""
162
+ ### {users[user]["display_name"]}
163
+
164
+ @{user}
165
+
166
+ Posts: {len(user_posts)}
167
+
168
+ Followers: {len(users[user]["followers"])}
169
+
170
+ Following: {len(users[user]["following"])}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  """
172
 
173
+ return stats,user_posts
174
+
175
+ # ==============================
176
+ # SEARCH
177
+ # ==============================
178
+
179
+ def search_users(q):
180
+
181
+ if len(q)<2:
182
+ return []
183
+
184
+ results=[]
185
+
186
+ for u,data in users.items():
187
+
188
+ if q.lower() in u.lower():
189
+
190
+ results.append([
191
+ u,
192
+ data["display_name"],
193
+ len(data["followers"])
194
+ ])
195
+
196
+ return results
197
+
198
+ # ==============================
199
+ # UI
200
+ # ==============================
201
+
202
+ with gr.Blocks(title="Vibes") as app:
203
+
204
+ current_user=gr.State()
205
+
206
+ gr.Markdown("# 📸 Vibes")
207
+
208
+ # LOGIN
209
+ with gr.Tab("Login"):
210
+
211
+ user=gr.Textbox(label="Username")
212
+ pwd=gr.Textbox(label="Password",type="password")
213
+
214
+ login_btn=gr.Button("Login")
215
+
216
+ login_msg=gr.Textbox()
217
+
218
+ # SIGNUP
219
+ with gr.Tab("Signup"):
220
+
221
+ su_user=gr.Textbox(label="Username")
222
+ su_pwd=gr.Textbox(label="Password",type="password")
223
+ su_disp=gr.Textbox(label="Display name")
224
+
225
+ su_btn=gr.Button("Create account")
226
+
227
+ su_msg=gr.Textbox()
228
+
229
+ # FEED
230
+ with gr.Tab("Feed"):
231
+
232
+ gallery=gr.Gallery(
233
+ columns=3,
234
+ height=600
235
+ )
236
+
237
+ refresh=gr.Button("Refresh")
238
+
239
+ like_btn=gr.Button("Like latest")
240
+
241
+ like_msg=gr.Textbox()
242
+
243
+ # CREATE
244
+ with gr.Tab("Create Post"):
245
+
246
+ img=gr.Image(type="numpy")
247
+
248
+ cap=gr.Textbox(label="Caption")
249
+
250
+ post_btn=gr.Button("Share")
251
+
252
+ post_msg=gr.Textbox()
253
+
254
+ # PROFILE
255
+ with gr.Tab("Profile"):
256
+
257
+ profile_stats=gr.Markdown()
258
+
259
+ my_gallery=gr.Gallery(columns=3)
260
+
261
+ load_profile_btn=gr.Button("Load profile")
262
+
263
+ # DISCOVER
264
+ with gr.Tab("Discover"):
265
+
266
+ search=gr.Textbox(label="Search users")
267
+
268
+ results=gr.Dataframe(
269
+ headers=["username","display name","followers"]
270
+ )
271
+
272
+ # =================
273
+ # EVENTS
274
+ # =================
275
+
276
+ login_btn.click(
277
+ login,
278
+ inputs=[user,pwd],
279
+ outputs=[login_msg,current_user]
280
+ ).then(
281
+ load_feed,
282
+ None,
283
+ gallery
284
+ )
285
+
286
+ su_btn.click(
287
+ signup,
288
+ [su_user,su_pwd,su_disp],
289
+ su_msg
290
+ )
291
+
292
+ refresh.click(
293
+ load_feed,
294
+ None,
295
+ gallery
296
+ )
297
+
298
+ post_btn.click(
299
+ create_post,
300
+ [current_user,img,cap],
301
+ post_msg
302
+ ).then(
303
+ load_feed,
304
+ None,
305
+ gallery
306
+ )
307
+
308
+ like_btn.click(
309
+ like_latest,
310
+ current_user,
311
+ like_msg
312
+ ).then(
313
+ load_feed,
314
+ None,
315
+ gallery
316
+ )
317
+
318
+ load_profile_btn.click(
319
+ load_profile,
320
+ current_user,
321
+ [profile_stats,my_gallery]
322
+ )
323
+
324
+ search.change(
325
+ search_users,
326
+ search,
327
+ results
328
+ )
329
+
330
+ app.launch()