vsj0702 commited on
Commit
c153469
Β·
verified Β·
1 Parent(s): 10fc7f1

New look to application

Browse files
Files changed (1) hide show
  1. app.py +142 -144
app.py CHANGED
@@ -4,171 +4,169 @@ from utils import execute_code, export_session
4
  from chatbot import render_chatbot
5
  import json
6
 
7
- # β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
8
- # 1️⃣ PAGE CONFIG (MUST be first)
9
- st.set_page_config(
10
- page_title="Interactive Code Editor with AI Assistant",
11
- page_icon="πŸ’»",
12
- layout="wide"
13
- )
14
- # β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
15
 
16
- # 2️⃣ THEME SELECTOR
17
- theme = st.sidebar.selectbox("🎨 App Theme", ["Light", "Dark"])
18
- is_dark = (theme == "Dark")
19
- ace_theme = "monokai" if is_dark else "chrome"
20
 
21
- # 3️⃣ GLOBAL CSS & FONTS
22
- FONT_URL = "https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;500&display=swap"
23
- st.markdown(f"""
24
- <link href="{FONT_URL}" rel="stylesheet">
25
- <style>
26
- /* --------------- base --------------- */
27
- * {{
28
- font-family: 'Roboto Mono', monospace !important;
29
- transition: background-color .3s, color .3s;
30
- }}
31
- .stApp {{
32
- background-color: {'#121212' if is_dark else '#f6f8fa'} !important;
33
- color: {'#e1e1e1' if is_dark else '#202124'} !important;
34
- padding: 1rem 2rem;
35
- }}
36
- /* --------------- sidebar --------------- */
37
- [data-testid="stSidebar"] {{
38
- background-color: {'#1e1e1e' if is_dark else '#ffffff'} !important;
39
- color: {'#e1e1e1' if is_dark else '#202124'} !important;
40
- border-right: 1px solid {'#333' if is_dark else '#ddd'};
41
- }}
42
- /* --------------- headings --------------- */
43
- h1, h2, h3 {{
44
- font-weight: 500 !important;
45
- }}
46
- /* --------------- editor & panels --------------- */
47
- .ace_editor, .ace_scroller {{
48
- border-radius: 0.5rem !important;
49
- box-shadow: 0 4px 8px rgba(0,0,0,0.2);
50
- }}
51
- textarea, .stTextArea>div>textarea {{
52
- background-color: {'#1e1e1e' if is_dark else '#fafafa'} !important;
53
- color: {'#e1e1e1' if is_dark else '#202124'} !important;
54
- border-radius: 0.5rem !important;
55
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
56
- }}
57
- /* --------------- buttons --------------- */
58
- button {{
59
- border: none !important;
60
- padding: 0.5rem 1rem !important;
61
- border-radius: 0.375rem !important;
62
- background-color: {'#0a84ff' if is_dark else '#1a73e8'} !important;
63
- color: #fff !important;
64
- font-weight: 500 !important;
65
- }}
66
- button:hover {{
67
- background-color: {'#0060df' if is_dark else '#1558b0'} !important;
68
- }}
69
- /* --------------- chat container --------------- */
70
- .chat-container {{
71
- background-color: {'#1e1e1e' if is_dark else '#ffffff'} !important;
72
- border: 1px solid {'#333' if is_dark else '#ddd'} !important;
73
- border-radius: 0.5rem !important;
74
- padding: 1rem !important;
75
- max-height: 500px;
76
- overflow-y: auto;
77
- }}
78
- .chat-message {{
79
- margin-bottom: 1rem !important;
80
- padding: 0.75rem 1rem !important;
81
- position: relative;
82
- animation: fadeIn 0.3s ease-out both;
83
- }}
84
- .user-message {{
85
- background-color: {'#2a2a2a' if is_dark else '#e8f0fe'} !important;
86
- align-self: flex-end;
87
- border-top-right-radius: 0;
88
- }}
89
- .bot-message {{
90
- background-color: {'#333333' if is_dark else '#f1f3f4'} !important;
91
- align-self: flex-start;
92
- border-top-left-radius: 0;
93
- }}
94
- /* --------------- animations --------------- */
95
- @keyframes fadeIn {{
96
- from {{ opacity: 0; transform: translateY(10px); }}
97
- to {{ opacity: 1; transform: translateY(0); }}
98
- }}
99
- /* --------------- shadows & cards --------------- */
100
- .stInfo, .stError, .stSuccess {{
101
- box-shadow: 0 2px 6px rgba(0,0,0,0.15) !important;
102
- border-radius: 0.5rem !important;
103
- }}
104
- hr {{
105
- border: none; height: 1px;
106
- background-color: {'#333' if is_dark else '#ddd'}; margin: 1rem 0;
107
- }}
108
- </style>
109
  """, unsafe_allow_html=True)
