Search
Results
Results
${ capture(/^projects\//, {
0: (data, captures) => (
data.params.project !== undefined ?
include('#filter-navigation-close-project', data) :
data.params.collection !== undefined ?
include('#filter-navigation-close-collection', data) :
include('#filter-navigation-search', data)
),
catch: () => console.log('TODO: SHOULDNT GET HERE')
}, data.location, data.location.name) }
${data.collections.reduce(function (acc, col) {
return acc + col.content_count
}, 0)}
${
merge([{ type: 'resize' }], events('resize', window))
// To size
.map(() => (window.innerWidth >= px('70em') ? 'big' : 'small'))
// Deduplicate
.filter(((prev) => (value) => {
const result = prev !== value;
prev = value;
return result;
})(null))
// Include
.map((size) => (size === 'big' ? 'Living Archives' : capture(/^projects\//, {
0: (data, captures) => (
data.identifier === 'filters' ? 'Search / Filter' :
data.params.project !== undefined ? 'Project' :
data.params.collection !== undefined ? 'Collection' :
'Results'
),
catch: () => console.log('TODO: SHOULDNT GET HERE')
}, data.location, data.location.name)))
}
${
merge([{ type: 'resize' }], events('resize', window))
// To size
.map(() => (window.innerWidth >= px('70em') ? 'big' : 'small'))
// Deduplicate
.filter(((prev) => (value) => {
const result = prev !== value;
prev = value;
return result;
})(null))
// Include
.map((size) => (size === 'big' ? '' : include('#search-template', data)))
}
Show ${ data.results_count } results
${ include('#filters-template', ((observer) => {
this.done(observe('params', this.data).each((params) => {
const requestParams = assign({ page: 0 }, this.data.params);
const search = new URLSearchParams(params);
request('/projects/results.json?' + search)
.then((results) => assign(observer, results, { params: this.data.params }));
}));
return observer;
})(Observer({ params: this.data.params }))) }
${ this.data.title }
${ this.data.authors.map(get('name')).join(' / ') }
Collection
${ this.data.years[0] } - ${ this.data.years[this.data.years.length -1] }
${ this.data.contents.join(', ') }
${ this.data.image.url ? include("#img-template", this.data.image) : include("#no-img-thumb-template", this.data.image) }
${ this.data.title }
${ this.data.authors.map(get('name')).join(', ') }
${ this.data.project_title }
Item
${ this.data.years[0] == this.data.years[this.data.years.length -1] ? this.data.years[0] : this.data.years[0] + ' - ' + this.data.years[this.data.years.length -1] }
${ this.data.contents.join(', ') }
${ include('#collections-thumb', {
pk: this.data.pk,
type: 'item',
module: { collections },
class: 'thumb-28'
}) }
${ this.data.image.url ? include("#img-template", this.data.image) : include("#no-img-thumb-template", this.data.image) }
${ this.data.title }
${ this.data.authors.map(get('name')).join(', ') }
Project
${ this.data.years[0] == this.data.years[this.data.years.length -1] ? this.data.years[0] : this.data.years[0] + ' - ' + this.data.years[this.data.years.length -1] }
${ this.data.contents.join(', ') }
${ include('#collections-thumb', {
pk: this.data.pk,
type: 'project',
module: { collections },
class: 'thumb-28'
}) }
${ this.data.label || this.data.value }${ (this.data.name === 'type' && (this.data.label || this.data.value) === 'All') ? '' : include('#filter-term-remove-template', data) }
Sorry, no results found.
${ data.response && data.response.results.map((result) => include('#' + result.type + '-result-template', assign({
url: '/projects/?' + paramify(assign({}, this.data.params,
result.type === 'item' ? { project: result.project_pk, collection: undefined } :
result.type === 'project' ? { project: result.pk, collection: undefined } :
result.type === 'collection' ? { project: undefined, collection: result.pk } :
nothing
)),
params: this.data.params,
location: this.data.location
}, result))) }
${
merge([{ type: 'resize' }], events('resize', window))
// To size
.map(() => (window.innerWidth >= px('70em') ? 'big' : 'small'))
// Deduplicate
.filter(((prev) => (value) => {
const result = prev !== value;
prev = value;
return result;
})(null))
// Include
.map((size) => (size === 'big' ? include('#search-template', data) : ''))
}
${ include('#view-template', { column: 2 }) }
${ data.masonryElement = element, '' }
${ data.response && data.response.results.length ?
include('#results-template', data) :
include('#no-results-template', data)
}
${ this.updateAuthors = (results) => results.reduce((authors, result) => (
result.authors ? result.authors.reduce((authors, author) => {
authors[author.id] = author.name;
return authors;
}, authors) :
authors
), window.config.app.authors),
capture(/^projects\//, {
0: (data, captures) => include('#first-results-template', ((observer) => {
let pageParams;
let req;
this.connected(() =>
Promise.resolve().then(() =>
this.done(setupView(element, observer))
)
);
// Update params when data.params changes
this.done(observe('params', this.data).each((params) => {
pageParams = assign({ page: 0 }, this.data.params);
const search = new URLSearchParams(pageParams);
req = request('/projects/results.json?' + search).then((response) => {
req = undefined;
// Update list of authors by id
this.updateAuthors(response.results);
assign(observer, { response }, { params: this.data.params })
});
// Why does it take 4 ticks to render? TODO: Investigate.
req.then(noop).then(noop).then(noop).then(() => {
// If we are not in grid-view ignore
if (!observer.masonry) { return; }
observer.masonry = new Masonry(observer.masonryElement, {
itemSelector: '.result-grid',
gutter: px('0.9375rem'),
transitionDuration: 0,
stagger: 0
});
/*
Force a re-layout of masonry after 0.25s.
If everything worked fine the first time
this should be transparent. If masonry fucked up before, this will fix things.
Also applied below.
*/
window.setTimeout(
function() {
observer.masonry.layout();
}, 250
);
});
}));
this.done(
merge(events({ type: 'scroll', pasive: true }, window), events({ type: 'scroll', passive: true }, element))
.each((e) => {
const current = e.currentTarget === element ? element : document.scrollingElement;
// If request is in progress
if (req) {
return;
}
// If scroll comes from something inside
if (current === element ?
e.target !== element :
(e.target !== document && e.target !== document.body && e.target !== document.documentElement && e.target !== window)
) {
return;
}
// Not near the end of scrollHeight
if (current.scrollTop < (current.scrollHeight - current.clientHeight - 160)) {
return;
}
++pageParams.page;
const search = new URLSearchParams(pageParams);
req = request('/projects/results.json?' + search)
.then((response) => {
// Update list of authors by id
this.updateAuthors(response.results);
return include('#results-template', { response, params: this.data.params, location: this.data.location })
})
.then((renderer) => {
req = undefined;
Promise.resolve(null).then(noop).then(noop).then(noop).then(() => {
//const children = Array.from(renderer.content.children);
// Keep new children within the template delimiter node
observer.masonryElement && observer.masonryElement.lastChild.before(renderer.content);
renderer.connect();
if (!observer.masonry) { return; }
observer.masonry = new Masonry(observer.masonryElement, {
itemSelector: '.result-grid',
gutter: px('0.9375rem'),
transitionDuration: 0,
stagger: 0
});
/*
Force a re-layout of masonry after 0.25s.
If everything worked fine the first time
this should be transparent. If masonry fucked up before, this will fix things.
Also applied above.
*/
window.setTimeout(
function() {
observer.masonry.layout();
}, 250
);
});
});
})
);
return observer;
})(Observer({
params: this.data.params,
location: this.data
}))),
catch: () => ''
}, data, data.name) }
${ includeHTML('/projects/' + this.data.params.project + '/project-name/')
.then((html) => {
// Highlight momentarily the item corresponding to location hash
setTimeout(() => {
if (!location.hash) { return; }
const target = element.querySelector(location.hash);
if (!target) { return; }
if (target.parentNode.matches('slide-show')) { return; }
target.scrollIntoView({ behavior: 'smooth', block: 'center' });
target.classList.add('target');
setTimeout(() => target.classList.remove('target'), 12000);
}, 800);
return html;
}) }
Close
${ include('#view-template', { column: 3 }) }
${ this.data.masonryElement = element, '' }
${ data.collection.objects.map((result) =>
include('#' + result.type + '-result-template', assign({
url: '/projects/?' + paramify(assign({}, data.location.params,
result.type === 'item' ? { project: result.project_pk } :
result.type === 'project' ? { project: result.pk } :
result.type === 'collection' ? { project: undefined, collection: result.pk } :
nothing
)),
params: data.location.params,
location: data.location
}, result))
) }
Close
${ capture(/^projects\//, {
0: (data, captures) => (data.params.collection !== undefined ?
include('#collection-template', request('/collections/' + data.params.collection + '.json')
.then((collection) => ({ collection, location: data }))) :
data.params.project !== undefined ?
include('#project-template', {
params: data.params,
location: data,
column: 3
}) :
''
),
catch: () => ''
}, data, data.name) }
${ capture(/^projects\/$/, {
0: (params, captures) => (params.collection !== undefined && params.project !== undefined ?
include('#project-template', {
id: params.project,
column: 4,
params: params,
location: data
}) :
''
),
catch: () => ''
}, data.params, data.name) }
${ data.id[0].toUpperCase() + data.id.slice(1) }
${ events('dom-activate', element)
.take(1)
.map(() =>
request('/cms/' + data.id + '/')
.then((html) => {
const template = document.createElement('template');
template.innerHTML = html;
return template.content.querySelector('.inline-content-block');
})
) }
Back to navigation
${ events({ type: 'mousedown', select: '[name="scrollLeft"], [name="scrollTop"]' }, element).each((e) => {
const button = e.target;
const target = element.querySelector('.layer');
let frame;
function scroll() {
frame = requestAnimationFrame(scroll);
target[button.name] += parseFloat(button.value);
}
scroll();
events('mouseup', document)
.take(1)
.each((e) => cancelAnimationFrame(frame));
}) }
${ this.done(
// Switch href when slide changes
merge([{target: element.children[0]}], events('slide-active', element))
.each((e) => assign(data, e.target.dataset, { pk: parseInt(e.target.dataset.pk, 10) }))
) }
${ this.done(
// Switch src when img clicked
events({ type: 'click', select: 'img, [name="zoom"]' }, element)
// Only react in fullscreen mode
.filter((e) => !!document.fullscreenElement || !!document.webkitFullscreenElement || !!document.boltFullscreenElement)
.each((e) => {
console.log('CLICK');
if (data.src) {
data.src = undefined;
data.alt = undefined;
}
else {
assign(data, {
src: element.active.dataset.itemUrl,
alt: element.active.querySelector('img').alt,
width: element.active.dataset.itemWidth,
height: element.active.dataset.itemHeight
});
}
})
) }
${ this.done(
events('fullscreenchange', element)
// Only react in fullscreen mode
//.filter((e) => getFullScreenElement() !== element)
.each((e) => {
data.src = undefined;
data.alt = undefined;
})
) }
${ data.src ? include('#img-viewer', data) : '' }
${ include('#zoom-icon-thumb', data) }
${ include('#collections-thumb', data) }