diff --git a/data/friday_hacks_1617_2.yml b/data/friday_hacks_1617_2.yml
new file mode 100644
index 00000000..2f25e33f
--- /dev/null
+++ b/data/friday_hacks_1617_2.yml
@@ -0,0 +1,79 @@
+start_date: 2017-01-20 18:00:00 +0800
+hacks:
+ - venue: The Hangar by NUS Enterprise
+ topics:
+ - speaker: Fazli Sapuan
+ from: Garena
+ title: The Art of Lockpicking
+ - speaker: Wang Chen
+ from: SAP
+ title: Smart Enterprise Software Empowered by Machine Learning
+ - nohack: CNY Eve
+ - venue: SR3, Town Plaza, University Town, NUS
+ topics:
+ - speaker: Jethro Kuan
+ from: NUS Hackers
+ title: 'Realtime Collaboration: A Brief History'
+ - speaker: Wang Leng
+ from: NUS School of Computing
+ title: Cross Site Scripting
+ - venue: SR3, Town Plaza, University Town, NUS
+ topics:
+ - speaker: Ding Feng
+ from: NUS CS
+ title: 'Hardware Hacks: The Whys and Hows'
+ - speaker: Raghav Sood
+ from: IBM Blockchain Innovation Center
+ title: 'Wi-Fi Hacks: Hacking the Air Around Us'
+ - venue: SR3, Town Plaza, University Town, NUS
+ topics:
+ - speaker: Emil Tan
+ from: Edgis
+ title: My Love-Hate Relationship with Honeypot
+ - speaker: Sunny Neo
+ from: BT Security
+ title: Web Security for Developers
+ - nohack: Recess Week
+ - venue: The Hangar by NUS Enterprise
+ topics:
+ - speaker: Kee Wee Teng
+ from: FSTD, MINDEF
+ title: An Introduction to DIY Laser Cutters
+ - speaker: Francis Regan, Xinxin Du and Shabbir
+ from: Ionic3DP
+ title: The Kappa 3D Printer
+ - venue: The Hangar by NUS Enterprise
+ topics:
+ - speaker: Virgil Griffith
+ from: Legalese
+ title: Bitcoin, Darkweb, Ethereum and LegalTech
+ - venue: SR5, Town Plaza, University Town, NUS
+ topics:
+ - speaker: John L. Gustafson
+ from: NUS
+ title: Weapons of Math Destruction
+ - venue: SR5, Town Plaza, University Town, NUS
+ topics:
+ - speaker: Abhilash Murthy
+ from: Bus Uncle
+ title: How to Build a Bot People Will Love
+ - speaker: Coreteam
+ from: NUS Hackers
+ title: Panel Discussion - Summer Plans
+ - venue: i-Cube Building Auditorium, NUS
+ topics:
+ - speaker: Jeff Moss
+ from: DEFCON & BlackHat
+ title: A Sharing on Cyber Security
+ - speaker: Halvar Flake
+ from: Google
+ title: Another Sharing on Cyber Security
+ - venue: SR5, Town Plaza, University Town, NUS
+ topics:
+ - speaker: Peter Hoeg
+ from: Speartail
+ title: '(Programming your OS && ignoring state) == bliss'
+ - speaker: Vishnu Prem
+ from: Coreteam
+ title: 'Row Hammer: Flipping Bits in Memory Without Accessing Them'
+ - nohack: Good Friday
diff --git a/data/hacker_school.yml b/data/hacker_school.yml
index f218773e..fca20f55 100644
--- a/data/hacker_school.yml
+++ b/data/hacker_school.yml
@@ -8,3 +8,15 @@ events:
- topic: Introduction to programming, in Swift Playgrounds
venue: The Hangar by NUS Enterprise
date: 2017-02-18T13:00:00
+ - topic: Introduction to programming, in Swift Playgrounds
+ venue: The Hangar by NUS Enterprise
+ date: 2017-02-25T13:00:00
+ - topic: Introduction to programming, in Swift Playgrounds
+ venue: The Hangar by NUS Enterprise
+ date: 2017-03-04T13:00:00
+ - topic: Introduction to programming, in Swift Playgrounds
+ venue: The Hangar by NUS Enterprise
+ date: 2017-03-11T13:00:00
+ - topic: Introduction to programming, in Swift Playgrounds
+ venue: The Hangar by NUS Enterprise
+ date: 2017-03-18T13:00:00
diff --git a/layouts/index.html b/layouts/index.html
index 820bdc1b..3f7b0749 100644
--- a/layouts/index.html
+++ b/layouts/index.html
@@ -18,64 +18,68 @@
What we do
-
+
-
-
-
- {{ $weekInSeconds := 604800 }}
- {{ $date := $.Site.Data.friday_hacks.start_date }}
- {{ $dateUnix := (time $date).Unix }}
+
+
+
+
+ {{ $weekInSeconds := 604800 }}
+ {{ $date := $.Site.Data.friday_hacks.start_date }}
+ {{ $dateUnix := (time $date).Unix }}
- {{ range $index, $hack := $.Site.Data.friday_hacks.hacks }}
- {{ if le $index 2 }}
- -
- {{ $hackDate := add $dateUnix (mul $index $weekInSeconds) }}
-
- {{ if eq $hack.nohack nil }}
- {{ $hack.venue }}
-
- {{ else }}
- {{ $hack.nohack }}, no Friday Hacks
- {{ end }}
-
- {{ end }}
- {{ end }}
-
-
-
-
-
- {{ range $index, $event := $.Site.Data.hacker_school.events }}
- {{ if le $index 2 }}
- -
-
- {{ $event.venue }}
-
{{ $event.topic }}
-
- {{ end }}
- {{ end }}
-
+ {{ range $index, $hack := $.Site.Data.friday_hacks.hacks }}
+
-
+ {{ $hackDate := add $dateUnix (mul $index $weekInSeconds) }}
+
+ {{ if eq $hack.nohack nil }}
+ {{ $hack.venue }}
+
+ {{ else }}
+ {{ $hack.nohack }}, no Friday Hacks
+ {{ end }}
+
+ {{ end }}
+
+
Show more
+
+
+
+
+ {{ range $index, $event := $.Site.Data.hacker_school.events }}
+ -
+
+ {{ $event.venue }}
+
{{ $event.topic }}
+
+ {{ end }}
+
+
Show more
+
+
{{ end }}
diff --git a/static/js/toggleShowMore.js b/static/js/toggleShowMore.js
new file mode 100644
index 00000000..b26bd757
--- /dev/null
+++ b/static/js/toggleShowMore.js
@@ -0,0 +1,66 @@
+(function toggleShowMore() {
+ const SECOND = 10 * 100;
+ const TWENTY_FOUR_HOURS = 24 * 60 * 60 * SECOND;
+ const TWO_WEEKS = 2 * 7 * TWENTY_FOUR_HOURS;
+ const HIDE_TEXT = 'Hide';
+ const VISUALLY_HIDDEN_CLASS_NAME = 'visually-hidden';
+ const HIDDEN_CLASS_NAME = 'item-hidden';
+ const NOW = new Date();
+ const NO_EVENTS_NOTICE = (function() {
+ const div = document.createElement('div');
+ div.innerText = 'No events';
+ return div;
+ })();
+
+ // Store events beyond two weeks to be toggled
+ const eventsByListIndex = [];
+
+ const lists = document.querySelectorAll('.events > .list');
+ const buttons = document.querySelectorAll('.events-button');
+
+ lists.forEach((list, index) => {
+ const futureEvents = [];
+ list.querySelectorAll('.item').forEach(event => {
+ const dateString = event.querySelector('time').getAttribute('datetime');
+ const date = new Date(dateString);
+
+ // Remove events that have already occured (with buffer)
+ const isPastEvent = NOW - date > TWENTY_FOUR_HOURS / 4;
+ if (isPastEvent) {
+ event.remove();
+ }
+
+ // Hide events that are more than two weeks ahead
+ const isWithinTwoWeeks = date - NOW < TWO_WEEKS;
+ if (!isWithinTwoWeeks) {
+ event.classList.add(HIDDEN_CLASS_NAME, VISUALLY_HIDDEN_CLASS_NAME);
+ futureEvents.push(event);
+ }
+ });
+
+ if (!futureEvents.length) {
+ list.parentNode.appendChild(NO_EVENTS_NOTICE);
+ buttons[index].remove();
+ }
+ eventsByListIndex[index] = futureEvents;
+ });
+
+ buttons.forEach(function(button, index) {
+ const initialText = button.textContent;
+ button.addEventListener('click', function click(ele) {
+ // Toggle text of button
+ const elementText =
+ ele.target.textContent === initialText ? HIDE_TEXT : initialText;
+ ele.target.textContent = elementText;
+
+ // Toggle visibility of events
+ const events = eventsByListIndex[index];
+ events.forEach((event, index) => {
+ event.classList.toggle(VISUALLY_HIDDEN_CLASS_NAME);
+ setTimeout(() => {
+ event.classList.toggle(HIDDEN_CLASS_NAME);
+ }, 30 * index);
+ });
+ });
+ });
+})();
diff --git a/static/scss/front-page.scss b/static/scss/front-page.scss
index 1dc2fca6..df33fcc8 100644
--- a/static/scss/front-page.scss
+++ b/static/scss/front-page.scss
@@ -67,6 +67,24 @@ $font-small: 0.9rem;
}
}
+.events {
+ .events-button {
+ display: block;
+ text-align: center;
+ color: $button-link-color;
+ border-bottom: 1px dotted rgba(0, 0, 0, 0.2);
+ }
+ .item {
+ opacity: 1;
+ transform: none;
+ @include transition(deceleration);
+ }
+ .item-hidden {
+ opacity: 0;
+ transform: translateY(-1rem);
+ }
+}
+
.fh {
.fh-time {
display: block;
diff --git a/static/scss/main.scss b/static/scss/main.scss
index 99020c96..a385db01 100644
--- a/static/scss/main.scss
+++ b/static/scss/main.scss
@@ -1,5 +1,6 @@
$hackers-orange: #cc4100;
$highlight-orange: #f8941d;
+$button-link-color: #4a4a4a;
$link-color: $hackers-orange;
$link-hover-color: $hackers-orange;
@@ -54,6 +55,17 @@ h6 {
list-style: none;
}
+.visually-hidden {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ border: 0;
+ clip: rect(0 0 0 0);
+}
+
.fh-sponsor {
display: block;
max-width: 16rem;