TootActionGroup: added share button (closes #18)
This commit is contained in:
parent
6506a60022
commit
161c72fea5
3 changed files with 129 additions and 6 deletions
|
@ -1,13 +1,15 @@
|
|||
//! This module has side effect.
|
||||
//! It recommended to include the module by <script> tag.
|
||||
if (!document.body.animate) {
|
||||
if (typeof document.body.animate === "undefined") {
|
||||
// @ts-ignore: this file is polyfill, no exposed decls
|
||||
import("web-animations-js").then(() => { // all target platforms supported, prepared to remove
|
||||
import("web-animations-js").then(() => {
|
||||
// all target platforms supported, prepared to remove
|
||||
console.warn("web animation polyfill is included");
|
||||
});
|
||||
}
|
||||
|
||||
if (!window.crypto.randomUUID) { // Chrome/Edge 92+
|
||||
if (typeof window.crypto.randomUUID === "undefined") {
|
||||
// Chrome/Edge 92+
|
||||
// https://stackoverflow.com/a/2117523/2800218
|
||||
// LICENSE: https://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
window.crypto.randomUUID =
|
||||
|
|
104
src/platform/share.tsx
Normal file
104
src/platform/share.tsx
Normal file
|
@ -0,0 +1,104 @@
|
|||
import {
|
||||
createEffect,
|
||||
createSignal,
|
||||
onCleanup,
|
||||
type Component,
|
||||
} from "solid-js";
|
||||
import Scaffold from "../material/Scaffold";
|
||||
import BottomSheet from "../material/BottomSheet";
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
Input,
|
||||
ThemeProvider,
|
||||
Toolbar,
|
||||
} from "@suid/material";
|
||||
import { Close as CloseIcon, ContentCopy } from "@suid/icons-material";
|
||||
import { Title } from "../material/typography";
|
||||
import { render } from "solid-js/web";
|
||||
import { useRootTheme } from "../material/mui";
|
||||
|
||||
const ShareBottomSheet: Component<{
|
||||
data?: ShareData;
|
||||
open?: boolean;
|
||||
onClose: () => void;
|
||||
}> = (props) => {
|
||||
return (
|
||||
<BottomSheet open={props.open} onClose={props.onClose} bottomUp>
|
||||
<Scaffold
|
||||
topbar={
|
||||
<Toolbar>
|
||||
<IconButton onClick={props.onClose}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Title>Share...</Title>
|
||||
</Toolbar>
|
||||
}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
"padding": "8px 8px calc(var(--safe-area-inset-bottom, 0px) + 40px)",
|
||||
display: "flex",
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
value={props.data?.url}
|
||||
onChange={() => undefined}
|
||||
fullWidth
|
||||
/>
|
||||
<Button
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(props.data?.url ?? "");
|
||||
}}
|
||||
>
|
||||
<ContentCopy sx={{ marginTop: "-.25em", marginRight: ".25em" }} />
|
||||
Copy
|
||||
</Button>
|
||||
</div>
|
||||
</Scaffold>
|
||||
</BottomSheet>
|
||||
);
|
||||
};
|
||||
|
||||
export function canShare(data?: ShareData) {
|
||||
if (navigator.canShare) {
|
||||
return navigator.canShare(data);
|
||||
}
|
||||
return !!data?.url;
|
||||
}
|
||||
|
||||
export async function share(data?: ShareData): Promise<void> {
|
||||
if (navigator.share) {
|
||||
return await navigator.share(data);
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const element = document.createElement("div");
|
||||
document.body.appendChild(element);
|
||||
|
||||
const dispose = render(() => {
|
||||
const [open, setOpen] = createSignal(true);
|
||||
const theme = useRootTheme();
|
||||
onCleanup(() => {
|
||||
element.remove();
|
||||
resolve();
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (!open()) {
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme()}>
|
||||
<ShareBottomSheet
|
||||
data={data}
|
||||
open={open()}
|
||||
onClose={() => setOpen(false)}
|
||||
/>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}, element);
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue