zarino / backchat Goto Github PK
View Code? Open in Web Editor NEWA hackable IRC client for Mac OS X, built with Electron (atom-shell), HTML and JavaScript
A hackable IRC client for Mac OS X, built with Electron (atom-shell), HTML and JavaScript
Channel topics, people joining and people leaving should not cause a notification to be added to the channelButtonView
in the sidebar, or to the dock icon.
Only messages and actions should trigger notifications.
If we join a channel that has logs from the past 24 hours, show that day's logs at the top of the scrollback, greyed out.
This is particularly handy when quitting IRC at lunchtime, and wanting to easily scroll back up to see what was discussed in the morning. Or when joining first thing in the morning and wanting to see what was discussed last thing the previous night.
If someone sends me a private message, and the app is in the background, I should be notified just as if they'd mentioned my name in a public channel.
That means an audible ping, and a red number on the dock icon.
Not sure whether there should also be a red number in the channelButton
, or whether we should keep that for mentions of keywords only. I have a feeling, for consistency, there should be a red number in the channelButton
, since otherwise, how am I meant to find out what triggered the beep that made me return to the app?
Building on top of #4 – if a keyword (eg: for now, the user's nick) is mentioned in a background channel, then a second badge should show in the sidebar for that channel, with the total number of missed mentions in that channel.
Focussing the channel should clear the badge, as normal.
The styling for this is already here:
backchat/src/client/sass/_sidebar.scss
Lines 95 to 97 in 4e8a355
Just a very unobtrusive line or something, to make it clear—when you switch back to a channel you've been ignoring for a while—where you last left it.
Things I would expect to be saved:
Perfectly happy for these to be saved to settings.json
, so they're all slurped in automatically next time I start up.
75df6f7 added native spellchecking for the message composition box. However, when you right-click underlined words, nothing happens.
Here's the menu I get when I right-click a misspelt word in a standard Chrome textarea:
The absolute minimum to satisfy this ticket would just have a right-click menu containing the spelling suggestions.
But to make it feel like a real Mac app (see #47), I'd also expect Cut/Copy/Paste/Delete, Select All, maybe even Look Up in Dictionary.
Messages are simply inserted into the DOM, without any HTML escaping. So structural and formatting tags are included, and script tags are evaluated.
We need to sanitize HTML tags (turn <
into <
etc) at some point before we add our own formatting (eg: the <strong>
tags around keyword mentions).
On tab press, match the current (partial) word against all the nicks in the channel, case-insensitively. If there's a match, replace the current (partial) word with the full nick.
Easy to do with HTML5 Notification API:
new Notification("#bots", { body: "Hey zarino welcome to bots" });
Nice to haves would also be: Twitter handles (Regexp @[A-Za-z0-9_]+
) and mailto:
links.
There are two cases when a message should be classed as "unread" and therefore added to an "unread count" next to the channel name in the sidebar:
Focussing a channel with missed messages (ie: by switching to it in the sidebar or, if the channel is current visible but the window is blurred, just switching to the window) should remove the unread count.
It should be obvious when I’m set as away on the current server.
The change in appearance (and its reversion back to normal) should happen as soon as my /away
command has been accepted by the server.
(Note: this is a per-server setting. I could be away on one server, and active on another.)
Double-clicking a person's name in a channel's user list, should create and focus a new (blank) channelView
, with a sidebar channelViewButton
named after the target user, and should focus the text input.
If a private message channel with the target user already exists, it should just be focussed instead (rather than creating a new one)
Enable spell-checking for outgoing messages: https://github.com/atom/electron/blob/master/docs/api/web-frame.md
Will require an external spellchecking library like http://atom.github.io/node-spellchecker
var webframe = require('web-frame');
var spellchecker = require('spellchecker');
webframe.setSpellCheckProvider("en-US", true, {
spellCheck: function(text) {
return ! spellchecker.isMisspelled(text);
}
});
Normally you'd run:
/join some-channel some-password
Make sure this works when run from the text input in the UI.
But more importantly, make sure it works in the settings.json file.
Required: Some sort of coloured background or visual difference for the whole message.
Nice to have: Highlight the specific keyword(s) in situ.
Right now lots of logic is split between main.js and client.js, meaning a confusing mix of events flying everywhere, and duplication of functions (like tracking which channel is currently active).
Really, anything on the raw IRC level should be handled by connection-pool.js (as it is currently), then everything else, including state storage like which users are connected to which channels, with which away messages, and which channel is currently active etc, should all be handled by main.js, with main.js sending events to client.js when something in the UI needs to change (ie: sending events like client:addUserToChannel
rather than generic events like channel:joined
).
Let me drag and drop channels and private messages in the sidebar, to put them into whatever order I want.
Once #6 has been done, having a menu item that opens the current channel's log file in the Finder would be handy!
var path = app.getPath('userData') + '/' + serverName + '/' + channelName + '/' + isoDate + '.txt';
shell.showItemInFolder(path);
We'll need to poll the server for user status. Probably more efficient to do this using client.send('WHO', '#channelName')
than to maintain a list of users we've seen in all the channels on the server and query each one with client.whois()
individually.
The response to a raw WHO
command will be sent in a raw
event, with one event per user. The events all have a command
attribute of 'rpl_whoreply'
.
Looks like the interesting bits of the response to a raw WHO
command are:
[raw] {
server: 'irc.server.org',
command: 'rpl_whoreply',
…
args: [
'MyNick',
'#channelName',
'TheirUsername',
'TheirHost',
'irc.server.org',
'TheirNick',
'H',
'0 TheirFullName'
]
}
This is repeated for each user in the channel. the 7th item in the args
array is the status, H
for “Here” and G
for “Gone”. Looks like it can be followed by characters like *
or @
if the user is an admin too.
Building on #46, I'd expect to be able to, at the very least, copy selected text in the scrollback. Maybe also Look Up in Dictionary.
The right-click menu shows the right options, which are some combination of "Remove from sidebar", "Close channel", and "Join channel", depending on the state and type of channel.
The main menu, however, always shows "Leave channel".
To fix this, the client will have to notify the server whenever the activeChannel
is changed, and send it information about the new active channel, so it can update the menu to say the right things.
The Dock should display a numeric total of all "unread counts" for all channels across all servers.
Currently, if the third-party user "zarino" sends a private message to "nodebot122" who’s running backchat, the following happens:
A new channel appears in nodebot122's window, but rather than being named after the person who started the conversation (zarino), it's named after nodebot122.
This is because the original message:sent
event looked like:
message:sent {
"server": "irc.freenode.net",
"fromUser": "zarino",
"toUserOrChannel": "nodebot122",
"messageText": "hello",
"myNick": "nodebot122"
}
Which is right, from zarino's perspective. But when the message reaches nodebot122, the name should really be switched around. Because if it's not, sending messages to this new channel actually means sending messages to yourself (hence the double reply in the screenshot: two message:sent
events are fired, one for the user, and one for the channel) – if the channel were named after the third-party user (zarino) then none of this would happen.
The channel:joined
event handler incorrectly adds each new user’s nick to the keywords
array. This means each user who joins after me is added to the array.
backchat/src/client/js/client.js
Line 86 in 3868fd8
I think the original intent of this line was to add my nick to the keywords array. Surely there must be a better way for the client to figure out what the current nick is and add it? Maybe the server could just add it to serverSettings.keywords
before it's passed to the client?
"Leave channel" should be "Close chat" if the channel is a private chat.
Selecting the item from the menu should leave the channel (if it's channel) and then (in any case) remove the ChannelView
and ChannelButtonView
.
Right now, channels listed in the settings.json are all joined at startup.
For channels I don't regularly access, I prefer having them listed in the sidebar but not joined automatically.
It's most future-proof to change the channels
property of the settings file, from a list of strings (channel names) to a list of objects, which contains the channel's settings, like:
{
"servers": [
{
"name": "Freenode",
"url": "irc.freenode.net",
…
"channels": [
{
name: "#bots",
autoJoin: false
},
{
name: "#poplus",
autoJoin: true
}
]
},
"keywords": [ "tannoy" ]
}
If an incoming message includes a URL and that URL looks like an image, render the URL inside an <img>
tag.
Given a the user is connected to more than one channel, ⌘-[
should switch to the channel above the current one in the sidebar, and ⌘-]
should switch to the one below. The movement should wrap around the edges of the list, so ⌘-]
at the end of the list will wrap back to the channel right at the top.
There are already hooks for this in the mac-menu.json template:
{ "label": "Next channel", "command": "application:nextChannel", "accelerator": "Command+]" },
{ "label": "Previous channel", "command": "application:previousChannel", "accelerator": "Command+[" },
We just need to add listeners for application:nextChannel
and application:previousChannel
in main.js. And then pass the message on to the client, and write the looping code in client.js.
If an incoming message includes a URL, scrape it and look for image meta tags that might be useful, eg:
<meta property="og:image" content="http://somedomain.com/image.png">
<meta name="twitter:image" value="http://somedomain.com/image.png">
This would probably be best done with an always-visible banner at the top of the chat window, rather than a repeated "response" to each message I send them.
When a user activates away, the banner appears, and when they deactivate away, it disappears. And if you start a private chat with a user who's away, the banner is there from the start.
The information's sent as part of a rpl_topicwhotime
message from the IRC server:
[irc event] [raw] { prefix: 'wolfe.freenode.net',
server: 'wolfe.freenode.net',
command: 'rpl_topicwhotime',
rawCommand: '333',
commandType: 'reply',
args:
[ 'nodebot122',
'#bots',
'RonG!~RonG@unaffiliated/rong',
'1409104006' ] }
The bit before the !
is the nickname.
Would be a really useful feature when you need to talk to someone but they're either not connected, or marked as away.
We already poll for the userlist of each active channel – it just needs to store a list of nicks we're interested in, and raise a notification when they join / come back from being “away”.
It's handy being able to see what the server is saying, especially for things like server notices during the connection process.
Right now, that stuff is output to the developer console. But when the app runs as a proper binary, there is no console. So a serverView
, just like the existing channelView
s, with a serverButtonView
that toggles its visibility, would be handy.
http://cloudinary.com/documentation/node_integration#getting_started_guide
When clicking on a channel means that the text input is immediately focussed, it doesn't make any sense to have a blue "focus" state for the channel buttons alongside the normal grey "active" state.
Textual IRC client gets round this by only having a single state, which is a strong blue, no matter whether the button is really focussed or just active.
Eg: irc.server.net/#somechannel/2015-05-04.txt
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.