Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
155 changes: 102 additions & 53 deletions daras_ai_v2/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
render_create_workspace_alert,
set_current_workspace,
)
from routers.root import PREVIEW_ROUTE_WORKFLOWS

MAX_SEED = 4294967294
gooey_rng = Random()
Expand Down Expand Up @@ -405,15 +406,59 @@ def render(self):
& button {
padding: 0.4rem !important;
}

& a:has(span.mobile-only-recipe-tab) {
display: block !important;
}

& li.nav-item:first-of-type button {
margin-left: 0 !important;
}

& ul.nav-tabs {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
flex-wrap: nowrap !important;
display: flex;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
gap: 0.5rem;
}

@media (min-width: 768px) {
& a:has(span.mobile-only-recipe-tab) {
display: none !important;
}

/* RUN as active tab in lg view for preview route */
& span.active-lg button {
color: #000;
border-bottom: 2px solid black;
}

& ul.nav-tabs {
gap: 0;
}
}
"""
),
gui.div(className="position-relative"),
gui.div(className="position-relative", id="recipe-nav-tabs"),
gui.nav_tabs(),
):
for tab in self.get_tabs():
url = self.current_app_url(tab)
with gui.nav_item(url, active=tab == self.tab):
gui.html(tab.title)
with gui.tag(
"span",
className="active-lg"
if (tab == RecipeTabs.run and self.tab == RecipeTabs.preview)
else "",
):
with gui.nav_item(
url,
active=tab == self.tab,
):
gui.html(tab.title)

self._render_saved_generated_timestamp()
with gui.nav_tab_content():
Expand All @@ -432,7 +477,7 @@ def _render_header(self):
can_save = self.can_user_save_run(sr, pr)
request_changed = self._has_request_changed()

if self.tab != RecipeTabs.run:
if self.tab != RecipeTabs.run and self.tab != RecipeTabs.preview:
# Examples, API, Saved, etc
if self.tab == RecipeTabs.saved or self.tab == RecipeTabs.history:
with gui.div(className="mb-2"):
Expand Down Expand Up @@ -609,7 +654,7 @@ def render_social_buttons(self):
):
publish_dialog_ref = gui.use_alert_dialog(key="publish-modal")

if self.tab == RecipeTabs.run:
if self.tab == RecipeTabs.run or self.tab == RecipeTabs.preview:
if self.current_pr.is_root():
render_help_button(self.workflow)
if self.is_logged_in():
Expand Down Expand Up @@ -1173,7 +1218,7 @@ def get_tabs(self):

def render_selected_tab(self):
match self.tab:
case RecipeTabs.run:
case RecipeTabs.run | RecipeTabs.preview:
if self.current_sr.retention_policy == RetentionPolicy.delete:
self.render_deleted_output()
return
Expand Down Expand Up @@ -1202,8 +1247,9 @@ def render_selected_tab(self):
)

with gui.styled(OUTPUT_TABS_CSS):
output_col, input_col = gui.tabs(
[f"{icons.preview} Preview", f"{icons.edit} Edit"]
input_col, output_col = gui.columns(
[3, 2],
gap="medium",
)
with input_col:
submitted = self._render_input_col()
Expand Down Expand Up @@ -1762,25 +1808,28 @@ def _render_report_button(self):
show_settings = True

def _render_input_col(self):
self.render_form_v2()
placeholder = gui.div()
with gui.div(
className="d-none d-lg-block" if self.tab == RecipeTabs.preview else ""
):
self.render_form_v2()
placeholder = gui.div()

if self.show_settings:
with gui.div(className="bg-white"):
with gui.expander("⚙️ Settings"):
self.render_settings()
if self.functions_in_settings:
functions_input(self.request.user)
if self.show_settings:
with gui.div(className="bg-white"):
with gui.expander("⚙️ Settings"):
self.render_settings()
if self.functions_in_settings:
functions_input(self.request.user)

with placeholder:
self.render_variables()
with placeholder:
self.render_variables()

submitted = self.render_submit_button()
with gui.div(style={"textAlign": "right", "fontSize": "smaller"}):
terms_caption = self.get_terms_caption()
gui.caption(f"_{terms_caption}_")
submitted = self.render_submit_button()
with gui.div(style={"textAlign": "right", "fontSize": "smaller"}):
terms_caption = self.get_terms_caption()
gui.caption(f"_{terms_caption}_")

return submitted
return submitted

def get_terms_caption(self):
return "With each run, you agree to Gooey.AI's [terms](https://gooey.ai/terms) & [privacy policy](https://gooey.ai/privacy)."
Expand Down Expand Up @@ -1832,7 +1881,12 @@ def _render_output_col(self, *, submitted: bool = False, is_deleted: bool = Fals
if submitted:
self.submit_and_redirect()

with gui.div(style=dict(position="sticky", top="0.5rem")):
with gui.div(
style=dict(position="sticky", top="0.5rem"),
className="d-none d-lg-block pb-2"
if self.tab == RecipeTabs.run and self.workflow in PREVIEW_ROUTE_WORKFLOWS
else "",
):
run_state = self.get_run_state(gui.session_state)
if run_state == RecipeRunState.failed:
self._render_failed_output()
Expand Down Expand Up @@ -1905,7 +1959,12 @@ def submit_and_redirect(
sr = self.on_submit(unsaved_state=unsaved_state)
if not sr:
return
raise gui.RedirectException(self.app_url(run_id=sr.run_id, uid=sr.uid))
if self.workflow in PREVIEW_ROUTE_WORKFLOWS:
raise gui.RedirectException(
self.app_url(run_id=sr.run_id, uid=sr.uid, tab=RecipeTabs.preview)
)
else:
raise gui.RedirectException(self.app_url(run_id=sr.run_id, uid=sr.uid))

def publish_and_redirect(self) -> typing.NoReturn | None:
assert self.is_logged_in()
Expand Down Expand Up @@ -2556,35 +2615,25 @@ class TitleValidationError(Exception):


OUTPUT_TABS_CSS = """
& [data-reach-tab-list] {
text-align: center; margin-top: 0
}
@media (min-width: 768px) {
& [data-reach-tab-list] {
display: none;
}
& [data-reach-tab-panels] {
display: flex;
flex-direction: row-reverse;
width: 100%;
background-color: #f9f9f9;
padding: 10px;
margin-top: -1rem;
& {
margin: -1rem 0 1rem 0;
padding-top: 1rem;
}
& [data-reach-tab-panels] > div:nth-child(2) {
flex: 0 1 auto;
width: 60%;
max-width: 100%;
padding-right: 0.75rem;

/* reset col padding in mobile */
& > div {
padding: 0;
}
& [data-reach-tab-panels] > div:nth-child(1) {
flex: 0 0 auto;
width: 40%;
max-width: 100%;
padding-left: 0.75rem;
}
& [data-reach-tab-panel][hidden] {
display: block !important;

@media (min-width: 768px) {
& {
background-color: #f9f9f9;
}
/* set col padding in mobile */
& > div {
padding-left: calc(var(--bs-gutter-x) * .5);
padding-right: calc(var(--bs-gutter-x) * .5);
}
}
}

"""
40 changes: 21 additions & 19 deletions daras_ai_v2/meta_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,25 +215,27 @@ def robots_tag_for_page(
is_root = pr and pr.saved_run == sr and pr.is_root()
is_example = pr and pr.saved_run == sr and not pr.is_root()

if not page.is_user_authorized(None):
# nofollow & noindex if page is not open for anonymous users
no_follow, no_index = True, True
else:
match page.tab:
case RecipeTabs.run if is_root or is_example:
no_follow, no_index = False, False
case RecipeTabs.run: # ordinary run (not example)
no_follow, no_index = False, True
case RecipeTabs.examples:
no_follow, no_index = False, False
case RecipeTabs.run_as_api:
no_follow, no_index = False, True
case RecipeTabs.integrations:
no_follow, no_index = True, True
case RecipeTabs.history:
no_follow, no_index = True, True
case RecipeTabs.saved:
no_follow, no_index = True, True
match page.tab:
case RecipeTabs.run if is_root or is_example:
no_follow, no_index = False, False
case RecipeTabs.preview if is_root or is_example:
no_follow, no_index = False, False
case RecipeTabs.run: # ordinary run (not example)
no_follow, no_index = False, True
case RecipeTabs.preview:
no_follow, no_index = False, True
case RecipeTabs.examples:
no_follow, no_index = False, False
case RecipeTabs.run_as_api:
no_follow, no_index = False, True
case RecipeTabs.integrations:
no_follow, no_index = True, True
case RecipeTabs.history:
no_follow, no_index = True, True
case RecipeTabs.saved:
no_follow, no_index = True, True
case _:
raise ValueError(f"Unknown tab: {page.tab}")

parts = []
if no_follow:
Expand Down
7 changes: 4 additions & 3 deletions recipes/VideoBots.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,12 +704,12 @@ def render_run_preview_output(self, state: dict):
scroll_into_view = False

def _render_running_output(self):
## The embedded web widget includes a running output, so just scroll it into view
## The embedded web widget includes a running output, so just scroll it into view to tabs which just above the widget

# language=JavaScript
gui.js(
"""
let elem = document.querySelector("#gooey-embed");
let elem = document.querySelector("#recipe-nav-tabs");
if (!elem) return;
if (elem.scrollIntoViewIfNeeded) {
elem.scrollIntoViewIfNeeded(false);
Expand Down Expand Up @@ -1546,11 +1546,12 @@ def lipsync_step(self, request, response):
response.output_video.append(lip_state["output_video"])

def render_header_extra(self):
if self.tab == RecipeTabs.run:
if self.tab == RecipeTabs.run or self.tab == RecipeTabs.preview:
render_demo_buttons_header(self.current_pr)

def get_tabs(self):
tabs = super().get_tabs()
tabs.insert(1, RecipeTabs.preview)
tabs.extend([RecipeTabs.integrations])
return tabs

Expand Down
24 changes: 22 additions & 2 deletions routers/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,18 @@ def chat_lib_route(request: Request, integration_id: str, integration_name: str
)


@gui.route(
app,
"/{page_slug}/preview/",
"/{page_slug}/{run_slug}/preview/",
"/{page_slug}/{run_slug}-{example_id}/preview/",
)
def preview_route(
request: Request, page_slug: str, run_slug: str = None, example_id: str = None
):
return render_recipe_page(request, page_slug, RecipeTabs.preview, example_id)


@gui.route(
app,
"/{path:path}",
Expand Down Expand Up @@ -876,9 +888,17 @@ class TabData(typing.NamedTuple):
route: typing.Callable


PREVIEW_ROUTE_WORKFLOWS = [Workflow.VIDEO_BOTS]


class RecipeTabs(TabData, Enum):
preview = TabData(
title=f"<span class='mobile-only-recipe-tab'>{icons.preview} Preview</span>",
label="",
route=preview_route,
)
run = TabData(
title=f"{icons.run} <span class='d-none d-lg-inline'>Run</span>",
title=f"{icons.run} Run</span>",
label="",
route=recipe_or_handle_or_static,
)
Expand All @@ -898,7 +918,7 @@ class RecipeTabs(TabData, Enum):
route=history_route,
)
integrations = TabData(
title=f'<img width="20" height="20" style="margin-right: 4px;margin-top: -3px" src="{icons.integrations_img}" alt="Facebook, Whatsapp, Slack, Instagram Icons"> <span class="d-none d-lg-inline">Integrations</span>',
title=f'<img width="20" height="20" style="margin-right: 4px;margin-top: -3px" src="{icons.integrations_img}" alt="Facebook, Whatsapp, Slack, Instagram Icons"> Integrations',
label="Integrations",
route=integrations_route,
)
Expand Down