Skip to content

Commit ad7ec7a

Browse files
committed
feat: highlight/show currently running session
Fixes #1
1 parent 4d5aeb7 commit ad7ec7a

6 files changed

+101
-40
lines changed

e2e-tests/browserWithFixedTime.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { BrowserContext, chromium } from '@playwright/test'
2+
import path from 'path'
3+
import sinon from 'sinon'
4+
5+
export const browserWithFixedTime = async (): Promise<BrowserContext> => {
6+
const browser = await chromium.launch()
7+
const context = await browser.newContext({
8+
locale: 'no-NO',
9+
timezoneId: 'Europe/Berlin',
10+
})
11+
// See https://github.com/microsoft/playwright/issues/6347#issuecomment-965887758
12+
await context.addInitScript({
13+
path: path.join(process.cwd(), 'node_modules/sinon/pkg/sinon.js'),
14+
})
15+
// Auto-enable sinon right away
16+
// and enforce our "current" date
17+
await context.addInitScript(() => {
18+
const clock = sinon.useFakeTimers()
19+
clock.setSystemTime(new Date('2022-03-11T12:00:00Z'))
20+
;(window as any).__clock = clock
21+
})
22+
23+
return context
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { expect, test } from '@playwright/test'
2+
import { browserWithFixedTime } from './browserWithFixedTime.js'
3+
4+
test.describe('Highlight ongoing session', () => {
5+
test('the currently ongoing session should be highlighted', async () => {
6+
const context = await browserWithFixedTime()
7+
const page = await context.newPage()
8+
await page.goto('http://localhost:8080/')
9+
await expect(
10+
page.locator('td:has-text("Lunch Break") >> xpath=ancestor::tr'),
11+
).toHaveClass('ongoing')
12+
// There should only be one highlighted row
13+
await expect(page.locator('tr.ongoing')).toHaveCount(1)
14+
})
15+
})

e2e-tests/example.spec.ts e2e-tests/session-in-local-time.spec.ts

+3-19
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,10 @@
1-
import { BrowserContext, chromium, expect, test } from '@playwright/test'
2-
import path from 'path'
3-
import sinon from 'sinon'
1+
import { BrowserContext, expect, test } from '@playwright/test'
2+
import { browserWithFixedTime } from './browserWithFixedTime.js'
43

54
test.describe('Adding an item', () => {
65
let context: BrowserContext
76
test.beforeAll(async () => {
8-
const browser = await chromium.launch() // Or 'firefox' or 'webkit'.
9-
context = await browser.newContext({
10-
locale: 'no-NO',
11-
timezoneId: 'Europe/Berlin',
12-
})
13-
// See https://github.com/microsoft/playwright/issues/6347#issuecomment-965887758
14-
await context.addInitScript({
15-
path: path.join(process.cwd(), 'node_modules/sinon/pkg/sinon.js'),
16-
})
17-
// Auto-enable sinon right away
18-
// and enforce our "current" date
19-
await context.addInitScript(() => {
20-
const clock = sinon.useFakeTimers()
21-
clock.setSystemTime(new Date('2022-03-11T12:00:00Z'))
22-
;(window as any).__clock = clock
23-
})
7+
context = await browserWithFixedTime()
248
})
259

2610
test('should allow me to add todo items', async () => {

public/theme.css

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ html[data-theme="dark"] {
77
--color-countdownWarning: #ff5e007a;
88
--color-borderColor: #7d7d7d;
99
--filter-calendar-picker-indicator: invert(1);
10+
--color-ongoing: #007500;
1011
}
1112

1213
html[data-theme="light"] {
@@ -17,6 +18,7 @@ html[data-theme="light"] {
1718
--color-delete: #dc2000;
1819
--color-countdownWarning: #ff000052;
1920
--color-borderColor: #a7a7a7;
21+
--color-ongoing: #7cff7c;
2022
}
2123

2224
body {

src/Schedule.tsx

+53-21
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ const diff = (startTime: Date, conferenceDate: Date) => {
1515
// If difference is > 1 day
1616
// show distance in days to conference start, so all entries have the same difference
1717
const daysDistance = differenceInCalendarDays(conferenceDate, now)
18-
return daysDistance > 1 ? `about ${daysDistance} days` : 'about 1 day'
18+
return daysDistance > 1 ? `${daysDistance} days` : '1 day'
1919
}
20-
return formatDistance(startTime, now)
20+
return formatDistance(startTime, now).replace('about ', '')
2121
}
2222

2323
const startsInMinutes = (startTime: Date) => {
@@ -78,6 +78,16 @@ export const Schedule = ({
7878
const eventTime = toEventTime({ conferenceDate, userTimeZone })
7979
const userTime = toUserTime({ conferenceDate, eventTimezoneName })
8080
const userFormat = formatUserTime({ userTimeZone })
81+
const [currentTime, setCurrentTime] = useState<Date>(new Date())
82+
83+
useEffect(() => {
84+
const i = setInterval(() => {
85+
setCurrentTime(new Date())
86+
}, 60 * 1000)
87+
return () => {
88+
clearInterval(i)
89+
}
90+
}, [])
8191

8292
return (
8393
<table className={tableStyles.Table}>
@@ -91,7 +101,9 @@ export const Schedule = ({
91101
<th>
92102
Your Time
93103
<br />
94-
<small>{formatTimezone(userTimeZone)}</small>
104+
<small>
105+
{formatTimezone(userTimeZone)} ({userFormat(currentTime)})
106+
</small>
95107
</th>
96108
<th>Starts in</th>
97109
<th>Session</th>
@@ -104,24 +116,44 @@ export const Schedule = ({
104116
!hidePastSessions ||
105117
startsInMinutes(userTime(time as unknown as number)) > 0,
106118
)
107-
.map(([time, name]) => (
108-
<tr key={time}>
109-
<td className={'time'}>
110-
{formatEventTime(eventTime(time as unknown as number))}
111-
</td>
112-
<td className={'time'}>
113-
{userFormat(userTime(time as unknown as number))}
114-
</td>
115-
<Countdown
116-
key={conferenceDate}
117-
conferenceDate={userTime(0)}
118-
startTime={userTime(time as unknown as number)}
119-
/>
120-
<td>
121-
<SessionName name={name} />
122-
</td>
123-
</tr>
124-
))}
119+
.map(([time, name], i, sessions) => {
120+
const nextIsOngoing =
121+
sessions[i + 1] !== undefined
122+
? startsInMinutes(
123+
userTime(sessions[i + 1][0] as unknown as number),
124+
) < 0
125+
: false
126+
127+
const isOngoing =
128+
startsInMinutes(userTime(time as unknown as number)) < 0 &&
129+
!nextIsOngoing
130+
131+
return (
132+
<tr key={time} className={isOngoing ? 'ongoing' : ''}>
133+
<td className={'time'}>
134+
{formatEventTime(eventTime(time as unknown as number))}
135+
</td>
136+
<td className={'time'}>
137+
{userFormat(userTime(time as unknown as number))}
138+
</td>
139+
{isOngoing && (
140+
<td>
141+
<em>ongoing</em>
142+
</td>
143+
)}
144+
{!isOngoing && (
145+
<Countdown
146+
key={conferenceDate}
147+
conferenceDate={userTime(0)}
148+
startTime={userTime(time as unknown as number)}
149+
/>
150+
)}
151+
<td>
152+
<SessionName name={name} />
153+
</td>
154+
</tr>
155+
)
156+
})}
125157
</tbody>
126158
</table>
127159
)

src/Table.module.css

+4
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@
5757
.Table a {
5858
color: var(--color-text);
5959
}
60+
61+
.Table tr:global(.ongoing) {
62+
background-color: var(--color-ongoing);
63+
}

0 commit comments

Comments
 (0)