Update pages/type_text.py
Browse files- pages/type_text.py +46 -203
pages/type_text.py
CHANGED
@@ -12,210 +12,53 @@ os.getenv("HF_TOKEN")
|
|
12 |
import time
|
13 |
import base64
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
background: white;
|
38 |
-
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
39 |
-
padding: 10px;
|
40 |
-
z-index: 1000;
|
41 |
-
}}
|
42 |
-
.status-widget {{
|
43 |
-
padding: 15px;
|
44 |
-
border-radius: 4px;
|
45 |
-
margin-bottom: 5px;
|
46 |
-
display: flex;
|
47 |
-
align-items: center;
|
48 |
-
}}
|
49 |
-
.status-icon {{
|
50 |
-
width: 24px;
|
51 |
-
height: 24px;
|
52 |
-
margin-right: 15px;
|
53 |
-
display: flex;
|
54 |
-
align-items: center;
|
55 |
-
justify-content: center;
|
56 |
-
}}
|
57 |
-
.status-content {{
|
58 |
-
flex-grow: 1;
|
59 |
-
}}
|
60 |
-
.status-processing {{
|
61 |
-
background-color: #f0f2f6;
|
62 |
-
border-left: 4px solid #31333f;
|
63 |
-
}}
|
64 |
-
.status-complete {{
|
65 |
-
background-color: #e6f4ea;
|
66 |
-
border-left: 4px solid #0cce6b;
|
67 |
-
}}
|
68 |
-
.status-error {{
|
69 |
-
background-color: #fce8e6;
|
70 |
-
border-left: 4px solid #ff5252;
|
71 |
-
}}
|
72 |
-
.spinner {{
|
73 |
-
border: 3px solid rgba(0, 0, 0, 0.1);
|
74 |
-
border-radius: 50%;
|
75 |
-
border-top: 3px solid #31333f;
|
76 |
-
width: 20px;
|
77 |
-
height: 20px;
|
78 |
-
animation: spin 1s linear infinite;
|
79 |
-
}}
|
80 |
-
@keyframes spin {{
|
81 |
-
0% {{ transform: rotate(0deg); }}
|
82 |
-
100% {{ transform: rotate(360deg); }}
|
83 |
-
}}
|
84 |
-
.checkmark {{
|
85 |
-
color: #0cce6b;
|
86 |
-
font-size: 20px;
|
87 |
-
font-weight: bold;
|
88 |
-
}}
|
89 |
-
</style>
|
90 |
-
</head>
|
91 |
-
<body>
|
92 |
-
<div class="status-container">
|
93 |
-
<div id="status-widget" class="status-widget status-processing">
|
94 |
-
<div class="status-icon">
|
95 |
-
<div class="spinner" id="spinner"></div>
|
96 |
-
<div class="checkmark" id="checkmark" style="display:none;">✓</div>
|
97 |
-
</div>
|
98 |
-
<div class="status-content">
|
99 |
-
<h3 id="status-title" style="margin: 0 0 5px 0;">Processing data...</h3>
|
100 |
-
<p id="status-message" style="margin: 0;">Starting the operation...</p>
|
101 |
-
<div id="progress-container" style="margin-top: 10px; background: #eee; border-radius: 5px;">
|
102 |
-
<div id="progress-bar" style="height: 10px; width: 0%; background: #31333f; border-radius: 5px;"></div>
|
103 |
-
</div>
|
104 |
-
</div>
|
105 |
-
</div>
|
106 |
-
</div>
|
107 |
-
|
108 |
-
<script>
|
109 |
-
// Function to receive messages from parent (Streamlit)
|
110 |
-
window.addEventListener('message', function(event) {{
|
111 |
-
try {{
|
112 |
-
const data = JSON.parse(event.data);
|
113 |
-
if (data.type === 'update_status') {{
|
114 |
-
document.getElementById('status-title').innerText = data.title;
|
115 |
-
document.getElementById('status-message').innerText = data.message;
|
116 |
-
document.getElementById('progress-bar').style.width = data.progress + '%';
|
117 |
-
|
118 |
-
if (data.state === 'complete') {{
|
119 |
-
document.getElementById('status-widget').className = 'status-widget status-complete';
|
120 |
-
document.getElementById('spinner').style.display = 'none';
|
121 |
-
document.getElementById('checkmark').style.display = 'block';
|
122 |
-
}}
|
123 |
-
}}
|
124 |
-
}} catch (e) {{
|
125 |
-
console.error('Error processing message:', e);
|
126 |
-
}}
|
127 |
-
}});
|
128 |
-
</script>
|
129 |
-
</body>
|
130 |
-
</html>
|
131 |
-
"""
|
132 |
-
return f"data:text/html;base64,{base64.b64encode(html.encode()).decode()}"
|
133 |
-
|
134 |
-
# Create two columns - one for the iframe and one for the content
|
135 |
-
col1, col2 = st.columns([1, 3])
|
136 |
-
|
137 |
-
# Create the iframe in col1 with the status widget
|
138 |
-
with col1:
|
139 |
-
iframe_height = 150
|
140 |
-
iframe_src = get_iframe_html(iframe_height)
|
141 |
-
st.markdown(
|
142 |
-
f'<iframe src="{iframe_src}" height="{iframe_height}" width="100%" frameBorder="0"></iframe>',
|
143 |
-
unsafe_allow_html=True
|
144 |
-
)
|
145 |
-
|
146 |
-
# Create a hidden element that will contain our JavaScript
|
147 |
-
st.markdown(
|
148 |
-
"""
|
149 |
-
<div id="iframe-connector"></div>
|
150 |
-
<script>
|
151 |
-
// Function to send messages to the iframe
|
152 |
-
function updateStatus(title, message, progress, state) {
|
153 |
-
const iframes = document.getElementsByTagName('iframe');
|
154 |
-
if (iframes.length > 0) {
|
155 |
-
const data = {
|
156 |
-
type: 'update_status',
|
157 |
-
title: title,
|
158 |
-
message: message,
|
159 |
-
progress: progress,
|
160 |
-
state: state
|
161 |
-
};
|
162 |
-
iframes[0].contentWindow.postMessage(JSON.stringify(data), '*');
|
163 |
-
}
|
164 |
-
}
|
165 |
-
|
166 |
-
// Store the function in window object so Python can access it
|
167 |
-
window.updateStatus = updateStatus;
|
168 |
-
</script>
|
169 |
-
""",
|
170 |
-
unsafe_allow_html=True
|
171 |
-
)
|
172 |
-
|
173 |
-
# Create main content in col2
|
174 |
-
with col2:
|
175 |
-
st.title("Main Content Area")
|
176 |
-
st.write("Scroll down to see the sticky status widget in action")
|
177 |
-
|
178 |
-
# Button to start the process
|
179 |
-
if st.button("Start Process"):
|
180 |
-
# Simulate a process
|
181 |
-
for i in range(0, 101, 5):
|
182 |
-
# Update the message based on progress
|
183 |
-
if i < 30:
|
184 |
-
step = "Step 1: Loading data..."
|
185 |
-
elif i < 70:
|
186 |
-
step = "Step 2: Processing information..."
|
187 |
-
else:
|
188 |
-
step = "Step 3: Finalizing results..."
|
189 |
-
|
190 |
-
# Use JavaScript to update the iframe
|
191 |
-
js_code = f"""
|
192 |
-
<script>
|
193 |
-
if (window.updateStatus) {{
|
194 |
-
window.updateStatus(
|
195 |
-
"Processing data... {i}%",
|
196 |
-
"{step}",
|
197 |
-
{i},
|
198 |
-
"{('complete' if i == 100 else 'processing')}"
|
199 |
-
);
|
200 |
-
}}
|
201 |
-
</script>
|
202 |
-
"""
|
203 |
-
st.markdown(js_code, unsafe_allow_html=True)
|
204 |
-
|
205 |
-
# Wait a bit to simulate work
|
206 |
-
time.sleep(0.2)
|
207 |
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
|
220 |
#hide_streamlit_style = """
|
221 |
# <style>
|
|
|
12 |
import time
|
13 |
import base64
|
14 |
|
15 |
+
st.markdown("---")
|
16 |
+
st.subheader("Alternative Approach Using Components")
|
17 |
+
st.write("""
|
18 |
+
If the iframe approach doesn't work for you, try this alternate solution:
|
19 |
+
|
20 |
+
```python
|
21 |
+
import streamlit as st
|
22 |
+
|
23 |
+
# First, inject the CSS
|
24 |
+
st.markdown('''
|
25 |
+
<style>
|
26 |
+
/* Create a fixed container at the top */
|
27 |
+
.fixed-container {
|
28 |
+
position: fixed;
|
29 |
+
top: 3.8rem; /* Position below Streamlit header */
|
30 |
+
left: 0;
|
31 |
+
right: 0;
|
32 |
+
background: white;
|
33 |
+
z-index: 999;
|
34 |
+
padding: 1rem;
|
35 |
+
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
36 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
+
/* Add padding to the main content to prevent overlap */
|
39 |
+
.main-content {
|
40 |
+
padding-top: 7rem; /* Adjust this value based on your status height */
|
41 |
+
}
|
42 |
+
</style>
|
43 |
+
''', unsafe_allow_html=True)
|
44 |
+
|
45 |
+
# Create a container for the fixed status
|
46 |
+
st.markdown('<div class="fixed-container">', unsafe_allow_html=True)
|
47 |
+
status = st.status("Processing data...")
|
48 |
+
with status:
|
49 |
+
st.write("This status widget will remain fixed while scrolling")
|
50 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
51 |
+
|
52 |
+
# Add padding to prevent content overlap
|
53 |
+
st.markdown('<div class="main-content">', unsafe_allow_html=True)
|
54 |
+
|
55 |
+
# Your main content
|
56 |
+
st.title("Main Content")
|
57 |
+
for i in range(30):
|
58 |
+
st.write(f"Content row {i}")
|
59 |
+
|
60 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
61 |
+
```
|
62 |
|
63 |
#hide_streamlit_style = """
|
64 |
# <style>
|