File size: 3,472 Bytes
930ea3d
05a5cc7
 
930ea3d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
904c6e9
930ea3d
 
 
 
 
 
 
 
29346cd
b63ac8c
930ea3d
 
 
 
 
904c6e9
930ea3d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05a5cc7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
930ea3d
05a5cc7
930ea3d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import base64
import os
from urllib import request
from pathlib import Path

import streamlit as st


def _icon_data_uri(filename: str) -> str:
    icon_path = Path(__file__).resolve().parent.parent / "icons" / filename
    if not icon_path.exists():
        return ""
    try:
        encoded = base64.b64encode(icon_path.read_bytes()).decode("ascii")
    except Exception:
        return ""
    return f"data:image/png;base64,{encoded}"


def _build_sidebar_icon_css() -> str:
    """Use named icons for sidebar items: home/prob/batch/molecule/manual/ai."""
    fallback = {
        1: "🏠",
        2: "🔎",
        3: "📦",
        4: "🧬",
        5: "⚙️",
        6: "🧠",
        7: "✨",
        8: "💬",
    }
    icon_name = {
        1: "home1.png",
        2: "probe1.png",
        3: "batch1.png",
        4: "molecule1.png",
        5: "manual1.png",
        6: "ai1.png",
        7: "rnn1.png",
        8: "feedback.png",
    }
    rules = [
        '[data-testid="stSidebarNav"] ul li a { position: relative; padding-left: 3.9rem !important; }',
        '[data-testid="stSidebarNav"] ul li a::before { content: ""; position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 46px; height: 46px; background-size: contain; background-repeat: no-repeat; background-position: center; }',
    ]
    for idx in range(1, 9):
        uri = _icon_data_uri(icon_name[idx])
        if uri:
            rules.append(
                '[data-testid="stSidebarNav"] ul li:nth-of-type(%d) a::before { content: ""; background-image: url("%s"); }'
                % (idx, uri)
            )
        else:
            emoji = fallback[idx]
            rules.append(
                '[data-testid="stSidebarNav"] ul li:nth-of-type(%d) a::before { content: "%s "; background-image: none; width: auto; height: auto; }'
                % (idx, emoji)
            )
    return "\n".join(rules)


def _log_visit_once_per_session() -> None:
    if st.session_state.get("_visit_logged"):
        return
    webhook_url = os.getenv("FEEDBACK_WEBHOOK_URL", "").strip()
    webhook_token = os.getenv("FEEDBACK_WEBHOOK_TOKEN", "").strip()
    if not webhook_url:
        return
    endpoint = webhook_url
    sep = "&" if "?" in webhook_url else "?"
    endpoint = f"{webhook_url}{sep}event=visit"
    if webhook_token:
        endpoint = f"{endpoint}&token={webhook_token}"
    try:
        with request.urlopen(endpoint, timeout=10):
            pass
    except Exception:
        pass
    st.session_state["_visit_logged"] = True


def apply_global_style() -> None:
    _log_visit_once_per_session()
    icon_css = _build_sidebar_icon_css()

    css = """
    <style>
    [data-testid="stSidebarNav"] ul li a {
        font-size: 1.2rem !important;
        font-weight: 600 !important;
        border-radius: 12px !important;
        padding: 0.42rem 0.65rem !important;
        margin-bottom: 0.38rem !important;
    }

    [data-testid="stSidebarNav"] ul li a span {
        font-size: 1.2rem !important;
        font-weight: 600 !important;
    }

    [data-testid="stSidebarNav"] ul li a[aria-current="page"] {
        background-color: rgba(44, 123, 29, 0.24) !important;
    }

    [data-testid="stSidebarNav"] ul li a[aria-current="page"] span {
        color: #1f3f7a !important;
        font-weight: 700 !important;
    }

    __ICON_CSS__
    </style>
    """
    st.markdown(css.replace("__ICON_CSS__", icon_css), unsafe_allow_html=True)