init
This commit is contained in:
612
calendar/Events/EventDetails.js
Normal file
612
calendar/Events/EventDetails.js
Normal file
@@ -0,0 +1,612 @@
|
||||
import server from "/@server/server.js"
|
||||
import calendarUtil from "../calendarUtil.js"
|
||||
import "./EventForm.js"
|
||||
import "../../components/BottomSheet.js"
|
||||
import "../../components/BackButton.js"
|
||||
import "../../components/Avatar.js"
|
||||
|
||||
css(`
|
||||
eventdetails- {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
eventdetails- ::-webkit-scrollbar { display: none; width: 0; height: 0; }
|
||||
eventdetails- ::-webkit-scrollbar-thumb { background: transparent; }
|
||||
eventdetails- ::-webkit-scrollbar-track { background: transparent; }
|
||||
#eventdetails-toast-wrap {
|
||||
transition: max-height 0.25s ease, opacity 0.22s ease, padding-top 0.25s ease;
|
||||
}
|
||||
`)
|
||||
|
||||
class EventDetails extends Shadow {
|
||||
attachmentsOpen = false;
|
||||
selectedCalendars = [];
|
||||
_pendingCalendars = null;
|
||||
_prevCalendars = null;
|
||||
|
||||
constructor(calendars, event = null, onEventEdited = null, onEventDeleted = null) {
|
||||
super()
|
||||
this.calendars = calendars;
|
||||
this.event = event;
|
||||
this.onEventEdited = onEventEdited;
|
||||
this.onEventDeleted = onEventDeleted;
|
||||
this.selectedCalendars = calendars.filter(c => event?.calendars?.includes(c.id));
|
||||
}
|
||||
|
||||
render() {
|
||||
this.editSheet = BottomSheet(100) // separate sheet for the edit form, layered above this one
|
||||
|
||||
const isOwner = this.event?.creator_id === global.profile?.id;
|
||||
|
||||
VStack(() => {
|
||||
this.renderHeader(isOwner)
|
||||
|
||||
// ── Error toast ───────────────────────────────────────
|
||||
VStack(() => {
|
||||
p("")
|
||||
.attr({ id: "eventdetails-toast" })
|
||||
.margin(0)
|
||||
.padding("0.55em 1.1em")
|
||||
.background("var(--quillred)")
|
||||
.color("white")
|
||||
.fontSize(0.85, em)
|
||||
.fontWeight("500")
|
||||
.fontFamily("Arial")
|
||||
.borderRadius("0.5em")
|
||||
.boxShadow("0 2px 10px rgba(0,0,0,0.15)")
|
||||
.whiteSpace("nowrap")
|
||||
})
|
||||
.attr({ id: "eventdetails-toast-wrap" })
|
||||
.alignItems("center")
|
||||
.overflow("hidden")
|
||||
.maxHeight(0)
|
||||
.opacity(0)
|
||||
.flexShrink(0)
|
||||
|
||||
// ── Scrollable body ───────────────────────────────────
|
||||
VStack(() => {
|
||||
if (!this.event) return
|
||||
|
||||
// VStack(() => {}).height(0.85, em).flexShrink(0)
|
||||
|
||||
// ── Calendar / Location / Notes card ──────────────
|
||||
VStack(() => {
|
||||
|
||||
// Calendar row — tappable to expand
|
||||
HStack(() => {
|
||||
p("Calendar")
|
||||
.margin(0).fontSize(0.92, em).color("var(--headertext)").flexShrink(0)
|
||||
|
||||
HStack(() => {
|
||||
this.selectedCalendars.forEach(cal => {
|
||||
HStack(() => {
|
||||
p("").width(0.6, em).height(0.6, em)
|
||||
.background(cal.color)
|
||||
.borderRadius(50, pct)
|
||||
.flexShrink(0)
|
||||
p(cal.name)
|
||||
.margin(0)
|
||||
.fontSize(0.82, em)
|
||||
.fontWeight("600")
|
||||
.color("var(--text)")
|
||||
.whiteSpace("nowrap")
|
||||
})
|
||||
.gap(0.3, em)
|
||||
.alignItems("center")
|
||||
})
|
||||
})
|
||||
.attr({ id: "calendar-display" })
|
||||
.flex(1)
|
||||
.justifyContent("flex-end")
|
||||
.flexWrap("wrap")
|
||||
.gap(0.5, em)
|
||||
|
||||
let chevron = p("›")
|
||||
chevron
|
||||
.attr({ id: "cal-chevron" })
|
||||
.margin(0).opacity(0.3).fontSize(1.1, em).flexShrink(0)
|
||||
.transition("transform 0.25s ease")
|
||||
.state(chevron.parentElement, "open", function (value) {
|
||||
if(value === "true") {
|
||||
this.style.transform = "rotate(90deg)"
|
||||
} else {
|
||||
console.log("no trans")
|
||||
this.style.transform = ""
|
||||
}
|
||||
})
|
||||
})
|
||||
.attr({id: "calendar-row"})
|
||||
.paddingHorizontal(1, em).paddingVertical(0.78, em)
|
||||
.alignItems("center").gap(0.5, em)
|
||||
.borderBottom("1px solid var(--divider)").cursor("pointer")
|
||||
.onTap(function () {
|
||||
const isOpen = this.getAttribute("open") === "true"
|
||||
if (isOpen) {
|
||||
this.setAttribute("open", "false")
|
||||
} else {
|
||||
this.setAttribute("open", "true")
|
||||
}
|
||||
})
|
||||
|
||||
// Calendar Expandable List
|
||||
VStack(() => {
|
||||
this.calendars.forEach(cal => {
|
||||
const isSelected = this.selectedCalendars.some(c => c.id === cal.id)
|
||||
HStack(() => {
|
||||
HStack(() => {
|
||||
p("").width(0.65, em).height(0.65, em)
|
||||
.background(cal.color).borderRadius(50, pct).flexShrink(0)
|
||||
p(cal.name)
|
||||
.margin(0).fontSize(0.9, em).color("var(--text)").fontFamily("Arial")
|
||||
})
|
||||
.gap(0.45, em).alignItems("center").flex(1)
|
||||
|
||||
p("✓")
|
||||
.attr({ id: `cal-check-${cal.id}` })
|
||||
.margin(0).fontSize(0.88, em)
|
||||
.color("var(--quillred)").fontWeight("700")
|
||||
.display(isSelected ? "" : "none")
|
||||
})
|
||||
.paddingHorizontal(1.25, em).paddingVertical(0.72, em)
|
||||
.alignItems("center")
|
||||
.borderBottom("1px solid var(--divider)")
|
||||
.cursor("pointer")
|
||||
.onTap(() => {
|
||||
const prevCalendars = [...this.selectedCalendars]
|
||||
const i = this.selectedCalendars.findIndex(c => c.id === cal.id)
|
||||
if (i >= 0) {
|
||||
if (this.selectedCalendars.length > 1) {
|
||||
this.selectedCalendars.splice(i, 1)
|
||||
const check = this.$(`#cal-check-${cal.id}`)
|
||||
if (check) check.style.display = "none"
|
||||
}
|
||||
} else {
|
||||
this.selectedCalendars.push(cal)
|
||||
const check = this.$(`#cal-check-${cal.id}`)
|
||||
if (check) check.style.display = ""
|
||||
}
|
||||
this.updateCalendarDisplay()
|
||||
this.saveCalendars(prevCalendars)
|
||||
})
|
||||
})
|
||||
})
|
||||
.state(this.$("#calendar-row"), "open", function (value) {
|
||||
if(value === "false") {
|
||||
this.style.maxHeight = "0"
|
||||
} else {
|
||||
this.style.maxHeight = this.scrollHeight + "px"
|
||||
}
|
||||
})
|
||||
.attr({ id: "cal-picker"})
|
||||
.overflow("hidden").maxHeight(0)
|
||||
.transition("max-height 0.3s ease")
|
||||
|
||||
// Location row
|
||||
if (this.event.location) {
|
||||
HStack(() => {
|
||||
p("📍").margin(0).fontSize(0.85, em).flexShrink(0)
|
||||
p(this.event.location)
|
||||
.margin(0).fontSize(0.9, em).color("var(--text)").fontFamily("Arial")
|
||||
})
|
||||
.paddingHorizontal(1, em).paddingVertical(0.78, em)
|
||||
.alignItems("center").gap(0.65, em)
|
||||
.borderBottom("1px solid var(--divider)")
|
||||
}
|
||||
|
||||
// Notes row
|
||||
if (this.event.description) {
|
||||
HStack(() => {
|
||||
p("📝").margin(0).fontSize(0.85, em).flexShrink(0).alignSelf("flex-start").paddingTop(0.1, em)
|
||||
p(this.event.description)
|
||||
.margin(0).fontSize(0.9, em).color("var(--text)").fontFamily("Arial")
|
||||
.whiteSpace("pre-wrap").lineHeight("1.45")
|
||||
})
|
||||
.paddingHorizontal(1, em).paddingVertical(0.78, em)
|
||||
.alignItems("flex-start").gap(0.65, em)
|
||||
}
|
||||
})
|
||||
.background("var(--darkaccent)").border("1px solid var(--divider)")
|
||||
.borderRadius(12, px).marginHorizontal(1, em).overflow("hidden").flexShrink(0)
|
||||
|
||||
// ── Attachments card ──────────────────────────────
|
||||
if (this.event.attachments?.length > 0) {
|
||||
// VStack(() => {}).height(0.85, em).flexShrink(0)
|
||||
VStack(() => {
|
||||
HStack(() => {
|
||||
p("📎").margin(0).fontSize(0.85, em).flexShrink(0)
|
||||
p("Attachments")
|
||||
.margin(0).fontSize(0.92, em).color("var(--headertext)").flex(1)
|
||||
p("▼")
|
||||
.attr({ id: "attachments-chevron" })
|
||||
.margin(0).fontSize(0.7, em).color("var(--text)").opacity(0.5)
|
||||
.display("inline-block")
|
||||
.transition("transform 0.3s ease")
|
||||
.transform(this.attachmentsOpen ? "rotate(180deg)" : "rotate(0deg)")
|
||||
})
|
||||
.paddingHorizontal(1, em).paddingVertical(0.78, em)
|
||||
.alignItems("center").gap(0.65, em).cursor("pointer")
|
||||
.onTap(() => this.toggleAttachments())
|
||||
|
||||
VStack(() => {
|
||||
VStack(() => {
|
||||
this.event.attachments.forEach(file => this.renderFile(file))
|
||||
})
|
||||
.gap(0.75, em).width(100, pct)
|
||||
.padding("0 1em 0.75em").boxSizing("border-box")
|
||||
})
|
||||
.attr({ id: "attachments-content" })
|
||||
.overflow("hidden").maxHeight("0")
|
||||
.transition("max-height 0.5s ease")
|
||||
})
|
||||
.background("var(--darkaccent)").border("1px solid var(--divider)")
|
||||
.borderRadius(12, px).marginHorizontal(1, em).overflow("hidden").flexShrink(0)
|
||||
}
|
||||
})
|
||||
.overflowY("scroll").flex(1).minHeight(0).paddingTop(0.85, em).paddingBottom(1.5, em).gap(0.85, em)
|
||||
|
||||
// ── Footer: creator avatar + timestamps ───────────────
|
||||
if (this.event) {
|
||||
const members = global.currentNetwork.data?.members || []
|
||||
const creator = members.find(m => m.id === this.event.creator_id)
|
||||
if (creator) {
|
||||
HStack(() => {
|
||||
Avatar(creator, 2)
|
||||
VStack(() => {
|
||||
p(`Created ${calendarUtil.timeAgo(this.event.created)} by ${creator.first_name}`)
|
||||
.margin(0).fontSize(0.9, em).color("var(--headertext)").opacity(0.5)
|
||||
if (this.event.updated_at && this.event.updated_at !== this.event.created) {
|
||||
p(`Last updated ${calendarUtil.timeAgo(this.event.updated_at)}`)
|
||||
.margin(0).fontSize(0.9, em).color("var(--headertext)").opacity(0.4)
|
||||
}
|
||||
})
|
||||
.gap(0.15, em)
|
||||
})
|
||||
.paddingHorizontal(1, em)
|
||||
.paddingVertical(0.65, em)
|
||||
.alignItems("center")
|
||||
.gap(0.5, em)
|
||||
.flexShrink(0)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
.height(100, pct)
|
||||
}
|
||||
|
||||
renderHeader(isOwner) {
|
||||
VStack(() => {
|
||||
HStack(() => {
|
||||
BackButton(false, true, () => $("bottomsheet-").toggle())
|
||||
if (isOwner) {
|
||||
HStack(() => {
|
||||
// ── Delete button ─────────────────────────────────
|
||||
button("Delete")
|
||||
.attr({ type: "button" })
|
||||
.padding(0.4, rem)
|
||||
.fontSize(1.25, em)
|
||||
.boxSizing("border-box")
|
||||
.outline("none")
|
||||
.border("none")
|
||||
.background("transparent")
|
||||
.color("var(--quillred)")
|
||||
.onTap(() => this.handleDelete())
|
||||
|
||||
button("Edit")
|
||||
.padding(0.4, rem)
|
||||
.fontSize(1.25, em)
|
||||
.color("var(--darkaccent)")
|
||||
.boxSizing("border-box")
|
||||
.outline("none")
|
||||
.border("none")
|
||||
.zIndex(3)
|
||||
.onTap((e) => {
|
||||
e.preventDefault()
|
||||
let formEl
|
||||
const closeForm = () => {
|
||||
this.editSheet._closeOverride = null
|
||||
this.editSheet.setSheet(false)
|
||||
}
|
||||
const onSaveError = () => {
|
||||
this.editSheet._closeOverride = () => this.editSheet.forceClose()
|
||||
}
|
||||
this.editSheet.show(() => {
|
||||
// For override rows, attach template dates so scope='all' anchors correctly
|
||||
let eventForForm = this.event;
|
||||
if (this.event.recurrence_parent_id && !this.event._templateStart) {
|
||||
const template = global.currentNetwork.data.events.find(e => e.id === this.event.recurrence_parent_id);
|
||||
if (template) {
|
||||
eventForForm = {
|
||||
...this.event,
|
||||
_templateStart: new Date(template.time_start),
|
||||
_templateEnd: new Date(template.time_end)
|
||||
};
|
||||
}
|
||||
}
|
||||
formEl = EventForm(
|
||||
this.calendars,
|
||||
(updateResult) => {
|
||||
closeForm()
|
||||
const updatedEvent = updateResult?.scope ? updateResult.event : updateResult;
|
||||
this.event = { ...updatedEvent, time_start: new Date(updatedEvent.time_start), time_end: new Date(updatedEvent.time_end) }
|
||||
this.selectedCalendars = this.calendars.filter(c => updatedEvent.calendars?.includes(c.id))
|
||||
setTimeout(() => {
|
||||
this.onEventEdited(updateResult)
|
||||
this.rerender()
|
||||
}, 300)
|
||||
},
|
||||
eventForForm,
|
||||
closeForm,
|
||||
(deleteResult) => {
|
||||
closeForm()
|
||||
$("bottomsheet-").toggle()
|
||||
this.onEventDeleted(deleteResult)
|
||||
},
|
||||
null,
|
||||
onSaveError
|
||||
)
|
||||
})
|
||||
this.editSheet._closeOverride = () => {
|
||||
this.editSheet.setSheet(true)
|
||||
formEl?.handleBack()
|
||||
}
|
||||
})
|
||||
})
|
||||
.fontFamily("Arial")
|
||||
.cursor("pointer")
|
||||
.paddingHorizontal(0.8, rem)
|
||||
.gap(0.4, rem)
|
||||
}
|
||||
})
|
||||
.width(100, pct)
|
||||
.justifyContent("space-between")
|
||||
.alignItems("center")
|
||||
|
||||
VStack(() => {
|
||||
h2(this.event?.title ?? "")
|
||||
.color("var(--headertext)")
|
||||
.fontFamily("Arial")
|
||||
.margin(0)
|
||||
.fontSize(1.4, em)
|
||||
p(this.event ? calendarUtil.formatEventTime(this.event) : "")
|
||||
.margin(0)
|
||||
.color("var(--headertext)")
|
||||
.opacity(0.7)
|
||||
.fontSize(0.85, em)
|
||||
})
|
||||
.paddingHorizontal(1, em)
|
||||
.paddingBottom(1, em)
|
||||
.gap(0.3, em)
|
||||
.alignItems("flex-start")
|
||||
})
|
||||
.width(100, pct)
|
||||
.background(util.darkMode() ? "var(--darkred)" : "var(--sidebottombars)")
|
||||
.borderTopLeftRadius("10px").borderTopRightRadius("10px")
|
||||
.border("1px solid var(--divider)")
|
||||
.boxSizing("border-box").flexShrink(0)
|
||||
.alignItems("flex-start")
|
||||
}
|
||||
|
||||
updateCalendarDisplay() {
|
||||
const el = this.$("#calendar-display")
|
||||
if (!el) return
|
||||
el.innerHTML = this.selectedCalendars.map(cal => `
|
||||
<div style="display:flex;align-items:center;gap:0.3em;">
|
||||
<div style="width:0.6em;height:0.6em;background:${cal.color};border-radius:50%;flex-shrink:0;"></div>
|
||||
<p style="font-size:0.82em;font-weight:600;margin:0;color:var(--text);white-space:nowrap;">${cal.name}</p>
|
||||
</div>
|
||||
`).join('')
|
||||
}
|
||||
|
||||
showError(msg) {
|
||||
const wrap = this.$("#eventdetails-toast-wrap")
|
||||
const toast = this.$("#eventdetails-toast")
|
||||
if (!wrap || !toast) return
|
||||
clearTimeout(this._errorTimer)
|
||||
if (msg) {
|
||||
toast.innerText = msg
|
||||
wrap.style.maxHeight = "3em"
|
||||
wrap.style.opacity = "1"
|
||||
wrap.style.paddingTop = "0.85em"
|
||||
this._errorTimer = setTimeout(() => this.hideError(), 3500)
|
||||
} else {
|
||||
this.hideError()
|
||||
}
|
||||
}
|
||||
|
||||
hideError() {
|
||||
const wrap = this.$("#eventdetails-toast-wrap")
|
||||
if (!wrap) return
|
||||
clearTimeout(this._errorTimer)
|
||||
wrap.style.maxHeight = "0"
|
||||
wrap.style.opacity = "0"
|
||||
wrap.style.paddingTop = "0"
|
||||
}
|
||||
|
||||
saveCalendars(prevCalendars) {
|
||||
const event = this.event;
|
||||
const newCalendars = this.selectedCalendars.map(c => c.id);
|
||||
const isRecurring = !!(event._isOccurrence || event.recurrence_parent_id || event.recurrence_id);
|
||||
|
||||
this._prevCalendars = prevCalendars;
|
||||
this._pendingCalendars = newCalendars;
|
||||
|
||||
if (isRecurring) {
|
||||
$('actionsheetpopup-').show(
|
||||
"Edit Recurring Event",
|
||||
[
|
||||
{ label: "Edit just this event", onTap: () => this.performCalendarSave('single'), destructive: false },
|
||||
{ label: "Edit this and future events", onTap: () => this.performCalendarSave('future'), destructive: false },
|
||||
{ label: "Edit all events in series", onTap: () => this.performCalendarSave('all'), destructive: false },
|
||||
],
|
||||
() => {
|
||||
this._pendingCalendars = null;
|
||||
this._revertCalendars(prevCalendars);
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.performCalendarSave(null);
|
||||
}
|
||||
|
||||
_revertCalendars(prev) {
|
||||
this.selectedCalendars = prev;
|
||||
this.calendars.forEach(cal => {
|
||||
const check = this.$(`#cal-check-${cal.id}`);
|
||||
if (check) check.style.display = prev.some(c => c.id === cal.id) ? "" : "none";
|
||||
});
|
||||
this.updateCalendarDisplay();
|
||||
}
|
||||
|
||||
async performCalendarSave(scope) {
|
||||
const event = this.event;
|
||||
const newCalendars = this._pendingCalendars ?? this.selectedCalendars.map(c => c.id);
|
||||
this._pendingCalendars = null;
|
||||
const prevCalendars = this._prevCalendars;
|
||||
|
||||
try {
|
||||
if (scope) {
|
||||
const isOverride = !!event.recurrence_parent_id;
|
||||
const templateId = isOverride ? event.recurrence_parent_id : event.id;
|
||||
const occurrenceDate = isOverride
|
||||
? (event.recurrence_exception_date instanceof Date
|
||||
? event.recurrence_exception_date.toISOString()
|
||||
: event.recurrence_exception_date) ?? null
|
||||
: event._occurrenceDate?.toISOString() ?? null;
|
||||
const serverEventId = (scope === 'single' && isOverride) ? event.id : templateId;
|
||||
|
||||
const result = await server.editEvent(serverEventId, {
|
||||
title: event.title,
|
||||
description: event.description ?? null,
|
||||
location: event.location ?? null,
|
||||
time_start: event.time_start instanceof Date ? event.time_start.toISOString() : event.time_start,
|
||||
time_end: event.time_end instanceof Date ? event.time_end.toISOString() : event.time_end,
|
||||
all_day: event.all_day,
|
||||
calendars: newCalendars,
|
||||
scope,
|
||||
exception_date: occurrenceDate
|
||||
}, global.currentNetwork.id);
|
||||
|
||||
if (result.status === 200) {
|
||||
const editResult = {
|
||||
scope,
|
||||
event: { ...result.event, calendars: newCalendars, attachments: event.attachments ?? [] },
|
||||
templateId,
|
||||
occurrenceDate
|
||||
};
|
||||
this.event = { ...editResult.event, time_start: new Date(result.event.time_start), time_end: new Date(result.event.time_end) };
|
||||
this.selectedCalendars = this.calendars.filter(c => newCalendars.includes(c.id));
|
||||
this._prevCalendars = null;
|
||||
$("bottomsheet-")._closeOverride = null;
|
||||
this.onEventEdited(editResult);
|
||||
} else {
|
||||
this._revertCalendars(prevCalendars);
|
||||
this.showError(result.error ?? "Failed to update calendars.");
|
||||
$("bottomsheet-")._closeOverride = () => $("bottomsheet-").forceClose();
|
||||
}
|
||||
} else {
|
||||
const result = await server.editEvent(event.id, { ...event, calendars: newCalendars }, global.currentNetwork.id);
|
||||
if (result.status === 200) {
|
||||
this.event = { ...event, calendars: newCalendars };
|
||||
this._prevCalendars = null;
|
||||
$("bottomsheet-")._closeOverride = null;
|
||||
this.onEventEdited(this.event);
|
||||
} else {
|
||||
this._revertCalendars(prevCalendars);
|
||||
this.showError(result.error ?? "Failed to update calendars.");
|
||||
$("bottomsheet-")._closeOverride = () => $("bottomsheet-").forceClose();
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to update calendars:", err);
|
||||
this._revertCalendars(prevCalendars);
|
||||
this.showError("Failed to update calendars.");
|
||||
$("bottomsheet-")._closeOverride = () => $("bottomsheet-").forceClose();
|
||||
}
|
||||
}
|
||||
|
||||
handleDelete() {
|
||||
const event = this.event;
|
||||
const isRecurring = !!(event?._isOccurrence || event?.recurrence_parent_id || event?.recurrence_id);
|
||||
if (isRecurring) {
|
||||
$('actionsheetpopup-').show(
|
||||
"Delete Recurring Event",
|
||||
[
|
||||
{ label: "Delete just this event", onTap: () => this.performDelete('single') },
|
||||
{ label: "Delete this and future events", onTap: () => this.performDelete('future') },
|
||||
{ label: "Delete all events in series", onTap: () => this.performDelete('all') },
|
||||
],
|
||||
() => {}
|
||||
)
|
||||
return;
|
||||
}
|
||||
this.performDelete(null);
|
||||
}
|
||||
|
||||
async performDelete(scope) {
|
||||
const event = this.event;
|
||||
const isOverride = !!event.recurrence_parent_id;
|
||||
const templateId = isOverride ? event.recurrence_parent_id : event.id;
|
||||
const occurrenceDate = isOverride
|
||||
? (event.recurrence_exception_date instanceof Date
|
||||
? event.recurrence_exception_date.toISOString()
|
||||
: event.recurrence_exception_date) ?? null
|
||||
: event._occurrenceDate?.toISOString() ?? null;
|
||||
const serverEventId = (scope === 'single' && isOverride) ? event.id : templateId;
|
||||
|
||||
try {
|
||||
const result = await server.deleteEvent(serverEventId, global.currentNetwork.id, scope, occurrenceDate)
|
||||
if (result.status === 200) {
|
||||
$("bottomsheet-").toggle()
|
||||
const deleteResult = { scope: scope ?? 'all', templateId, occurrenceDate, overrideId: isOverride ? event.id : null };
|
||||
setTimeout(() => this.onEventDeleted(deleteResult), 300)
|
||||
} else {
|
||||
this.showError(result.error ?? "Failed to delete event.")
|
||||
$("bottomsheet-")._closeOverride = () => $("bottomsheet-").forceClose()
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to delete event:", err)
|
||||
this.showError("Failed to delete event.")
|
||||
$("bottomsheet-")._closeOverride = () => $("bottomsheet-").forceClose()
|
||||
}
|
||||
}
|
||||
|
||||
renderFile(file) {
|
||||
const isImage = file.type?.startsWith("image/");
|
||||
const url = `${config.SERVER}/db/images/events/${file.name}`;
|
||||
|
||||
if (isImage) {
|
||||
img(url, "100%", "100%")
|
||||
.borderRadius(8, px).display("block").boxSizing("border-box")
|
||||
.cursor("pointer")
|
||||
.onTap(() => $("filepreview-")?.open(file, url))
|
||||
} else {
|
||||
HStack(() => {
|
||||
p("📎").margin(0).fontSize(1, em)
|
||||
p(file.original_name ?? file.name)
|
||||
.margin(0).color("var(--text)").fontSize(0.9, em)
|
||||
.overflow("hidden").whiteSpace("nowrap").textOverflow("ellipsis")
|
||||
})
|
||||
.gap(0.5, em).alignItems("center")
|
||||
.padding(0.5, em)
|
||||
.background("var(--searchbackground)")
|
||||
.borderRadius(8, px).boxSizing("border-box")
|
||||
.cursor("pointer")
|
||||
.onTap(() => $("filepreview-")?.open(file, url))
|
||||
}
|
||||
}
|
||||
|
||||
toggleAttachments() {
|
||||
this.attachmentsOpen = !this.attachmentsOpen;
|
||||
const content = this.$("#attachments-content");
|
||||
const chevron = this.$("#attachments-chevron");
|
||||
if (content) content.style.maxHeight = this.attachmentsOpen ? content.scrollHeight + "px" : "0";
|
||||
if (chevron) chevron.style.transform = this.attachmentsOpen ? "rotate(180deg)" : "rotate(0deg)";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
register(EventDetails)
|
||||
Reference in New Issue
Block a user