Browse Source

alps theme: initial layout for calendar

master
Drew DeVault 4 years ago
committed by Simon Ser
parent
commit
7142da950d
No known key found for this signature in database GPG Key ID: FDE7BE0E88F5E48
4 changed files with 262 additions and 1 deletions
  1. +60
    -0
      plugins/caldav/routes.go
  2. +100
    -1
      themes/alps/assets/style.css
  3. +18
    -0
      themes/alps/calendar-header.html
  4. +84
    -0
      themes/alps/calendar.html

+ 60
- 0
plugins/caldav/routes.go View File

@@ -18,9 +18,16 @@ import (
type CalendarRenderData struct {
alps.BaseRenderData
Time time.Time
Now time.Time
Dates [7 * 6]time.Time
Calendar *caldav.Calendar
Events []CalendarObject
PrevPage, NextPage string
PrevTime, NextTime time.Time

EventsForDate func(time.Time) []CalendarObject
DaySuffix func(n int) string
Sub func(a, b int) int
}

type EventRenderData struct {
@@ -96,13 +103,66 @@ func registerRoutes(p *alps.GoPlugin, u *url.URL) {
return fmt.Errorf("failed to query calendar: %v", err)
}

// TODO: Time zones are hard
var dates [7 * 6]time.Time
initialDate := start.UTC()
initialDate = initialDate.AddDate(0, 0, -int(initialDate.Weekday()))
for i := 0; i < len(dates); i += 1 {
dates[i] = initialDate
initialDate = initialDate.AddDate(0, 0, 1)
}

eventMap := make(map[time.Time][]CalendarObject)
for _, ev := range events {
ev := ev // make a copy
// TODO: include event on each date for which it is active
co := ev.Data.Events()[0]
startTime, _ := co.DateTimeStart(nil)
startTime = startTime.UTC().Truncate(time.Hour * 24)
eventMap[startTime] = append(eventMap[startTime], CalendarObject{&ev})
}

return ctx.Render(http.StatusOK, "calendar.html", &CalendarRenderData{
BaseRenderData: *alps.NewBaseRenderData(ctx),
Time: start,
Now: time.Now(), // TODO: Use client time zone
Calendar: calendar,
Dates: dates,
Events: newCalendarObjectList(events),
PrevPage: start.AddDate(0, -1, 0).Format(monthPageLayout),
NextPage: start.AddDate(0, 1, 0).Format(monthPageLayout),
PrevTime: start.AddDate(0, -1, 0),
NextTime: start.AddDate(0, 1, 0),

EventsForDate: func(when time.Time) []CalendarObject {
if events, ok := eventMap[when.Truncate(time.Hour * 24)]; ok {
return events
}
return nil
},

DaySuffix: func(n int) string {
if n % 100 >= 11 && n % 100 <= 13 {
return "th"
}
return map[int]string{
0: "th",
1: "st",
2: "nd",
3: "rd",
4: "th",
5: "th",
6: "th",
7: "th",
8: "th",
9: "th",
}[n % 10]
},

Sub: func (a, b int) int {
// Why isn't this built-in, come on Go
return a - b
},
})
})



+ 100
- 1
themes/alps/assets/style.css View File

@@ -261,6 +261,11 @@ main.new-contact .actions > *:not(:last-child) {
margin-right: 1rem;
}

.actions h3 {
align-self: center;
margin: 0 1.3rem 0 1rem;
}

