|
"""Predefined button to copy a shareable link to the current Gradio Space.""" |
|
|
|
from __future__ import annotations |
|
|
|
import textwrap |
|
import time |
|
from collections.abc import Sequence |
|
from pathlib import Path |
|
from typing import TYPE_CHECKING, Literal |
|
|
|
from gradio_client.documentation import document |
|
|
|
from gradio import utils |
|
from gradio.components.base import Component |
|
from gradio.components.button import Button |
|
from gradio.context import get_blocks_context |
|
|
|
if TYPE_CHECKING: |
|
from gradio.components import Timer |
|
|
|
from gradio.events import Dependency |
|
|
|
@document() |
|
class DeepLinkButton(Button): |
|
""" |
|
Creates a button that copies a shareable link to the current Gradio Space. |
|
The link includes the current session hash as a query parameter. |
|
""" |
|
|
|
is_template = True |
|
n_created = 0 |
|
|
|
def __init__( |
|
self, |
|
value: str = "Share via Link", |
|
copied_value: str = "Link Copied!", |
|
*, |
|
inputs: Component | Sequence[Component] | set[Component] | None = None, |
|
variant: Literal["primary", "secondary"] = "secondary", |
|
size: Literal["sm", "md", "lg"] = "lg", |
|
icon: str | Path | None = utils.get_icon_path("link.svg"), |
|
link: str | None = None, |
|
visible: bool = True, |
|
interactive: bool = True, |
|
elem_id: str | None = None, |
|
elem_classes: list[str] | str | None = None, |
|
render: bool = True, |
|
key: int | str | tuple[int | str, ...] | None = None, |
|
preserved_by_key: list[str] | str | None = "value", |
|
scale: int | None = None, |
|
min_width: int | None = None, |
|
every: Timer | float | None = None, |
|
): |
|
""" |
|
Parameters: |
|
value: The text to display on the button. |
|
copied_value: The text to display on the button after the link has been copied. |
|
""" |
|
self.copied_value = copied_value |
|
super().__init__( |
|
value, |
|
inputs=inputs, |
|
variant=variant, |
|
size=size, |
|
icon=icon, |
|
link=link, |
|
visible=visible, |
|
interactive=interactive, |
|
elem_id=f"gradio-share-link-button-{self.n_created}", |
|
elem_classes=elem_classes, |
|
render=render, |
|
key=key, |
|
preserved_by_key=preserved_by_key, |
|
scale=scale, |
|
min_width=min_width, |
|
every=every, |
|
) |
|
self.elem_id: str |
|
self.n_created += 1 |
|
if get_blocks_context(): |
|
self.activate() |
|
|
|
def activate(self): |
|
"""Attach the click event to copy the share link.""" |
|
_js = self.get_share_link(self.value, self.copied_value) |
|
|
|
|
|
self.click(fn=None, inputs=[], outputs=[self], js=_js) |
|
self.click( |
|
fn=lambda: time.sleep(1) or self.value, |
|
inputs=[], |
|
outputs=[self], |
|
queue=False, |
|
show_api=False, |
|
) |
|
|
|
def get_share_link( |
|
self, value: str = "Share via Link", copied_value: str = "Link Copied!" |
|
): |
|
delete_sign_line = ( |
|
"currentUrl.searchParams.delete('__sign');" if utils.get_space() else "" |
|
) |
|
return textwrap.dedent( |
|
f""" |
|
() => {{ |
|
const sessionHash = window.__gradio_session_hash__; |
|
fetch(`/gradio_api/deep_link?session_hash=${{sessionHash}}`) |
|
.then(response => {{ |
|
if (!response.ok) {{ |
|
throw new Error('Network response was not ok'); |
|
}} |
|
return response.text(); |
|
}}) |
|
.then(data => {{ |
|
const currentUrl = new URL(window.location.href); |
|
const cleanData = data.replace(/^"|"$/g, ''); |
|
if (cleanData) {{ |
|
currentUrl.searchParams.set('deep_link', cleanData); |
|
}} |
|
{delete_sign_line} |
|
navigator.clipboard.writeText(currentUrl.toString()); |
|
}}) |
|
.catch(error => {{ |
|
console.error('Error fetching deep link:', error); |
|
return "Error"; |
|
}}); |
|
|
|
return "BUTTON_COPIED_VALUE"; |
|
}} |
|
""".replace("BUTTON_DEFAULT_VALUE", value).replace( |
|
"BUTTON_COPIED_VALUE", copied_value |
|
) |
|
).replace("ID", self.elem_id) |
|
from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING |
|
from gradio.blocks import Block |
|
if TYPE_CHECKING: |
|
from gradio.components import Timer |
|
from gradio.components.base import Component |