Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
# -*- coding: utf-8 -*-
|
|
|
|
| 2 |
import base64, mimetypes
|
| 3 |
from html import escape
|
| 4 |
from pathlib import Path
|
|
@@ -30,7 +31,7 @@ STRIP_PILL_PAD_V_PX = 8
|
|
| 30 |
STRIP_PILL_PAD_H_PX = 14
|
| 31 |
STRIP_PILL_FONT_PX = 16
|
| 32 |
TAGLINE_FONT_PX = 15
|
| 33 |
-
STRIP_BELOW_GAP_PX = 30 # space between the strip row and the hero
|
| 34 |
|
| 35 |
HERO_LOGO_WIDTH_PX = 400 # width of the hero logo
|
| 36 |
HERO_MARGIN_BOTTOM_PX= 30 # space under the hero logo
|
|
@@ -87,16 +88,19 @@ APPS = [
|
|
| 87 |
]
|
| 88 |
|
| 89 |
# ========= HELPERS =========
|
| 90 |
-
def data_uri(path: Path) -> str
|
| 91 |
-
if not path or not path.exists():
|
|
|
|
| 92 |
mime, _ = mimetypes.guess_type(path.name)
|
| 93 |
-
if not mime:
|
|
|
|
| 94 |
b64 = base64.b64encode(path.read_bytes()).decode("utf-8")
|
| 95 |
return f"data:{mime};base64,{b64}"
|
| 96 |
|
| 97 |
def img_tag(path: Path, alt: str, cls: str = "", style: str = "") -> str:
|
| 98 |
uri = data_uri(path)
|
| 99 |
-
if not uri:
|
|
|
|
| 100 |
cls_attr = f' class="{cls}"' if cls else ""
|
| 101 |
style_attr = f' style="{style}"' if style else ""
|
| 102 |
return f'<img{cls_attr}{style_attr} src="{uri}" alt="{escape(alt)}" />'
|
|
@@ -146,9 +150,7 @@ st.markdown(f"""
|
|
| 146 |
}}
|
| 147 |
|
| 148 |
html, body, [data-testid="stAppViewContainer"] {{ height: 100%; }}
|
| 149 |
-
[data-testid="stAppViewContainer"] > .main {{
|
| 150 |
-
padding-top: 0 !important; padding-bottom: 0 !important;
|
| 151 |
-
}}
|
| 152 |
|
| 153 |
.block-container {{
|
| 154 |
max-width: 1120px;
|
|
@@ -168,7 +170,7 @@ st.markdown(f"""
|
|
| 168 |
.suite-row {{
|
| 169 |
display:flex; align-items:center; gap: var(--strip-gap);
|
| 170 |
justify-content:flex-start; flex-wrap: wrap;
|
| 171 |
-
margin: 0 0 var(--strip-row-mb) 0;
|
| 172 |
}}
|
| 173 |
|
| 174 |
.suite-pill {{
|
|
@@ -310,7 +312,7 @@ def app_card(app: dict) -> str:
|
|
| 310 |
tint = app.get("tint") if USE_TINTED_CARD_BG else f"linear-gradient(180deg, {PAPER_TOP} 0%, {PAPER_BOT} 100%)"
|
| 311 |
icon_html = img_tag(app.get("icon"), "icon",
|
| 312 |
style=f"width:{ICON_IMG_PX}px;height:{ICON_IMG_PX}px;border-radius:9999px;") \
|
| 313 |
-
|
| 314 |
target = "_self"
|
| 315 |
chip = f"<div class='suite-chip'>{escape(SUITE_NAME)}</div>" if SHOW_CARD_CHIP else ""
|
| 316 |
style_vars = f"--card-bg:{tint};"
|
|
|
|
| 1 |
# -*- coding: utf-8 -*-
|
| 2 |
+
from typing import Optional
|
| 3 |
import base64, mimetypes
|
| 4 |
from html import escape
|
| 5 |
from pathlib import Path
|
|
|
|
| 31 |
STRIP_PILL_PAD_H_PX = 14
|
| 32 |
STRIP_PILL_FONT_PX = 16
|
| 33 |
TAGLINE_FONT_PX = 15
|
| 34 |
+
STRIP_BELOW_GAP_PX = 30 # space between the top-left strip row and the hero
|
| 35 |
|
| 36 |
HERO_LOGO_WIDTH_PX = 400 # width of the hero logo
|
| 37 |
HERO_MARGIN_BOTTOM_PX= 30 # space under the hero logo
|
|
|
|
| 88 |
]
|
| 89 |
|
| 90 |
# ========= HELPERS =========
|
| 91 |
+
def data_uri(path: Path) -> Optional[str]:
|
| 92 |
+
if not path or not path.exists():
|
| 93 |
+
return None
|
| 94 |
mime, _ = mimetypes.guess_type(path.name)
|
| 95 |
+
if not mime:
|
| 96 |
+
mime = "image/png"
|
| 97 |
b64 = base64.b64encode(path.read_bytes()).decode("utf-8")
|
| 98 |
return f"data:{mime};base64,{b64}"
|
| 99 |
|
| 100 |
def img_tag(path: Path, alt: str, cls: str = "", style: str = "") -> str:
|
| 101 |
uri = data_uri(path)
|
| 102 |
+
if not uri:
|
| 103 |
+
return ""
|
| 104 |
cls_attr = f' class="{cls}"' if cls else ""
|
| 105 |
style_attr = f' style="{style}"' if style else ""
|
| 106 |
return f'<img{cls_attr}{style_attr} src="{uri}" alt="{escape(alt)}" />'
|
|
|
|
| 150 |
}}
|
| 151 |
|
| 152 |
html, body, [data-testid="stAppViewContainer"] {{ height: 100%; }}
|
| 153 |
+
[data-testid="stAppViewContainer"] > .main {{ padding-top: 0 !important; padding-bottom: 0 !important; }}
|
|
|
|
|
|
|
| 154 |
|
| 155 |
.block-container {{
|
| 156 |
max-width: 1120px;
|
|
|
|
| 170 |
.suite-row {{
|
| 171 |
display:flex; align-items:center; gap: var(--strip-gap);
|
| 172 |
justify-content:flex-start; flex-wrap: wrap;
|
| 173 |
+
margin: 0 0 var(--strip-row-mb) 0;
|
| 174 |
}}
|
| 175 |
|
| 176 |
.suite-pill {{
|
|
|
|
| 312 |
tint = app.get("tint") if USE_TINTED_CARD_BG else f"linear-gradient(180deg, {PAPER_TOP} 0%, {PAPER_BOT} 100%)"
|
| 313 |
icon_html = img_tag(app.get("icon"), "icon",
|
| 314 |
style=f"width:{ICON_IMG_PX}px;height:{ICON_IMG_PX}px;border-radius:9999px;") \
|
| 315 |
+
if app.get("icon") and app["icon"].exists() else ""
|
| 316 |
target = "_self"
|
| 317 |
chip = f"<div class='suite-chip'>{escape(SUITE_NAME)}</div>" if SHOW_CARD_CHIP else ""
|
| 318 |
style_vars = f"--card-bg:{tint};"
|