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];
break;
case CHANNEL_NAMES_LIST:
if (params.length > 2 && params[1] == "=")
if (params.length > 2 && (params[1] == "=" || params[1] == "@"))
target = params[2];
break;
default:
@ -174,6 +174,22 @@ class UserList {
_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 {
@ -215,6 +231,12 @@ class IRCChannel {
Log.d("user list for " ~ name ~ " : " ~ userListBuffer);
userListBuffer = null;
break;
case JOIN:
users.addUser(msg.sourceAddress.nick);
break;
case PART:
users.removeUser(msg.sourceAddress.nick);
break;
default:
break;
}
@ -274,6 +296,8 @@ protected:
case CHANNEL_TOPIC_SET_BY:
case CHANNEL_NAMES_LIST:
case CHANNEL_NAMES_LIST_END:
case JOIN:
case PART:
if (msg.target.startsWith("#")) {
auto channel = channelByName(msg.target, true);
channel.handleMessage(msg);

View File

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

View File

@ -568,8 +568,8 @@ class ListWidget : WidgetGroup, OnScrollHandler, OnAdapterChangeHandler {
@property ListWidget orientation(Orientation value) {
_orientation = value;
_scrollbar.orientation = value;
requestLayout();
return this;
requestLayout();
return this;
}
protected Rect[] _itemRects;
@ -1313,23 +1313,24 @@ class StringListWidget : ListWidget {
this(string ID, string[] items) {
super(ID);
styleId = STYLE_EDIT_BOX;
adapter = new StringListAdapter(items);
ownAdapter = new StringListAdapter(items);
}
this(string ID, dstring[] items) {
super(ID);
styleId = STYLE_EDIT_BOX;
adapter = new StringListAdapter(items);
ownAdapter = new StringListAdapter(items);
}
this(string ID, StringListValue[] items) {
super(ID);
styleId = STYLE_EDIT_BOX;
adapter = new StringListAdapter(items);
ownAdapter = new StringListAdapter(items);
}
@property void items(string[] itemResourceIds) {
adapter = new StringListAdapter(itemResourceIds);
_selectedItemIndex = -1;
ownAdapter = new StringListAdapter(itemResourceIds);
if(itemResourceIds.length > 0) {
selectedItemIndex = 0;
}
@ -1337,7 +1338,8 @@ class StringListWidget : ListWidget {
}
@property void items(dstring[] items) {
adapter = new StringListAdapter(items);
_selectedItemIndex = -1;
ownAdapter = new StringListAdapter(items);
if(items.length > 0) {
selectedItemIndex = 0;
}
@ -1345,7 +1347,8 @@ class StringListWidget : ListWidget {
}
@property void items(StringListValue[] items) {
adapter = new StringListAdapter(items);
_selectedItemIndex = -1;
ownAdapter = new StringListAdapter(items);
if(items.length > 0) {
selectedItemIndex = 0;
}