Skip to content

Commit

Permalink
Merge branch 'people-index'
Browse files Browse the repository at this point in the history
Some outstanding issues remain: #658, #659, #660, #661
  • Loading branch information
wjdp committed Nov 1, 2016
2 parents 3a8bb3c + 78a10a3 commit 4906121
Show file tree
Hide file tree
Showing 63 changed files with 1,539 additions and 242 deletions.
12 changes: 12 additions & 0 deletions .postcss.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"use": [
"postcss-cssnext",
"cssnano"
],
"input": "_site/css/main.css",
"output": "_site/css/main.css",
"local-plugins": true,
"cssnano": {
"autoprefixer": false
}
}
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude" : {
".sass-cache": true,
"_site": true,
"_smugmug_cache": true,
"smugmug_cache": true,
"node_modules": true,
"tmp": true
}
}
5 changes: 5 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,17 @@ task :build do
logline "NTHP BUILD"
sh "bundle exec jekyll build --trace --profile"

logline "POSTCSS"
sh "node_modules/gulp/bin/gulp.js css"

logline "JS UGLIFY "
jsminify("_site/js/app.js")
jsminify("_site/js/lib.js")
jsminify("_site/js/utility.js")

logline "SEARCH INDEX"
sh "coffee ./_coffee/search_index_generator.coffee"
sh "coffee ./_coffee/people_index_generator.coffee"
end

task :debug do
Expand All @@ -53,6 +57,7 @@ task :debug do

logline "SEARCH INDEX"
sh "coffee ./_coffee/search_index_generator.coffee"
sh "coffee ./_coffee/people_index_generator.coffee"
end

task :test do
Expand Down
69 changes: 69 additions & 0 deletions _coffee/PeopleGrid.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
class PeopleGrid
constructor: (opts) ->
@gridEl = opts.gridEl
@scrollerEl = opts.scrollerEl
@gridScrollEls = @gridEl.querySelectorAll('.scroll-detect')
@gridActiveEl = null
@windowPos = -1 # Make run on pageload

@currentEl = null

@enabled = true

window.requestAnimationFrame(@update)

update: (timestamp) =>
# Only run if scroll has occurred
if @windowPos == window.scrollY
window.requestAnimationFrame(@update) if @enabled
@windowPos = window.scrollY
return 0
else
@windowPos = window.scrollY

lastEl = @gridScrollEls[0]
for el in @gridScrollEls
ePosCurrent = el.getBoundingClientRect().top

if ePosCurrent > 60
# The previous element is the current element
@setCurrent(lastEl) if @currentEl isnt lastEl
found = true
break

lastEl = el

# Selection of last element
unless found
if ePosCurrent < 60
@setCurrent(lastEl) if @currentEl isnt lastEl

window.requestAnimationFrame(@update) if @enabled

setCurrent: (el) ->
# Get sort data (A, B, C, &c)
sort = el.dataset.sortLabel
# Remove old active class
old_active = @scrollerEl.querySelector('.active')
old_active.classList.remove('active') if old_active
# Add new active class
new_active = @scrollerEl.querySelector("[data-sort='#{sort}']")
new_active.classList.add('active')
# Save current el
@currentEl = el

destructor: ->
@enabled = false

$(document).ready ->
peopleGridEl = document.querySelector('#pg')
peopleScrollerEl = document.querySelector('#pgScroller')
if peopleGridEl
window.prodShotsGallery = new PeopleGrid
gridEl: peopleGridEl
scrollerEl: peopleScrollerEl

document.addEventListener 'turbolinks:visit', ->
if window.peopleGridEl
window.peopleGridEl.destructor()
delete window.peopleGridEl
204 changes: 204 additions & 0 deletions _coffee/PeopleSearch.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
class PeopleSearch
SEARCH_WORKER_URL = '/js/search_worker.js'
SEARCH_INDEX_URL = '/feeds/people_index.json'
SEARCH_DATA_URL = '/feeds/people.json'
FIELDS = [
['people-filter-name', '']
['people-filter-graduated', 'graduated']
['people-filter-career', 'career']
['people-filter-course', 'course']
['people-filter-award', 'award']
['people-filter-srole', 'srole']
['people-filter-crole', 'crole']
]