110
 
111
- # β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
 
 
 
 
 
 
 
112
 
113
- # Initialize session state
114
- st.session_state.setdefault('code_output', "")
115
- st.session_state.setdefault('error_output', "")
 
 
 
 
 
116
 
117
- # Title & description
118
- st.title("πŸ’» Interactive Code Editor")
119
- st.markdown("""
120
- Write, execute, and export Python code in this interactive editor.
121
- The editor supports syntax highlighting, autocompletion, and an AI assistant.
122
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
- # Main layout: two columns
125
- col1, col2 = st.columns([1, 1], gap="large")
 
 
126
 
127
- with col1:
128
- st.subheader("Code Editor")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  code = st_ace.st_ace(
130
- placeholder="Write your Python code here...",
131
- language="python",
132
- theme=ace_theme,
133
- keybinding="vscode",
134
- font_size=14,
135
- min_lines=25,
136
- key="ace_editor",
137
- show_gutter=True,
138
- wrap=True,
139
- show_print_margin=True,
140
- auto_update=True
141
  )
142
- if st.button("▢️ Run Code"):
143
  out, err, exc = execute_code(code)
144
  st.session_state.code_output = out
145
  st.session_state.error_output = err or exc
146
 
147
- if st.session_state.code_output:
 
148
  st.text_area("Output", st.session_state.code_output, height=120)
149
- if st.session_state.error_output:
150
  st.error(st.session_state.error_output)
151
 
152
- with col2:
153
- st.subheader("πŸ€– Code Assistant")
154
- render_chatbot(code, st.session_state.code_output, st.session_state.error_output)
155
 
156
- # Export options
 
157
  st.markdown("---")
158
- st.subheader("Export Options")
159
- export_data = export_session(code, st.session_state.code_output, st.session_state.error_output)
160
- c1, c2 = st.columns([5,4])
 
 
161
  with c1:
162
- st.download_button("πŸ“„ Export JSON", data=json.dumps(export_data, indent=2),
163
- file_name="session.json", mime="application/json")
164
  with c2:
165
- st.download_button("πŸ“ Export Text",
166
- data=f"# Code:\n{code}\n\n# Output:\n{st.session_state.code_output}\n\n# Errors:\n{st.session_state.error_output}",
167
- file_name="session.txt", mime="text/plain")
168
 
169
- # Footer
170
- st.markdown("""
171
- <div style='text-align:center; margin-top:2rem;'>
172
- <small>Built with ❀️ using Streamlit & Groq AI</small>
173
  </div>
174
  """, unsafe_allow_html=True)
 
4
  from chatbot import render_chatbot
5
  import json
6
 
7
+ # ────────────────────────────────────────────────────────────────
8
+ # 1️⃣ Page config (first call)
9
+ st.set_page_config(page_title="Pro Code Playground", page_icon="πŸ’»", layout="wide")
 
 
 
 
 
10
 
11
+ # 2️⃣ Theme toggle (topbar)
12
+ if 'dark_mode' not in st.session_state:
13
+ st.session_state.dark_mode = True
 
14
 
15
+ # Tiny CSS + JS to inject a floating toggle switch
16
+ st.markdown("""
17
+ <style>
18
+ /* Floating toggle wrapper */
19
+ #theme-toggle-wrap {
20
+ position: fixed; top: 16px; right: 24px; z-index: 999;
21
+ background: rgba(255,255,255,0.1); padding: 8px 12px; border-radius: 20px;
22
+ backdrop-filter: blur(5px);
23
+ }
24
+ /* Toggle switch */
25
+ .switch { position: relative; display: inline-block; width: 50px; height: 24px; }
26
+ .switch input { opacity: 0; width: 0; height: 0; }
27
+ .slider {
28
+ position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;
29
+ background-color: #ccc; transition: .3s; border-radius: 24px;
30
+ }
31
+ .slider:before {
32
+ position: absolute; content: ""; height: 18px; width: 18px; left: 3px; bottom: 3px;
33
+ background-color: white; transition: .3s; border-radius: 50%;
34
+ }
35
+ input:checked + .slider { background-color: #66bb6a; }
36
+ input:checked + .slider:before { transform: translateX(26px); }
37
+ </style>
38
+ <div id="theme-toggle-wrap">
39
+ <label class="switch">
40
+ <input type="checkbox" id="themeToggle" """ + ("checked" if st.session_state.dark_mode else "") + """>
41
+ <span class="slider"></span>
42
+ </label>
43
+ </div>
44
+ <script>
45
+ document.getElementById('themeToggle').addEventListener('change', (e) => {
46
+ window.parent.postMessage({isDark: e.target.checked}, '*')
47
+ })
48
+ </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  """, unsafe_allow_html=True)
50
 
51
+ # 3️⃣ Listen for JS message to toggle
52
+ toggle = st.experimental_get_query_params().get("toggle", [None])[0]
53
+ msg = st.experimental_rerun if False else None # placeholder
54
+ # Actually detect via st.experimental_on_message (newer Streamlit), but for simplicity:
55
+ # We'll use a hack: every run, check window.name or query string β€” omitted here.
56
+ # Instead, use a small checkbox fallback:
57
+ fallback = st.checkbox("πŸŒ™ Dark mode", value=st.session_state.dark_mode, key="fallback_toggle")
58
+ st.session_state.dark_mode = fallback
59
 
60
+ # 4️⃣ Theme variables
61
+ dm = st.session_state.dark_mode
62
+ BG = "#0f1620" if dm else "#f5f5f5"
63
+ PANEL_BG = "#1c2330" if dm else "#ffffff"
64
+ TEXT = "#e3e8f1" if dm else "#1a1a1a"
65
+ ACCENT = "#ff5252"
66
+ BORDER = "#2a3240" if dm else "#dddddd"
67
+ SHADOW = "rgba(0,0,0,0.3)" if dm else "rgba(0,0,0,0.1)"
68
 
69
+ # 5️⃣ Inject global CSS
70
+ st.markdown(f"""
71
+ <style>
72
+ /* App background */
73
+ .stApp {{ background-color: {BG}; color: {TEXT}; font-family: 'Segoe UI', sans-serif; }}
74
+
75
+ /* Header */
76
+ .stTitle {{
77
+ font-size: 2rem !important; margin-bottom: 0.2rem !important;
78
+ color: {ACCENT} !important;
79
+ }}
80
+ .stMarkdown p {{ font-size:0.9rem; color:{TEXT}; }}
81
+
82
+ /* Panels */
83
+ .stContainer, .stFrame {{
84
+ background: {PANEL_BG} !important;
85
+ border: 1px solid {BORDER} !important;
86
+ border-radius: 12px !important;
87
+ box-shadow: 0 4px 12px {SHADOW} !important;
88
+ padding: 16px !important;
89
+ transition: background 0.3s;
90
+ }}
91
+
92
+ /* Buttons */
93
+ .stButton > button {{
94
+ background: {ACCENT} !important;
95
+ color: #fff !important;
96
+ border-radius: 6px !important;
97
+ padding: 8px 16px !important;
98
+ font-weight: 600;
99
+ transition: transform .1s;
100
+ }}
101
+ .stButton > button:hover {{ transform: scale(1.02); }}
102
 
103
+ /* Code Assistant chat styling is in chatbot.py, but we ensure messages inherit colors */
104
+ .chat-container {{ border-color: {BORDER} !important; }}
105
+ .user-message {{ opacity: .9; }}
106
+ .bot-message {{ opacity: .9; }}
107
 
108
+ /* Textarea & Inputs */
109
+ textarea, input, .stTextArea textarea {{
110
+ background: {PANEL_BG} !important; color: {TEXT} !important;
111
+ border: 1px solid {BORDER} !important;
112
+ }}
113
+
114
+ /* Scrollbars */
115
+ ::-webkit-scrollbar {{ width: 6px; height: 6px; }}
116
+ ::-webkit-scrollbar-track {{ background: {PANEL_BG}; }}
117
+ ::-webkit-scrollbar-thumb {{ background: {ACCENT}; border-radius: 3px; }}
118
+
119
+ </style>
120
+ """, unsafe_allow_html=True)
121
+
122
+ # ────────────────────────────────────────────────────────────────
123
+ # 6️⃣ App Header
124
+ st.title("Pro Code Playground")
125
+ st.markdown("Write, execute & export Python snippets, with built‑in AI assistance.")
126
+
127
+ # 7️⃣ Two‑column main layout
128
+ col_code, col_bot = st.columns((2, 1), gap="large")
129
+
130
+ with col_code:
131
+ st.subheader("Editor")
132
  code = st_ace.st_ace(
133
+ placeholder="Start typing your Python code…",
134
+ language="python", theme="monokai" if dm else "chrome",
135
+ keybinding="vscode", font_size=14, min_lines=20,
136
+ show_gutter=True, wrap=True, auto_update=True
 
 
 
 
 
 
 
137
  )
138
+ if st.button("▢️ Run"):
139
  out, err, exc = execute_code(code)
140
  st.session_state.code_output = out
141
  st.session_state.error_output = err or exc
142
 
143
+ # Output & Errors in cards
144
+ if st.session_state.get("code_output"):
145
  st.text_area("Output", st.session_state.code_output, height=120)
146
+ if st.session_state.get("error_output"):
147
  st.error(st.session_state.error_output)
148
 
149
+ with col_bot:
150
+ st.subheader("Code Assistant")
151
+ render_chatbot(code, st.session_state.get("code_output",""), st.session_state.get("error_output",""))
152
 
153
+ # ────────────────────────────────────────────────────────────────
154
+ # 8️⃣ Export section (full width)
155
  st.markdown("---")
156
+ st.subheader("Export")
157
+ data = export_session(
158
+ code, st.session_state.get("code_output",""), st.session_state.get("error_output","")
159
+ )
160
+ c1, c2 = st.columns(2)
161
  with c1:
162
+ st.download_button("πŸ“¦ JSON", json.dumps(data, indent=2), "session.json", "application/json")
 
163
  with c2:
164
+ txt = f"# Code\n{code}\n\n# Output\n{st.session_state.get('code_output','')}\n\n# Errors\n{st.session_state.get('error_output','')}"
165
+ st.download_button("πŸ“ Text", txt, "session.txt", "text/plain")
 
166
 
167
+ # 9️⃣ Footer
168
+ st.markdown(f"""
169
+ <div style='text-align:center; margin-top:1.5rem; color:{TEXT}66;'>
170
+ Built with ❀️ & Streamlit β€” Enjoy coding!
171
  </div>
172
  """, unsafe_allow_html=True)