from dataclasses import dataclass from pathlib import Path from typing import Optional from dataclasses import dataclass import rio @dataclass class NewsPostImage: path: Path link: Optional[str] class NewsPost(rio.Component): header: str date: str article_text_path_or_text: str | Path images: list[NewsPostImage] article_text = "" @rio.event.on_populate def on_populate(self): self.align_y = 0 self.margin_top = 0 self.margin_bottom = 2 self.margin_right = 1 if isinstance(self.article_text_path_or_text, str): self.article_text = self.article_text_path_or_text elif isinstance(self.article_text_path_or_text, Path): with open(self.article_text_path_or_text, "r", encoding="utf-8") as f: self.article_text = f.read() def build(self) -> rio.Component: image_column = rio.Column(margin=0.5) for news_post_image in self.images: image_obj = rio.Image( news_post_image.path, fill_mode="fit", width=20, height=20, align_x=0.01 ) image_column.add( rio.Link(image_obj, target_url=news_post_image.link, open_in_new_tab=True ) if bool(news_post_image.link) else image_obj ) return rio.Rectangle( content=rio.Column( rio.Row( rio.Text(self.header, align_x=0.1, style="heading2"), rio.Text(self.date, align_x=0.9, style=rio.TextStyle(italic=True)), margin_top=0.5 ), rio.Column( rio.Markdown(self.article_text, margin=1) ), image_column ), fill=self.session.theme.neutral_color, corner_radius=self.session.theme.corner_radius_medium, shadow_radius=0.5, shadow_color=self.session.theme.hud_color, shadow_offset_y=0 ) def build_news_post(header: str, article_text_path_or_text: str | Path, date: str, images: Optional[list[NewsPostImage]] = None) -> NewsPost: if images is None: images = [] return NewsPost( header=header, article_text_path_or_text=article_text_path_or_text, images=images, date=date, align_y=0, margin_top=0, margin_bottom=2, margin_right=1 )