This repository was archived by the owner on Feb 26, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathutils.js
169 lines (155 loc) · 5.07 KB
/
utils.js
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import {
SHARE_SITES
} from './enums';
/**
* Converts Date String with UTC timezone to date consumable by calendar
* apps. Changes +00:00 to Z.
* @param {string} Date in YYYYMMDDTHHmmssZ format
* @returns {string} Date with +00:00 replaceed with Z
*/
export const formatDate = date => date && date.replace('+00:00', 'Z');
export const formatDuration = duration => {
if (typeof duration === 'string') return duration;
const parts = duration.toString().split('.');
if (parts.length < 2) {
parts.push('00');
}
return parts.map(part => part.length === 2 ? part : `0${part}`).join('');
};
/**
* Tests provided UserAgent against Known Mobile User Agents
* @returns {bool} isMobileDevice
*/
export const isMobile = () => /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile/.test(window.navigator.userAgent || window.navigator.vendor || window.opera);
/**
* Tests userAgent to see if browser is IE
* @returns {bool} isInternetExplorer
*/
export const isInternetExplorer = () => /MSIE/.test(window.navigator.userAgent) || /Trident/.test(window.navigator.userAgent);
export const escapeICSDescription = description => description.replace(/(\r?\n|<br ?\/?>)/g, '\\n');
/**
* Takes an event object and returns a Google Calendar Event URL
* @param {string} event.description
* @param {string} event.endDatetime
* @param {string} event.location
* @param {string} event.startDatetime
* @param {string} event.title
* @returns {string} Google Calendar Event URL
*/
const googleShareUrl = ({
description,
altdescription,
endDatetime,
location,
startDatetime,
timezone,
title,
}) =>
`https://calendar.google.com/calendar/render?action=TEMPLATE&dates=${
startDatetime
}/${endDatetime}${timezone && `&ctz=${timezone}`}&location=${location}&text=${title}&details=${altdescription}`;
/**
* Takes an event object and returns a Yahoo Calendar Event URL
* @param {string} event.description
* @param {string} event.duration
* @param {string} event.location
* @param {string} event.startDatetime
* @param {string} event.title
* @returns {string} Yahoo Calendar Event URL
*/
const yahooShareUrl = ({
description,
duration,
location,
startDatetime,
title,
}) =>
`https://calendar.yahoo.com/?v=60&view=d&type=20&title=${title}&st=${
startDatetime
}&dur=${duration}&desc=${description}&in_loc=${location}`;
/**
* Takes an event object and returns an array to be downloaded as ics file
* @param {string} event.description
* @param {string} event.endDatetime
* @param {string} event.location
* @param {string} event.startDatetime
* @param {string} event.title
* @param {string} event.reminder
* @returns {array} ICS Content
*/
const buildShareFile = ({
description = '',
altdescription = '',
ctz = '',
endDatetime,
location = '',
startDatetime,
timezone = '',
title = '',
reminder = ''
}) => {
let content = [
'BEGIN:VCALENDAR',
'VERSION:2.0',
'BEGIN:VEVENT',
`URL:${document.URL}`,
'METHOD:PUBLISH',
// TODO: Will need to parse the date without Z for ics
// This means I'll probably have to require a date lib - luxon most likely or datefns
timezone === '' ? `DTSTART:${startDatetime}` : `DTSTART;TZID=${timezone}:${startDatetime}`,
timezone === '' ? `DTEND:${endDatetime}` : `DTEND;TZID=${timezone}:${endDatetime}`,
`SUMMARY:${title}`,
`DESCRIPTION:${escapeICSDescription(description)}`,
`X-ALT-DESC;FMTTYPE=text/html:${escapeICSDescription(altdescription)}`,
`LOCATION:${location}`,
reminder === '' ? 'END:VEVENT' : `BEGIN:VALARM\nTRIGGER:-PT${reminder}\nACTION:DISPLAY\nEND:VALARM\nEND:VEVENT`,
'END:VCALENDAR',
].join('\n');
return isMobile() ? encodeURI(`data:text/calendar;charset=utf8,${content}`) : content;
}
/**
* Takes an event object and a type of URL and returns either a calendar event
* URL or the contents of an ics file.
* @param {string} event.description
* @param {string} event.duration
* @param {string} event.endDatetime
* @param {string} event.location
* @param {string} event.startDatetime
* @param {string} event.title
* @param {string} event.reminder
* @param {enum} type One of SHARE_SITES from ./enums
*/
export const buildShareUrl = ({
description = '',
altdescription = '',
duration,
endDatetime,
location = '',
startDatetime,
timezone = '',
title = '',
reminder = ''
},
type,
) => {
const encodeURI = type !== SHARE_SITES.ICAL && type !== SHARE_SITES.OUTLOOK;
const data = {
description: encodeURI ? encodeURIComponent(description) : description,
altdescription: encodeURI ? encodeURIComponent(altdescription) : altdescription,
duration: formatDuration(duration),
endDatetime: formatDate(endDatetime),
location: encodeURI ? encodeURIComponent(location) : location,
startDatetime: formatDate(startDatetime),
timezone,
title: encodeURI ? encodeURIComponent(title) : title,
reminder,
};
switch (type) {
case SHARE_SITES.GOOGLE:
return googleShareUrl(data);
case SHARE_SITES.YAHOO:
return yahooShareUrl(data);
default:
return buildShareFile(data);
}
};