Skip to content

Commit

Permalink
feat(Events): Add appleLocation method (#170)
Browse files Browse the repository at this point in the history
commit de16a66
Author: Sebastian Pekarek <mail@sebbo.net>
Date:   Mon Apr 13 15:04:39 2020 +0200

    docs(README): Add Apple Location method

commit d8b176f
Author: Sebastian Pekarek <mail@sebbo.net>
Date:   Mon Apr 13 15:04:16 2020 +0200

    test(Event): Apple Location tests

commit aa840b8
Merge: 8e5f3b6 6e351b3
Author: Sebastian Pekarek <mail@sebbo.net>
Date:   Mon Apr 13 14:27:54 2020 +0200

    Merge branch 'apple-event-feature' of https://github.com/focux/ical-generator into feature/apple-calendar

commit 6e351b3
Author: Leonardo Dominguez <focuux@gmail.com>
Date:   Mon Oct 21 15:59:47 2019 -0400

    fix: location and apple location must match

commit 28a0b15
Author: Leonardo Dominguez <focuux@gmail.com>
Date:   Mon Oct 21 15:26:45 2019 -0400

    fix types and line break

commit 10b8014
Author: Leonardo Dominguez <focuux@gmail.com>
Date:   Mon Oct 21 15:05:55 2019 -0400

    🙌 implement apple event tag
  • Loading branch information
sebbo2002 committed Apr 13, 2020
1 parent 8e5f3b6 commit 0956ba2
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 1 deletion.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,42 @@ Some calendar apps may support HTML descriptions. Like in emails, supported HTML
Appointment location


#### appleLocation([_Object_ appleLocation])

This method can be used to pass the location as a structured object. The location is then displayed on the map in iCal.
The passed object looks like this:

```
interface AppleLocationData {
title: string;
address: string;
radius: number;
geo: GeoData;
}
interface GeoData {
lat: number;
lon: number;
}
```

An example:

```js
event.appleLocation({
title: 'My Title',
address: 'My Address',
radius: 40,
geo: {
lat: '52.063921',
lon: '5.128511'
}
});
```

You can either use location() or appleLocation(), but now both. Thanks to [@focux](https://github.com/focux) for the [pull request](https://github.com/sebbo2002/ical-generator/pull/170)


#### geo([_String_|_Object_ geo])

Appointment geo position (gps). See [rfc](https://tools.ietf.org/html/rfc5545#section-3.8.1.6) for more details
Expand Down
10 changes: 10 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ declare module 'ical-generator' {
lastModified?: moment.Moment | Date;
description?: string;
location?: string;
appleLocation?: AppleLocationData;
geo?: GeoData;
url?: string;
sequence?: number;
Expand Down Expand Up @@ -137,6 +138,13 @@ declare module 'ical-generator' {
lon: number;
}

interface AppleLocationData {
title: string;
address: string;
radius: number;
geo: GeoData;
}

/**
* The calendar object containing all event data
*/
Expand Down Expand Up @@ -203,6 +211,8 @@ declare module 'ical-generator' {
summary(summary: string): ICalEvent;
location(): string;
location(location: string): ICalEvent;
appleLocation(): AppleLocationData;
appleLocation(location: AppleLocationData): ICalEvent;
geo(): string | null;
geo(geo: string | GeoData | null): ICalEvent;
description(): string;
Expand Down
44 changes: 43 additions & 1 deletion src/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ICalEvent {
repeating: null,
summary: '',
location: null,
appleLocation: null,
geo: null,
description: null,
htmlDescription: null,
Expand Down Expand Up @@ -54,6 +55,7 @@ class ICalEvent {
'repeating',
'summary',
'location',
'appleLocation',
'geo',
'description',
'htmlDescription',
Expand Down Expand Up @@ -545,11 +547,45 @@ class ICalEvent {
if (location === undefined) {
return this._data.location;
}
if (this._data.appleLocation && location) {
this._data.appleLocation = null;
}

this._data.location = location ? location.toString() : null;
return this;
}

/**
* Set/Get the Apple event's location
*
* @param {object|null} [appleLocation]
* @param {string} [appleLocation.title]
* @param {string} [appleLocation.address]
* @param {number} [appleLocation.radius]
* @param {object} [appleLocation.geo]
* @param {string|number} [appleLocation.lat]
* @param {string|number} [appleLocation.lon]
* @since 1.10.0
* @returns {ICalEvent|String}
*/
appleLocation (appleLocation) {
if (appleLocation === undefined) {
return this._data.appleLocation;
}
if (appleLocation === null) {
this._data.location = null;
return this;
}

if (!appleLocation.title || !appleLocation.address || !appleLocation.radius || !appleLocation.geo || !appleLocation.geo.lat || !appleLocation.geo.lon) {
throw new Error('`appleLocation` isn\'t formatted correctly. See https://github.com/sebbo2002/ical-generator#applelocationobject-applelocation');
}

this._data.appleLocation = appleLocation;
this._data.location = this._data.appleLocation.title + '\n' + this._data.appleLocation.address;
return this;
}

/**
* Set/Get the event's geo
*
Expand Down Expand Up @@ -955,7 +991,7 @@ class ICalEvent {
* @returns {ICalEvent|Array<Object<{key: String, value: String}>>}
*/
x (keyOrArray, value) {
return ICalTools.addOrGetCustomAttributes (this, keyOrArray, value);
return ICalTools.addOrGetCustomAttributes(this, keyOrArray, value);
}


Expand Down Expand Up @@ -1080,6 +1116,12 @@ class ICalEvent {
g += 'LOCATION:' + ICalTools.escape(this._data.location) + '\r\n';
}

// APPLE LOCATION
if (this._data.appleLocation) {
g += 'X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-ADDRESS=' + ICalTools.escape(this._data.appleLocation.address) + ';X-APPLE-RADIUS=' + ICalTools.escape(this._data.appleLocation.radius) + ';X-TITLE=' + ICalTools.escape(this._data.appleLocation.title) +
':geo:' + ICalTools.escape(this._data.appleLocation.geo.lat) + ',' + ICalTools.escape(this._data.appleLocation.geo.lon) + '\r\n';
}

// GEO
if (this._data.geo) {
g += 'GEO:' + ICalTools.escape(this._data.geo.lat) + ';' + ICalTools.escape(this._data.geo.lon) + '\r\n';
Expand Down
116 changes: 116 additions & 0 deletions test/test_event.js
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,122 @@ describe('ical-generator Event', function () {
event.location('Europa-Park');
assert.strictEqual(event._data.location, 'Europa-Park');
});

it('should reset appleLocation', function () {
const event = new ICalEvent({
start: moment(),
summary: 'Example Event',
appleLocation: {
title: 'My Title',
address: 'My Address',
radius: 40,
geo: {
lat: '52.063921',
lon: '5.128511'
}
}
}, new ICalCalendar());

event.location('Europa-Park');
assert.strictEqual(event._data.appleLocation, null);
});
});

describe('appleLocation()', function () {
it('getter should return value', function () {
const e = new ICalEvent(null, new ICalCalendar());
assert.strictEqual(e.appleLocation(), null);

e._data.appleLocation = {
title: 'My Title',
address: 'My Address',
radius: 40,
geo: {
lat: '52.063921',
lon: '5.128511',
}
};
assert.deepEqual(e.appleLocation(), {
title: 'My Title',
address: 'My Address',
radius: 40,
geo: {
lat: '52.063921',
lon: '5.128511',
}
});

e._data.appleLocation = null;
assert.strictEqual(e.appleLocation(), null);
});

it('setter should return this', function () {
const e = new ICalEvent(null, new ICalCalendar());
assert.deepStrictEqual(e, e.appleLocation(null));
assert.deepStrictEqual(e, e.appleLocation({
title: 'My Title',
address: 'My Address',
radius: 40,
geo: {
lat: '52.063921',
lon: '5.128511',
}
}));
});

it('should update appleLocation', function () {
const event = new ICalEvent({
start: moment(),
summary: 'Example Event'
}, new ICalCalendar());

event.appleLocation({
title: 'My Title',
address: 'My Address',
radius: 40,
geo: {
lat: '52.063921',
lon: '5.128511',
}
});
assert.deepEqual(event._data.appleLocation, {
title: 'My Title',
address: 'My Address',
radius: 40,
geo: {
lat: '52.063921',
lon: '5.128511',
}
});
});

it('should reset location', function () {
const event = new ICalEvent({
start: moment(),
summary: 'Example Event',
location: 'Batman Cave'
}, new ICalCalendar());

event.appleLocation({
title: 'My Title',
address: 'My Address',
radius: 40,
geo: {
lat: '52.063921',
lon: '5.128511',
}
});
assert.ok(event._data.location !== 'Batman Cave', null);
});

it('should throw error when string is not valid', function () {
const event = new ICalEvent({
start: moment(),
summary: 'Example Event'
}, new ICalCalendar());

assert.throws(() => event.appleLocation({}), /`appleLocation` isn't formatted correctly/i);
});
});

describe('description()', function () {
Expand Down

0 comments on commit 0956ba2

Please sign in to comment.