.message-list-subject a { color: #77c; }

.message-list-unread.message-list-sender,
@@ -370,7 +375,7 @@ main table tfoot {
padding: 0.3rem 0.5rem;
}

.actions-pagination .button-link:first-child:not(:last-child) {
.actions-pagination .button-link:not(:last-child) {
margin-right: 0.3rem;
}

@@ -444,6 +449,100 @@ main table tfoot {
margin-top: 1rem;
}

main.calendar .dates {
flex-grow: 1;
padding: 0.3rem;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: auto 1fr 1fr 1fr 1fr 1fr 1fr auto;
grid-template-areas:
"sunday-top monday-top wednesday-top tuesday-top thursday-top friday-top saturday-top"
"dates dates dates dates dates dates dates"
"dates dates dates dates dates dates dates"
"dates dates dates dates dates dates dates"
"dates dates dates dates dates dates dates"
"dates dates dates dates dates dates dates"
"dates dates dates dates dates dates dates"
"sunday-bottom monday-bottom wednesday-bottom tuesday-bottom thursday-bottom friday-bottom saturday-bottom";
grid-gap: 0.3rem;
}

main.calendar .dates .weekday {
text-align: center;
font-size: 1.1rem;
font-weight: normal;
}

main.calendar .dates .sunday-top { grid-area: sunday-top; }
main.calendar .dates .monday-top { grid-area: monday-top; }
main.calendar .dates .tuesday-top { grid-area: tuesday-top; }
main.calendar .dates .wednesday-top { grid-area: wednesday-top; }
main.calendar .dates .thursday-top { grid-area: thursday-top; }
main.calendar .dates .friday-top { grid-area: friday-top; }
main.calendar .dates .saturday-top { grid-area: saturday-top; }
main.calendar .dates .sunday-bottom { grid-area: sunday-bottom; }
main.calendar .dates .monday-bottom { grid-area: monday-bottom; }
main.calendar .dates .tuesday-bottom { grid-area: tuesday-bottom; }
main.calendar .dates .wednesday-bottom { grid-area: wednesday-bottom; }
main.calendar .dates .thursday-bottom { grid-area: thursday-bottom; }
main.calendar .dates .friday-bottom { grid-area: friday-bottom; }
main.calendar .dates .saturday-bottom { grid-area: saturday-bottom; }

main.calendar .date {
border: 1px solid #eee;
padding: 0.3rem;
background: white;
display: flex;
flex-direction: column;
position: relative;
}

main.calendar .date.active {
background-color: #f6fff6;
border: 1px solid #afa;
}

main.calendar .date .date-link {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}

main.calendar .date.extra {
background: transparent;
border: none;
}

main.calendar .date ul {
list-style: none;
margin: 0;
padding-left: 0.3rem;
}

main.calendar .date .events {
flex-grow: 1;
}

main.calendar .date.extra .events {
visibility: hidden;
}

main.calendar .events .start-time {
color: #444;
}

main.calendar .events .overflow {
color: #444;
text-align: right;
}

main.calendar .date h4 {
font-weight: normal;
text-align: right;
color: #666;
}

main.calendar .date h4 .da { font-size: 1.2rem; }

input[type="submit"],
.button,
button,


+ 18
- 0
themes/alps/calendar-header.html View File

@@ -0,0 +1,18 @@
<div class="actions-wrap">
<div class="actions-pagination" style="margin-left: 0;">
<a href="?month={{.PrevPage}}" class="button-link">« {{.PrevTime.Format "January"}}</a>
<h3>{{.Time.Format "January 2006"}}</h3>
<a href="?month={{.NextPage}}" class="button-link">{{.NextTime.Format "January"}} »</a>
{{if ne .Time.Month .Now.Month}}
<a href="/calendar" class="button-link">Today »</a>
{{end}}
</div>

<form method="get" class="actions-search action-group">
<input
type="text"
name="query"
placeholder="Search {{.Calendar.Name}} events...">
<button>Search</button>
</form>
</div>

+ 84
- 0
themes/alps/calendar.html View File

@@ -0,0 +1,84 @@
{{template "head.html" .}}
{{template "nav.html" .}}

<div class="page-wrap">
<aside>
<a href="/calendar/create" class="new">New event</a>
<!-- TODO: fetch list of address books -->
<a href="#" class="active">{{.Calendar.Name}}</a>
<a href="#">Personal</a>
</aside>

<div class="container">
<main class="calendar">
<section class="actions">
{{ template "calendar-header.html" . }}
</section>

<section class="dates">
<h4 class="weekday sunday-top">Sunday</h4>
<h4 class="weekday monday-top">Monday</h4>
<h4 class="weekday tuesday-top">Tuesday</h4>
<h4 class="weekday wednesday-top">Wednesday</h4>
<h4 class="weekday thursday-top">Thursday</h4>
<h4 class="weekday friday-top">Friday</h4>
<h4 class="weekday saturday-top">Saturday</h4>

{{$base := .}}
{{range .Dates}}
<div class="date
{{if ne $base.Time.Month .Month}}extra{{end}}
{{if and (eq $base.Now.Month .Month) (eq $base.Now.Day .Day)}}active{{end}}
">
{{if eq $base.Time.Month .Month}}
<a href="#" class="date-link"></a>
{{end}}
<div class="events">
{{$events := (call $base.EventsForDate .)}}
{{if $events}}
<ul>
{{$overflow := 0}}
{{if gt (len $events) 3}}
{{$overflow = call $base.Sub (len $events) 3}}
{{$events = slice $events 0 3}}
{{end}}

{{range $events}}
{{$event := index .Data.Events 0}}
<li>
<span class="start-time">
{{($event.DateTimeStart nil).Format "15:04"}}
</span>
{{$event.Props.Text "SUMMARY"}}
</li>
{{end}}
{{if ne $overflow 0}}
<li class="overflow">...and {{$overflow}} more</li>
{{end}}
</ul>
{{end}}
</div>
<h4>
<span class="mo">{{.Format "Jan"}}</span>
<span class="da">{{.Format "2"}}{{call $base.DaySuffix .Day}}</span>
</h4>
</div>
{{end}}

<h4 class="weekday sunday-bottom">Sunday</h4>
<h4 class="weekday monday-bottom">Monday</h4>
<h4 class="weekday tuesday-bottom">Tuesday</h4>
<h4 class="weekday wednesday-bottom">Wednesday</h4>
<h4 class="weekday thursday-bottom">Thursday</h4>
<h4 class="weekday friday-bottom">Friday</h4>
<h4 class="weekday saturday-bottom">Saturday</h4>
</section>

<section class="actions">
{{ template "calendar-header.html" . }}
</section>
</main>
</div>
</div>

{{template "foot.html"}}

Loading…
Cancel
Save