blob: fed9acd95b7b3b425c84dace4bd8fb8626c6acf0 [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001// Copyright 2019 The Chromium Authors
Copybara854996b2021-09-07 19:36:02 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import {LitElement, html, css} from 'lit-element';
6import './mr-day-icon.js';
7
8const MONTH_NAMES = ['January', 'February', 'March', 'April', 'May', 'June',
9 'July', 'August', 'September', 'October', 'November', 'December'];
10const WEEKDAY_ABBREVIATIONS = 'M T W T F S S'.split(' ');
11const SECONDS_PER_DAY = 24 * 60 * 60;
12// Only show comments from this many days ago and later.
13const MAX_COMMENT_AGE = 31 * 3;
14
15export class MrActivityTable extends LitElement {
16 /** @override */
17 static get styles() {
18 return css`
19 :host {
20 display: grid;
21 grid-auto-flow: column;
22 grid-auto-columns: repeat(13, auto);
23 grid-template-rows: repeat(7, auto);
24 margin: auto;
25 width: 90%;
26 text-align: center;
27 line-height: 110%;
28 align-items: center;
29 justify-content: space-between;
30 }
31 :host[hidden] {
32 display: none;
33 }
34 `;
35 }
36
37 /** @override */
38 render() {
39 return html`
40 ${WEEKDAY_ABBREVIATIONS.map((weekday) => html`<span>${weekday}</span>`)}
41 ${this._weekdayOffset.map(() => html`<span></span>`)}
42 ${this._activityArray.map((day) => html`
43 <mr-day-icon
44 .selected=${this.selectedDate === day.date}
45 .commentCount=${day.commentCount}
46 .date=${day.date}
47 @click=${this._selectDay}
48 ></mr-day-icon>
49 `)}
50 `;
51 }
52
53 /** @override */
54 static get properties() {
55 return {
56 comments: {type: Array},
57 selectedDate: {type: Number},
58 };
59 }
60
61 _selectDay(event) {
62 const target = event.target;
63 if (this.selectedDate === target.date) {
64 this.selectedDate = undefined;
65 } else {
66 this.selectedDate = target.date;
67 }
68
69 this.dispatchEvent(new CustomEvent('dateChange', {
70 detail: {
71 date: this.selectedDate,
72 },
73 }));
74 }
75
76 get months() {
77 const currentMonth = (new Date()).getMonth();
78 return [MONTH_NAMES[currentMonth],
79 MONTH_NAMES[currentMonth - 1],
80 MONTH_NAMES[currentMonth - 2]];
81 }
82
83 get _weekdayOffset() {
84 const startDate = new Date(this._activityArray[0].date * 1000);
85 const startWeekdayNum = startDate.getDay()-1;
86 const emptyDays = [];
87 for (let i = 0; i < startWeekdayNum; i++) {
88 emptyDays.push(' ');
89 }
90 return emptyDays;
91 }
92
93 get _todayUnixTime() {
94 const now = new Date();
95 const today = new Date(Date.UTC(
96 now.getUTCFullYear(),
97 now.getUTCMonth(),
98 now.getUTCDate(),
99 24, 0, 0));
100 const todayEndTime = today.getTime() / 1000;
101 return todayEndTime;
102 }
103
104 get _activityArray() {
105 const todayUnixEndTime = this._todayUnixTime;
106 const comments = this.comments || [];
107
108 const activityArray = [];
109 for (let i = 0; i < MAX_COMMENT_AGE; i++) {
110 const arrayDate = (todayUnixEndTime - ((i) * SECONDS_PER_DAY));
111 activityArray.unshift({
112 commentCount: 0,
113 date: arrayDate,
114 });
115 }
116
117 for (let i = 0; i < comments.length; i++) {
118 const commentAge = Math.floor(
119 (todayUnixEndTime - comments[i].timestamp) / SECONDS_PER_DAY);
120 if (commentAge < MAX_COMMENT_AGE) {
121 const pos = MAX_COMMENT_AGE - commentAge - 1;
122 activityArray[pos].commentCount++;
123 }
124 }
125
126 return activityArray;
127 }
128}
129customElements.define('mr-activity-table', MrActivityTable);