com.fusionx.lightirc.ui.UserListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.fusionx.lightirc.ui.UserListFragment.java

Source

/*
HoloIRC - an IRC client for Android
    
Copyright 2013 Lalit Maganti
    
This file is part of HoloIRC.
    
HoloIRC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
HoloIRC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with HoloIRC. If not, see <http://www.gnu.org/licenses/>.
 */

package com.fusionx.lightirc.ui;

import com.fusionx.lightirc.R;
import com.fusionx.lightirc.adapters.UserListAdapter;
import com.fusionx.lightirc.event.OnConversationChanged;
import com.fusionx.lightirc.misc.FragmentType;
import com.fusionx.lightirc.util.FragmentUtils;
import com.fusionx.relay.Channel;
import com.fusionx.relay.WorldUser;
import com.fusionx.relay.event.channel.NameEvent;
import com.fusionx.relay.event.channel.WorldUserEvent;
import com.fusionx.relay.misc.IRCUserComparator;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.TreeSet;

import de.greenrobot.event.EventBus;
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;

public class UserListFragment extends Fragment
        implements AbsListView.MultiChoiceModeListener, AdapterView.OnItemClickListener {

    private ActionMode mActionMode;

    private Callback mCallback;

    private Channel mChannel;

    private final Object mEventHandler = new Object() {
        @SuppressWarnings("unused")
        public void onEvent(final OnConversationChanged conversationChanged) {
            // If it's null then remove the old conversation
            if (conversationChanged.conversation == null
                    || conversationChanged.fragmentType != FragmentType.CHANNEL) {
                if (mChannel != null) {
                    mChannel.getServer().getServerEventBus().unregister(UserListFragment.this);
                }
                mChannel = null;
                return;
            }
            if (mChannel != null) {
                mChannel.getServer().getServerEventBus().unregister(UserListFragment.this);
            }

            mChannel = (Channel) conversationChanged.conversation;
            mChannel.getServer().getServerEventBus().register(UserListFragment.this);
            onUpdateUserList();
        }
    };

    private UserListAdapter mAdapter;

    private TreeSet<WorldUser> mWorldUsers;

    private StickyListHeadersListView mStickyListView;

    @Override
    public void onAttach(final Activity activity) {
        super.onAttach(activity);

        mCallback = FragmentUtils.getParent(this, Callback.class);
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
            final Bundle savedInstanceState) {
        return inflater.inflate(R.layout.default_stickylist_view, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mStickyListView = (StickyListHeadersListView) view.findViewById(android.R.id.list);
        mAdapter = new UserListAdapter(view.getContext(), mWorldUsers);

        getListView().setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
        getListView().getWrappedList().setMultiChoiceModeListener(this);
        getListView().setOnItemClickListener(this);
        getListView().setFastScrollEnabled(true);
    }

    @Override
    public void onResume() {
        super.onResume();

        // On resume, we may have missed events in the background - make sure we have the most
        // up-to-date user list - register the event handler sticky so we can get the latest info
        EventBus.getDefault().registerSticky(mEventHandler);
    }

    @Override
    public void onPause() {
        super.onPause();

        EventBus.getDefault().unregister(mEventHandler);

        // On a pause, it could lead to a stop in which case we don't actually know what's going
        // on in the background - stop observation and restart when we return
        if (mChannel != null) {
            mChannel.getServer().getServerEventBus().unregister(this);
        }
    }

    public void onUpdateUserList() {
        mCallback.updateUserListVisibility();

        final Collection<WorldUser> userList = mChannel.getUsers();

        getListView().setAdapter(null);
        mAdapter.setChannel(mChannel);
        mWorldUsers = new TreeSet<>(new IRCUserComparator(mChannel));
        mWorldUsers.addAll(userList);
        mAdapter.setInternalSet(mWorldUsers);
        getListView().setAdapter(mAdapter);

        if (mActionMode != null) {
            mActionMode.finish();
        }
    }

    /*
     * Subscribed events
     *
     * Only perform an action if the channel that is being observed currently is the one the
     * event is referring to
     */
    @SuppressWarnings("unused")
    public void onEventMainThread(final WorldUserEvent event) {
        if (mChannel != null && event.channelName.equals(mChannel.getName()) && event.isUserListChangeEvent()) {
            onUpdateUserList();
        }
    }

    @SuppressWarnings("unused")
    public void onEventMainThread(final NameEvent event) {
        if (mChannel != null && event.channelName.equals(mChannel.getName())) {
            onUpdateUserList();
        }
    }
    // End of subscribed events

    public StickyListHeadersListView getListView() {
        return mStickyListView;
    }

    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
        int selectedItemCount = getCheckedItems().size();

        if (selectedItemCount != 0) {
            final String quantityString = getResources().getQuantityString(R.plurals.user_selection,
                    selectedItemCount, selectedItemCount);
            mode.setTitle(quantityString);

            mode.getMenu().getItem(1).setVisible(selectedItemCount == 1);
            mode.getMenu().getItem(2).setVisible(selectedItemCount == 1);
        }
    }

    @Override
    public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
        mActionMode = mode;

        final MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.fragment_userlist_cab, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(final ActionMode mode, final Menu menu) {
        return true;
    }

    @Override
    public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
        final List<WorldUser> selectedItems = getCheckedItems();
        final String nick = selectedItems.get(0).getNick();
        switch (item.getItemId()) {
        case R.id.fragment_userlist_cab_mention:
            mCallback.onMentionMultipleUsers(selectedItems);
            mode.finish();
            mCallback.closeDrawer();
            return true;
        case R.id.fragment_userlist_cab_pm: {
            onPrivateMessageUser(nick);
            return true;
        }
        case R.id.fragment_userlist_cab_whois:
            mChannel.getServer().getServerCallBus().sendUserWhois(nick);
            return true;
        default:
            return false;
        }
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mActionMode = null;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final boolean checked = getListView().getCheckedItemPositions().get(position);
        getListView().setItemChecked(position, !checked);

        if (mActionMode == null) {
            getActivity().startActionMode(this);
        }
    }

    protected List<WorldUser> getCheckedItems() {
        final List<WorldUser> checkedSessionPositions = new ArrayList<>();
        if (mStickyListView == null) {
            return checkedSessionPositions;
        }

        final SparseBooleanArray checkedPositionsBool = mStickyListView.getCheckedItemPositions();
        for (int i = 0; i < checkedPositionsBool.size(); i++) {
            if (checkedPositionsBool.valueAt(i)) {
                checkedSessionPositions.add(mAdapter.getItem(checkedPositionsBool.keyAt(i)));
            }
        }

        return checkedSessionPositions;
    }

    boolean isNickOtherUsers(final String nick) {
        return !mChannel.getServer().getUser().getNick().equals(nick);
    }

    private void onPrivateMessageUser(final String nick) {
        if (isNickOtherUsers(nick)) {
            mChannel.getServer().getServerCallBus().sendMessageToUser(nick, "");
            mCallback.closeDrawer();
            mActionMode.finish();
        } else {
            final AlertDialog.Builder build = new AlertDialog.Builder(getActivity());
            build.setTitle(getActivity().getString(R.string.user_list_not_possible))
                    .setMessage(getActivity().getString(R.string.user_list_pm_self_not_possible))
                    .setPositiveButton(getActivity().getString(R.string.ok), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    });
            build.show();
        }
    }

    public interface Callback {

        public void onMentionMultipleUsers(final List<WorldUser> users);

        public void updateUserListVisibility();

        public void closeDrawer();
    }
}