Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit 2d99bf5

Browse files
Merge pull request #1 from jasonleibowitz/fix-yahoo-and-ical
Fix Yahoo & iCal Links
2 parents 31edf21 + 8986b85 commit 2d99bf5

File tree

13 files changed

+41
-95
lines changed

13 files changed

+41
-95
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ var AddToCalendarHOC = require('react-add-to-calendar-hoc');
3838
### Dropdown Example
3939
<details>
4040
<summary>Button Component</summary>
41-
41+
4242
```
4343
// components/my-button-component.jsx
4444
import React from 'react';
@@ -59,7 +59,7 @@ export default function Button({ children, onClick }) {
5959

6060
<details>
6161
<summary>Dropdown Component</summary>
62-
62+
6363
```
6464
// components/my-dropdown-component.jsx
6565
import React from 'react';
@@ -106,7 +106,7 @@ export default function Component({ event }) {
106106
### Modal Example
107107
<details>
108108
<summary>Button Component</summary>
109-
109+
110110
```
111111
// components/my-button-component.jsx
112112
import React from 'react';
@@ -127,7 +127,7 @@ export default function Button({ children, onClick }) {
127127

128128
<details>
129129
<summary>Modal Component</summary>
130-
130+
131131
```
132132
import React from 'react';
133133
import Modal from 'react-modal'; // You don't have to use react-modal, just consume the callback
@@ -217,7 +217,7 @@ The component takes the following props
217217
|className |string | |`null` |className to use on AddToCalendar container |
218218
|dropdownProps |object | |`{}` |Spread props to the dropdown or modal component you pass in to the HOC |
219219
|event |object |Yes | |Event object we use to create calendar links |
220-
|items |array of enums | |`[GOOGLE, ICAL, OUTLOOK_WEB, YAHOO]` |By default AddToCalendar renders all of these calendar links. To render a subset of these provide a list of items using the enum SHARE_SITES, which is a named import from the library |
220+
|items |array of enums | |`[GOOGLE, ICAL, OUTLOOK, YAHOO]` |By default AddToCalendar renders all of these calendar links. To render a subset of these or to list them in a different order, provide a list of items using the enum SHARE_SITES, which is a named import from the library |
221221
|linkProps |object | |`{}` |Spread props to the link components we render for each calendar item |
222222

223223
#### Event Object Shape
@@ -226,7 +226,7 @@ All of these properties are required.
226226
| Prop | Type | Description |
227227
|--------------|---------------|-------------|
228228
|description |string |Description of event. Put in the notes or body section of event. |
229-
|duration |number |Duration of event in hours. e.g. `2:00` or `2`. This is only used for Yahoo. |
229+
|duration |string |Duration of event in hours. Must be four digits, e.g. `0200` or `0130`. This is only used for Yahoo. |
230230
|endDatetime |string |End date time of event. Must be formatted in `YYYYMMDDTHHmmssZ` format. Use any date lib you want, but the format must match this. |
231231
|location |string |Location of event. Use an address for best specificity and for Google Maps to populate a Map. Sometimes a location name will also populate a map. |
232232
|startDatetime |string |Start date time of event. Must be formatted in `YYYYMMDDTHHmmssZ` format. Use any date lib you want, but the format must match this. |

docs/bundle.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/enums.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ exports.SHARE_SITES = void 0;
77
var SHARE_SITES = {
88
GOOGLE: 'Google',
99
ICAL: 'iCal',
10-
OUTLOOK_WEB: 'Outlook Web',
10+
OUTLOOK: 'Outlook',
1111
YAHOO: 'Yahoo'
1212
};
1313
exports.SHARE_SITES = SHARE_SITES;

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ function AddToCalendar(WrappedButton, WrappedDropdown) {
133133
dropdownProps: _propTypes.default.shape(),
134134
event: _propTypes.default.shape({
135135
description: _propTypes.default.string,
136+
duration: _propTypes.default.string,
136137
endDatetime: _propTypes.default.string,
137138
location: _propTypes.default.string,
138139
startDatetime: _propTypes.default.string,

lib/utils.js

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -66,44 +66,25 @@ var yahooShareUrl = function yahooShareUrl(_ref2) {
6666
location = _ref2.location,
6767
startDatetime = _ref2.startDatetime,
6868
title = _ref2.title;
69-
return "https://calendar.yahoo.com/v=60&view=d&type=20&title=".concat(title, "&st=").concat(startDatetime, "&dur=").concat(duration, "&desc=").concat(description, "&in_loc=").concat(location);
69+
return "https://calendar.yahoo.com/?v=60&view=d&type=20&title=".concat(title, "&st=").concat(startDatetime, "&dur=").concat(duration, "&desc=").concat(description, "&in_loc=").concat(location);
7070
};
7171
/**
72-
* Takes an event object and returns a Outlook Web Calendar Event URL
72+
* Takes an event object and returns an array to be downloaded as ics file
7373
* @param {string} event.description
7474
* @param {string} event.endDatetime
7575
* @param {string} event.location
7676
* @param {string} event.startDatetime
7777
* @param {string} event.title
78-
* @returns {string} Outlook Web Calendar Event URL
78+
* @returns {array} ICS Content
7979
*/
8080

8181

82-
var outlookWebUrl = function outlookWebUrl(_ref3) {
82+
var buildShareFile = function buildShareFile(_ref3) {
8383
var description = _ref3.description,
8484
endDatetime = _ref3.endDatetime,
8585
location = _ref3.location,
8686
startDatetime = _ref3.startDatetime,
8787
title = _ref3.title;
88-
return "https://outlook.live.com/owa/?rru=addevent&startdt=".concat(startDatetime, "&enddt=").concat(endDatetime, "&subject=").concat(title, "&location=").concat(location, "&body=").concat(description, "&allday=false&uid=123&path=/calendar/view/Month");
89-
};
90-
/**
91-
* Takes an event object and returns an array to be downloaded as ics file
92-
* @param {string} event.description
93-
* @param {string} event.endDatetime
94-
* @param {string} event.location
95-
* @param {string} event.startDatetime
96-
* @param {string} event.title
97-
* @returns {array} ICS Content
98-
*/
99-
100-
101-
var buildShareFile = function buildShareFile(_ref4) {
102-
var description = _ref4.description,
103-
endDatetime = _ref4.endDatetime,
104-
location = _ref4.location,
105-
startDatetime = _ref4.startDatetime,
106-
title = _ref4.title;
10788
var content = ['BEGIN:VCALENDAR', 'VERSION:2.0', 'BEGIN:VEVENT', "URL:".concat(document.URL), "DTSTART:".concat(startDatetime), "DTEND:".concat(endDatetime), "SUMMARY:".concat(title), "DESCRIPTION:".concat(description), "LOCATION:".concat(location), 'END:VEVENT', 'END:VCALENDAR'].join('\n');
10889
return isMobile() ? "data:text/calendar;charset=utf8".concat(content) : content;
10990
};
@@ -120,20 +101,20 @@ var buildShareFile = function buildShareFile(_ref4) {
120101
*/
121102

122103

123-
var buildShareUrl = function buildShareUrl(_ref5, type) {
124-
var description = _ref5.description,
125-
duration = _ref5.duration,
126-
endDatetime = _ref5.endDatetime,
127-
location = _ref5.location,
128-
startDatetime = _ref5.startDatetime,
129-
title = _ref5.title;
104+
var buildShareUrl = function buildShareUrl(_ref4, type) {
105+
var description = _ref4.description,
106+
duration = _ref4.duration,
107+
endDatetime = _ref4.endDatetime,
108+
location = _ref4.location,
109+
startDatetime = _ref4.startDatetime,
110+
title = _ref4.title;
130111
var encodeURI = type !== _enums.SHARE_SITES.ICAL;
131112
var data = {
132113
description: encodeURI ? encodeURIComponent(description) : description,
133114
duration: duration,
134-
endDatetime: encodeURI ? formatDate(endDatetime) : endDatetime,
115+
endDatetime: formatDate(endDatetime),
135116
location: encodeURI ? encodeURIComponent(location) : location,
136-
startDatetime: encodeURI ? formatDate(startDatetime) : startDatetime,
117+
startDatetime: formatDate(startDatetime),
137118
title: encodeURI ? encodeURIComponent(title) : title
138119
};
139120

@@ -144,9 +125,6 @@ var buildShareUrl = function buildShareUrl(_ref5, type) {
144125
case _enums.SHARE_SITES.YAHOO:
145126
return yahooShareUrl(data);
146127

147-
case _enums.SHARE_SITES.OUTLOOK_WEB:
148-
return outlookWebUrl(data);
149-
150128
default:
151129
return buildShareFile(data);
152130
}

lib/utils.test.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
1010

1111
var testEvent = {
1212
description: 'Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.',
13-
duration: '2',
13+
duration: '0200',
1414
endDatetime: '20150126T020000+00:00',
1515
location: 'NYC',
1616
startDatetime: '20150126T000000+00:00',
@@ -28,22 +28,18 @@ describe('buildShareUrl', function () {
2828
});
2929
it('returns a proper Yahoo share URL', function () {
3030
var result = (0, _utils.buildShareUrl)(testEvent, _enums.SHARE_SITES.YAHOO);
31-
expect(result).toEqual('https://calendar.yahoo.com/v=60&view=d&type=20&title=Super%20Fun%20Event&st=20150126T000000Z&dur=2&desc=Description%20of%20event.%20Going%20to%20have%20a%20lot%20of%20fun%20doing%20things%20that%20we%20scheduled%20ahead%20of%20time.&in_loc=NYC');
32-
});
33-
it('returns a proper Outlook Web share URL', function () {
34-
var result = (0, _utils.buildShareUrl)(testEvent, _enums.SHARE_SITES.OUTLOOK_WEB);
35-
expect(result).toEqual('https://outlook.live.com/owa/?rru=addevent&startdt=20150126T000000Z&enddt=20150126T020000Z&subject=Super%20Fun%20Event&location=NYC&body=Description%20of%20event.%20Going%20to%20have%20a%20lot%20of%20fun%20doing%20things%20that%20we%20scheduled%20ahead%20of%20time.&allday=false&uid=123&path=/calendar/view/Month');
31+
expect(result).toEqual('https://calendar.yahoo.com/?v=60&view=d&type=20&title=Super%20Fun%20Event&st=20150126T000000Z&dur=0200&desc=Description%20of%20event.%20Going%20to%20have%20a%20lot%20of%20fun%20doing%20things%20that%20we%20scheduled%20ahead%20of%20time.&in_loc=NYC');
3632
});
3733
it('returns a proper iCal content object', function () {
3834
var result = (0, _utils.buildShareUrl)(testEvent, _enums.SHARE_SITES.ICAL);
39-
expect(result).toEqual('BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nURL:about:blank\nDTSTART:20150126T000000+00:00\nDTEND:20150126T020000+00:00\nSUMMARY:Super Fun Event\nDESCRIPTION:Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.\nLOCATION:NYC\nEND:VEVENT\nEND:VCALENDAR');
35+
expect(result).toEqual('BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nURL:about:blank\nDTSTART:20150126T000000Z\nDTEND:20150126T020000Z\nSUMMARY:Super Fun Event\nDESCRIPTION:Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.\nLOCATION:NYC\nEND:VEVENT\nEND:VCALENDAR');
4036
});
4137
it('prepends a data URL when userAgent is mobile', function () {
4238
navigator.__defineGetter__('userAgent', function () {
4339
return "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1";
4440
});
4541

4642
var result = (0, _utils.buildShareUrl)(testEvent, _enums.SHARE_SITES.ICAL);
47-
expect(result).toEqual('data:text/calendar;charset=utf8BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nURL:about:blank\nDTSTART:20150126T000000+00:00\nDTEND:20150126T020000+00:00\nSUMMARY:Super Fun Event\nDESCRIPTION:Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.\nLOCATION:NYC\nEND:VEVENT\nEND:VCALENDAR');
43+
expect(result).toEqual('data:text/calendar;charset=utf8BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nURL:about:blank\nDTSTART:20150126T000000Z\nDTEND:20150126T020000Z\nSUMMARY:Super Fun Event\nDESCRIPTION:Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.\nLOCATION:NYC\nEND:VEVENT\nEND:VCALENDAR');
4844
});
4945
});

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-add-to-calendar-hoc",
3-
"version": "1.0.1",
3+
"version": "1.0.3",
44
"description": "Simple Unopinionated React Add to Calendar Button. Bring your own components.",
55
"main": "lib/index.js",
66
"scripts": {

src/docs/index.jsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ const subTitleSTyles = css`
5252

5353
const startDatetime = moment().utc().add(2, 'days');
5454
const endDatetime = startDatetime.clone().add(2, 'hours');
55-
const duration = endDatetime.diff(startDatetime, 'hours');
5655
const event = {
5756
description: 'Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.',
58-
duration,
57+
duration: '0200',
5958
endDatetime: endDatetime.format('YYYYMMDDTHHmmssZ'),
6059
location: 'NYC',
6160
startDatetime: startDatetime.format('YYYYMMDDTHHmmssZ'),

src/lib/enums.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export const SHARE_SITES = {
22
GOOGLE: 'Google',
33
ICAL: 'iCal',
4-
OUTLOOK_WEB: 'Outlook Web',
4+
OUTLOOK: 'Outlook',
55
YAHOO: 'Yahoo',
66
};

src/lib/index.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default function AddToCalendar(WrappedButton, WrappedDropdown) {
1313
dropdownProps: PropTypes.shape(),
1414
event: PropTypes.shape({
1515
description: PropTypes.string,
16+
duration: PropTypes.string,
1617
endDatetime: PropTypes.string,
1718
location: PropTypes.string,
1819
startDatetime: PropTypes.string,

src/lib/utils.js

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -53,32 +53,10 @@ const yahooShareUrl = ({
5353
startDatetime,
5454
title,
5555
}) =>
56-
`https://calendar.yahoo.com/v=60&view=d&type=20&title=${title}&st=${
56+
`https://calendar.yahoo.com/?v=60&view=d&type=20&title=${title}&st=${
5757
startDatetime
5858
}&dur=${duration}&desc=${description}&in_loc=${location}`;
5959

60-
/**
61-
* Takes an event object and returns a Outlook Web Calendar Event URL
62-
* @param {string} event.description
63-
* @param {string} event.endDatetime
64-
* @param {string} event.location
65-
* @param {string} event.startDatetime
66-
* @param {string} event.title
67-
* @returns {string} Outlook Web Calendar Event URL
68-
*/
69-
const outlookWebUrl = ({
70-
description,
71-
endDatetime,
72-
location,
73-
startDatetime,
74-
title,
75-
}) =>
76-
`https://outlook.live.com/owa/?rru=addevent&startdt=${startDatetime}&enddt=${
77-
endDatetime
78-
}&subject=${title}&location=${location}&body=${
79-
description
80-
}&allday=false&uid=123&path=/calendar/view/Month`;
81-
8260
/**
8361
* Takes an event object and returns an array to be downloaded as ics file
8462
* @param {string} event.description
@@ -132,9 +110,9 @@ export const buildShareUrl = (
132110
const data = {
133111
description: encodeURI ? encodeURIComponent(description) : description,
134112
duration,
135-
endDatetime: encodeURI ? formatDate(endDatetime) : endDatetime,
113+
endDatetime: formatDate(endDatetime),
136114
location: encodeURI ? encodeURIComponent(location) : location,
137-
startDatetime: encodeURI ? formatDate(startDatetime) : startDatetime,
115+
startDatetime: formatDate(startDatetime),
138116
title: encodeURI ? encodeURIComponent(title) : title,
139117
};
140118

@@ -143,8 +121,6 @@ export const buildShareUrl = (
143121
return googleShareUrl(data);
144122
case SHARE_SITES.YAHOO:
145123
return yahooShareUrl(data);
146-
case SHARE_SITES.OUTLOOK_WEB:
147-
return outlookWebUrl(data);
148124
default:
149125
return buildShareFile(data);
150126
}

src/lib/utils.test.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import moment from 'moment';
22
import { SHARE_SITES } from './enums';
3-
import { buildShareUrl, formatDate } from './utils';
3+
import { buildShareUrl, formatDate, padString } from './utils';
44

55
const testEvent = {
66
description: 'Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.',
7-
duration: '2',
7+
duration: '0200',
88
endDatetime: '20150126T020000+00:00',
99
location: 'NYC',
1010
startDatetime: '20150126T000000+00:00',
@@ -25,17 +25,12 @@ describe('buildShareUrl', () => {
2525

2626
it('returns a proper Yahoo share URL', () => {
2727
const result = buildShareUrl(testEvent, SHARE_SITES.YAHOO);
28-
expect(result).toEqual('https://calendar.yahoo.com/v=60&view=d&type=20&title=Super%20Fun%20Event&st=20150126T000000Z&dur=2&desc=Description%20of%20event.%20Going%20to%20have%20a%20lot%20of%20fun%20doing%20things%20that%20we%20scheduled%20ahead%20of%20time.&in_loc=NYC');
29-
});
30-
31-
it('returns a proper Outlook Web share URL', () => {
32-
const result = buildShareUrl(testEvent, SHARE_SITES.OUTLOOK_WEB);
33-
expect(result).toEqual('https://outlook.live.com/owa/?rru=addevent&startdt=20150126T000000Z&enddt=20150126T020000Z&subject=Super%20Fun%20Event&location=NYC&body=Description%20of%20event.%20Going%20to%20have%20a%20lot%20of%20fun%20doing%20things%20that%20we%20scheduled%20ahead%20of%20time.&allday=false&uid=123&path=/calendar/view/Month');
28+
expect(result).toEqual('https://calendar.yahoo.com/?v=60&view=d&type=20&title=Super%20Fun%20Event&st=20150126T000000Z&dur=0200&desc=Description%20of%20event.%20Going%20to%20have%20a%20lot%20of%20fun%20doing%20things%20that%20we%20scheduled%20ahead%20of%20time.&in_loc=NYC')
3429
});
3530

3631
it('returns a proper iCal content object', () => {
3732
const result = buildShareUrl(testEvent, SHARE_SITES.ICAL);
38-
expect(result).toEqual('BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nURL:about:blank\nDTSTART:20150126T000000+00:00\nDTEND:20150126T020000+00:00\nSUMMARY:Super Fun Event\nDESCRIPTION:Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.\nLOCATION:NYC\nEND:VEVENT\nEND:VCALENDAR');
33+
expect(result).toEqual('BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nURL:about:blank\nDTSTART:20150126T000000Z\nDTEND:20150126T020000Z\nSUMMARY:Super Fun Event\nDESCRIPTION:Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.\nLOCATION:NYC\nEND:VEVENT\nEND:VCALENDAR');
3934
});
4035

4136
it('prepends a data URL when userAgent is mobile', () => {
@@ -44,6 +39,6 @@ describe('buildShareUrl', () => {
4439
});
4540

4641
const result = buildShareUrl(testEvent, SHARE_SITES.ICAL);
47-
expect(result).toEqual('data:text/calendar;charset=utf8BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nURL:about:blank\nDTSTART:20150126T000000+00:00\nDTEND:20150126T020000+00:00\nSUMMARY:Super Fun Event\nDESCRIPTION:Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.\nLOCATION:NYC\nEND:VEVENT\nEND:VCALENDAR');
42+
expect(result).toEqual('data:text/calendar;charset=utf8BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nURL:about:blank\nDTSTART:20150126T000000Z\nDTEND:20150126T020000Z\nSUMMARY:Super Fun Event\nDESCRIPTION:Description of event. Going to have a lot of fun doing things that we scheduled ahead of time.\nLOCATION:NYC\nEND:VEVENT\nEND:VCALENDAR');
4843
});
4944
});

0 commit comments

Comments
 (0)