IRC Client fixes; List fixes

This commit is contained in:
Vadim Lopatin 2016-03-16 14:49:32 +03:00
parent 9388461f7b
commit 5220409a4d
3 changed files with 80 additions and 22 deletions

View File

@ -114,7 +114,7 @@ class IRCMessage {
target = params[1]; target = params[1];
break; break;
case CHANNEL_NAMES_LIST: case CHANNEL_NAMES_LIST:
if (params.length > 2 && params[1] == "=") if (params.length > 2 && (params[1] == "=" || params[1] == "@"))
target = params[2]; target = params[2];
break; break;
default: default:
@ -174,6 +174,22 @@ class UserList {
_users.add(u); _users.add(u);
} }
} }
int findUser(string name) {
for(int i = 0; i < _users.length; i++) {
if (_users[i].nick == name)
return i;
}
return -1;
}
void addUser(string name) {
if (findUser(name) < 0)
_users.add(new IRCUser(name));
}
void removeUser(string name) {
if (int index = findUser(name)) {
_users.remove(index);
}
}
} }
class IRCChannel { class IRCChannel {
@ -215,6 +231,12 @@ class IRCChannel {
Log.d("user list for " ~ name ~ " : " ~ userListBuffer); Log.d("user list for " ~ name ~ " : " ~ userListBuffer);
userListBuffer = null; userListBuffer = null;
break; break;
case JOIN:
users.addUser(msg.sourceAddress.nick);
break;
case PART:
users.removeUser(msg.sourceAddress.nick);
break;
default: default:
break; break;
} }
@ -274,6 +296,8 @@ protected:
case CHANNEL_TOPIC_SET_BY: case CHANNEL_TOPIC_SET_BY:
case CHANNEL_NAMES_LIST: case CHANNEL_NAMES_LIST:
case CHANNEL_NAMES_LIST_END: case CHANNEL_NAMES_LIST_END:
case JOIN:
case PART:
if (msg.target.startsWith("#")) { if (msg.target.startsWith("#")) {
auto channel = channelByName(msg.target, true); auto channel = channelByName(msg.target, true);
channel.handleMessage(msg); channel.handleMessage(msg);

View File

@ -174,6 +174,11 @@ class IRCFrame : AppFrame, IRCClientCallback {
_tabs.layoutHeight = FILL_PARENT; _tabs.layoutHeight = FILL_PARENT;
//tabs.addTab(new IRCWindow("sample"), "Sample"d); //tabs.addTab(new IRCWindow("sample"), "Sample"d);
statusLine.setStatusText(toUTF32("Not Connected")); statusLine.setStatusText(toUTF32("Not Connected"));
_tabs.tabChanged = delegate(string newActiveTabId, string previousTabId) {
if (IRCWindow w = cast(IRCWindow)_tabs.tabBody(newActiveTabId)) {
w.onTabActivated();
}
};
return _tabs; return _tabs;
} }
@ -187,18 +192,23 @@ class IRCFrame : AppFrame, IRCClientCallback {
_client.connect(_settings.host, _settings.port); _client.connect(_settings.host, _settings.port);
} }
IRCWindow getOrCreateWindowFor(string party) { IRCWindow getOrCreateWindowFor(string party, bool activate) {
string winId = party; string winId = party;
IRCWindow w = cast(IRCWindow)_tabs.tabBody(winId); IRCWindow w = cast(IRCWindow)_tabs.tabBody(winId);
if (!w) { if (!w) {
w = new IRCWindow(winId, _client); w = new IRCWindow(winId, this, _client);
_tabs.addTab(w, toUTF32(winId)); _tabs.addTab(w, toUTF32(winId));
activate = true;
}
if (activate) {
_tabs.selectTab(winId);
w.onTabActivated();
} }
return w; return w;
} }
void onIRCConnect(IRCClient client) { void onIRCConnect(IRCClient client) {
IRCWindow w = getOrCreateWindowFor(client.hostPort); IRCWindow w = getOrCreateWindowFor(client.hostPort, true);
w.addLine("connected to " ~ client.hostPort); w.addLine("connected to " ~ client.hostPort);
client.sendMessage("USER " ~ _settings.userName ~ " 0 * :" ~ _settings.userRealName); client.sendMessage("USER " ~ _settings.userName ~ " 0 * :" ~ _settings.userRealName);
client.nick(_settings.nick); client.nick(_settings.nick);
@ -209,13 +219,13 @@ class IRCFrame : AppFrame, IRCClientCallback {
} }
void onIRCDisconnect(IRCClient client) { void onIRCDisconnect(IRCClient client) {
IRCWindow w = getOrCreateWindowFor(client.hostPort); IRCWindow w = getOrCreateWindowFor(client.hostPort, false);
w.addLine("disconnected from " ~ client.hostPort); w.addLine("disconnected from " ~ client.hostPort);
statusLine.setStatusText(toUTF32("Disconnected")); statusLine.setStatusText(toUTF32("Disconnected"));
} }
void onIRCPing(IRCClient client, string message) { void onIRCPing(IRCClient client, string message) {
IRCWindow w = getOrCreateWindowFor(client.hostPort); IRCWindow w = getOrCreateWindowFor(client.hostPort, false);
w.addLine("PING " ~ message); w.addLine("PING " ~ message);
client.pong(message); client.pong(message);
} }
@ -226,32 +236,34 @@ class IRCFrame : AppFrame, IRCClientCallback {
wid = source.nick; wid = source.nick;
else if (source.nick == client.nick) else if (source.nick == client.nick)
wid = target; wid = target;
IRCWindow w = getOrCreateWindowFor(wid); IRCWindow w = getOrCreateWindowFor(wid, false);
w.addLine("<" ~ (!source.nick.empty ? source.nick : source.full) ~ "> " ~ message); w.addLine("<" ~ (!source.nick.empty ? source.nick : source.full) ~ "> " ~ message);
} }
void onIRCNotice(IRCClient client, IRCAddress source, string target, string message) { void onIRCNotice(IRCClient client, IRCAddress source, string target, string message) {
IRCWindow w = getOrCreateWindowFor(target.startsWith("#") ? target : client.hostPort); IRCWindow w = getOrCreateWindowFor(target.startsWith("#") ? target : client.hostPort, false);
w.addLine("-" ~ source.full ~ "- " ~ message); w.addLine("-" ~ source.full ~ "- " ~ message);
} }
void onIRCMessage(IRCClient client, IRCMessage message) { void onIRCMessage(IRCClient client, IRCMessage message) {
IRCWindow w = getOrCreateWindowFor(client.hostPort); IRCWindow w = getOrCreateWindowFor(client.hostPort, false);
switch (message.commandId) with (IRCCommand) { switch (message.commandId) with (IRCCommand) {
case JOIN: case JOIN:
case PART: case PART:
if (message.sourceAddress && !message.sourceAddress.nick.empty && message.target.startsWith("#")) { if (message.sourceAddress && !message.sourceAddress.nick.empty && message.target.startsWith("#")) {
w = getOrCreateWindowFor(message.target); w = getOrCreateWindowFor(message.target, false);
if (message.commandId == JOIN) { if (message.commandId == JOIN) {
w.addLine("* " ~ message.sourceAddress.longName ~ " has joined " ~ message.target); w.addLine("* " ~ message.sourceAddress.longName ~ " has joined " ~ message.target);
} else { } else {
w.addLine("* " ~ message.sourceAddress.longName ~ " has left " ~ message.target ~ (message.message.empty ? "" : ("(Reason: " ~ message.message ~ ")"))); w.addLine("* " ~ message.sourceAddress.longName ~ " has left " ~ message.target ~ (message.message.empty ? "" : ("(Reason: " ~ message.message ~ ")")));
} }
IRCChannel channel = _client.channelByName(message.target);
w.updateUserList(channel);
} }
return; return;
case CHANNEL_NAMES_LIST_END: case CHANNEL_NAMES_LIST_END:
if (message.target.startsWith("#")) { if (message.target.startsWith("#")) {
w = getOrCreateWindowFor(message.target); w = getOrCreateWindowFor(message.target, false);
IRCChannel channel = _client.channelByName(message.target); IRCChannel channel = _client.channelByName(message.target);
w.updateUserList(channel); w.updateUserList(channel);
} }
@ -275,14 +287,19 @@ enum IRCWindowKind {
} }
class IRCWindow : VerticalLayout, EditorActionHandler { class IRCWindow : VerticalLayout, EditorActionHandler {
private:
IRCFrame _frame;
LogWidget _editBox; LogWidget _editBox;
StringListWidget _listBox; StringListWidget _listBox;
EditLine _editLine; EditLine _editLine;
IRCClient _client; IRCClient _client;
IRCWindowKind _kind; IRCWindowKind _kind;
this(string ID, IRCClient client) { dstring[] _userNames;
public:
this(string ID, IRCFrame frame, IRCClient client) {
super(ID); super(ID);
_client = client; _client = client;
_frame = frame;
layoutWidth = FILL_PARENT; layoutWidth = FILL_PARENT;
layoutHeight = FILL_PARENT; layoutHeight = FILL_PARENT;
HorizontalLayout hlayout = new HorizontalLayout(); HorizontalLayout hlayout = new HorizontalLayout();
@ -302,6 +319,15 @@ class IRCWindow : VerticalLayout, EditorActionHandler {
//_listBox.items = ["Nick1"d, "Nick2"d]; //_listBox.items = ["Nick1"d, "Nick2"d];
hlayout.addChild(new ResizerWidget(null, Orientation.Horizontal)); hlayout.addChild(new ResizerWidget(null, Orientation.Horizontal));
hlayout.addChild(_listBox); hlayout.addChild(_listBox);
_listBox.itemClick = delegate(Widget source, int itemIndex) {
auto user = itemIndex >= 0 && itemIndex < _userNames.length ? toUTF8(_userNames[itemIndex]) : null;
if (!user.empty && user != _client.nick) {
_frame.getOrCreateWindowFor(user, true);
}
return true;
};
_kind = IRCWindowKind.Channel; _kind = IRCWindowKind.Channel;
} else { } else {
if (id.indexOf(':') >= 0) if (id.indexOf(':') >= 0)
@ -320,8 +346,10 @@ class IRCWindow : VerticalLayout, EditorActionHandler {
window.update(); window.update();
} }
void updateUserList(IRCChannel channel) { void updateUserList(IRCChannel channel) {
_listBox.items = channel.userNames; _userNames = channel.userNames;
window.update(); _listBox.items = _userNames;
if (window)
window.update();
} }
bool onEditorAction(const Action action) { bool onEditorAction(const Action action) {
if (!_editLine.text.empty) { if (!_editLine.text.empty) {
@ -359,4 +387,7 @@ class IRCWindow : VerticalLayout, EditorActionHandler {
} }
return true; return true;
} }
void onTabActivated() {
_editLine.setFocus();
}
} }

View File

@ -1313,23 +1313,24 @@ class StringListWidget : ListWidget {
this(string ID, string[] items) { this(string ID, string[] items) {
super(ID); super(ID);
styleId = STYLE_EDIT_BOX; styleId = STYLE_EDIT_BOX;
adapter = new StringListAdapter(items); ownAdapter = new StringListAdapter(items);
} }
this(string ID, dstring[] items) { this(string ID, dstring[] items) {
super(ID); super(ID);
styleId = STYLE_EDIT_BOX; styleId = STYLE_EDIT_BOX;
adapter = new StringListAdapter(items); ownAdapter = new StringListAdapter(items);
} }
this(string ID, StringListValue[] items) { this(string ID, StringListValue[] items) {
super(ID); super(ID);
styleId = STYLE_EDIT_BOX; styleId = STYLE_EDIT_BOX;
adapter = new StringListAdapter(items); ownAdapter = new StringListAdapter(items);
} }
@property void items(string[] itemResourceIds) { @property void items(string[] itemResourceIds) {
adapter = new StringListAdapter(itemResourceIds); _selectedItemIndex = -1;
ownAdapter = new StringListAdapter(itemResourceIds);
if(itemResourceIds.length > 0) { if(itemResourceIds.length > 0) {
selectedItemIndex = 0; selectedItemIndex = 0;
} }
@ -1337,7 +1338,8 @@ class StringListWidget : ListWidget {
} }
@property void items(dstring[] items) { @property void items(dstring[] items) {
adapter = new StringListAdapter(items); _selectedItemIndex = -1;
ownAdapter = new StringListAdapter(items);
if(items.length > 0) { if(items.length > 0) {
selectedItemIndex = 0; selectedItemIndex = 0;
} }
@ -1345,7 +1347,8 @@ class StringListWidget : ListWidget {
} }
@property void items(StringListValue[] items) { @property void items(StringListValue[] items) {
adapter = new StringListAdapter(items); _selectedItemIndex = -1;
ownAdapter = new StringListAdapter(items);
if(items.length > 0) { if(items.length > 0) {
selectedItemIndex = 0; selectedItemIndex = 0;
} }