Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
37 changes: 37 additions & 0 deletions src/components/ConversationSettings/LobbySettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
:input-class="['mx-input', { focusable: !lobbyTimerFieldDisabled }]"
v-bind="dateTimePickerAttrs"
@change="saveLobbyTimer" />
<div class="lobby_timer--timezone">
{{ getTimeZone }}
</div>
<div v-if="showRelativeTime" class="lobby_timer--relative">
{{ getRelativeTime }}
</div>
</form>
</div>
</div>
Expand All @@ -64,6 +70,9 @@ import NcDateTimePicker from '@nextcloud/vue/dist/Components/NcDateTimePicker.js
import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'

import { WEBINAR } from '../../constants.js'
import { futureRelativeTime } from '../../utils/formattedTime.ts'

const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000

export default {
name: 'LobbySettings',
Expand Down Expand Up @@ -140,6 +149,24 @@ export default {
valueType: 'timestamp',
}
},

showRelativeTime() {
return this.lobbyTimer
&& this.lobbyTimer > Date.now()
&& (this.lobbyTimer - Date.now()) < ONE_DAY_IN_MS // less than 24 hours
},

getTimeZone() {
if (!this.lobbyTimer) {
return ''
}
const date = new Date(this.lobbyTimer)
return t('spreed', `Start time: ${date}`)
Copy link
Member

Choose a reason for hiding this comment

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

This is illegal... It will always be english and never translated.

return t('spreed', 'Start time: {date}', { date })

},

getRelativeTime() {
return futureRelativeTime(this.lobbyTimer)
},
},

methods: {
Expand Down Expand Up @@ -189,6 +216,16 @@ export default {
</script>

<style lang="scss" scoped>

.lobby_timer {
&--relative {
color: var(--color-text-maxcontrast);
}
&--timezone {
padding-top: 4px;
}
}

:deep(.mx-input) {
margin: 0;
}
Expand Down
7 changes: 4 additions & 3 deletions src/components/LobbyScreen.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
<p v-if="countdown"
class="lobby__countdown">
{{ message }} -
<span class="lobby__countdown live-relative-timestamp"
:data-timestamp="countdown * 1000"
<span class="lobby__countdown relative-timestamp"
:title="startTime">
{{ relativeDate }}
</span>
Expand All @@ -60,6 +59,8 @@ import NcRichText from '@nextcloud/vue/dist/Components/NcRichText.js'
import GuestWelcomeWindow from './GuestWelcomeWindow.vue'
import SetGuestUsername from './SetGuestUsername.vue'

import { futureRelativeTime } from '../utils/formattedTime.ts'

export default {

name: 'LobbyScreen',
Expand Down Expand Up @@ -94,7 +95,7 @@ export default {
if (diff > -45000 && diff < 45000) {
return t('spreed', 'The meeting will start soon')
}
return this.timerInMoment.fromNow()
return futureRelativeTime(this.timerInMoment.valueOf())
},

timerInMoment() {
Expand Down
31 changes: 30 additions & 1 deletion src/utils/__tests__/formattedTime.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { formattedTime } from '../formattedTime.ts'
import { formattedTime, futureRelativeTime } from '../formattedTime.ts'

const TIME = (61 * 60 + 5) * 1000 // 1 hour, 1 minute, 5 seconds in ms

Expand All @@ -17,3 +17,32 @@ describe('formattedTime', () => {
expect(resultCondensed).toBe('--:--')
})
})

describe('futureRelativeTime', () => {
const fixedDate = new Date('2024-01-01T00:00:00Z')
jest.spyOn(Date, 'now').mockImplementation(() => fixedDate.getTime())

it('should return the correct string for time in hours', () => {
const timeInFuture = Date.now() + (2 * 60 * 60 * 1000) // 2 hours from now
const result = futureRelativeTime(timeInFuture)
expect(result).toBe('In 2 hours')
})

it('should return the correct string for time in minutes', () => {
const timeInFuture = Date.now() + (30 * 60 * 1000) // 30 minutes from now
const result = futureRelativeTime(timeInFuture)
expect(result).toBe('In 30 minutes')
})

it('should return the correct string for time in hours and minutes', () => {
const timeInFuture = Date.now() + (2 * 60 * 60 * 1000) + (15 * 60 * 1000) // 2 hours and 15 minutes from now
const result = futureRelativeTime(timeInFuture)
expect(result).toBe('In 2 hours and 15 minutes')
})

it('should return the correct string for 1 hour and minutes', () => {
const timeInFuture = Date.now() + (60 * 60 * 1000) + (15 * 60 * 1000) // 1 hour and 15 minutes from now
const result = futureRelativeTime(timeInFuture)
expect(result).toBe('In 1 hour and 15 minutes')
})
})
27 changes: 27 additions & 0 deletions src/utils/formattedTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,33 @@ function formattedTime(time: number, condensed: boolean = false): string {
].filter(num => !!num).join(condensed ? ':' : ' : ')
}

/**
* Calculates the future relative time string given the time (ms)
*
* @param time the time in ms
*/
function futureRelativeTime(time: number): string {
const diff = time - Date.now()
const hours = Math.floor(diff / (60 * 60 * 1000))
const minutes = Math.floor((diff - hours * 60 * 60 * 1000) / (60 * 1000))
if (hours >= 1) {
if (minutes === 0) {
// TRANSLATORS: hint for the time when the meeting starts (only hours)
return n('spreed', 'In %n hour', 'In %n hours', hours)
} else {
// TRANSLATORS: hint for the time when the meeting starts (hours and minutes)
return t('spreed', 'In {hours} and {minutes}', {
hours: n('spreed', '%n hour', '%n hours', hours),
minutes: n('spreed', '%n minute ', '%n minutes', minutes),
})
}
} else {
// TRANSLATORS: hint for the time when the meeting starts (only minutes)
return n('spreed', 'In %n minute', 'In %n minutes', minutes)
}
}

export {
formattedTime,
futureRelativeTime,
}