--:--:--`;
}
var hh = date.getHours().toString().padStart(2, "0");
var mm = date.getMinutes().toString().padStart(2, "0");
var ss = date.getSeconds().toString().padStart(2, "0");
var timestamp = `${hh}:${mm}:${ss}`;
return html`
event.preventDefault()}>${timestamp}
`;
}
class LogLine extends Component {
shouldComponentUpdate(nextProps) {
return this.props.message !== nextProps.message;
}
render() {
var msg = this.props.message;
function createNick(nick) {
return html`
<${Nick} nick=${nick} onClick=${() => props.onNickClick(nick)}/>
`;
}
var lineClass = "";
var content;
switch (msg.command) {
case "NOTICE":
case "PRIVMSG":
var text = msg.params[1];
var ctcp = irc.parseCTCP(msg);
if (ctcp) {
if (ctcp.command == "ACTION") {
lineClass = "me-tell";
content = html`* ${createNick(msg.prefix.name)} ${linkify(stripANSI(ctcp.param))}`;
} else {
content = html`
${createNick(msg.prefix.name)} has sent a CTCP command: ${ctcp.command} ${ctcp.param}
`;
}
} else {
lineClass = "talk";
var prefix = "<", suffix = ">";
if (msg.command == "NOTICE") {
prefix = suffix = "-";
}
content = html`${prefix}${createNick(msg.prefix.name)}${suffix} ${linkify(stripANSI(text))}`;
}
if (msg.isHighlight) {
lineClass += " highlight";
}
break;
case "JOIN":
content = html`
${createNick(msg.prefix.name)} has joined
`;
break;
case "PART":
content = html`
${createNick(msg.prefix.name)} has left
`;
break;
case "QUIT":
content = html`
${createNick(msg.prefix.name)} has quit
`;
break;
case "NICK":
var newNick = msg.params[0];
content = html`
${createNick(msg.prefix.name)} is now known as ${createNick(newNick)}
`;
break;
case "TOPIC":
var topic = msg.params[1];
content = html`
${createNick(msg.prefix.name)} changed the topic to: ${linkify(stripANSI(topic))}
`;
break;
default:
if (irc.isError(msg.command) && msg.command != irc.ERR_NOMOTD) {
lineClass = "error";
}
content = html`${msg.command} ${msg.params.join(" ")}`;
}
return html`
<${Timestamp} date=${new Date(msg.tags.time)} url=${getMessageURL(this.props.buffer, msg)}/>
${" "}
${content}
`;
}
}
class NotificationNagger extends Component {
state = { nag: false };
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state.nag = this.shouldNag();
}
shouldNag() {
return window.Notification && Notification.permission !== "granted" && Notification.permission !== "denied";
}
handleClick(event) {
event.preventDefault();
Notification.requestPermission((permission) => {
this.setState({ nag: this.shouldNag() });
});
}
render() {
if (!this.state.nag) {
return null;
}
return html`
`;
}
}
class DateSeparator extends Component {
constructor(props) {
super(props);
}
shouldComponentUpdate(nextProps) {
return this.props.date.getTime() !== nextProps.date.getTime();
}
render() {
var date = this.props.date;
var YYYY = date.getFullYear().toString().padStart(4, "0");
var MM = (date.getMonth() + 1).toString().padStart(2, "0");
var DD = date.getDate().toString().padStart(2, "0");
var text = `${YYYY}-${MM}-${DD}`;
return html`
${text}
`;
}
}
function UnreadSeparator(props) {
return html`New messages
`;
}
function sameDate(d1, d2) {
return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate();
}
export default class Buffer extends Component {
shouldComponentUpdate(nextProps) {
return this.props.buffer !== nextProps.buffer;
}
render() {
var buf = this.props.buffer;
if (!buf) {
return null;
}
var children = [];
if (buf.type == BufferType.SERVER) {
children.push(html`<${NotificationNagger}/>`);
}
var hasUnreadSeparator = false;
var prevDate = new Date();
buf.messages.forEach((msg) => {
if (!hasUnreadSeparator && buf.type != BufferType.SERVER && buf.lastReadReceipt && msg.tags.time > buf.lastReadReceipt.time) {
children.push(html`<${UnreadSeparator} key="unread"/>`);
hasUnreadSeparator = true;
}
var date = new Date(msg.tags.time);
if (!sameDate(prevDate, date)) {
children.push(html`<${DateSeparator} key=${"date-" + date} date=${date}/>`);
}
prevDate = date;
children.push(html`
<${LogLine} key=${"msg-" + msg.key} message=${msg} buffer=${buf} onNickClick=${this.props.onNickClick}/>
`);
});
return html`
${children}
`;
}
}