new web ract
This commit is contained in:
@@ -1,9 +1,41 @@
|
||||
import re
|
||||
import flet as ft
|
||||
import designer as d
|
||||
import api_client as api
|
||||
import theme_manager
|
||||
|
||||
|
||||
def _html_to_markdown(html: str) -> str:
|
||||
"""Convert TipTap HTML output to Markdown for ft.Markdown rendering."""
|
||||
t = html or ""
|
||||
# Headings
|
||||
t = re.sub(r"<h([1-6])[^>]*>(.*?)</h\1>",
|
||||
lambda m: "#" * int(m[1]) + " " + m[2] + "\n\n",
|
||||
t, flags=re.DOTALL | re.IGNORECASE)
|
||||
# Bold / italic
|
||||
t = re.sub(r"<(strong|b)[^>]*>(.*?)</\1>", r"**\2**", t, flags=re.DOTALL | re.IGNORECASE)
|
||||
t = re.sub(r"<(em|i)[^>]*>(.*?)</\1>", r"*\2*", t, flags=re.DOTALL | re.IGNORECASE)
|
||||
# Links
|
||||
t = re.sub(r'<a[^>]+href=["\']([^"\']+)["\'][^>]*>(.*?)</a>',
|
||||
r"[\2](\1)", t, flags=re.DOTALL | re.IGNORECASE)
|
||||
# Images
|
||||
t = re.sub(r'<img[^>]+src=["\']([^"\']+)["\'][^>]*>', r"", t, flags=re.IGNORECASE)
|
||||
# Lists
|
||||
t = re.sub(r"<li[^>]*>(.*?)</li>", r"- \1\n", t, flags=re.DOTALL | re.IGNORECASE)
|
||||
t = re.sub(r"</?[uo]l[^>]*>", "\n", t, flags=re.IGNORECASE)
|
||||
# Paragraphs / line breaks
|
||||
t = re.sub(r"<br\s*/?>", "\n", t, flags=re.IGNORECASE)
|
||||
t = re.sub(r"<p[^>]*>(.*?)</p>", r"\1\n\n", t, flags=re.DOTALL | re.IGNORECASE)
|
||||
# Strip remaining tags
|
||||
t = re.sub(r"<[^>]+>", "", t)
|
||||
# HTML entities
|
||||
t = (t.replace(" ", " ").replace("&", "&")
|
||||
.replace("<", "<").replace(">", ">").replace(""", '"'))
|
||||
# Collapse excessive blank lines
|
||||
t = re.sub(r"\n{3,}", "\n\n", t)
|
||||
return t.strip()
|
||||
|
||||
|
||||
class NewsDetailView:
|
||||
def __init__(self, page: ft.Page, slug: str):
|
||||
self.page = page
|
||||
@@ -159,7 +191,7 @@ class NewsDetailView:
|
||||
|
||||
controls.append(
|
||||
ft.Markdown(
|
||||
value=a.get("content", ""),
|
||||
value=_html_to_markdown(a.get("content", "")),
|
||||
selectable=True,
|
||||
extension_set=ft.MarkdownExtensionSet.GITHUB_WEB,
|
||||
on_tap_link=lambda e: self.page.launch_url(e.data),
|
||||
@@ -167,6 +199,26 @@ class NewsDetailView:
|
||||
)
|
||||
)
|
||||
|
||||
if a.get("source_url"):
|
||||
source_url = a["source_url"]
|
||||
controls.append(
|
||||
ft.Container(
|
||||
content=ft.Row([
|
||||
ft.Icon(ft.icons.OPEN_IN_NEW, size=15, color=d.PRIMARY),
|
||||
ft.Text("Источник:", size=13, color=d.TEXT_SECONDARY),
|
||||
ft.TextButton(
|
||||
source_url,
|
||||
style=ft.ButtonStyle(color=d.PRIMARY),
|
||||
on_click=lambda e, url=source_url: self.page.launch_url(url),
|
||||
),
|
||||
], spacing=6, vertical_alignment=ft.CrossAxisAlignment.CENTER, wrap=True),
|
||||
bgcolor=ft.colors.with_opacity(0.04, d.PRIMARY),
|
||||
border_radius=8,
|
||||
padding=12,
|
||||
border=ft.border.all(1, ft.colors.with_opacity(0.15, d.PRIMARY)),
|
||||
)
|
||||
)
|
||||
|
||||
controls.append(ft.Divider(height=32, color="transparent"))
|
||||
controls.append(
|
||||
ft.TextButton(
|
||||
|
||||
Reference in New Issue
Block a user