Skip to content

Commit

Permalink
time zone management (#62)
Browse files Browse the repository at this point in the history
* temp fix: convert date with a custom time zone

* feat: settings to change timezone

* Update calendar.js
  • Loading branch information
kernoeb authored Jan 19, 2024
1 parent 2641dbc commit 9e278bd
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 6 deletions.
64 changes: 63 additions & 1 deletion components/DialogSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,45 @@

<v-divider />

<v-subheader
class="mt-3"
style="height: 20px"
>
Utiliser une timezone personnalisée
</v-subheader>
<v-list-item
inactive
:ripple="false"
class="mb-2"
>
<v-list-item-content class="pt-0">
<div class="d-flex flex-row">
<v-text-field
v-model="localeUtils.oldTZ"
hide-details
placeholder="Europe/Paris"
class="mr-2"
@change="$nextTick(() => updateLocaleUtils({oldTZ: $event || null, newTZ: localeUtils.newTZ || null}))"
/>
<v-icon
small
:disabled="!localeUtils.oldTZ"
class="align-self-end mr-2"
>
{{ mdiArrowRightCircleOutline }}
</v-icon>
<v-text-field
v-model="localeUtils.newTZ"
hide-details
placeholder="America/New_York"
@change="$nextTick(() => updateLocaleUtils({oldTZ: localeUtils.oldTZ || null, newTZ: $event || null}))"
/>
</div>
</v-list-item-content>
</v-list-item>

<v-divider />

<div>
<v-subheader>FAQ / Aide</v-subheader>
<lazy-help-info style="width: 98%;" />
Expand Down Expand Up @@ -304,7 +343,7 @@
</template>

<script>
import { mdiClose, mdiCheckboxBlankOutline, mdiCheckboxMarked, mdiCogOutline, mdiMail, mdiMenuDown, mdiTwitter } from '@mdi/js'
import { mdiClose, mdiCheckboxBlankOutline, mdiCheckboxMarked, mdiCogOutline, mdiMail, mdiMenuDown, mdiTwitter, mdiArrowRightCircleOutline } from '@mdi/js'
export default {
name: 'DialogSettings',
Expand Down Expand Up @@ -332,10 +371,13 @@ export default {
mdiCheckboxBlankOutline,
mdiCheckboxMarked,
mdiClose,
mdiArrowRightCircleOutline,
blocklist: ['Maths', 'Communication', 'Férié'], // Oui, bon...
blocklistSelect: [],
localeUtils: {},
colorTP: '#bbe0ff',
colorTD: '#d4fbcc',
colorAmphi: '#efd6d8',
Expand Down Expand Up @@ -421,6 +463,19 @@ export default {
if (c.other) this.colorOthers = c.other
} catch (err) {}
if (this.$cookies.get('locale-utils') !== undefined) {
try {
const tmp = this.$cookies.get('locale-utils', { parseJSON: true })
if (tmp && Object.keys(tmp).length > 0 && tmp.oldTZ && tmp.newTZ) {
this.localeUtils = tmp
} else {
this.$cookies.remove('locale-utils')
}
} catch (e) {
this.$cookies.remove('locale-utils')
}
}
try {
const highlightTeacher = this.$cookies.get('highlightTeacher', { parseJSON: true })
if (typeof highlightTeacher === 'boolean') this.highlightTeacher = highlightTeacher
Expand Down Expand Up @@ -471,6 +526,13 @@ export default {
} catch (err) {
}
},
updateLocaleUtils (event) {
try {
this.$cookies.set('locale-utils', JSON.stringify(event), { maxAge: 2147483646 })
if ((event.oldTZ && event.newTZ) || (!event.oldTZ && !event.newTZ)) this.delayedFetch()
} catch (err) {
}
},
setColor (type, color) {
try {
const tmpCookie = this.$cookies.get('customColorList') || {}
Expand Down
14 changes: 12 additions & 2 deletions server/routes/calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ router.get('/calendars', asyncWrapper(async (req, res) => {
if (Object.keys(customColorList).length === 0) customColorList = null
} catch (e) {}

// Get custom timezone and locale
let localeUtils = null
try {
if (req.cookies?.['locale-utils']) {
const { oldTZ, newTZ } = JSON.parse(req.cookies['locale-utils'])
if (oldTZ && newTZ) localeUtils = { oldTZ, newTZ }
}
} catch (e) {
}

// Highlight courses with teachers
let highlightTeacher = false
try {
Expand All @@ -68,7 +78,7 @@ router.get('/calendars', asyncWrapper(async (req, res) => {
status: 'ok',
title: allPlannings[id].title,
timestamp: new Date().toISOString(),
events: getFormattedEvents({ data: fetched, blocklist, colors: customColorList, highlightTeacher })
events: getFormattedEvents({ data: fetched, blocklist, colors: customColorList, localeUtils, highlightTeacher })
}
} else {
const backed = await getBackedPlanning(id)
Expand All @@ -78,7 +88,7 @@ router.get('/calendars', asyncWrapper(async (req, res) => {
status: 'backup',
title: allPlannings[id].title,
timestamp: backed.timestamp || undefined,
events: getFormattedEvents({ data: backed.backup, blocklist, colors: customColorList, highlightTeacher })
events: getFormattedEvents({ data: backed.backup, blocklist, colors: customColorList, localeUtils, highlightTeacher })
}
} else {
return { id, title: allPlannings[id].title, status: 'off' }
Expand Down
25 changes: 22 additions & 3 deletions server/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { Planning } = require('../models/planning')
const { CustomEvent } = require('../models/customevent')
const http = require('./http')
const logger = require('./signale')
const { DateTime } = require('luxon')

const dateStartTemplate = '{date-start}'
const dateEndTemplate = '{date-end}'
Expand Down Expand Up @@ -84,6 +85,23 @@ const cleanName = (name) => {
return (name && name.replace(/([A-Za-z])\?([A-Za-z])/gi, (_, b, c) => b + "'" + c).trim()) || ''
}

/**
* Get date
* @param {Date} date
* @param {{newTZ: string, oldTZ: string}|null} localeUtils
* @returns {number}
*/
const getDate = (date, localeUtils) => {
if (!localeUtils || !localeUtils.oldTZ || !localeUtils.newTZ) return date.getTime() // default behavior
try {
const tmpDate = DateTime.fromJSDate(date, { zone: localeUtils.oldTZ }).setZone(localeUtils.newTZ, { keepLocalTime: true }).toMillis()
if (!isNaN(tmpDate)) return tmpDate
return date.getTime()
} catch (err) {
return date.getTime()
}
}

module.exports = {
/**
* Get custom events for a planning
Expand Down Expand Up @@ -117,17 +135,18 @@ module.exports = {
* @param {object} j
* @param {string[]} blocklist
* @param {object} colors
* @param {object|null} localeUtils
* @param {boolean} highlightTeacher
* @returns {[]}
*/
getFormattedEvents: ({ data: j, blocklist, colors, highlightTeacher }) => {
getFormattedEvents: ({ data: j, blocklist, colors, localeUtils, highlightTeacher }) => {
const events = []
for (const i of j.events || j) {
if (!blocklist.some(str => i.summary.value.toUpperCase().includes(str))) {
events.push({
name: cleanName(i.summary.value),
start: new Date(i.dtstart.value).getTime(),
end: new Date(i.dtend.value).getTime(),
start: getDate(new Date(i.dtstart.value), localeUtils),
end: getDate(new Date(i.dtend.value), localeUtils),
color: getColor(i.summary.value, i.location.value, i.description.value, { customColor: colors, highlightTeacher }),
location: cleanLocation(i.location.value),
description: cleanDescription(i.description.value),
Expand Down

0 comments on commit 9e278bd

Please sign in to comment.