Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modified for SImplicity #72

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
module.exports = {
extends: 'airbnb',
extends: "airbnb",
plugins: [],
rules: {
'prefer-rest-params': 'off',
'prefer-spread': 'off',
'function-paren-newline': 'off',
'comma-dangle': ['error', {
'objects': 'always-multiline',
'functions': 'never',
}]
},
"prefer-rest-params": "off",
"prefer-spread": "off",
"function-paren-newline": "off",
"comma-dangle": [
"error",
{
objects: "always-multiline",
functions: "never"
}
]
}
};
2 changes: 2 additions & 0 deletions .exenv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Use Example Below to add slack token to environment.
SLACK_TOKEN='xoxp-254112160503-252950188691-252375361712-6cbf56aada30951a9d310a5f23d032a0'
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.swp
*.swo
node_modules/
.env
1 change: 1 addition & 0 deletions FASTstart.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npm start
134 changes: 80 additions & 54 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const notifier = require('node-notifier');
const path = require('path');
const notifier = require("node-notifier");
const path = require("path");

const ui = require('./userInterface.js');
const slack = require('./slackClient.js');
const ui = require("./userInterface.js");
const slack = require("./slackClient.js");

const components = ui.init(); // ui components
let users;
let currentUser;
let channels;
let currentChannelId;

