From 3197f747d915220b4499d86a49126be0a9c77a66 Mon Sep 17 00:00:00 2001 From: Kush Shanware <115879636+Kushanware@users.noreply.github.com> Date: Sat, 21 Mar 2026 16:37:52 +0530 Subject: [PATCH 1/2] feat: enhance Streamlit UI with custom CSS (#5) --- streamlit_app.py | 483 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 398 insertions(+), 85 deletions(-) diff --git a/streamlit_app.py b/streamlit_app.py index a84c125..a6c5f6a 100644 --- a/streamlit_app.py +++ b/streamlit_app.py @@ -83,14 +83,23 @@ def transcribe_audio(audio_path): "English": { "title": "Shakti", "subtitle": "Your story is still alive", + "share_tab": "Share Your Story", + "community_tab": "Community Stories", "upload_audio": "Upload your voice (MP3, WAV, M4A)", "write_story": "Write your story", "submit": "Submit", "success": "Your story has been saved. Thank you!", "error": "Please do not submit an empty story.", "transcribed": "Transcribed Text (editable):", + "transcribing": "Transcribing audio...", + "transcription_success": "Transcription successful!", + "transcription_error": "Error", "add_tags": "Add tags (e.g., #domesticviolence, #healingjourney)", "enter_tags": "Enter tags separated by commas:", + "story_hint": "You can share by voice or text. Your identity remains anonymous.", + "tags_hint": "Example: healing, courage, support", + "community_header": "Community Stories", + "story_card": "Story", "comment_placeholder": "Add a comment to this story:", "post_comment": "Post Comment", "comment_empty": "Comment cannot be empty.", @@ -100,14 +109,23 @@ def transcribe_audio(audio_path): "Hindi": { "title": "Shakti", "subtitle": "हर आवाज़ अब साँस ले रही है", + "share_tab": "अपनी कहानी साझा करें", + "community_tab": "सामुदायिक कहानियाँ", "upload_audio": "अपनी आवाज़ अपलोड करें (MP3, WAV, M4A)", "write_story": "अपनी कहानी लिखें", "submit": "सबमिट करें", "success": "आपकी कहानी सेव हो गई है। धन्यवाद!", "error": "कृपया खाली कहानी सबमिट न करें।", "transcribed": "बदला गया टेक्स्ट (संपादन करें):", + "transcribing": "ऑडियो ट्रांसक्राइब हो रहा है...", + "transcription_success": "ट्रांसक्रिप्शन सफल रहा!", + "transcription_error": "त्रुटि", "add_tags": "टैग जोड़ें (जैसे, #domesticviolence, #healingjourney)", "enter_tags": "कॉमा से टैग दर्ज करें:", + "story_hint": "आप आवाज़ या टेक्स्ट से साझा कर सकते हैं। आपकी पहचान गुमनाम रहती है।", + "tags_hint": "उदाहरण: healing, courage, support", + "community_header": "सामुदायिक कहानियाँ", + "story_card": "कहानी", "comment_placeholder": "इस कहानी पर टिप्पणी जोड़ें:", "post_comment": "टिप्पणी भेजें", "comment_empty": "टिप्पणी खाली नहीं हो सकती।", @@ -117,14 +135,23 @@ def transcribe_audio(audio_path): "Tamil": { "title": "என் கதை உயிருடன் உள்ளது", "subtitle": "உங்கள் கதை இன்னும் உயிருடன் உள்ளது", + "share_tab": "உங்கள் கதையை பகிருங்கள்", + "community_tab": "சமூகக் கதைகள்", "upload_audio": "உங்கள் குரலை பதிவேற்றவும் (MP3, WAV, M4A)", "write_story": "உங்கள் கதையை எழுதுங்கள்", "submit": "சமர்ப்பிக்கவும்", "success": "உங்கள் கதை சேமிக்கப்பட்டது. நன்றி!", "error": "காலியான கதையை சமர்ப்பிக்க வேண்டாம்.", "transcribed": "மாற்றிய உரை (திருத்தக்கூடியது):", + "transcribing": "ஆடியோ உரையாக மாற்றப்படுகிறது...", + "transcription_success": "உரைமாற்றம் வெற்றிகரமாக முடிந்தது!", + "transcription_error": "பிழை", "add_tags": "டேக்கள் சேர்க்கவும் (எ.கா., #domesticviolence, #healingjourney)", "enter_tags": "டேக்களை கமாஸ் கொண்டு பிரித்து உள்ளிடவும்:", + "story_hint": "குரல் அல்லது உரை மூலம் பகிரலாம். உங்கள் அடையாளம் மறைக்கப்படும்.", + "tags_hint": "உதாரணம்: healing, courage, support", + "community_header": "சமூகக் கதைகள்", + "story_card": "கதை", "comment_placeholder": "இந்த கதைக்கு கருத்து சேர்:", "post_comment": "கருத்து பதிவிடு", "comment_empty": "கருத்து காலியானதாக இருக்க முடியாது.", @@ -134,14 +161,23 @@ def transcribe_audio(audio_path): "Bengali": { "title": "আমার গল্প এখনও বেঁচে আছে", "subtitle": "আপনার কণ্ঠ এখনো জীবিত", + "share_tab": "আপনার গল্প শেয়ার করুন", + "community_tab": "কমিউনিটি গল্প", "upload_audio": "আপনার কণ্ঠ আপলোড করুন (MP3, WAV, M4A)", "write_story": "আপনার গল্প লিখুন", "submit": "জমা দিন", "success": "আপনার গল্প সংরক্ষিত হয়েছে। ধন্যবাদ!", "error": "অনুগ্রহ করে খালি গল্প জমা দেবেন না।", "transcribed": "লিপ্যন্তরিত পাঠ্য (সম্পাদনাযোগ্য):", + "transcribing": "অডিও ট্রান্সক্রাইব করা হচ্ছে...", + "transcription_success": "ট্রান্সক্রিপশন সফল হয়েছে!", + "transcription_error": "ত্রুটি", "add_tags": "ট্যাগ যোগ করুন (যেমন, #domesticviolence, #healingjourney)", "enter_tags": "কমা দিয়ে ট্যাগ লিখুন:", + "story_hint": "আপনি কণ্ঠ বা টেক্সটে শেয়ার করতে পারেন। আপনার পরিচয় গোপন থাকে।", + "tags_hint": "উদাহরণ: healing, courage, support", + "community_header": "কমিউনিটি গল্প", + "story_card": "গল্প", "comment_placeholder": "এই গল্পে মন্তব্য যোগ করুন:", "post_comment": "মন্তব্য পোস্ট করুন", "comment_empty": "মন্তব্য খালি হতে পারে না।", @@ -152,92 +188,369 @@ def transcribe_audio(audio_path): T = translations[language] + +def count_all_comments(): + return sum(len(items) for items in st.session_state.comments.values()) + + +def get_unique_tag_count(stories): + tags = set() + for story in stories: + for tag in story.get("tags", []): + tags.add(tag) + return len(tags) + + +# ========== Visual Theme ========== +st.markdown( + """ + + """, + unsafe_allow_html=True, +) + # ========== Header ========== -st.markdown(f""" -
-

📖 {T['title']}

-

{T['subtitle']}

-
-""", unsafe_allow_html=True) -st.markdown("---") - -# ========== Audio Upload ========== -st.subheader("🎙️ " + T['upload_audio']) -uploaded_audio = st.file_uploader(label="", type=["mp3", "wav", "m4a", "ogg"]) - -story = "" - -if uploaded_audio: - st.info("⏳ Transcribing audio...") - try: - wav_path = convert_to_wav(uploaded_audio) - text = transcribe_audio(wav_path) - st.success("✅ Transcription successful!") - story = st.text_area(T["transcribed"], value=text, height=200) - except Exception as e: - st.error(f"⚠️ Error: {e}") - story = "" - -# ========== Text Area ========== -st.subheader("✍️ " + T['write_story']) -story_text = st.text_area(label="", value="", height=300) - -if not story and story_text: - story = story_text - -# ========== Tags Input ========== -st.subheader("🏷️ " + T["add_tags"]) -tags_input = st.text_input(T["enter_tags"], value="") -tags = [tag.strip().lower() for tag in tags_input.split(",") if tag.strip()] - -# ========== Submit Button ========== -if st.button("📤 " + T['submit']): - if story.strip(): - save_story(story, tags) - - story_id = str(uuid.uuid4()) - st.session_state.stories.append({"id": story_id, "text": story.strip(), "tags": tags}) - st.session_state.comments[story_id] = [] - - st.success("✅ " + T['success']) - else: - st.warning("⚠️ " + T['error']) -st.markdown("---") +st.markdown( + f""" +
+

📖 {T['title']}

+

{T['subtitle']}

+
+ """, + unsafe_allow_html=True, +) -# ========== Community Stories ========== -st.header("📚 Community Stories") +stats_col1, stats_col2, stats_col3 = st.columns(3) +with stats_col1: + st.markdown( + f""" +
+
Stories
+
{len(st.session_state.stories)}
+
+ """, + unsafe_allow_html=True, + ) +with stats_col2: + st.markdown( + f""" +
+
Comments
+
{count_all_comments()}
+
+ """, + unsafe_allow_html=True, + ) +with stats_col3: + st.markdown( + f""" +
+
Unique Tags
+
{get_unique_tag_count(st.session_state.stories)}
+
+ """, + unsafe_allow_html=True, + ) -if not st.session_state.stories: - st.info(T["no_stories"]) -else: - for story_obj in reversed(st.session_state.stories): - st.markdown(f"### 🗣️ {story_obj['text']}") - if story_obj.get("tags"): - tags_display = " ".join([f"`#{tag}`" for tag in story_obj["tags"]]) - st.markdown(f"**Tags:** {tags_display}") - - # Comment form for each story - with st.form(key=f"comment_form_{story_obj['id']}"): - comment_input = st.text_input( - "💬 " + T["comment_placeholder"], - key=f"input_{story_obj['id']}" - ) - post = st.form_submit_button(T["post_comment"]) - - if post: - if comment_input.strip(): - st.session_state.comments.setdefault(story_obj['id'], []).append( - comment_input.strip() +share_tab, community_tab = st.tabs([f"✍️ {T['share_tab']}", f"📚 {T['community_tab']}"]) + +with share_tab: + st.markdown(f"
{T['story_hint']}
", unsafe_allow_html=True) + + story = "" + + with st.container(border=True): + st.markdown("

Voice Input

", unsafe_allow_html=True) + st.subheader("🎙️ " + T['upload_audio']) + uploaded_audio = st.file_uploader(label="", type=["mp3", "wav", "m4a", "ogg"]) + + if uploaded_audio: + st.info("⏳ " + T["transcribing"]) + try: + wav_path = convert_to_wav(uploaded_audio) + text = transcribe_audio(wav_path) + st.success("✅ " + T["transcription_success"]) + story = st.text_area(T["transcribed"], value=text, height=200) + except Exception as e: + st.error(f"⚠️ {T['transcription_error']}: {e}") + story = "" + + with st.container(border=True): + st.markdown("

Story Input

", unsafe_allow_html=True) + st.subheader("✍️ " + T['write_story']) + story_text = st.text_area(label="", value="", height=260) + + if not story and story_text: + story = story_text + + st.subheader("🏷️ " + T["add_tags"]) + tags_input = st.text_input(T["enter_tags"], value="", placeholder=T["tags_hint"]) + tags = [tag.strip().lower() for tag in tags_input.split(",") if tag.strip()] + + if st.button("📤 " + T['submit'], use_container_width=True): + if story.strip(): + save_story(story, tags) + + story_id = str(uuid.uuid4()) + st.session_state.stories.append({"id": story_id, "text": story.strip(), "tags": tags}) + st.session_state.comments[story_id] = [] + + st.success("✅ " + T['success']) + else: + st.warning("⚠️ " + T['error']) + +with community_tab: + st.markdown("

Read, reflect, and support

", unsafe_allow_html=True) + st.subheader("📚 " + T["community_header"]) + if not st.session_state.stories: + st.info(T["no_stories"]) + else: + for index, story_obj in enumerate(reversed(st.session_state.stories), start=1): + preview = story_obj['text'] if len(story_obj['text']) <= 180 else story_obj['text'][:180] + "..." + with st.expander(f"🗣️ {T['story_card']} {index}: {preview}", expanded=(index == 1)): + st.write(story_obj["text"]) + if story_obj.get("tags"): + tags_display = " ".join([f"`#{tag}`" for tag in story_obj["tags"]]) + st.markdown(f"**Tags:** {tags_display}") + + with st.form(key=f"comment_form_{story_obj['id']}"): + comment_input = st.text_input( + "💬 " + T["comment_placeholder"], + key=f"input_{story_obj['id']}" ) - st.success("💬 " + T["comment_posted"]) - else: - st.warning("⚠️ " + T["comment_empty"]) - - # Display existing comments - comments = st.session_state.comments.get(story_obj['id'], []) - if comments: - st.markdown("**🧵 Comments:**") - for idx, c in enumerate(comments, 1): - st.markdown(f"- {c}") - - st.markdown("---") + post = st.form_submit_button(T["post_comment"]) + + if post: + if comment_input.strip(): + st.session_state.comments.setdefault(story_obj['id'], []).append( + comment_input.strip() + ) + st.success("💬 " + T["comment_posted"]) + else: + st.warning("⚠️ " + T["comment_empty"]) + + comments = st.session_state.comments.get(story_obj['id'], []) + if comments: + st.markdown("**🧵 Comments:**") + for c in comments: + st.markdown(f"- {c}") From ad7b03713fc075fc91df46b9d0dbe914914b9539 Mon Sep 17 00:00:00 2001 From: Kush Shanware <115879636+Kushanware@users.noreply.github.com> Date: Sat, 21 Mar 2026 17:13:29 +0530 Subject: [PATCH 2/2] fix: correct pyproject.toml and enhance UI --- package-lock.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9057685 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "Shakti-app", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}