Skip to content

Commit d28853a

Browse files
committed
Add progress indicators and a proper progressbar to flashing step
1 parent f665349 commit d28853a

5 files changed

Lines changed: 233 additions & 27 deletions

File tree

openandroidinstaller/views/base.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ def __init__(self, state: AppState, image: str = "placeholder.png"):
3030
self.state = state
3131

3232
# configs
33-
column_width = 600
33+
self.column_width = 600
3434
# right part of the display, add content here.
35-
self.right_view_header = Column(width=column_width, height=100, spacing=30)
36-
self.right_view = Column(alignment="center", width=column_width, height=650)
35+
self.right_view_header = Column(width=self.column_width, height=100, spacing=30)
36+
self.right_view = Column(
37+
alignment="center", width=self.column_width, height=650
38+
)
3739
# left part of the display: used for displaying the images
3840
self.left_view = Column(
39-
width=column_width,
41+
width=self.column_width,
4042
controls=[Image(src=f"/assets/imgs/{image}", height=600)],
4143
expand=True,
4244
horizontal_alignment="center",

openandroidinstaller/views/step_view.py

Lines changed: 84 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
Switch,
3232
alignment,
3333
ProgressBar,
34+
ProgressRing,
3435
colors,
3536
)
3637

@@ -75,9 +76,6 @@ def __init__(
7576
self.inputtext = TextField(
7677
hint_text="your unlock code", expand=False
7778
) # textfield for the unlock code
78-
79-
# placeholder for the flashing progressbar
80-
self.progressbar = None
8179

8280
def build(self):
8381
"""Create the content of a view from step."""
@@ -104,6 +102,9 @@ def check_advanced_switch(e):
104102
# text box for terminal output
105103
self.terminal_box = TerminalBox(expand=True)
106104

105+
# container for progress indicators
106+
self.progress_indicator = ProgressIndicator(expand=True)
107+
107108
# main controls
108109
steps_indictor_img_lookup = {
109110
"Unlock the bootloader": "steps-header-unlock.png",
@@ -132,6 +133,7 @@ def check_advanced_switch(e):
132133
self.right_view.controls.extend(
133134
[
134135
Row([self.error_text]),
136+
Row([self.progress_indicator]),
135137
Column(
136138
[
137139
self.advanced_switch,
@@ -150,6 +152,7 @@ def check_advanced_switch(e):
150152
[
151153
self.inputtext,
152154
Row([self.error_text]),
155+
Row([self.progress_indicator]),
153156
Column(
154157
[
155158
self.advanced_switch,
@@ -193,6 +196,8 @@ def call_to_phone(self, e, command: str):
193196
"""
194197
# disable the call button while the command is running
195198
self.call_button.disabled = True
199+
# reset the progress indicators
200+
self.progress_indicator.clear()
196201
# reset terminal output
197202
if self.state.advanced:
198203
self.terminal_box.clear()
@@ -230,27 +235,14 @@ def call_to_phone(self, e, command: str):
230235
# run the right command
231236
if command in cmd_mapping.keys():
232237
for line in cmd_mapping.get(command)(bin_path=self.state.bin_path):
238+
# write the line to advanced output terminal
233239
self.terminal_box.write_line(line)
234240
# in case the install command is run, we want to update the progress bar
235241
if command == "adb_twrp_wipe_and_install":
236-
# TODO: add and/or update the progressbar here
237-
percentage_done = -1
238-
# get the progress numbers from the output lines
239-
result = re.search(r"\(~(\d{1,3})\%\)|(Total xfer: 1.00x)", line)
240-
if result.group(1):
241-
percentage_done = int(result.group(1))
242-
elif result.group(2):
243-
percentage_done = 100
244-
245-
# create the progress bar on first occurrence
246-
if percentage_done == 0:
247-
self.progressbar = ProgressBar(width=400, bar_height=8, color="#00d886")
248-
self.right_view.controls.append(self.progressbar)
249-
# update the progress bar
250-
if self.progressbar:
251-
self.progressbar.value = percentage_done / 100
252-
self.right_view.update()
253-
242+
self.progress_indicator.display_progress_bar(line)
243+
self.progress_indicator.update()
244+
else:
245+
self.progress_indicator.display_progress_ring()
254246
else:
255247
msg = f"Unknown command type: {command}. Stopping."
256248
logger.error(msg)
@@ -270,6 +262,9 @@ def call_to_phone(self, e, command: str):
270262
# enable the confirm button and disable the call button
271263
self.confirm_button.disabled = False
272264
self.call_button.disabled = True
265+
# reset the progress indicator (let the progressbar stay for the install command)
266+
if command != "adb_twrp_wipe_and_install":
267+
self.progress_indicator.clear()
273268
self.view.update()
274269

275270

@@ -302,7 +297,7 @@ def write_line(self, line: str):
302297
self.update()
303298

304299
def toggle_visibility(self):
305-
"""Toogle the visibility of the terminal box."""
300+
"""Toggle the visibility of the terminal box."""
306301
self._box.visible = not self._box.visible
307302
self.update()
308303

@@ -314,3 +309,70 @@ def clear(self):
314309
def update(self):
315310
"""Update the view."""
316311
self._box.update()
312+
313+
314+
class ProgressIndicator(UserControl):
315+
def __init__(self, expand: bool = True):
316+
super().__init__(expand=expand)
317+
# placeholder for the flashing progressbar
318+
self.progress_bar = None
319+
# progress ring to display
320+
self.progress_ring = None
321+
322+
def build(self):
323+
self._container = Container(
324+
content=Column(scroll="auto", expand=True),
325+
margin=10,
326+
alignment=alignment.center,
327+
height=50,
328+
expand=True,
329+
visible=True,
330+
)
331+
return self._container
332+
333+
def display_progress_bar(self, line: str):
334+
"""Display and update the progress bar for the given line."""
335+
percentage_done = None
336+
result = None
337+
# get the progress numbers from the output lines
338+
if (type(line) == str) and line.strip():
339+
result = re.search(r"\(\~(\d{1,3})\%\)|(Total xfer: 1\.00x)", line.strip())
340+
if result:
341+
if result.group(1):
342+
percentage_done = int(result.group(1))
343+
elif result.group(2):
344+
percentage_done = 100
345+
346+
# create the progress bar on first occurrence
347+
if percentage_done == 0:
348+
self.progress_bar = ProgressBar(
349+
width=500, bar_height=32, color="#00d886", bgcolor="#eeeeee"
350+
)
351+
self.percentage_text = Text(f"{percentage_done}%")
352+
self._container.content.controls.append(
353+
Row([self.percentage_text, self.progress_bar])
354+
)
355+
# update the progress bar
356+
if self.progress_bar:
357+
self.progress_bar.value = percentage_done / 100
358+
self.percentage_text.value = f"{percentage_done}%"
359+
360+
def display_progress_ring(
361+
self,
362+
):
363+
"""Display a progress ring to signal progress."""
364+
if not self.progress_ring:
365+
self.progress_ring = ProgressRing(color="#00d886")
366+
self._container.content.controls.append(self.progress_ring)
367+
self._container.update()
368+
369+
def clear(self):
370+
"""Clear output."""
371+
self._container.content.controls = []
372+
self.progress_ring = None
373+
self.progress_bar = None
374+
self.update()
375+
376+
def update(self):
377+
"""Update the view."""
378+
self._container.update()

poetry.lock

Lines changed: 93 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ schema = "^0.7.5"
2323
py7zr = "^0.20.0"
2424
pytest-cov = "^4.0.0"
2525
pytest-mock = "^3.10.0"
26+
bandit = "^1.7.4"
2627

2728
[tool.poetry.dev-dependencies]
2829

0 commit comments

Comments
 (0)