ToDoList / app.py
Mrym834's picture
Create app.py
d0f7ae6 verified
Raw
History Blame Contribute Delete
3.91 kB
import gradio as gr
import uuid
# ---------- Helpers ----------
def new_item(text):
return {"id": str(uuid.uuid4()), "text": text.strip(), "done": False}
def build_choices(items):
return [f"{i}:{'βœ… ' if it['done'] else '◻️ '}{it['text']}" for i, it in enumerate(items)]
def parse_idx(choice):
return int(choice.split(":", 1)[0]) if choice else None
def progress_html(done, total):
pct = int(done / total * 100) if total else 0
return f"<progress value='{done}' max='{total}' style='width:100%'></progress><br>{done}/{total} done ({pct}%)"
def render_ui(state):
"""Returns CheckboxGroup + HTML for a given state"""
ch = build_choices(state)
html = "<ul>"
for it in state:
t = f"<s>{it['text']}</s>" if it["done"] else it["text"]
html += f"<li>{t}</li>"
html += "</ul>" if state else "<i>No items yet</i>"
done = sum(i["done"] for i in state)
prog = progress_html(done, len(state))
return gr.update(choices=ch, value=[]), gr.update(value=html + "<br>" + prog)
# ---------- Actions ----------
def add_item(txt, state):
if txt.strip():
state.append(new_item(txt))
cbx_update, html_update = render_ui(state)
return cbx_update, html_update, gr.update(value=""), state
def toggle_item(selected, state):
for s in selected:
idx = parse_idx(s)
if 0 <= idx < len(state):
state[idx]["done"] = not state[idx]["done"]
cbx_update, html_update = render_ui(state)
return cbx_update, html_update, state
def delete_item(selected, state):
idxs = sorted([parse_idx(s) for s in selected], reverse=True)
for i in idxs:
if 0 <= i < len(state):
state.pop(i)
cbx_update, html_update = render_ui(state)
return cbx_update, html_update, state
# ---------- Build Gradio Interface ----------
with gr.Blocks(title="To-Do & Habit Tracker") as demo:
gr.Markdown("# βœ… To-Do & Habit Tracker\nKeep your daily routine organized!")
with gr.Row():
# --- To-Do Section ---
with gr.Column():
gr.Markdown("### πŸ“ To-Do Tasks")
task_input = gr.Textbox(label="Add a new task")
add_task_btn = gr.Button("βž• Add Task")
todo_box = gr.CheckboxGroup(label="Tasks")
toggle_task_btn = gr.Button("βœ”οΈ Toggle Complete")
del_task_btn = gr.Button("πŸ—‘οΈ Delete Selected")
todo_html = gr.HTML()
todo_state = gr.State([])
# --- Habits Section ---
with gr.Column():
gr.Markdown("### πŸ” Daily Habits")
habit_input = gr.Textbox(label="Add a new habit")
add_habit_btn = gr.Button("βž• Add Habit")
habit_box = gr.CheckboxGroup(label="Habits")
toggle_habit_btn = gr.Button("βœ”οΈ Toggle Complete")
del_habit_btn = gr.Button("πŸ—‘οΈ Delete Selected")
habit_html = gr.HTML()
habit_state = gr.State([])
# Connect To-Do events
add_task_btn.click(add_item, [task_input, todo_state], [todo_box, todo_html, task_input, todo_state])
toggle_task_btn.click(toggle_item, [todo_box, todo_state], [todo_box, todo_html, todo_state])
del_task_btn.click(delete_item, [todo_box, todo_state], [todo_box, todo_html, todo_state])
# Connect Habit events
add_habit_btn.click(add_item, [habit_input, habit_state], [habit_box, habit_html, habit_input, habit_state])
toggle_habit_btn.click(toggle_item, [habit_box, habit_state], [habit_box, habit_html, habit_state])
del_habit_btn.click(delete_item, [habit_box, habit_state], [habit_box, habit_html, habit_state])
# Initialize UI
def init():
cbx1, html1 = render_ui([])
cbx2, html2 = render_ui([])
return cbx1, html1, cbx2, html2, [], []
demo.load(init, None, [todo_box, todo_html, habit_box, habit_html, todo_state, habit_state])
demo.launch()