const UNKNOWN_USER_NAME = 'Unknown User';
const UNKNOWN_USER_NAME = "Unknown User";
// This is a hack to make the message list scroll to the bottom whenever a message is sent.
// Multiline messages would otherwise only scroll one line per message leaving part of the message
// cut off. This assumes that messages will be less than 50 lines high in the chat window.
Expand All @@ -33,14 +33,14 @@ function handleSentConfirmation(message) {
let line;
let i;
for (i = keys.length - 1; i >= 0; i -= 1) {
line = lines[keys[i]].split('(pending - ');
line = lines[keys[i]].split("(pending - ");
if (parseInt(line.pop()[0], 10) === message.reply_to) {
components.chatWindow.deleteLine(parseInt(keys[i], 10));

if (message.ok) {
components.chatWindow.insertLine(i, line.join(''));
components.chatWindow.insertLine(i, line.join(""));
} else {
components.chatWindow.insertLine(i, `${line.join('')} (FAILED)`);
components.chatWindow.insertLine(i, `${line.join("")} (FAILED)`);
}
break;
}
Expand All @@ -51,8 +51,8 @@ function handleSentConfirmation(message) {

// formats channel and user mentions readably
function formatMessageMentions(text) {
if (text === null || typeof text === 'undefined') {
return '';
if (text === null || typeof text === "undefined") {
return "";
}

let formattedText = text;
Expand All @@ -61,20 +61,21 @@ function formatMessageMentions(text) {
if (userMentions !== null) {
userMentions
.map(match => match.substr(2, match.length - 3))
.forEach((userId) => {
.forEach(userId => {
let username;
let modifier;
if (userId === currentUser.id) {
username = currentUser.name;
modifier = 'yellow-fg';
modifier = "yellow-fg";
} else {
const user = users.find(potentialUser => potentialUser.id === userId);
username = typeof user === 'undefined' ? UNKNOWN_USER_NAME : user.name;
modifier = 'underline';
username =
typeof user === "undefined" ? UNKNOWN_USER_NAME : user.name;
modifier = "underline";
}

formattedText = text.replace(
new RegExp(`<@${userId}>`, 'g'),
new RegExp(`<@${userId}>`, "g"),
`{${modifier}}@${username}{/${modifier}}`
);
});
Expand All @@ -83,7 +84,7 @@ function formatMessageMentions(text) {
// find special words
return formattedText.replace(
/<!channel>/g,
'{yellow-fg}@channel{/yellow-fg}'
"{yellow-fg}@channel{/yellow-fg}"
);
}

Expand All @@ -96,15 +97,17 @@ function handleNewMessage(message) {
username = (author && author.name) || UNKNOWN_USER_NAME;

notifier.notify({
icon: path.join(__dirname, 'Slack_Mark_Black_Web.png'),
icon: path.join(__dirname, "Slack_Mark_Black_Web.png"),
message: `${username}: ${message.text}`,
sound: true,
title: 'Terminal Slack',
title: "Terminal Slack"
});
}

if (message.channel !== currentChannelId ||
typeof message.text === 'undefined') {
if (
message.channel !== currentChannelId ||
typeof message.text === "undefined"
) {
return;
}

Expand All @@ -125,12 +128,12 @@ slack.init((data, ws) => {
// re render screen
components.screen.render();

ws.on('message', (message /* , flags */) => {
ws.on("message", (message /* , flags */) => {
const parsedMessage = JSON.parse(message);

if ('reply_to' in parsedMessage) {
if ("reply_to" in parsedMessage) {
handleSentConfirmation(parsedMessage);
} else if (parsedMessage.type === 'message') {
} else if (parsedMessage.type === "message") {
handleNewMessage(parsedMessage);
}
});
Expand All @@ -139,7 +142,7 @@ slack.init((data, ws) => {
// that relies on websockets

// event handler when message is submitted
components.messageInput.on('submit', (text) => {
components.messageInput.on("submit", text => {
if (!text || !text.length) {
components.messageInput.focus();
return;
Expand All @@ -148,48 +151,60 @@ slack.init((data, ws) => {
const id = getNextId();
components.messageInput.clearValue();
components.messageInput.focus();
components.chatWindow.scrollTo(components.chatWindow.getLines().length * SCROLL_PER_MESSAGE);
components.chatWindow.scrollTo(
components.chatWindow.getLines().length * SCROLL_PER_MESSAGE
);
components.chatWindow.insertBottom(
`{bold}${currentUser.name}{/bold}: ${text} (pending - ${id})`
);
components.chatWindow.scroll(SCROLL_PER_MESSAGE);

components.screen.render();
ws.send(JSON.stringify({
id,
type: 'message',
channel: currentChannelId,
text,
}));
ws.send(
JSON.stringify({
id,
type: "message",
channel: currentChannelId,
text
})
);
});

// set the user list to the users returned from slack
// called here to check against currentUser
slack.getUsers((error, response, userData) => {
if (error || response.statusCode !== 200) {
console.log( // eslint-disable-line no-console
'Error: ', error, response || response.statusCode
console.log(
// eslint-disable-line no-console
"Error: ",
error,
response || response.statusCode
);
return;
}

const parsedUserData = JSON.parse(userData);
users = parsedUserData.members.filter(user => !user.deleted && user.id !== currentUser.id);
users = parsedUserData.members.filter(
user => !user.deleted && user.id !== currentUser.id
);

components.userList.setItems(users.map(slackUser => slackUser.name));
components.screen.render();
});
});

// set the channel list
components.channelList.setItems(['Connecting to Slack...']);
components.channelList.setItems(["Connecting to Slack..."]);
components.screen.render();

// set the channel list to the channels returned from slack
slack.getChannels((error, response, data) => {
if (error || response.statusCode !== 200) {
console.log( // eslint-disable-line no-console
'Error: ', error, response && response.statusCode
console.log(
// eslint-disable-line no-console
"Error: ",
error,
response && response.statusCode
);
return;
}
Expand All @@ -210,11 +225,11 @@ function updateMessages(data, markFn) {
// filter and map the messages before displaying them
data.messages
.filter(item => !item.hidden)
.filter(item => item.type === 'message')
.filter(item => item.type === "message")
// Some messages related to message threading don't have text. This feature
// isn't supported by terminal-slack right now so we filter them out
.filter(item => typeof item.text !== 'undefined')
.map((message) => {
.filter(item => typeof item.text !== "undefined")
.map(message => {
const len = users.length;
let username;
let i;
Expand All @@ -232,10 +247,12 @@ function updateMessages(data, markFn) {
}
return { text: message.text, username: username || UNKNOWN_USER_NAME };
})
.forEach((message) => {
.forEach(message => {
// add messages to window
components.chatWindow.unshiftLine(
`{bold}${message.username}{/bold}: ${formatMessageMentions(message.text)}`
`{bold}${message.username}{/bold}: ${formatMessageMentions(
message.text
)}`
);
});

Expand All @@ -246,39 +263,45 @@ function updateMessages(data, markFn) {

// reset messageInput and give focus
components.messageInput.clearValue();
components.chatWindow.scrollTo(components.chatWindow.getLines().length * SCROLL_PER_MESSAGE);
components.chatWindow.scrollTo(
components.chatWindow.getLines().length * SCROLL_PER_MESSAGE
);
components.messageInput.focus();
components.screen.render();
}

components.userList.on('select', (data) => {
components.userList.on("select", data => {
const username = data.content;

// a channel was selected
components.mainWindowTitle.setContent(`{bold}${username}{/bold}`);
components.chatWindow.setContent('Getting messages...');
components.chatWindow.setContent("Getting messages...");
components.screen.render();

// get user's id
const userId = users.find(potentialUser => potentialUser.name === username).id;
const userId = users.find(potentialUser => potentialUser.name === username)
.id;

slack.openIm(userId, (error, response, imData) => {
const parsedImData = JSON.parse(imData);
currentChannelId = parsedImData.channel.id;

// load im history
slack.getImHistory(currentChannelId, (histError, histResponse, imHistoryData) => {
updateMessages(JSON.parse(imHistoryData), slack.markIm);
});
slack.getImHistory(
currentChannelId,
(histError, histResponse, imHistoryData) => {
updateMessages(JSON.parse(imHistoryData), slack.markIm);
}
);
});
});

components.channelList.on('select', (data) => {
components.channelList.on("select", data => {
const channelName = data.content;

// a channel was selected
components.mainWindowTitle.setContent(`{bold}${channelName}{/bold}`);
components.chatWindow.setContent('Getting messages...');
components.chatWindow.setContent("Getting messages...");
components.screen.render();

// join the selected channel
Expand All @@ -287,8 +310,11 @@ components.channelList.on('select', (data) => {
currentChannelId = parsedChannelData.channel.id;

// get the previous messages of the channel and display them
slack.getChannelHistory(currentChannelId, (histError, histResponse, channelHistoryData) => {
updateMessages(JSON.parse(channelHistoryData), slack.markChannel);
});
slack.getChannelHistory(
currentChannelId,
(histError, histResponse, channelHistoryData) => {
updateMessages(JSON.parse(channelHistoryData), slack.markChannel);
}
);
});
});
Loading