@@ -44,3 +44,22 @@ | |||
.post .text p:first-child { | |||
display: inline; | |||
} | |||
.badge { | |||
display: inline-flex; | |||
justify-content: center; | |||
align-items: center; | |||
color: white; | |||
background-color: silver; | |||
border: none; | |||
border-radius: 5px; | |||
font-family: verdana; | |||
font-size: xx-small; | |||
font-weight: bold; | |||
min-width: 15px; | |||
padding: 0 3px; | |||
margin: 3px 3px; | |||
line-height: 1.5; | |||
} | |||
.badge.on { | |||
background-color: crimson; | |||
} |
@@ -101,31 +101,47 @@ const Post = { | |||
} | |||
const ChatConfig = { | |||
isOn: false, | |||
toggle() { | |||
ChatConfig.isOn = !ChatConfig.isOn | |||
}, | |||
view() { | |||
return m('button', {onclick: () => {ChatConfig.isOn = !ChatConfig.isOn}}, 'chat') | |||
} | |||
const on = Chat.unseenCount ? '.on' : '' | |||
return m('button', {onclick: this.toggle}, 'chat ', | |||
m('.badge' + on, Chat.unseenCount), | |||
) | |||
}, | |||
} | |||
const Chat = { | |||
posts: [], | |||
oncreate() { | |||
listen('post', ({detail}) => { | |||
this.posts.push(detail) | |||
m.redraw() | |||
}) | |||
listen('logout', () => { | |||
this.posts = [] | |||
}) | |||
marked.setOptions({ | |||
breaks: true, | |||
}) | |||
unseenCount: 0, | |||
originalTitle: 'pico.chat', | |||
onupdate: () => { | |||
if(document.hasFocus() && ChatConfig.isOn) { | |||
Chat.unseenCount = 0 | |||
} | |||
const extra = Chat.unseenCount ? ` (${Chat.unseenCount})` : `` | |||
document.title = Chat.originalTitle + extra | |||
}, | |||
view() { | |||
return ChatConfig.isOn ? [ | |||
m('.not-chat', {onclick: () => ChatConfig.isOn = false}), | |||
m('.chat', | |||
m('.posts', this.posts.map(post => m(Post, {post}))), | |||
m('.posts', Chat.posts.map(post => m(Post, {post}))), | |||
m(TextBox), | |||
) | |||
] : null | |||
}, | |||
} | |||
addEventListener('focus', m.redraw) | |||
addEventListener('post', ({detail}) => { | |||
Chat.posts.push(detail) | |||
Chat.unseenCount += !(document.hasFocus() && ChatConfig.isOn) | |||
m.redraw() | |||
}) | |||
addEventListener('logout', () => { | |||
Chat.posts = [] | |||
Chat.unseenCount = 0 | |||
}) | |||
marked.setOptions({ | |||
breaks: true, | |||
}) |
@@ -2,7 +2,6 @@ const State = Object.seal({ | |||
username: null, | |||
websocket: null, | |||
online: [], | |||
messages: [], | |||
get isConnected() { | |||
return State.websocket && State.websocket.readyState === 1 | |||
}, | |||
@@ -21,7 +20,6 @@ const listen = (kind, handler) => { | |||
} | |||
listen('login', ({detail}) => { | |||
State.username = detail.value | |||
State.messages = [] | |||
}) | |||
listen('logout', ({detail}) => { | |||
State.online = [] | |||
@@ -32,18 +30,6 @@ listen('state', ({detail}) => { | |||
Object.assign(State, detail) | |||
}) | |||
const doNotLog = new Set(['login', 'state', 'post', 'peerInfo', 'join', 'leave']) | |||
/* | |||
* | |||
* ALERTS | |||
* | |||
*/ | |||
State.unseen = 0 | |||
listen('beep', () => {State.unseen += !document.hasFocus(); updateTitle()}) | |||
listen('focus', () => {State.unseen = 0; updateTitle()}) | |||
const updateTitle = () => { | |||
document.title = location.href.split('//')[1] + (State.unseen ? ` (${State.unseen})` : ``) | |||
} | |||
/* | |||
* | |||
* UTILS | |||
@@ -148,7 +134,6 @@ const Base = { | |||
), | |||
State.isConnected ? [ | |||
m('button', {onclick: Base.sendLogout}, 'pick name'), | |||
m('button', {onclick: () => navigator.clipboard.writeText(location)}, 'copy url'), | |||
] : null, | |||
State.isConnected ? m(VideoConfig) : null, | |||
State.isConnected ? m(ChatConfig) : null, |