Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ To ensure clean code structure and organization:
- All new screens should be generated in their own file and cliss within the @app/screens/ directory.
- Larger functionality requests should be broken down in reusable functions for single pieces of functionality.
- When updating or adding functionality, ensure relevant usage information is added to the project README.
- This application uses a redis cache for data pulled from the MLB-StatsAPI library. If new functionality requires new data_service requests ensure these requests leverage the application caching strategy with reasonable TTLs.

## Testing Instructions
- All changes MUST have their style verified. Use pylint as described in @.github/workflows/pylint.yml after making any code changes. Ensure tests are included in linting checks.
Expand Down
25 changes: 15 additions & 10 deletions app/widgets/animations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
from pytermgui.animations import Direction


# pylint: disable=too-many-arguments,too-many-positional-arguments
def slide_transition(window, manager, widgets, title, duration=290, on_finish=None):
# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals
def slide_transition(window, manager, widgets, title, duration=290, on_finish=None,
new_width=None, new_height=None):
"""
Performs a slide-out and slide-in transition for a window.

Expand All @@ -18,17 +19,21 @@ def slide_transition(window, manager, widgets, title, duration=290, on_finish=No
title (str): The new title to set after sliding out.
duration (int): Duration of each slide stage in milliseconds.
on_finish (callable, optional): Callback to run when the entire transition finishes.
new_width (int, optional): The target width for the window.
new_height (int, optional): The target height for the window.
"""
static_width = window.width
static_height = window.height
# Use provided dimensions or fallback to current ones
target_width = new_width if new_width is not None else window.width
target_height = new_height if new_height is not None else window.height

target_x = (manager.terminal.width - static_width) // 2
# Calculate starting position for slide-in (centered)
final_target_x = (manager.terminal.width - target_width) // 2
_, start_y = window.pos
off_screen_right = manager.terminal.width

def slide_step(anim, off_x):
def slide_step(anim, off_x, current_target_x):
"""Updates the window position based on animation state and off-screen target."""
curr_x = int(target_x + (off_x - target_x) * anim.state)
curr_x = int(current_target_x + (off_x - current_target_x) * anim.state)
window.pos = (curr_x, start_y)
return False

Expand All @@ -41,15 +46,15 @@ def on_slide_out_finish(_):
"""Updates window content and starts the slide-in animation using Direction.BACKWARD."""
window.set_widgets(widgets)
window.set_title(title)
window.width = static_width
window.height = static_height
window.width = target_width
window.height = target_height
window.styles.border = "green"
window.styles.corner = "green"

ptg.animator.animate_float(
duration=duration,
direction=Direction.BACKWARD,
on_step=lambda anim: slide_step(anim, off_screen_right),
on_step=lambda anim: slide_step(anim, off_screen_right, final_target_x),
on_finish=on_slide_in_finish
)

Expand Down
26 changes: 23 additions & 3 deletions mlb_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@
)
from app.widgets import CalendarWidget, slide_transition

# TODO: Consider making this dynamic as opposed to a hardcoded value.
# This value ensures a the initial calendar view is correct, assuming
# a 3 month view.
INITIAL_HEIGHT = 36


class MLBApp:
"""
Main application class that manages the WindowManager and screen transitions.
"""
# pylint: disable=too-many-instance-attributes

# pylint: disable=too-many-instance-attributes

def __init__(self):
"""Initializes the application state and UI components."""
fetch_teams()
Expand Down Expand Up @@ -54,21 +61,34 @@ def set_window_data(self, widgets, title, page_name, on_finish=None):
on_finish()
return

# Calculate required height based on content
max_height = self.manager.terminal.height - 2
temp_window = ptg.Window(*widgets, width=self.static_width)
temp_window.set_title(title)
target_height = min(max_height, temp_window.height)

self.active_page = page_name
if not self.is_initialized:
self.is_initialized = True
self.main_window.set_widgets(widgets)
self.main_window.set_title(title)
self.main_window.width = self.static_width
self.main_window.height = self.static_height
self.main_window.height = target_height
self.main_window.styles.border = "green"
self.main_window.styles.corner = "green"
self.main_window.center()
if on_finish:
on_finish()
return

slide_transition(self.main_window, self.manager, widgets, title, on_finish=on_finish)
slide_transition(
self.main_window,
self.manager,
widgets,
title,
on_finish=on_finish,
new_height=target_height
)

def update_to_schedule(self, *_args, **_kwargs):
"""Transitions the main window to show the schedule for current_date."""
Expand Down Expand Up @@ -278,7 +298,7 @@ def exit_app(self, *_args, **_kwargs):
def run(self):
"""Starts the application main loop."""
with self.manager:
self.static_height = min(50, self.manager.terminal.height - 2)
self.static_height = min(INITIAL_HEIGHT, self.manager.terminal.height - 2)

self.main_window = ptg.Window(
width=self.static_width,
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tool.pylint.messages_control]
disable = ["fixme"]
2 changes: 2 additions & 0 deletions tests/test_mlb_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def setUp(self):
patch('mlb_cli.ptg.WindowManager') as mock_manager:
self.app = MLBApp()
self.app.manager = mock_manager.return_value
self.app.manager.terminal.width = 100
self.app.manager.terminal.height = 40
self.app.main_window = MagicMock(spec=ptg.Window)
self.app.main_window.__iter__.return_value = iter([])

Expand Down
Loading