PS_FILTER_FIXED_TOP = 27
PS_FILTER_FIXED_CLASS = 'people-index__filters--fixed'
PS_MORE_TOGGLE_CLASS = 'people-index__filters__more--open'
PS_TOGGLE_TOGGLE_CLASS = 'people-index__filters__toggle--open'
PS_BODY_PUSH_CLASS = 'people-index--push'

constructor: (opts) ->
@enabled = true

@psFilterEl = opts.psFilterEl
@psMoreEl = @psFilterEl.querySelector('#psMore')
@psMoreToggleEl = @psFilterEl.querySelector('#psMoreToggle')
@psBodyEl = opts.psBodyEl
@psResults = new PeopleResults
psResultsEl: opts.psResultsEl
@footerEl = document.querySelector('.site-footer')

@moreIsOpen = false
@scrollIsFixed = false

@searchWorker = new Worker(SEARCH_WORKER_URL)
@searchWorker.postMessage
cmd: 'init'
indexUrl: SEARCH_INDEX_URL
dataUrl: SEARCH_DATA_URL
@searchWorker.addEventListener 'message', @onMessage

@bindSearchFields()

@psMoreToggleEl.addEventListener('click', @toggleMore)

@psFilterElOffsetTop = $(@psFilterEl).offset().top
@psFilterHeight = @psFilterEl.offsetHeight
window.requestAnimationFrame(@update)

destructor: ->
@searchWorker.postMessage
cmd: 'stop'
@enabled = false

bindSearchFields: ->
@searchFields = Array()
for field in FIELDS
elem = document.getElementById(field[0])
if FIELDS.indexOf(field) == 0
elem.addEventListener 'input', debounce =>
@onSearch()
else
elem.addEventListener('change', @onSearch)
@searchFields.push [elem, field[1]]

searchTerm: ->
query_terms = Array()
for field in @searchFields
if field[1] == '' and field[0].value != ""
query_terms.push(field[0].value)
else if field[0].value != ""
query_terms.push("#{field[1]}:#{field[0].value}".replace(/ /g, '_'))

query_terms.join ' '

onSearch: =>
# Event listener for field changes
q = @searchTerm()

if q.length > 0
@searchWorker.postMessage
cmd: 'search'
query: q
else
@psResults.clear()

onMessage: (e) =>
data = e.data
switch (data.cmd)
when 'ready'
# Search worker is ready
$( @searchFields[0][0] ).attr('placeholder','')
when 'results'
@psResults.render(data.results)

toggleMore: =>
# Open/close the 'more' drawer, applicable to mobile
@moreIsOpen = !@moreIsOpen
@psMoreEl.classList.toggle(PS_MORE_TOGGLE_CLASS)
@psBodyEl.classList.toggle(PS_BODY_PUSH_CLASS) if @scrollIsFixed
@psMoreToggleEl.classList.toggle(PS_TOGGLE_TOGGLE_CLASS)

update: =>
# Only run if scroll changed AND not mobile
if (@windowPos != window.scrollY)
# No top gap on mobile between header and filter box
if isMobile()
top_limit = @psFilterElOffsetTop
else
top_limit = @psFilterElOffsetTop - PS_FILTER_FIXED_TOP

