Skip to content

Create Calendar page #253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jan 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ Assets should be stored in a folder within that category, for example, `talks/sl
Asset file names should have enough info in the file name to know what references it (such as the associated talk date for slides) or be in a subfolder for things with a lot of assets (such as the TigerOS project).

Current categories:
* ~Announcements (`announcements/`)~ (deprecated)
* Announcements (`announcements/`)
* Events (`events/`)
* Meetings & Meetups (`meetings-meetups/`) (note that these pages aren't linked from anywhere other than feeds, they are more for the metadata)
* Meetings & Meetups (`meetings-meetups/`) (Note: these are not pages; they are placeholder metadata for the calendar feed and should be deleted when creating the announcement post)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this mean? Does this require additional metadata when creating announcement posts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "pages" in that folder should be entirely metadata and are meant to be used for the Calendar feed generation only. E.g., meetings that haven't had a topic or speaker determined yet and thus have no announcement nor talk page. These use the same metadata that the rest of the site has available, but tends to utilize some functionality more heavily, e.g. redirect page type. Technically you could use these as real pages, but I would discourage that in favor of other sections of the site, namely, announcements, talks, and events.

* Projects (`projects/`)
* Talks (`talks/`)

_Note on timezones: assume times are `America_New_York` and that DST is accounted for_

Please see [this runbook page](http://runbook.ritlug.com/infrastructure/website/) and [CONTRIBUTING.md](https://github.com/RITlug/ritlug.github.io/tree/master/CONTRIBUTING.md) for more info.

## Updating meeting times / places
Expand Down
4 changes: 2 additions & 2 deletions announcements/_posts/2019-11-15-w12-kernel-tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
author: Jeffery Russell (@jrtechs)
title: "Kernel Tracing"
layout: post-event
date-start: "2019-10-18 16:30"
date-end: "2019-10-18 18:00"
date-start: "2019-11-15 16:30"
date-end: "2019-11-15 18:00"
location: "GOL-2620 (Med. DB Lab)"
---

Expand Down
4 changes: 2 additions & 2 deletions announcements/_posts/2019-12-6-w13-final-meeting.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
author: Jeffery Russell (@jrtechs)
title: "Final Meeting"
layout: post-event
date-start: "2019-12-6 16:30"
date-end: "2019-10-18 18:00"
date-start: "2019-12-06 16:30"
date-end: "2019-12-06 18:00"
location: "GOL-2620 (Med. DB Lab)"
---

Expand Down
201 changes: 201 additions & 0 deletions calendar.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
layout: default
title: Calendar
---
<article class="container card">
<div class="card-body">
<h1 class="card-title">Calendar <a href="/feeds/calendar.ics" target="_blank"><span class="far fa-calendar-alt icon-orange"></span></a></h1>
<div id="menu">
<span id="menu-navi">
<button type="button" class="btn btn-default btn-sm move-today" data-action="move-today">Today</button>
<button type="button" class="btn btn-default btn-sm move-day" data-action="move-prev">
<i class="fas fa-chevron-left" data-action="move-prev"></i>
</button>
<button type="button" class="btn btn-default btn-sm move-day" data-action="move-next">
<i class="fas fa-chevron-right" data-action="move-next"></i>
</button>
</span>
<span id="renderRange" class="render-range"></span>
</div>
<br>

<div id="calendar"></div>
<br>
</div>
</article>

<link rel="stylesheet" type="text/css" href="https://uicdn.toast.com/tui-calendar/latest/tui-calendar.css" />
<script src="https://uicdn.toast.com/tui.code-snippet/latest/tui-code-snippet.js"></script>
<script src="https://uicdn.toast.com/tui.dom/v3.0.0/tui-dom.js"></script>
<script src="https://uicdn.toast.com/tui-calendar/latest/tui-calendar.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ical.js/1.3.0/ical.min.js" integrity="sha256-1oaCObP6yNz1ouAW50FOpNBBSNqZtpINrbL8B4W+kmM=" crossorigin="anonymous"></script>
<script>
// Load iCal feed (generated by Jekyll)
fetch('/feeds/calendar.ics').then((res) => {
// If fails to load, error and stop
if(!res.ok) {
document.querySelector('#calendar').innerText = 'Could not load feed (request failed)';
return;
}

// Get body of request
res.text().then((str) => {
try {
// Parse with ical.js
let parsed = ICAL.parse(str);

// Helpers for month text
const monthText = document.querySelector('.render-range');
const updateMonthText = () => {
monthText.innerText = new Intl.DateTimeFormat('en-US', { month: 'long', year: 'numeric' }).format(calendar.getDate().toDate());
}

// Initialize calendar
let calendar = new tui.Calendar('#calendar', {
defaultView: 'month',
isReadOnly: true,
usageStatistics: false,
useCreationPopup: false,
useDetailPopup: true
});

// Bind buttons to calendar
document.querySelector('[data-action="move-today"]').addEventListener('click', () => { calendar.today(); updateMonthText(); });
document.querySelector('[data-action="move-next"]').addEventListener('click', () => { calendar.next(); updateMonthText(); });
document.querySelector('[data-action="move-prev"]').addEventListener('click', () => { calendar.prev(); updateMonthText(); });
updateMonthText();

// Array of events to eventually be loaded into the calendar
let evtArr = [];

// Iterate through events from iCal feed
parsed[2].forEach((i, no) => {
// Define base parameters
let obj = {
bgColor: 'black',
body: '',
category: 'time',
color: 'white',
id: `${no}`,
isReadOnly: true,
isVisible: true
};

// Define vars for special cases
let rrule = false;
let url = '';

// Iterate through parameters and map to object properties
// (Convert iCal property names to tui.calendar property names)
i[1].forEach((j) => {
switch (j[0]) {
//case 'uid':
// obj.id = j[3];
// break;
case 'summary':
// Remove prefix added in iCal generation
obj.title = (j[3].startsWith('RITlug: ') ? j[3].substring(8) : j[3]);
break;
case 'description':
obj.body = j[3];
break;
case 'dtstart':
// ical.js adds empty time strings if an all-day event
// strip these and set all-day properties instead if needed
if(j[3].endsWith('T::')) {
obj.category = 'allday';
obj.isAllDay = true;
obj.start = j[3].replace('T::','');
} else {
obj.start = j[3];
}
break;
case 'dtend':
// Strip empty time strings if needed (see dtstart comments)
obj.end = j[3].replace('T::','');
break;
case 'location':
obj.location = j[3];
break;
case 'rrule':
// RRULE will get interpreted from object later
// Just set special case var to trigger parsing later
rrule = true;
break;
case 'url':
url = j[3];
break;
}
});

// If has URL, append to body (since no field for in details popup)
if(url !== '') {
obj.body += `${(obj.body === '' ? '' : '<br>')}<a href="${url}">${url}</a>`;
}

// tui.calendar can't handle RRULEs (recurrence rules)
// So, if an RRULE is set, use ical.js to expand occurances manually
if(rrule) {
// Create ical.js component from jCal output of parse
let comp = new ICAL.Component(i);

// Figure out the duration of the event (since can't directly expand start & end at the same time)
let duration = ICAL.Time.fromString(obj.end).subtractDate(ICAL.Time.fromString(obj.start));

// Create RRULE Expansion with ical.js
// (Creates an interable)
let expand = new ICAL.RecurExpansion({
component: comp,
dtstart: comp.getFirstPropertyValue('dtstart')
});

// Counter to prevent infinite iteration of RRULE (since by spec is allowed)
let count = 0;

// next defined here b/c of block scoping
let next;

// Iterate through occurances
// Arbitrary limit of 25 is for infinite iteration prevention
while(count < 25 && (next = expand.next())) {
// Increment infinite iteration prevention counter
count++;

// Duplicate event with RRULE
let o = {};
Object.assign(o, obj);

// Give unique ID
o.id += `::RRULE-n${count}`;

// Set start to this occurance from RRULE expansion
o.start = next.toString();

// Reconstruct end from duration and set
let end = ICAL.Time.fromJSDate(next.toJSDate());
end.addDuration(duration);
o.end = end.toString();

// Add to events array
evtArr.push(o);
}
} else {
// If no RRULE, directly add to events array
evtArr.push(obj);
}
});

// Add events in array to calendar
calendar.createSchedules(evtArr);
} catch(err) {
// Error on parsing fail
document.querySelector('#calendar').innerText = `Could not parse: ${err}`;
return;
}
}).catch(() => {
// Error on load fail
document.querySelector('#calendar').innerText = 'Could not load feed (no body)';
return;
});
});
</script>
5 changes: 3 additions & 2 deletions feeds/calendar.ics
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//{{site.title}}//{{site.url}}//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH{% for post in site.posts %}{% if post.categories.last == "meetings-meetups" or post.categories.first == "events" or post.categories.first == "talks" %}
METHOD:PUBLISH{% for post in site.posts %}{% if post.categories.last == "meetings-meetups" or post.categories.first == "events" or post.categories.first == "talks" or post.categories.first == "announcements" and post.layout == "post-event" %}
BEGIN:VEVENT
UID:{{site.url}}{{site.baseurl}}{{post.url}}
DTSTAMP:{{ post.date | date: "%Y%m%dT000000Z" }}{% if post.date-start %}
DTSTART;TZID=America/New_York:{{ post.date-start | date: "%Y%m%dT%H%M00" }}{% else %}
DTSTART:{{ post.date | date: "%Y%m%d" }}{% endif %}{% if post.date-end %}
DTEND;TZID=America/New_York:{{ post.date-end | date: "%Y%m%dT%H%M00" }}{% else %}
DTEND:{{ post.date | date: "%Y%m%d" }}{% endif %}
DTEND:{{ post.date | date: "%Y%m%d" }}{% endif %}{% if post.rrule %}
RRULE:{{post.rrule}}{% endif %}
ORGANIZER;CN="{{site.title}}":MAILTO:{{site.email}}
SUMMARY:RITlug: {{post.title}}
DESCRIPTION:{{post.excerpt | strip_html | newline_to_br | replace: "<br />", " " | strip_newlines | strip}}
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ <h2>Discuss</h2>
<h2>Do</h2>
<div class="list-group">
<a href="/get-involved" class="list-group-item list-group-item-action">Get Involved</a>
<a href="/talks" class="list-group-item list-group-item-action">Talks</a>
<a href="/calendar" class="list-group-item list-group-item-action">Calendar</a>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So does the calendar replace the Talks tab?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the home page list, not the navbar. The navbar is already really full so I opted to not add more to it. I think further linking/navbar changes would be best for another issue/PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the talks tab is still on the page's main navbar

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was part of what I meant; this is intended behavior and not a bug

<a href="/projects" class="list-group-item list-group-item-action">Projects</a>
<a href="https://github.com/RITlug" class="list-group-item list-group-item-action">GitHub</a>
</div>
Expand Down
10 changes: 10 additions & 0 deletions meetings-meetups/_posts/2020-01-16-foss-hours.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
layout: redirect
redirect: https://fossrit.github.io/
date-start: "2020-01-16 17:00"
date-end: "2020-01-16 19:00"
location: "MSS-3190"
title: "FOSS Hours"
rrule: "FREQ=WEEKLY;UNTIL=20200423T190000"
---
Not a RITlug event, but one we think is worthwhile to share and you'll likely see some of us there
8 changes: 8 additions & 0 deletions meetings-meetups/_posts/2020-01-17-mtg-intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
layout: redirect
redirect: https://ritlug.com/get-involved
date-start: "2020-01-17 16:30"
date-end: "2020-01-17 18:00"
location: "GOL-2620"
title: "Intro to RITlug"
---
9 changes: 9 additions & 0 deletions meetings-meetups/_posts/2020-01-24-mtg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
layout: redirect
redirect: https://ritlug.com/get-involved
date-start: "2020-01-24 16:30"
date-end: "2020-01-24 18:00"
location: "GOL-2620"
title: "Meeting (Topic TBD)"
rrule: "FREQ=WEEKLY;UNTIL=20200306T180000"
---
9 changes: 9 additions & 0 deletions meetings-meetups/_posts/2020-02-08-09-brickhack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
layout: redirect
redirect: https://brickhack.io/
date-start: "2020-02-08 08:00"
date-end: "2020-02-09 12:00"
location: "SAU"
title: "BrickHack"
---
Not a RITlug event, but one we think is worthwhile to share and you'll likely see some of us there
8 changes: 8 additions & 0 deletions meetings-meetups/_posts/2020-03-08-15-spring-break.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
layout: redirect
redirect: https://rit.edu/calendar/
date-start: "2020-03-08 00:00"
date-end: "2020-03-15 11:59"
location: "GOL-2620"
title: "Spring Break"
---
9 changes: 9 additions & 0 deletions meetings-meetups/_posts/2020-03-20-mtg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
layout: redirect
redirect: https://ritlug.com/get-involved
date-start: "2020-03-20 16:30"
date-end: "2020-03-20 18:00"
location: "GOL-2620"
title: "Meeting (Topic TBD)"
rrule: "FREQ=WEEKLY;UNTIL=20200501T180000"
---
11 changes: 11 additions & 0 deletions meetings-meetups/_posts/2020-04-25-imaginerit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
layout: redirect
redirect: https://ritlug.com/get-involved
date-start: "2020-04-25 16:30"
date-end: "2020-04-25 18:00"
location: "TBD"
title: "ImagineRIT"
---
Help or visit RITlug at ImagineRIT!

Stay tuned for more info closer to the event.