diff --git a/src/edit_python_pe/main.py b/src/edit_python_pe/main.py index 5f12fd0..b37514d 100755 --- a/src/edit_python_pe/main.py +++ b/src/edit_python_pe/main.py @@ -5,6 +5,7 @@ from textual.app import App, ComposeResult from textual.containers import Horizontal, Vertical from textual.events import Event +from textual.types import NoSelection from textual.widgets import (Button, Input, ListItem, ListView, Select, Static, TextArea) @@ -23,6 +24,66 @@ load_file_into_form) +class SocialEntry(Horizontal): + DEFAULT_CSS = """ + SocialEntry Select { + width: 25%; + } + SocialEntry Input { + width: 50%; + } + SocialEntry Button { + width: 25%; + } + """ + + def __init__(self, index: int, value: str) -> None: + super().__init__() + self.index = index + self.select = Select( + options=[ + GITHUB_OPTION, + GITLAB_OPTION, + BITBUCKET_OPTION, + LINKEDIN_OPTION, + FACEBOOK_OPTION, + INSTAGRAM_OPTION, + X_OPTION, + YOUTUBE_OPTION, + ], + prompt=PROMPT_SOCIAL_NETWORK, + value=value, + ) + self.url_input = Input(placeholder=PLACEHOLDER_SOCIAL_URL) + self.delete_btn = Button(BUTTON_DELETE, id=f"delete_social_{index}") + + def compose(self) -> ComposeResult: + yield self.select + yield self.url_input + yield self.delete_btn + + +class AliasEntry(Horizontal): + DEFAULT_CSS = """ + AliasEntry Input { + width: 75%; + } + AliasEntry Button { + width: 25%; + } + """ + + def __init__(self, index: int) -> None: + super().__init__() + self.index = index + self.alias_input = Input(placeholder=PLACEHOLDER_ALIAS) + self.delete_btn = Button(BUTTON_DELETE, id=f"delete_alias_{index}") + + def compose(self) -> ComposeResult: + yield self.alias_input + yield self.delete_btn + + class MemberApp(App): """Single app that toggles between a file list and a form while connected to a GitHub fork+push flow.""" @@ -129,8 +190,8 @@ def on_mount(self) -> None: self.form_container.display = False # Some data structures - self.social_entries = [] - self.alias_entries = [] + self.social_entries: list[SocialEntry] = [] + self.alias_entries: list[AliasEntry] = [] self.social_index = 0 self.alias_index = 0 self.current_file = None @@ -206,47 +267,10 @@ def on_button_pressed(self, event: Button.Pressed) -> None: index = int(bid.replace("delete_alias_", "")) self.remove_alias_entry(index) - def add_social_entry(self) -> None: - class SocialEntry(Horizontal): - DEFAULT_CSS = """ - SocialEntry Select { - width: 25%; - } - SocialEntry Input { - width: 50%; - } - SocialEntry Button { - width: 25%; - } - """ - - def __init__(se, index): - super().__init__() - se.index = index - se.select = Select( - options=[ - GITHUB_OPTION, - GITLAB_OPTION, - BITBUCKET_OPTION, - LINKEDIN_OPTION, - FACEBOOK_OPTION, - INSTAGRAM_OPTION, - X_OPTION, - YOUTUBE_OPTION, - ], - prompt=PROMPT_SOCIAL_NETWORK, - ) - se.url_input = Input(placeholder=PLACEHOLDER_SOCIAL_URL) - se.delete_btn = Button( - BUTTON_DELETE, id=f"delete_social_{index}" - ) - - def compose(se) -> ComposeResult: - yield se.select - yield se.url_input - yield se.delete_btn - - new_entry = SocialEntry(self.social_index) + def add_social_entry( + self, value: str | NoSelection = Select.BLANK + ) -> None: + new_entry = SocialEntry(self.social_index, value) self.social_index += 1 self.social_entries.append(new_entry) self.social_container.mount(new_entry) @@ -262,28 +286,6 @@ def remove_social_entry(self, index: int) -> None: found.remove() def add_alias_entry(self) -> None: - class AliasEntry(Horizontal): - DEFAULT_CSS = """ - AliasEntry Input { - width: 75%; - } - AliasEntry Button { - width: 25%; - } - """ - - def __init__(se, index): - super().__init__() - se.index = index - se.alias_input = Input(placeholder=PLACEHOLDER_ALIAS) - se.delete_btn = Button( - BUTTON_DELETE, id=f"delete_alias_{index}" - ) - - def compose(se) -> ComposeResult: - yield se.alias_input - yield se.delete_btn - row = AliasEntry(self.alias_index) self.alias_index += 1 self.alias_entries.append(row) diff --git a/src/edit_python_pe/utils.py b/src/edit_python_pe/utils.py index c153a20..179246b 100644 --- a/src/edit_python_pe/utils.py +++ b/src/edit_python_pe/utils.py @@ -271,9 +271,8 @@ def load_file_into_form(app: "MemberApp", filename: str) -> None: for match in social_link_pattern.finditer(social_html): url = match.group(1) platform = match.group(2) - app.add_social_entry() + app.add_social_entry(platform) last_entry = app.social_entries[-1] - last_entry.select.value = platform last_entry.url_input.value = url # Extract aliases, city, homepage from colon-prefixed lines diff --git a/tests/test_member_app.py b/tests/test_member_app.py index ca6af0e..7c89f5c 100644 --- a/tests/test_member_app.py +++ b/tests/test_member_app.py @@ -80,7 +80,7 @@ def test_add_social_entry(self): # Patch mount to accept any object self.app.social_container.mount = lambda x: None # type: ignore - def stub_add_social_entry(): + def stub_add_social_entry(value): entry = self.StubSocialEntry() entry.index = self.app.social_index self.app.social_index += 1 @@ -89,7 +89,7 @@ def stub_add_social_entry(): self.app.add_social_entry = stub_add_social_entry initial_count = len(self.app.social_entries) - self.app.add_social_entry() + self.app.add_social_entry("") self.assertEqual(len(self.app.social_entries), initial_count + 1) def test_add_list_button_clears_form(self): @@ -350,7 +350,7 @@ def test_clear_form(self): self.app.social_container.remove_children = lambda: None # type: ignore self.app.alias_container.remove_children = lambda: None # type: ignore - def stub_add_social_entry(): + def stub_add_social_entry(value): entry = self.StubSocialEntry() entry.index = self.app.social_index self.app.social_index += 1 @@ -366,7 +366,7 @@ def stub_add_alias_entry(): self.app.add_social_entry = stub_add_social_entry self.app.add_alias_entry = stub_add_alias_entry - self.app.add_social_entry() + self.app.add_social_entry("") self.app.add_alias_entry() self.app.clear_form() self.assertEqual(len(self.app.social_entries), 0) @@ -407,7 +407,7 @@ def test_load_file_into_form(self, mock_exists, mock_open): self.app.social_entries = [] self.app.alias_entries = [] - def stub_add_social_entry(): + def stub_add_social_entry(value): entry = self.StubSocialEntry() entry.index = self.app.social_index self.app.social_index += 1