Merge pull request #1353 from matrix-org/luke/feature-sticky-date-separators
Implement sticky date separatorspull/21833/head
commit
262d66f579
|
@ -73,6 +73,7 @@
|
||||||
"react-addons-css-transition-group": "15.3.2",
|
"react-addons-css-transition-group": "15.3.2",
|
||||||
"react-dom": "^15.4.0",
|
"react-dom": "^15.4.0",
|
||||||
"react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef",
|
"react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef",
|
||||||
|
"react-sticky": "^6.0.1",
|
||||||
"sanitize-html": "^1.14.1",
|
"sanitize-html": "^1.14.1",
|
||||||
"text-encoding-utf-8": "^1.0.1",
|
"text-encoding-utf-8": "^1.0.1",
|
||||||
"url": "^0.11.0",
|
"url": "^0.11.0",
|
||||||
|
|
|
@ -30,6 +30,18 @@ function getDaysArray() {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLongDaysArray() {
|
||||||
|
return [
|
||||||
|
_t('Sunday'),
|
||||||
|
_t('Monday'),
|
||||||
|
_t('Tuesday'),
|
||||||
|
_t('Wednesday'),
|
||||||
|
_t('Thursday'),
|
||||||
|
_t('Friday'),
|
||||||
|
_t('Saturday'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
function getMonthsArray() {
|
function getMonthsArray() {
|
||||||
return [
|
return [
|
||||||
_t('Jan'),
|
_t('Jan'),
|
||||||
|
@ -96,6 +108,38 @@ module.exports = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
formatDateSeparator: function(date) {
|
||||||
|
const days = getDaysArray();
|
||||||
|
const longDays = getLongDaysArray();
|
||||||
|
const months = getMonthsArray();
|
||||||
|
|
||||||
|
const today = new Date();
|
||||||
|
const yesterday = new Date();
|
||||||
|
yesterday.setDate(today.getDate() - 1);
|
||||||
|
|
||||||
|
if (date.toDateString() === today.toDateString()) {
|
||||||
|
return _t('Today');
|
||||||
|
} else if (date.toDateString() === yesterday.toDateString()) {
|
||||||
|
return _t('Yesterday');
|
||||||
|
} else if (today.getTime() - date.getTime() < 6 * 24 * 60 * 60 * 1000) {
|
||||||
|
return longDays[date.getDay()];
|
||||||
|
} else if (today.getTime() - date.getTime() < 365 * 24 * 60 * 60 * 1000) {
|
||||||
|
return _t('%(weekDayName)s, %(monthName)s %(day)s', {
|
||||||
|
weekDayName: days[date.getDay()],
|
||||||
|
monthName: months[date.getMonth()],
|
||||||
|
day: date.getDate(),
|
||||||
|
fullYear: date.getFullYear(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return _t('%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s', {
|
||||||
|
weekDayName: days[date.getDay()],
|
||||||
|
monthName: months[date.getMonth()],
|
||||||
|
day: date.getDate(),
|
||||||
|
fullYear: date.getFullYear(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
formatTime: function(date, showTwelveHour=false) {
|
formatTime: function(date, showTwelveHour=false) {
|
||||||
if (showTwelveHour) {
|
if (showTwelveHour) {
|
||||||
return twelveHourTime(date);
|
return twelveHourTime(date);
|
||||||
|
|
|
@ -61,9 +61,6 @@ module.exports = React.createClass({
|
||||||
// for pending messages.
|
// for pending messages.
|
||||||
ourUserId: React.PropTypes.string,
|
ourUserId: React.PropTypes.string,
|
||||||
|
|
||||||
// true to suppress the date at the start of the timeline
|
|
||||||
suppressFirstDateSeparator: React.PropTypes.bool,
|
|
||||||
|
|
||||||
// whether to show read receipts
|
// whether to show read receipts
|
||||||
showReadReceipts: React.PropTypes.bool,
|
showReadReceipts: React.PropTypes.bool,
|
||||||
|
|
||||||
|
@ -517,10 +514,10 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_wantsDateSeparator: function(prevEvent, nextEventDate) {
|
_wantsDateSeparator: function(prevEvent, nextEventDate) {
|
||||||
if (prevEvent == null) {
|
if (prevEvent == null) {
|
||||||
// first event in the panel: depends if we could back-paginate from
|
// First event in the panel always wants a DateSeparator
|
||||||
// here.
|
return true;
|
||||||
return !this.props.suppressFirstDateSeparator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevEventDate = prevEvent.getDate();
|
const prevEventDate = prevEvent.getDate();
|
||||||
if (!nextEventDate || !prevEventDate) {
|
if (!nextEventDate || !prevEventDate) {
|
||||||
return false;
|
return false;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1147,7 +1147,6 @@ var TimelinePanel = React.createClass({
|
||||||
highlightedEventId={ this.props.highlightedEventId }
|
highlightedEventId={ this.props.highlightedEventId }
|
||||||
readMarkerEventId={ this.state.readMarkerEventId }
|
readMarkerEventId={ this.state.readMarkerEventId }
|
||||||
readMarkerVisible={ this.state.readMarkerVisible }
|
readMarkerVisible={ this.state.readMarkerVisible }
|
||||||
suppressFirstDateSeparator={ this.state.canBackPaginate }
|
|
||||||
showUrlPreview={ this.props.showUrlPreview }
|
showUrlPreview={ this.props.showUrlPreview }
|
||||||
showReadReceipts={ this.props.showReadReceipts }
|
showReadReceipts={ this.props.showReadReceipts }
|
||||||
ourUserId={ MatrixClientPeg.get().credentials.userId }
|
ourUserId={ MatrixClientPeg.get().credentials.userId }
|
||||||
|
|
|
@ -234,7 +234,6 @@ describe('TimelinePanel', function() {
|
||||||
// 5 times, and we should have given up paginating
|
// 5 times, and we should have given up paginating
|
||||||
expect(client.paginateEventTimeline.callCount).toEqual(5);
|
expect(client.paginateEventTimeline.callCount).toEqual(5);
|
||||||
expect(messagePanel.props.backPaginating).toBe(false);
|
expect(messagePanel.props.backPaginating).toBe(false);
|
||||||
expect(messagePanel.props.suppressFirstDateSeparator).toBe(false);
|
|
||||||
|
|
||||||
// now, if we update the events, there shouldn't be any
|
// now, if we update the events, there shouldn't be any
|
||||||
// more requests.
|
// more requests.
|
||||||
|
@ -339,7 +338,6 @@ describe('TimelinePanel', function() {
|
||||||
awaitScroll().then(() => {
|
awaitScroll().then(() => {
|
||||||
// we should now have loaded the first few events
|
// we should now have loaded the first few events
|
||||||
expect(messagePanel.props.backPaginating).toBe(false);
|
expect(messagePanel.props.backPaginating).toBe(false);
|
||||||
expect(messagePanel.props.suppressFirstDateSeparator).toBe(true);
|
|
||||||
|
|
||||||
// back-paginate until we hit the start
|
// back-paginate until we hit the start
|
||||||
return backPaginate();
|
return backPaginate();
|
||||||
|
@ -347,7 +345,6 @@ describe('TimelinePanel', function() {
|
||||||
// hopefully, we got to the start of the timeline
|
// hopefully, we got to the start of the timeline
|
||||||
expect(messagePanel.props.backPaginating).toBe(false);
|
expect(messagePanel.props.backPaginating).toBe(false);
|
||||||
|
|
||||||
expect(messagePanel.props.suppressFirstDateSeparator).toBe(false);
|
|
||||||
var events = scryEventTiles(panel);
|
var events = scryEventTiles(panel);
|
||||||
expect(events[0].props.mxEvent).toBe(timeline.getEvents()[0]);
|
expect(events[0].props.mxEvent).toBe(timeline.getEvents()[0]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue