Skip to content

Commit

Permalink
Add alarms (reminder)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaylinski committed Aug 26, 2024
1 parent 72c94da commit 7a55bb7
Show file tree
Hide file tree
Showing 13 changed files with 1,492 additions and 25 deletions.
6 changes: 0 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"color-convert": "^2.0.1",
"debounce": "^2.1.0",
"ical.js": "^2.0.1",
"jstimezonedetect": "",
"linkify-it": "^5.0.0",
"markdown-it": "^14.1.0",
"markdown-it-emoji": "^3.0.0",
Expand Down
165 changes: 165 additions & 0 deletions src/components/AppSidebar/Alarm/AlarmList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<!--
- SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<template>
<div class="component">
<div class="component__icon">
<slot name="icon" />
</div>
<div class="component__items">
<AlarmListItem v-for="(alarm, index) in alarmComponents"
:key="index"
:alarm="alarm"
:is-read-only="readOnly"
@remove-alarm="removeAlarm" />
<div class="new">
<div>
<p v-if="alarms.length === 0">
{{ t('tasks', 'No reminders') }}
</p>
</div>
<AlarmListNew v-if="!readOnly"
:has-start-date="hasStartDate"
:has-due-date="hasDueDate"
:is-all-day="allDay"
@add-alarm="addAlarm" />
</div>
</div>
</div>
</template>

<script>
import AlarmListNew from './AlarmListNew.vue'
import AlarmListItem from './AlarmListItem.vue'
import { mapAlarmComponentToAlarmObject } from '../../../models/alarm.js'

import { translate as t } from '@nextcloud/l10n'
import { AlarmComponent } from '@nextcloud/calendar-js'
import ICAL from 'ical.js'

export default {
name: 'AlarmList',
components: {
AlarmListItem,
AlarmListNew,
},
props: {
hasStartDate: {
type: Boolean,
required: true,
},
hasDueDate: {
type: Boolean,
required: true,
},
readOnly: {
type: Boolean,
required: true,
},
allDay: {
type: Boolean,
required: true,
},
alarms: {
type: Array,
required: true,
},
},
emits: [
'add-alarm',
],
computed: {
alarmComponents() {
return this.alarms.map((alarm) => {
try {
return mapAlarmComponentToAlarmObject(AlarmComponent.fromICALJs(alarm))
} catch (e) {
// Instead of breaking the whole page when parsing an invalid alarm,
// we just print a warning on the console.
console.warn(e)
}
}).filter(Boolean)
},
},
methods: {
t,

/**
* Adds another of the default alarms to the event
*
* @param {object} alarm The alarm time or duration
* @param {number|Date} alarm.value Value of the trigger
* @param {object|undefined} alarm.parameter Name and value of the trigger parameter
*/
addAlarm({ value, parameter }) {
const valarm = {
action: 'DISPLAY',
repeat: 1,
trigger: { value: undefined, parameter },
}

if (typeof value === 'number') {
valarm.trigger.value = ICAL.Duration.fromSeconds(value)
} else if (value instanceof Date) {
valarm.trigger.value = ICAL.Time.fromJSDate(value, true)
}

this.$emit('add-alarm', valarm)
},
/**
* Removes an alarm from this event
*
* @param {object} alarm The alarm object
*/
removeAlarm(alarm) {
console.debug('remove ', alarm)
// TODO Implement
},
},
}
</script>

<style lang="scss" scoped>
.component {
display: flex;
border-bottom: 1px solid var(--color-border);
width: 100%;
color: var(--color-text-lighter);

.component {
&__icon {
display: flex;
height: 44px;
width: 44px;
min-width: 44px;
justify-content: center;

.material-design-icon__svg {
vertical-align: middle;
}
}

&__items {
display: flex;
flex-direction: column;
flex-grow: 1;
gap: 4px;
padding-inline-end: 4px;
padding-block: 4px;
overflow: auto;
text-overflow: ellipsis;
white-space: nowrap;

.new {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding-block: 2px;
}
}
}
}
</style>
Loading

0 comments on commit 7a55bb7

Please sign in to comment.