105 lines
2.2 KiB
Go
105 lines
2.2 KiB
Go
package models
|
|
|
|
import (
|
|
"sort"
|
|
"time"
|
|
)
|
|
|
|
// TimelineEntry represents any item that can appear in the timeline.
|
|
type TimelineEntry struct {
|
|
Date time.Time
|
|
Type EntryType
|
|
Event *Event
|
|
Diary *DiaryEntry
|
|
Photo *Photo
|
|
}
|
|
|
|
// EntryType indicates what kind of entry this is.
|
|
type EntryType string
|
|
|
|
const (
|
|
EntryTypeEvent EntryType = "event"
|
|
EntryTypeDiary EntryType = "diary"
|
|
EntryTypePhoto EntryType = "photo"
|
|
)
|
|
|
|
// DayContent aggregates all content for a specific day.
|
|
type DayContent struct {
|
|
Date time.Time
|
|
Events []*Event
|
|
Diary *DiaryEntry
|
|
Photos []*Photo
|
|
}
|
|
|
|
// HasContent returns true if there is any content for this day.
|
|
func (d *DayContent) HasContent() bool {
|
|
return len(d.Events) > 0 || d.Diary != nil || len(d.Photos) > 0
|
|
}
|
|
|
|
// HasEvents returns true if there are events on this day.
|
|
func (d *DayContent) HasEvents() bool {
|
|
return len(d.Events) > 0
|
|
}
|
|
|
|
// HasDiary returns true if there is a diary entry for this day.
|
|
func (d *DayContent) HasDiary() bool {
|
|
return d.Diary != nil
|
|
}
|
|
|
|
// HasPhotos returns true if there are photos for this day.
|
|
func (d *DayContent) HasPhotos() bool {
|
|
return len(d.Photos) > 0
|
|
}
|
|
|
|
// ToTimelineEntries converts day content to a sorted slice of timeline entries.
|
|
func (d *DayContent) ToTimelineEntries() []TimelineEntry {
|
|
var entries []TimelineEntry
|
|
|
|
for _, event := range d.Events {
|
|
entries = append(entries, TimelineEntry{
|
|
Date: event.Start,
|
|
Type: EntryTypeEvent,
|
|
Event: event,
|
|
})
|
|
}
|
|
|
|
if d.Diary != nil {
|
|
entries = append(entries, TimelineEntry{
|
|
Date: d.Diary.Date,
|
|
Type: EntryTypeDiary,
|
|
Diary: d.Diary,
|
|
})
|
|
}
|
|
|
|
for _, photo := range d.Photos {
|
|
entries = append(entries, TimelineEntry{
|
|
Date: photo.Date,
|
|
Type: EntryTypePhoto,
|
|
Photo: photo,
|
|
})
|
|
}
|
|
|
|
sort.Slice(entries, func(i, j int) bool {
|
|
return entries[i].Date.Before(entries[j].Date)
|
|
})
|
|
|
|
return entries
|
|
}
|
|
|
|
// MonthData holds all data for a specific month.
|
|
type MonthData struct {
|
|
Year int
|
|
Month time.Month
|
|
Days map[int]*DayContent
|
|
}
|
|
|
|
// GetDay returns the day content for a specific day number.
|
|
func (m *MonthData) GetDay(day int) *DayContent {
|
|
if content, ok := m.Days[day]; ok {
|
|
return content
|
|
}
|
|
return &DayContent{
|
|
Date: time.Date(m.Year, m.Month, day, 0, 0, 0, 0, time.Local),
|
|
}
|
|
}
|