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": {} +} diff --git a/streamlit_app.py b/streamlit_app.py index f77f56d..92a8207 100644 --- a/streamlit_app.py +++ b/streamlit_app.py @@ -169,14 +169,23 @@ def transcribe_audio(audio_path): "English": { "title": "Shakti", "subtitle": "Your story is still alive", - "upload_audio": "Upload your voice (MP3, WAV)", + "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.", @@ -186,14 +195,23 @@ def transcribe_audio(audio_path): "Hindi": { "title": "Shakti", "subtitle": "हर आवाज़ अब साँस ले रही है", - "upload_audio": "अपनी आवाज़ अपलोड करें (MP3, WAV)", + "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": "टिप्पणी खाली नहीं हो सकती।", @@ -203,14 +221,23 @@ def transcribe_audio(audio_path): "Tamil": { "title": "என் கதை உயிருடன் உள்ளது", "subtitle": "உங்கள் கதை இன்னும் உயிருடன் உள்ளது", - "upload_audio": "உங்கள் குரலை பதிவேற்றவும் (MP3, WAV)", + "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": "கருத்து காலியானதாக இருக்க முடியாது.", @@ -220,14 +247,23 @@ def transcribe_audio(audio_path): "Bengali": { "title": "আমার গল্প এখনও বেঁচে আছে", "subtitle": "আপনার কণ্ঠ এখনো জীবিত", - "upload_audio": "আপনার কণ্ঠ আপলোড করুন (MP3, WAV)", + "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": "মন্তব্য খালি হতে পারে না।", @@ -238,152 +274,369 @@ def transcribe_audio(audio_path): T = translations.get(language, translations["English"]) -# ========== Submission Handler ========== -def handle_submission(): - tags = [tag.strip().lower() for tag in st.session_state.tags_input.split(",") if tag.strip()] - if st.session_state.story_input.strip(): - save_story(st.session_state.story_input, tags) +def count_all_comments(): + return sum(len(items) for items in st.session_state.comments.values()) - story_id = str(uuid.uuid4()) - st.session_state.stories.append({ - "id": story_id, - "text": st.session_state.story_input.strip(), - "tags": tags - }) - st.session_state.comments[story_id] = [] - - # Clear inputs - st.session_state.story_input = "" - st.session_state.tags_input = "" - st.session_state.audio_processed = False # Reset audio processing flag - st.session_state.submission_success = True # Flag for successful submission - else: - st.session_state.submission_error = True # Flag for error - -def handle_comment(story_id): - comment_key = f"comment_input_{story_id}" - if comment_key in st.session_state: - comment = st.session_state[comment_key] - if comment.strip(): - if story_id not in st.session_state.comments: - st.session_state.comments[story_id] = [] - st.session_state.comments[story_id].append(comment.strip()) - st.session_state[comment_key] = "" # Clear the comment input - st.session_state.comment_posted = story_id # Flag which comment was posted - else: - st.session_state.comment_empty = story_id # Flag which comment was empty - -# ========== UI Components ========== -st.markdown(f""" -
{T['subtitle']}
+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 = handle_audio_file(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']}" + ) + 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}")