Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit50d735a

Browse files
committed
Add date markers
1 parent34d89c7 commit50d735a

File tree

7 files changed

+218
-92
lines changed

7 files changed

+218
-92
lines changed

‎assets/bindata.go‎

Lines changed: 80 additions & 80 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎client/css/style.css‎

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,6 @@ input.chat-title {
595595
top:50px;
596596
bottom:50px;
597597
right:0;
598-
z-index:1;
599-
overflow: hidden;
600598
}
601599

602600
.chat-channel .messagebox {
@@ -615,6 +613,24 @@ input.chat-title {
615613
overflow-y: scroll!important;
616614
}
617615

616+
.messagebox-topdate-container {
617+
position: absolute;
618+
text-align: center;
619+
left:0;
620+
height:0;
621+
}
622+
623+
.messagebox-topdate {
624+
position: relative;
625+
top:-12px;
626+
background:#f0f0f0;
627+
color:#999;
628+
border-radius:50vh;
629+
padding:05px;
630+
font-size:12px;
631+
z-index:2;
632+
}
633+
618634
.message {
619635
padding:4px15px;
620636
}
@@ -637,6 +653,18 @@ input.chat-title {
637653
color:#ff6698;
638654
}
639655

656+
.message-date {
657+
text-align: center;
658+
color:#999;
659+
font-size:12px;
660+
margin-top:12px;
661+
}
662+
663+
.message-datehr {
664+
border: none;
665+
border-bottom:1px solid#ddd;
666+
}
667+
640668
.message-time {
641669
font-style: normal;
642670
font-weight:400;
@@ -706,7 +734,7 @@ input.message-input-nick.invalid {
706734
width:200px;
707735
border-left:1px solid#ddd;
708736
background:#f0f0f0;
709-
z-index:2;
737+
z-index:1;
710738
transition: transform0.2s;
711739
}
712740

‎client/js/components/pages/Chat/Chat.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export default class Chat extends Component {
9797
hasMoreMessages={hasMoreMessages}
9898
messages={messages}
9999
tab={tab}
100+
hideTopDate={search.show}
100101
onAddMore={addFetchedMessages}
101102
onFetchMore={fetchMessages}
102103
onNickClick={this.handleNickClick}

‎client/js/components/pages/Chat/Message.js‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ const Message = ({ message, coloredNick, style, onNickClick }) => {
77
[`message-${message.type}`]:message.type
88
});
99

10+
if(message.type==='date'){
11+
return(
12+
<divclassName={className}style={style}>
13+
{message.content}
14+
<hr/>
15+
</div>
16+
);
17+
}
18+
1019
style={
1120
...style,
1221
paddingLeft:`${window.messageIndent+15}px`,

‎client/js/components/pages/Chat/MessageBox.js‎

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { PureComponent, createRef } from 'react';
22
import{VariableSizeListasList}from'react-window';
33
importAutoSizerfrom'react-virtualized-auto-sizer';
44
importdebouncefrom'lodash/debounce';
5+
import{formatDate,measureScrollBarWidth}from'utils';
56
import{getScrollPos,saveScrollPos}from'utils/scrollPosition';
67
import{windowHeight}from'utils/size';
78
importMessagefrom'./Message';
@@ -12,7 +13,10 @@ const fetchThreshold = 600;
1213
// this is done to prevent the scroll from jumping all over the place
1314
constscrollbackDebounce=150;
1415

16+
constscrollBarWidth=measureScrollBarWidth()+'px';
17+
1518
exportdefaultclassMessageBoxextendsPureComponent{
19+
state={topDate:''};
1620
list=createRef();
1721
outer=createRef();
1822

@@ -177,6 +181,17 @@ export default class MessageBox extends PureComponent {
177181
this.bottom=scrollOffset+clientHeight>=scrollHeight-20;
178182
};
179183

184+
handleItemsRendered=({ visibleStartIndex})=>{
185+
conststartIndex=visibleStartIndex===0 ?0 :visibleStartIndex-1;
186+
constfirstVisibleMessage=this.props.messages[startIndex];
187+
188+
if(firstVisibleMessage&&firstVisibleMessage.date){
189+
this.setState({topDate:formatDate(firstVisibleMessage.date)});
190+
}else{
191+
this.setState({topDate:''});
192+
}
193+
};
194+
180195
handleMouseDown=()=>{
181196
this.mouseDown=true;
182197
};
@@ -221,25 +236,41 @@ export default class MessageBox extends PureComponent {
221236
};
222237

223238
render(){
239+
const{ messages, hideTopDate}=this.props;
240+
const{ topDate}=this.state;
241+
242+
constdateContainerStyle={
243+
right:scrollBarWidth
244+
};
245+
224246
return(
225247
<div
226248
className="messagebox"
227249
onMouseDown={this.handleMouseDown}
228250
onMouseUp={this.handleMouseUp}
229251
>
252+
<div
253+
className="messagebox-topdate-container"
254+
style={dateContainerStyle}
255+
>
256+
{!hideTopDate&&topDate&&(
257+
<spanclassName="messagebox-topdate">{topDate}</span>
258+
)}
259+
</div>
230260
<AutoSizer>
231261
{({ width, height})=>(
232262
<List
233263
ref={this.list}
234264
outerRef={this.outer}
235265
width={width}
236266
height={height}
237-
itemCount={this.props.messages.length+2}
267+
itemCount={messages.length+2}
238268
itemKey={this.getItemKey}
239269
itemSize={this.getRowHeight}
240270
estimatedItemSize={32}
241271
initialScrollOffset={this.initialScrollTop}
242272
onScroll={this.handleScroll}
273+
onItemsRendered={this.handleItemsRendered}
243274
className="messagebox-window"
244275
overscanCount={5}
245276
>

‎client/js/state/messages.js‎

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
messageHeight,
66
linkify,
77
timestamp,
8-
isChannel
8+
isChannel,
9+
formatDate
910
}from'utils';
1011
importcreateReducerfrom'utils/createReducer';
1112
import{getApp}from'./app';
@@ -43,22 +44,71 @@ function init(state, server, tab) {
4344
}
4445
}
4546

47+
letnextID=0;
48+
49+
functioncreateDateMessage(date){
50+
constmessage={
51+
id:nextID,
52+
type:'date',
53+
content:formatDate(date),
54+
height:40
55+
};
56+
57+
nextID++;
58+
59+
returnmessage;
60+
}
61+
62+
functionisSameDay(d1,d2){
63+
return(
64+
d1.getDate()===d2.getDate()&&
65+
d1.getMonth()===d2.getMonth()&&
66+
d1.getFullYear()===d2.getFullYear()
67+
);
68+
}
69+
70+
functionreducerAddMessage(message,server,tab,state,prepend){
71+
constmessages=state[server][tab];
72+
73+
if(messages.length>0){
74+
if(prepend){
75+
constfirstMessage=messages[0];
76+
if(firstMessage.date&&!isSameDay(firstMessage.date,message.date)){
77+
messages.unshift(createDateMessage(firstMessage.date));
78+
}
79+
}else{
80+
constlastMessage=messages[messages.length-1];
81+
if(lastMessage.date&&!isSameDay(lastMessage.date,message.date)){
82+
messages.push(createDateMessage(message.date));
83+
}
84+
}
85+
}
86+
87+
if(prepend){
88+
messages.unshift(message);
89+
}else{
90+
messages.push(message);
91+
}
92+
}
93+
4694
exportdefaultcreateReducer(
4795
{},
4896
{
4997
[actions.ADD_MESSAGE](state,{ server, tab, message}){
5098
init(state,server,tab);
51-
state[server][tab].push(message);
99+
reducerAddMessage(message,server,tab,state);
52100
},
53101

54102
[actions.ADD_MESSAGES](state,{ server, tab, messages, prepend}){
55103
if(prepend){
56104
init(state,server,tab);
57-
state[server][tab].unshift(...messages);
105+
for(leti=messages.length-1;i>=0;i--){
106+
reducerAddMessage(messages[i],server,tab,state,true);
107+
}
58108
}else{
59109
messages.forEach(message=>{
60110
init(state,server,message.tab||tab);
61-
state[server][message.tab||tab].push(message);
111+
reducerAddMessage(message,server,message.tab||tab,state);
62112
});
63113
}
64114
},
@@ -78,6 +128,10 @@ export default createReducer(
78128
Object.keys(state).forEach(server=>
79129
Object.keys(state[server]).forEach(target=>
80130
state[server][target].forEach(message=>{
131+
if(message.type==='date'){
132+
return;
133+
}
134+
81135
message.height=messageHeight(
82136
message,
83137
wrapWidth,
@@ -100,15 +154,15 @@ export default createReducer(
100154
}
101155
);
102156

103-
letnextID=0;
104-
105157
functioninitMessage(message,tab,state){
106158
if(message.time){
107-
message.time=timestamp(newDate(message.time*1000));
159+
message.date=newDate(message.time*1000);
108160
}else{
109-
message.time=timestamp();
161+
message.date=newDate();
110162
}
111163

164+
message.time=timestamp(message.date);
165+
112166
if(!message.id){
113167
message.id=nextID;
114168
nextID++;

‎client/js/utils/index.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ export function timestamp(date = new Date()) {
137137
return`${h}:${m}`;
138138
}
139139

140+
constdateFmt=newIntl.DateTimeFormat(window.navigator.language);
141+
exportconstformatDate=dateFmt.format;
142+
140143
constcanvas=document.createElement('canvas');
141144
constctx=canvas.getContext('2d');
142145

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp