/* * Copyright (C) 2014 Eric Butler * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.tapchatapp.android.client.model; import android.text.TextUtils; import android.util.Log; import com.google.common.collect.ImmutableMap; import com.tapchatapp.android.client.MessageHandler; import com.tapchatapp.android.client.message.ChannelInitMessage; import com.tapchatapp.android.client.message.ChannelModeIsMessage; import com.tapchatapp.android.client.message.ChannelModeMessage; import com.tapchatapp.android.client.message.ChannelTimestampMessage; import com.tapchatapp.android.client.message.ChannelTopicMessage; import com.tapchatapp.android.client.message.JoinedChannelMessage; import com.tapchatapp.android.client.message.KickedChannelMessage; import com.tapchatapp.android.client.message.MakeBufferMessage; import com.tapchatapp.android.client.message.NickchangeMessage; import com.tapchatapp.android.client.message.PartedChannelMessage; import com.tapchatapp.android.client.message.UserAwayMessage; import com.tapchatapp.android.client.message.UserBackMessage; import com.tapchatapp.android.client.message.UserChannelModeMessage; import com.tapchatapp.android.client.message.UserDetailsMessage; import com.tapchatapp.android.client.message.YouJoinedChannelMessage; import com.tapchatapp.android.client.message.YouNickchangeMessage; import com.tapchatapp.android.client.message.YouPartedChannelMessage; import com.tapchatapp.android.client.message.request.QuitMessage; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; public class ChannelBuffer extends ChatBuffer { private boolean mJoined; private String mTopic; private final Map<String, Member> mMembers = Collections.synchronizedMap(new TreeMap<String, Member>()); ChannelBuffer(Connection connection, MakeBufferMessage message) throws Exception { super(connection, message); updateDetails(message); } @Override public int getType() { return CHANNEL_TYPE; } public String getTopic() { return mTopic; } public boolean isJoined() { return mJoined; } @Override public boolean isActive() { return super.isActive() && isJoined(); } public ArrayList<Member> getMembers() { synchronized (mMembers) { return new ArrayList<Member>(mMembers.values()); } } public void join() { getConnection().join(getName(), null); } public void part() { getConnection().part(getName(), null); } @Override public void reload(MakeBufferMessage message) { super.reload(message); updateDetails(message); } private void updateDetails(MakeBufferMessage message) { /* { "bid":17909, "eid":-1, "type":"makebuffer", "time":-1, "highlight":false, "name":"#test", "buffer_type":"channel", "cid":2135, "max_eid":503, "focus":false, "last_seen_eid":389, "joined":false, "hidden":true, "backlog_length":100 } */ mJoined = message.joined; notifyChanged(); } @Override protected Map<String, MessageHandler> getMessageHandlers() { return new ImmutableMap.Builder<String, MessageHandler>() .put(ChannelInitMessage.TYPE, new MessageHandler<ChannelInitMessage>() { @Override public void handleMessage(ChannelInitMessage message) throws Exception { ChannelTopic topic = message.topic; if (!TextUtils.isEmpty("topic_text")) { mTopic = topic.topic_text; } else if (!TextUtils.isEmpty(topic.text)) { mTopic = topic.text; } synchronized (mMembers) { List<ChannelInitMessage.Member> members = message.members; for (ChannelInitMessage.Member member : members) { mMembers.put(member.nick, new Member(member.nick)); } } mJoined = true; // FIXME ? notifyChanged(); } }) .put(ChannelTimestampMessage.TYPE, new MessageHandler<ChannelTimestampMessage>() { @Override public void handleMessage(ChannelTimestampMessage message) throws Exception { // FIXME: } }) .put(UserAwayMessage.TYPE, new MessageHandler<UserAwayMessage>() { @Override public void handleMessage(UserAwayMessage message) throws Exception { // FIXME: } }) .put(UserBackMessage.TYPE, new MessageHandler<UserBackMessage>() { @Override public void handleMessage(UserBackMessage message) throws Exception { // FIXME: } }) .put(UserDetailsMessage.TYPE, new MessageHandler<UserDetailsMessage>() { @Override public void handleMessage(UserDetailsMessage message) throws Exception { // FIXME: } }) .build(); } @Override protected Map<String, MessageHandler> getInitializedMessageHandlers() { return new ImmutableMap.Builder<String, MessageHandler>() .put(ChannelTopicMessage.TYPE, new MessageHandler<ChannelTopicMessage>() { @Override public void handleMessage(ChannelTopicMessage message) throws Exception { mTopic = message.topic; notifyChanged(); } }) .put(UserChannelModeMessage.TYPE, new MessageHandler<UserChannelModeMessage>() { @Override public void handleMessage(UserChannelModeMessage message) throws Exception { // FIXME: mMembers.get(message.getString("nick")).setMode(message); } }) .put(ChannelModeMessage.TYPE, new MessageHandler<ChannelModeMessage>() { @Override public void handleMessage(ChannelModeMessage message) throws Exception { // FIXME: // {"bid":106792,"eid":40,"type":"channel_mode","time":1332377704,"highlight":false,"channel":"#iv","server":"efnet.xs4all.nl","cid":13599,"diff":"+nt","newmode":"nt","ops":{"add":[{"mode":"t","param":""},{"mode":"n","param":""}],"remove":[]}} } }) .put(ChannelModeIsMessage.TYPE, new MessageHandler<ChannelModeIsMessage>() { @Override public void handleMessage(ChannelModeIsMessage message) throws Exception { // FIXME } }) .put(JoinedChannelMessage.TYPE, new MessageHandler<JoinedChannelMessage>() { @Override public void handleMessage(JoinedChannelMessage message) throws Exception { addMember(new Member(message.nick)); } }) .put(PartedChannelMessage.TYPE, new MessageHandler<PartedChannelMessage>() { @Override public void handleMessage(PartedChannelMessage message) throws Exception { removeMember(message.nick); } }) .put(QuitMessage.TYPE, new MessageHandler<QuitMessage>() { @Override public void handleMessage(QuitMessage message) throws Exception { if (!TextUtils.isEmpty(message.nick)) { removeMember(message.nick); } } }) .put(KickedChannelMessage.TYPE, new MessageHandler<KickedChannelMessage>() { @Override public void handleMessage(KickedChannelMessage message) throws Exception { removeMember(message.nick); } }) .put(YouJoinedChannelMessage.TYPE, new MessageHandler<YouJoinedChannelMessage>() { @Override public void handleMessage(YouJoinedChannelMessage message) throws Exception { mJoined = true; notifyChanged(); } }) .put(YouPartedChannelMessage.TYPE, new MessageHandler<YouPartedChannelMessage>() { @Override public void handleMessage(YouPartedChannelMessage message) throws Exception { mJoined = false; notifyChanged(); } }) .put(NickchangeMessage.TYPE, new MessageHandler<NickchangeMessage>() { @Override public void handleMessage(NickchangeMessage message) throws Exception { updateMemberNick(message); } }) .put(YouNickchangeMessage.TYPE, new MessageHandler<YouNickchangeMessage>() { @Override public void handleMessage(YouNickchangeMessage message) throws Exception { updateMemberNick(message); } }) .build(); } private void updateMemberNick(NickchangeMessage message) throws Exception { String oldNick = message.oldnick; String newNick = message.newnick; synchronized (mMembers) { Member member = mMembers.get(oldNick); if (member != null) { member.setNick(newNick); mMembers.remove(oldNick); mMembers.put(newNick, member); } else { // FIXME: Why is this happening?! Log.w("ChannelBuffer", "Couldn't find member for nickchange!"); } } } private void addMember(Member member) { synchronized (mMembers) { mMembers.put(member.getNick(), member); } // FIXME: Fire onChannelMemberAdded event notifyChanged(); } private void removeMember(String nick) { synchronized (mMembers) { mMembers.remove(nick); } // FIXME: Fire onChannelMemberRemoved event notifyChanged(); } public boolean isInChannel(String nick) { synchronized (mMembers) { return mMembers.containsKey(nick); } } }