app/controllers/base_channel.js
import Controller, { inject as controller } from '@ember/controller';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { isPresent } from '@ember/utils';
import { capitalize } from '@ember/string';
import { tracked } from '@glimmer/tracking';
import Channel from 'hyperchannel/models/channel';
import Message from 'hyperchannel/models/message';
import generateMessageId from 'hyperchannel/utils/generate-message-id';
export default class BaseChannelController extends Controller {
@tracked newMessage = null;
@controller application;
@service coms;
@service router;
@service('remotestorage') storage;
get showChannelMenu () {
return this.application.showChannelMenu;
}
createMessage (content, type, attrs={}) {
const message = new Message({
id: generateMessageId(),
type: type,
date: new Date(),
// TODO nickname per channel
nickname: this.model.account.nickname,
content: content,
...attrs
});
// We only receive our own message from XMPP MUCs (but not DMs)
// TODO implement message carbons or another way of verifying sent status
if (this.model.protocol === 'XMPP' &&
(this.model instanceof Channel)) {
message.pending = true;
}
return message;
}
get sidebarClass () {
const route = this.router.currentRouteName;
const wideBars = ['shares', 'settings'].map(r => `channel.${r}`);
return wideBars.includes(route) ? 'sidebar-wide' : 'sidebar-normal';
}
@action
menu (which, what) {
// Do not toggle sidebav on desktop
if (which.match(/(global|channel)/) && window.innerWidth > 900) return;
let menuProp = `show${capitalize(which)}Menu`;
switch(what) {
case 'show':
this.application.set(menuProp, true);
break;
case 'hide':
this.application.set(menuProp, false);
break;
case 'toggle':
this.application.toggleProperty(menuProp);
break;
}
}
@action
sendMessage (content, attrs) {
// Create new message instance
const message = this.createMessage(content, 'message-chat', attrs);
// Send message job to Sockethub
this.coms.transferMessage(this.model, message);
// Add message to channel
this.model.addMessage(message);
// Reset message input
this.newMessage = null;
}
@action
executeCommand (newMessage) {
const availableCommands = [
"help",
"join",
"leave",
"me",
"msg",
"part",
"topic"
];
let commandText = newMessage.substr(1);
let commandSplitted = commandText.split(" ");
let command = commandSplitted[0];
if (availableCommands.includes(command.toLowerCase())) {
this.send(command + 'Command', commandSplitted.slice(1));
} else {
console.warn('[channel]', 'Unknown command', commandText);
}
this.newMessage = null;
}
@action
joinCommand (args) {
const channel = this.coms.createChannel(this.model.account, args[0]);
// TODO this.storage.saveChannel(channel);
this.transitionToRoute('channel', channel);
}
@action
partCommand () {
this.coms.removeChannel(this.model);
const lastChannel = this.coms.channels.lastObject;
if (isPresent(lastChannel)) {
this.transitionToRoute('channel', lastChannel);
} else {
// TODO handle zero channels left
console.warn('No channels left to transition to');
this.transitionToRoute('index');
}
}
@action
leaveCommand () {
this.send('partCommand');
}
@action
helpCommand () {
}
@action
meCommand (args) {
let newMessage = args.join(' ');
let message = this.createMessage(newMessage, 'message-chat-me');
this.coms.transferMeMessage(
this.model.account,
this.model.sockethubChannelId,
message.content,
message.id
);
this.model.addMessage(message);
}
@action
msgCommand (args) {
let username = args.shift();
this.coms.createUserChannel(this.model.account, username);
// TODO fix this, sockethub sends a failure event with error
// "TypeError: Cannot read property 'indexOf' of undefined"
// this.coms.transferMessage(username, args.join(' '));
}
@action
topicCommand (args) {
let channel = this.model;
let topic = args.join(' ');
this.coms.changeTopic(channel, topic);
}
@action
addUsernameMentionToMessage (username) {
const msg = this.newMessage || '';
if (!msg.match(new RegExp(`^${username}`))) {
this.newMessage = `${username}: ${msg}`;
}
}
@action
leaveChannel (channel) {
this.application.leaveChannel(channel);
}
}