Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion daras_ai_v2/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
)
from routers.root import PREVIEW_ROUTE_WORKFLOWS

from widgets.sidebar import render_default_sidebar, sidebar_mobile_header

MAX_SEED = 4294967294
gooey_rng = Random()
Expand Down Expand Up @@ -194,6 +195,9 @@ def __init__(
self.tab = tab
self.request = request

def render_sidebar(self, request, sidebar_ref):
render_default_sidebar(sidebar_ref, request)

@classmethod
def api_endpoint(cls) -> str:
return f"/v2/{cls.slug_versions[0]}"
Expand Down Expand Up @@ -391,7 +395,8 @@ def render(self):
self.render_report_form()
return

header_placeholder = gui.div(className="my-3 w-100")
sidebar_mobile_header(self.request)
header_placeholder = gui.div(className="my-1 w-100")
with (
gui.styled(NAV_TABS_CSS),
gui.div(className="position-relative", id="recipe-nav-tabs"),
Expand Down
2 changes: 2 additions & 0 deletions daras_ai_v2/icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
info = "<i class='fa-regular fa-circle-info'></i>"
search = '<i class="fa-solid fa-magnifying-glass"></i>'
library = '<i class="fa-solid fa-book"></i>'
sidebar_flip = "<i class='fa-light fa-sidebar-flip'></i>"
arrow_up_right = "<i class='fa-regular fa-arrow-up-right'></i>"

# brands
github = '<i class="fa-brands fa-github"></i>'
Expand Down
14 changes: 13 additions & 1 deletion daras_ai_v2/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@
GOOEY_LOGO_IMG = "https://storage.googleapis.com/dara-c1b52.appspot.com/daras_ai/media/2a3aacb4-0941-11ee-b236-02420a0001fb/thumbs/logo%20black.png_400x400.png"
GOOEY_LOGO_IMG_WHITE = "https://storage.googleapis.com/dara-c1b52.appspot.com/daras_ai/media/ea26bc06-7eda-11ef-89fa-02420a0001f6/gooey-white-logo.png"
GOOEY_LOGO_RECT = "https://storage.googleapis.com/dara-c1b52.appspot.com/daras_ai/media/d628be8a-9207-11ef-8aee-02420a000186/984x272%20rect%20gooey%20logo.png"
GOOEY_LOGO_FACE = "https://storage.googleapis.com/dara-c1b52.appspot.com/daras_ai/media/bb2587e4-66eb-11f0-a197-02420a00013e/gooey-logo-robo.png"

os.environ["REPLICATE_API_TOKEN"] = config("REPLICATE_API_TOKEN", default="")

Expand Down Expand Up @@ -310,7 +311,18 @@
("/pricing", "Pricing"),
(CONTACT_URL, "Contact"),
]
HEADER_ICONS = {}

SIDEBAR_LINKS = [
# ("/explore/", "Search", "<i class='fa-solid fa-magnifying-glass'></i>"),
(DOCS_URL, "Docs", "<i class='fa-regular fa-book'></i>"),
("/api/", "API", "<i class='fa-regular fa-code'></i>"),
(BLOG_URL, "Blog", "<i class='fa-regular fa-newspaper'></i>"),
("/pricing", "Pricing", "<i class='fa-regular fa-circle-dollar'></i>"),
(CONTACT_URL, "Contact", "<i class='fa-regular fa-envelope'></i>"),
]
SIDEBAR_ICON_SIZE = "32px"

HEADER_ICONS = {"/explore/": '<i class="fa-solid fa-magnifying-glass"></i>'}

GPU_SERVER_1 = furl(config("GPU_SERVER_1", "http://gpu-1.gooey.ai"))

Expand Down
3 changes: 2 additions & 1 deletion routers/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from workspaces.models import Workspace, WorkspaceInvite
from workspaces.views import invitation_page, workspaces_page
from workspaces.widgets import get_current_workspace, SWITCH_WORKSPACE_KEY
from widgets.sidebar import sidebar_mobile_header

if typing.TYPE_CHECKING:
from app_users.models import AppUser
Expand Down Expand Up @@ -381,7 +382,7 @@ def account_page_wrapper(request: Request, current_tab: TabData):
raise gui.RedirectException(str(redirect_url))

with page_wrapper(request) as current_workspace:
gui.div(className="mt-5")
sidebar_mobile_header(request)
with gui.nav_tabs():
for tab in AccountTabs.get_tabs_for_user(request.user, current_workspace):
with gui.nav_item(tab.url_path, active=tab == current_tab):
Expand Down
195 changes: 131 additions & 64 deletions routers/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from routers.static_pages import serve_static_file
from widgets.workflow_search import SearchFilters, render_search_bar_with_redirect
from workspaces.widgets import global_workspace_selector, workspace_selector_link
from widgets.sidebar import render_default_sidebar, sidebar_layout, use_sidebar

app = CustomAPIRouter()

Expand Down Expand Up @@ -250,7 +251,7 @@ def explore_page(
):
from widgets import explore

with page_wrapper(request, search_filters=search_filters, show_search_bar=False):
with page_wrapper(request):
explore.render(request, search_filters)

return {
Expand Down Expand Up @@ -689,7 +690,7 @@ def render_recipe_page(
if not gui.session_state:
gui.session_state.update(page.current_sr_to_session_state())

with page_wrapper(request):
with page_wrapper(request, page=page):
page.render()

return dict(
Expand All @@ -709,75 +710,138 @@ def get_og_url_path(request) -> str:
def page_wrapper(
request: Request,
className="",
search_filters: typing.Optional[SearchFilters] = None,
show_search_bar: bool = True,
page=None,
):
from routers.account import explore_in_current_workspace

context = {"request": request, "block_incognito": True}

with gui.div(className="d-flex flex-column min-vh-100"):
gui.html(templates.get_template("gtag.html").render(**context))

with (
gui.div(className="header"),
gui.div(className="navbar navbar-expand-xl bg-transparent p-0 m-0"),
gui.div(className="container-xxl my-2"),
gui.div(
className="position-relative w-100 d-flex justify-content-between gap-2"
),
):
with (
gui.div(className="d-md-block"),
gui.tag("a", href="/"),
):
gui.tag(
"img",
src=settings.GOOEY_LOGO_IMG,
width="300",
height="142",
className="img-fluid logo d-none d-sm-block",
)
gui.tag(
"img",
src=settings.GOOEY_LOGO_RECT,
width="145",
height="40",
className="img-fluid logo d-sm-none",
)

if show_search_bar:
_render_mobile_search_button(request, search_filters)
context = {
"request": request,
"block_incognito": True,
}

sidebar_ref = use_sidebar("main-sidebar", request.session, default_open=True)
sidebar_container, pane_container = sidebar_layout(sidebar_ref)

container = page if page else None
with sidebar_container:
with gui.styled("""
.gooey-sidebar-closed:hover {
& .hover-btn {
display: block !important;
}
& .logo-face {
display: none !important;
}
}
"""):
with gui.div(
className="d-flex gap-2 justify-content-end flex-wrap align-items-center"
className="flex-grow-1 position-relative",
id="sidebar-click-container",
):
for url, label in settings.HEADER_LINKS:
render_header_link(
url=url, label=label, icon=settings.HEADER_ICONS.get(url)
with gui.div(
className="d-flex px-md-2 px-3 py-2 align-items-center justify-content-between text-nowrap",
style={"height": "54px"},
):
# sidebar header
gui.tag(
"img",
src=settings.GOOEY_LOGO_FACE,
width=settings.SIDEBAR_ICON_SIZE,
height=settings.SIDEBAR_ICON_SIZE,
className=" logo-face d-none d-md-block",
)

if request.user and not request.user.is_anonymous:
render_header_link(
url=get_route_path(explore_in_current_workspace),
label="Saved",
icon=icons.save,
open_sidebar_btn = gui.button(
label=icons.sidebar_flip,
className="m-0 d-none hover-btn gooey-btn",
unsafe_allow_html=True,
type="tertiary",
)
if open_sidebar_btn:
sidebar_ref.set_open(True)
raise gui.RerunException()

current_workspace = global_workspace_selector(
request.user, request.session
current_workspace = None
with (
gui.styled(
"""
& > button {
max-width: 100%;
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 100%;
margin: auto;
}
""",
),
gui.div(
className="position-relative", style={"maxWidth": "50%"}
),
):
if sidebar_ref.is_open:
if request.user and not request.user.is_anonymous:
current_workspace = global_workspace_selector(
request.user, request.session
)
else:
current_workspace = None
anonymous_login_container(request, context)

close_mobile_sidebar = gui.button(
label=icons.cancel,
className="m-0 d-md-none gooey-btn",
unsafe_allow_html=True,
type="tertiary",
)
if close_mobile_sidebar:
sidebar_ref.set_mobile_open(False)
raise gui.RerunException()

if sidebar_ref.is_open:
close_sidebar = gui.button(
label=icons.sidebar_flip,
className="m-0 d-none d-md-block gooey-btn",
unsafe_allow_html=True,
type="tertiary",
)
if close_sidebar:
sidebar_ref.set_open(False)
raise gui.RerunException()

if container:
container.render_sidebar(request, sidebar_ref)
else:
current_workspace = None
anonymous_login_container(request, context)
render_default_sidebar(sidebar_ref, request)

gui.html(copy_to_clipboard_scripts)
# Bottom section with workspace selector when sidebar is closed
with (
gui.styled(
"& img { width: 32px !important; height: 32px !important; }"
),
gui.div(
className="p-3 position-absolute bottom-0 d-md-block d-none",
style={"width": "100%", "zIndex": 1000},
),
):
if not sidebar_ref.is_open:
if request.user and not request.user.is_anonymous:
current_workspace = global_workspace_selector(
request.user, request.session, hide_name=True
)
else:
current_workspace = None
anonymous_login_container(request, context, hide_sign_in=True)

# Main content pane
with pane_container:
with gui.div(className="d-flex flex-column min-vh-100 w-100 pt-md-2"):
gui.html(templates.get_template("gtag.html").render(**context))

with gui.div(id="main-content", className="container-xxl " + className):
yield current_workspace
gui.html(copy_to_clipboard_scripts)

gui.html(templates.get_template("footer.html").render(**context))
gui.html(templates.get_template("login_scripts.html").render(**context))
with gui.div(id="main-content", className="px-3 " + className):
yield current_workspace

gui.html(templates.get_template("footer.html").render(**context))
gui.html(templates.get_template("login_scripts.html").render(**context))


def _render_mobile_search_button(request: Request, search_filters: SearchFilters):
Expand All @@ -787,6 +851,7 @@ def _render_mobile_search_button(request: Request, search_filters: SearchFilters
gui.button(
icons.search,
type="tertiary",
unsafe_allow_html=True,
className="m-0",
onClick=JS_SHOW_MOBILE_SEARCH,
)
Expand Down Expand Up @@ -829,16 +894,18 @@ def _render_mobile_search_button(request: Request, search_filters: SearchFilters
"""


def anonymous_login_container(request: Request, context: dict):
def anonymous_login_container(
request: Request, context: dict, hide_sign_in: bool = False
):
next_url = str(furl(request.url).set(origin=None))
login_url = str(furl("/login/", query_params=dict(next=next_url)))

with gui.tag("a", href=login_url, className="pe-2 d-none d-lg-block"):
gui.html("Sign In")

popover, content = gui.popover(interactive=True)

with popover, gui.div(className="d-flex align-items-center"):
with popover, gui.div(className="d-flex align-items-center overflow-hidden"):
if not hide_sign_in:
with gui.tag("a", href=login_url, className="pe-2"):
gui.html("Sign In")
gui.html(
templates.get_template("google_one_tap_button.html").render(**context)
+ '<i class="ps-2 fa-regular fa-chevron-down d-xl-none"></i>'
Expand Down
5 changes: 0 additions & 5 deletions static/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -618,11 +618,6 @@ a.text-primary:hover {
font-size: 14px;
}

html {
/* fix for jumping scrollbar issue - https://css-tricks.com/elegant-fix-jumping-scrollbar-issue/ */
margin-left: calc(100vw - 100%);
}

.gui-img {
width: 100%;
max-width: 450px;
Expand Down
4 changes: 2 additions & 2 deletions templates/google_one_tap_button.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
</style>

<span class="pe-2" style="min-width: 40px; max-width: 200px;" data-replace-login-spinner>
<span id="g_id_signin_desktop" class="d-none d-md-inline"></span>
<span id="g_id_signin_mobile" class="d-md-none"></span>
<!-- <span id="g_id_signin_desktop" class="d-none d-md-inline"></span> -->
<span id="g_id_signin_mobile"></span>
Comment on lines +10 to +11
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Avoid calling renderButton on a missing element (desktop container removed).

You commented out #g_id_signin_desktop but still invoke renderButton for it, which will error when the container is null. Guard the call or remove it.

     async function oneTapSignin() {
         google.accounts.id.prompt();
-        google.accounts.id.renderButton(document.getElementById("g_id_signin_desktop"), {
-            shape: "rectangular",
-            width: 200,
-            text: "continue_with",
-            size: "large",
-        });
+        const desktopEl = document.getElementById("g_id_signin_desktop");
+        if (desktopEl) {
+            google.accounts.id.renderButton(desktopEl, {
+                shape: "rectangular",
+                width: 200,
+                text: "continue_with",
+                size: "large",
+            });
+        }
         google.accounts.id.renderButton(document.getElementById("g_id_signin_mobile"), {
             shape: "rectangular",
             width: 40,
             type: "icon",
             size: "large",
         });
     }

Also applies to: 25-33

🤖 Prompt for AI Agents
templates/google_one_tap_button.html around lines 10-11 (also check 25-33): the
desktop container span was commented out but the code still calls renderButton
for the desktop id, which will throw when document.getElementById returns null;
update the logic to check for the element before calling renderButton (e.g.,
getElementById(...) and if the result is truthy then call renderButton) or
remove the desktop render call entirely, and apply the same guard to the other
occurrences around lines 25-33.

</span>

<script>
Expand Down
2 changes: 2 additions & 0 deletions widgets/explore.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
render_search_filters,
render_search_results,
)
from widgets.sidebar import sidebar_mobile_header

META_TITLE = "Explore AI Workflows"
META_DESCRIPTION = "Find, fork and run your field’s favorite AI recipes on Gooey.AI"
Expand Down Expand Up @@ -52,6 +53,7 @@ def build_meta_tags(url: str, search_filters: SearchFilters | None):


def render(request: Request, search_filters: SearchFilters | None):
sidebar_mobile_header(request)
with gui.div(className="my-4"):
# note: using css instead of `if not search_filters: ...` stops re-render
# of the search bar. this preserves focus/blur between query-param redirects
Expand Down
Loading