# If beyond this limit, add fixed class, otherwise remove
# Toggle action
if (window.scrollY > top_limit) and !@scrollIsFixed
@scrollIsFixed = true
@psFilterEl.classList.add(PS_FILTER_FIXED_CLASS)
@psBodyEl.style.paddingTop = "#{@psFilterHeight + 6}px" if isMobile()
if isMobile() and @moreIsOpen
# http://stackoverflow.com/a/16575811/1345360
@psBodyEl.classList.add('noTransition')
@psBodyEl.classList.add(PS_BODY_PUSH_CLASS)
@psBodyEl.offsetHeight
@psBodyEl.classList.remove('noTransition')
else if !(window.scrollY > top_limit) and @scrollIsFixed
@scrollIsFixed = false
@psFilterEl.classList.remove(PS_FILTER_FIXED_CLASS)
@psBodyEl.style.paddingTop = "" if isMobile()
if isMobile()
# http://stackoverflow.com/a/16575811/1345360
@psBodyEl.classList.add('noTransition')
@psBodyEl.classList.remove(PS_BODY_PUSH_CLASS)
@psBodyEl.offsetHeight
@psBodyEl.classList.remove('noTransition')

# Stop the scroll following when we hit the footer
# Continious action
footerOffsetTop = $(@footerEl).offset().top - window.scrollY
filterFooterDistance = footerOffsetTop - (
@psFilterEl.getBoundingClientRect().height + PS_FILTER_FIXED_TOP)

if (filterFooterDistance < PS_FILTER_FIXED_TOP) and !isMobile()
@psFilterEl.style.top = "#{filterFooterDistance}px"
else
@psFilterEl.style.top = ""

@windowPos = window.scrollY
window.requestAnimationFrame(@update) if @enabled


class PeopleResults
constructor: (opts) ->
@psResultsEl = opts.psResultsEl
@psEmptyTemplate = _.template(
document.getElementById('psResultEmpty').textContent)
@psIntro = document.getElementById('psIntro')

clear: ->
if @psIntro?
@psIntro.parentNode.removeChild(@psIntro)
delete @psIntro
while @psResultsEl.hasChildNodes()
@psResultsEl.removeChild(@psResultsEl.lastChild)

render: (results) ->
@clear()

if results.length == 0
@psResultsEl.innerHTML = @psEmptyTemplate()

output = Array()
for result in results
pr = new PeopleResult(result)
@psResultsEl.appendChild pr.render()


class PeopleResult
TEMPLATE_RESULT = 'psResultTemplate'
constructor: (result) ->
@result = result
@node = document.createElement('li')
getTemplate: ->
_.template document.getElementById(TEMPLATE_RESULT).textContent
render: ->
html = @getTemplate()
item: @result
@node.innerHTML = html
return @node


$(document).ready ->
psFilter = document.querySelector('#psFilter')
psBody = document.querySelector('#psBody')
psResults = document.querySelector('#psResults')

if psFilter and psResults
window.peopleSearch = new PeopleSearch
psFilterEl: psFilter
psBodyEl: psBody
psResultsEl: psResults

document.addEventListener 'turbolinks:visit', ->
if window.peopleSearch
window.peopleSearch.destructor()
delete window.peopleSearch
File renamed without changes.
4 changes: 2 additions & 2 deletions _coffee/collect.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ course:
- #{form_dict['course']}
graduated: #{form_dict['graduation']}
contact_allowed: #{form_data_computed['contact_allowed_tf']}
career:
careers:
#{career_choices_yaml}
#{form_dict['career-other']}
links: *fill me out
Expand Down Expand Up @@ -203,7 +203,7 @@ award: *fill me out

disableCollectForm()

PEOPLE_FEED = "/feeds/people.json"
PEOPLE_FEED = "/feeds/people-collect.json"
TEMPLATE_DATA = "#collect-template-list"

collectPersonFormSetup = ->
Expand Down
5 changes: 5 additions & 0 deletions _coffee/globals.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ debounce = (fn) ->
fn.apply ctx, args
return
), 40)

isMobile = ->
$('#nthpMobileDetect').css('display') == 'block'

window.im = isMobile
Loading

0 comments on commit 4906121

Please sign in to comment.