Skip to content
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

feat: Agenda URL #hash scrolls to 'now' or specific day #7772

Merged
merged 14 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion client/agenda/Agenda.vue
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ function reconnectScrollObservers () {
scrollObserver.disconnect()
visibleDays.length = 0
for (const mDay of agendaStore.meetingDays) {
const el = document.getElementById(`agenda-day-${mDay.slug}`)
const el = document.getElementById(mDay.slug)
el.dataset.dayId = mDay.slug.toString()
el.dataset.dayTs = mDay.ts
scrollObserver.observe(el)
Expand Down
29 changes: 25 additions & 4 deletions client/agenda/AgendaQuickAccess.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
li.nav-item(v-for='day of agendaStore.meetingDays')
a.nav-link(
:class='agendaStore.dayIntersectId === day.slug ? `active` : ``'
:href='`#slot-` + day.slug'
:href='`#${day.slug}`'
@click='scrollToDay(day.slug, $event)'
)
i.bi.bi-arrow-right-short.d-none.d-xxl-inline.me-2
Expand All @@ -119,7 +119,7 @@ import {
useMessage
} from 'naive-ui'

import { useAgendaStore } from './store'
import { useAgendaStore, daySlugPrefix } from './store'
import { useSiteStore } from '../shared/store'
import { getUrl } from '../shared/urls'

Expand Down Expand Up @@ -206,8 +206,6 @@ function scrollToDay (dayId, ev) {
}

function scrollToNow (ev) {
ev.preventDefault()
Copy link
Contributor Author

@holloway holloway Jul 31, 2024

Choose a reason for hiding this comment

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

Removed so that when clicking 'Now' <a href="#now">Now</a>
Screenshot from 2024-08-01 10-52-50

...it will update the browser location with #now so that future reloads will have a hashstate that expresses 'Now'


const lastEventId = agendaStore.findCurrentEventId()

if (lastEventId) {
Expand All @@ -217,6 +215,29 @@ function scrollToNow (ev) {
}
}

/**
* On page load when browser location hash contains '#now' or '#agenda-day-*' then scroll accordingly
*/
(function scrollToHashInit() {
if (!window.location.hash) {
return
}
if (!(window.location.hash === "#now" || window.location.hash.startsWith(`#${daySlugPrefix}`))) {
return
}
const unsubscribe = agendaStore.$subscribe((_mutation, agendaStoreState) => {
if (agendaStoreState.schedule.length === 0) {
return
}
unsubscribe() // we only need to scroll once, so unsubscribe from future updates
if(window.location.hash === "#now") {
scrollToNow()
} else if(window.location.hash.startsWith(`#${daySlugPrefix}`)) {
document.getElementById(window.location.hash.substring(1))?.scrollIntoView(true)
}
})
})()

</script>

<style lang="scss">
Expand Down
5 changes: 3 additions & 2 deletions client/agenda/AgendaScheduleList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
)
//- ROW - DAY HEADING -----------------------
template(v-if='item.displayType === `day`')
td(:id='`agenda-day-` + item.id', :colspan='pickerModeActive ? 6 : 5') {{item.date}}
td(:id='item.slug', :colspan='pickerModeActive ? 6 : 5') {{item.date}}
//- ROW - SESSION HEADING -------------------
template(v-else-if='item.displayType === `session-head`')
td.agenda-table-cell-check(v-if='pickerModeActive') &nbsp;
Expand Down Expand Up @@ -200,7 +200,7 @@ import {

import AgendaDetailsModal from './AgendaDetailsModal.vue'

import { useAgendaStore } from './store'
import { useAgendaStore, daySlug } from './store'
import { useSiteStore } from '../shared/store'
import { getUrl } from '../shared/urls'

Expand Down Expand Up @@ -248,6 +248,7 @@ const meetingEvents = computed(() => {
if (itemDate.toISODate() !== acc.lastDate) {
acc.result.push({
id: item.id,
slug: daySlug(item),
key: `day-${itemDate.toISODate()}`,
displayType: 'day',
date: itemDate.toLocaleString(DateTime.DATE_HUGE),
Expand Down
30 changes: 29 additions & 1 deletion client/agenda/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export const useAgendaStore = defineStore('agenda', {
meetingDays () {
const siteStore = useSiteStore()
return uniqBy(this.scheduleAdjusted, 'adjustedStartDate').sort().map(s => ({
slug: s.id.toString(),
slug: daySlug(s),
ts: s.adjustedStartDate,
label: siteStore.viewport < 1350 ? DateTime.fromISO(s.adjustedStartDate).toFormat('ccc LLL d') : DateTime.fromISO(s.adjustedStartDate).toLocaleString(DateTime.DATE_HUGE)
}))
Expand Down Expand Up @@ -154,6 +154,29 @@ export const useAgendaStore = defineStore('agenda', {
this.timezone = agendaData.meeting.timezone
}

// The following is for developers to modify `agendaData` dates to match
// your current system time so that features depending on an overlap of times
// such as the 'Now' button and red divider are available.
// This should be commented out when not in
// (function(){
holloway marked this conversation as resolved.
Show resolved Hide resolved
// if (location.hostname !== "localhost") {
// console.log(`Not modifying \`agendaData\` because we're not on localhost: ${location.host}`)
// return
// }
// const originalStartDateMs = new Date(agendaData.meeting.startDate).getTime()
// const oneDayInMilliseconds = 24 * 60 * 60 * 1000
// const startDate = new Date(Date.now() - (2 * oneDayInMilliseconds))
// agendaData.meeting.startDate = `${startDate.getFullYear()}-${("00" + (startDate.getMonth() + 1)).slice (-2)}-${startDate.getDate()}`
// const startDateDifferenceMs = new Date(agendaData.meeting.startDate).getTime() - originalStartDateMs
// const endDate = new Date(Date.now() + (5 * oneDayInMilliseconds))
// agendaData.meeting.endDate = `${endDate.getFullYear()}-${("00" + (endDate.getMonth() + 1)).slice (-2)}-${endDate.getDate()}`
// agendaData.schedule = agendaData.schedule.map(schedule => ({
// ...schedule,
// startDateTime: new Date(new Date(schedule.startDateTime).getTime() + startDateDifferenceMs).toISOString()
// }))
// console.log("Server `agendaData` has dates modified for your system time. This should not be done in prod.", agendaData)
// }())

// -> Load meeting data
this.categories = agendaData.categories
this.floors = agendaData.floors
Expand Down Expand Up @@ -292,3 +315,8 @@ function findFirstConferenceUrl (txt) {
} catch (err) { }
return null
}

export const daySlugPrefix = 'agenda-day-'
export function daySlug(s) {
return `${daySlugPrefix}${s.adjustedStartDate}` // eg 'agenda-day-2024-08-13'
}
Loading