forked from solidjs-community/solid-primitives
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweb-share.ts
More file actions
98 lines (90 loc) · 2.48 KB
/
web-share.ts
File metadata and controls
98 lines (90 loc) · 2.48 KB
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
import { Accessor, createEffect, createSignal, on, OnOptions } from "solid-js";
import { isServer } from "solid-js/web";
/**
* Generates a simple non-reactive WebShare primitive for sharing.
*
* @returns share - start web share with ShareData.
*
* @example
* ```ts
* const share = makeWebShare();
* try {
* await share({ url: "https://solidjs.com" });
* } catch (e) {
* console.error(e);
* }
* ```
*/
export const makeWebShare = () => {
const share = (data: ShareData) => {
// Some browsers do not support `WebShare`, so sharing failed.
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!navigator.share) {
return Promise.reject("your browser does not support web share.");
}
// Some browsers do not support `files` and `navigator.canShare`, so sharing failed.
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (data.files && (!navigator.canShare || !navigator.canShare(data))) {
return Promise.reject("your browser does not support share files.");
}
try {
return navigator.share(data);
} catch (e) {
return Promise.reject(e);
}
};
return share;
};
export type ShareStatus = {
/** The status of sharing success, failed or pending. */
status?: boolean;
/** The reason why sharing failed. */
message?: string;
};
/**
* Creates a reactive status about web share.
*
* @param data Data signal to share on web.
* @param deferInitial - Sets the value of the web share data from the signal. defaults to false.
* @return A store shows sharing status and failing message.
*
* @example
* ```ts
* const [data, setData] = createSignal<ShareData>({});
* const shareStatus = createWebShare(data);
*
* createEffect(() => {
* console.log(shareStatus.status, shareStatus.message)
* })
* ```
*/
export const createWebShare = (
data: Accessor<ShareData>,
deferInitial: boolean = false,
): ShareStatus => {
if (isServer) {
return {};
}
const [status, setStatus] = createSignal<ShareStatus>({});
const share = makeWebShare();
createEffect(
on(
data,
dataValue => {
setStatus({});
share(dataValue)
.then(() => setStatus({ status: true }))
.catch(e => setStatus({ status: false, message: e.toString() }));
},
{ defer: deferInitial } satisfies OnOptions as any,
),
);
return {
get status() {
return status().status;
},
get message() {
return status().message;
},
};
};