Skip to content

Commit

Permalink
Add progress indicators and a proper progressbar to flashing step
Browse files Browse the repository at this point in the history
  • Loading branch information
tsterbak committed Jan 9, 2023
1 parent f665349 commit d28853a
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 27 deletions.
10 changes: 6 additions & 4 deletions openandroidinstaller/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ def __init__(self, state: AppState, image: str = "placeholder.png"):
self.state = state

# configs
column_width = 600
self.column_width = 600
# right part of the display, add content here.
self.right_view_header = Column(width=column_width, height=100, spacing=30)
self.right_view = Column(alignment="center", width=column_width, height=650)
self.right_view_header = Column(width=self.column_width, height=100, spacing=30)
self.right_view = Column(
alignment="center", width=self.column_width, height=650
)
# left part of the display: used for displaying the images
self.left_view = Column(
width=column_width,
width=self.column_width,
controls=[Image(src=f"/assets/imgs/{image}", height=600)],
expand=True,
horizontal_alignment="center",
Expand Down
106 changes: 84 additions & 22 deletions openandroidinstaller/views/step_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
Switch,
alignment,
ProgressBar,
ProgressRing,
colors,
)

Expand Down Expand Up @@ -75,9 +76,6 @@ def __init__(
self.inputtext = TextField(
hint_text="your unlock code", expand=False
) # textfield for the unlock code

# placeholder for the flashing progressbar
self.progressbar = None

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

# container for progress indicators
self.progress_indicator = ProgressIndicator(expand=True)

# main controls
steps_indictor_img_lookup = {
"Unlock the bootloader": "steps-header-unlock.png",
Expand Down Expand Up @@ -132,6 +133,7 @@ def check_advanced_switch(e):
self.right_view.controls.extend(
[
Row([self.error_text]),
Row([self.progress_indicator]),
Column(
[
self.advanced_switch,
Expand All @@ -150,6 +152,7 @@ def check_advanced_switch(e):
[
self.inputtext,
Row([self.error_text]),
Row([self.progress_indicator]),
Column(
[
self.advanced_switch,
Expand Down Expand Up @@ -193,6 +196,8 @@ def call_to_phone(self, e, command: str):
"""
# disable the call button while the command is running
self.call_button.disabled = True
# reset the progress indicators
self.progress_indicator.clear()
# reset terminal output
if self.state.advanced:
self.terminal_box.clear()
Expand Down Expand Up @@ -230,27 +235,14 @@ def call_to_phone(self, e, command: str):
# run the right command
if command in cmd_mapping.keys():
for line in cmd_mapping.get(command)(bin_path=self.state.bin_path):
# write the line to advanced output terminal
self.terminal_box.write_line(line)
# in case the install command is run, we want to update the progress bar
if command == "adb_twrp_wipe_and_install":
# TODO: add and/or update the progressbar here
percentage_done = -1
# get the progress numbers from the output lines
result = re.search(r"\(~(\d{1,3})\%\)|(Total xfer: 1.00x)", line)
if result.group(1):
percentage_done = int(result.group(1))
elif result.group(2):
percentage_done = 100

# create the progress bar on first occurrence
if percentage_done == 0:
self.progressbar = ProgressBar(width=400, bar_height=8, color="#00d886")
self.right_view.controls.append(self.progressbar)
# update the progress bar
if self.progressbar:
self.progressbar.value = percentage_done / 100
self.right_view.update()

self.progress_indicator.display_progress_bar(line)
self.progress_indicator.update()
else:
self.progress_indicator.display_progress_ring()
else:
msg = f"Unknown command type: {command}. Stopping."
logger.error(msg)
Expand All @@ -270,6 +262,9 @@ def call_to_phone(self, e, command: str):
# enable the confirm button and disable the call button
self.confirm_button.disabled = False
self.call_button.disabled = True
# reset the progress indicator (let the progressbar stay for the install command)
if command != "adb_twrp_wipe_and_install":
self.progress_indicator.clear()
self.view.update()


Expand Down Expand Up @@ -302,7 +297,7 @@ def write_line(self, line: str):
self.update()

def toggle_visibility(self):
"""Toogle the visibility of the terminal box."""
"""Toggle the visibility of the terminal box."""
self._box.visible = not self._box.visible
self.update()

Expand All @@ -314,3 +309,70 @@ def clear(self):
def update(self):
"""Update the view."""
self._box.update()


class ProgressIndicator(UserControl):
def __init__(self, expand: bool = True):
super().__init__(expand=expand)
# placeholder for the flashing progressbar
self.progress_bar = None
# progress ring to display
self.progress_ring = None

def build(self):
self._container = Container(
content=Column(scroll="auto", expand=True),
margin=10,
alignment=alignment.center,
height=50,
expand=True,
visible=True,
)
return self._container

def display_progress_bar(self, line: str):
"""Display and update the progress bar for the given line."""
percentage_done = None
result = None
# get the progress numbers from the output lines
if (type(line) == str) and line.strip():
result = re.search(r"\(\~(\d{1,3})\%\)|(Total xfer: 1\.00x)", line.strip())
if result:
if result.group(1):
percentage_done = int(result.group(1))
elif result.group(2):
percentage_done = 100

# create the progress bar on first occurrence
if percentage_done == 0:
self.progress_bar = ProgressBar(
width=500, bar_height=32, color="#00d886", bgcolor="#eeeeee"
)
self.percentage_text = Text(f"{percentage_done}%")
self._container.content.controls.append(
Row([self.percentage_text, self.progress_bar])
)
# update the progress bar
if self.progress_bar:
self.progress_bar.value = percentage_done / 100
self.percentage_text.value = f"{percentage_done}%"

def display_progress_ring(
self,
):
"""Display a progress ring to signal progress."""
if not self.progress_ring:
self.progress_ring = ProgressRing(color="#00d886")
self._container.content.controls.append(self.progress_ring)
self._container.update()

def clear(self):
"""Clear output."""
self._container.content.controls = []
self.progress_ring = None
self.progress_bar = None
self.update()

def update(self):
"""Update the view."""
self._container.update()
94 changes: 93 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ schema = "^0.7.5"
py7zr = "^0.20.0"
pytest-cov = "^4.0.0"
pytest-mock = "^3.10.0"
bandit = "^1.7.4"

[tool.poetry.dev-dependencies]

Expand Down
Loading

0 comments on commit d28853a

Please sign in to comment.