simonlang.coastdove.messengerencryption.ChatOverlay.java Source code

Java tutorial

Introduction

Here is the source code for simonlang.coastdove.messengerencryption.ChatOverlay.java

Source

/*  Coast Dove
Copyright (C) 2016  Simon Lang
Contact: simon.lang7 at gmail dot com
    
This program 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.
    
This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package simonlang.coastdove.messengerencryption;

import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import android.support.v4.util.SparseArrayCompat;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.ListView;

import java.util.Iterator;
import java.util.LinkedList;

import simonlang.coastdove.lib.ScrollPosition;
import simonlang.coastdove.lib.ViewTreeNode;

/**
 * Chat overlay
 */
public class ChatOverlay extends Overlay {
    private EncryptionService mService;
    private ListView mListView;
    private MessageListAdapter mListAdapter;
    private ViewTreeNode mIdListNode;
    private ScrollPosition mScrollPosition;
    private SparseArrayCompat<ViewTreeNode> mMessages;
    private Pair<Integer, Integer> mLastListItemMapping;

    public ChatOverlay(@NonNull EncryptionService service, int resource) {
        super(service, resource);
        mService = service;
        mListAdapter = new MessageListAdapter(service);
        mMessages = new SparseArrayCompat<>(60);
        mLastListItemMapping = new Pair<>(0, 0);
    }

    public void addMessages(ViewTreeNode idListNode, LinkedList<ViewTreeNode> messages,
            ScrollPosition scrollPosition) {
        if (idListNode == null || scrollPosition == null) {
            mMessages.clear();
            mListAdapter.clear();
            return;
        }

        mIdListNode = idListNode;
        if (mScrollPosition == null || mScrollPosition.getItemCount() != scrollPosition.getItemCount()) {
            mMessages.clear();
        }

        mScrollPosition = scrollPosition;
        Iterator<ViewTreeNode> it = messages.iterator();
        if (messages.size() != scrollPosition.getToIndex() + 1 - scrollPosition.getFromIndex()) {
            return;
        }
        for (int i = scrollPosition.getFromIndex(); i <= scrollPosition.getToIndex() && it.hasNext(); ++i) {
            mMessages.put(i, it.next());
        }

        mListAdapter.clear();
        for (int i = 0; i < mMessages.size(); ++i) {
            int key = mMessages.keyAt(i);
            mListAdapter.add(mMessages.get(key));
        }
        mLastListItemMapping = new Pair<>(mMessages.size() - 1, scrollPosition.getItemCount() - 1);
    }

    @Override
    public void inflate() {
        super.inflate();
        mListView = (ListView) findViewById(R.id.list);
        mListView.setAdapter(mListAdapter);
        Button previous = (Button) findViewById(R.id.button_load_previous);
        Button next = (Button) findViewById(R.id.button_load_next);
        if (Build.VERSION.SDK_INT >= 23) {
            previous.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mService.requestAction(mIdListNode,
                            AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
                }
            });
            next.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Bundle args = new Bundle();
                    args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_ROW_INT, 103);
                    mService.requestAction(mIdListNode,
                            AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
                }
            });
        }

        mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            private boolean mScrollingUp = false;
            private int mPrevFirstVisibileItem = 0;

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (mPrevFirstVisibileItem > view.getFirstVisiblePosition())
                    mScrollingUp = true;
                else
                    mScrollingUp = false;
                if (scrollState == SCROLL_STATE_IDLE) {
                    mPrevFirstVisibileItem = view.getFirstVisiblePosition();

                    Bundle args = new Bundle();

                    if (view.getFirstVisiblePosition() == 0) {
                        mService.requestAction(mIdListNode,
                                AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
                    } else if (view.getLastVisiblePosition() == view.getCount() - 1) {
                        mService.requestAction(mIdListNode,
                                AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
                    } else {
                        int differenceFromLast = mLastListItemMapping.first
                                - (mScrollingUp ? view.getFirstVisiblePosition() : view.getLastVisiblePosition());
                        args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_ROW_INT,
                                mLastListItemMapping.second - differenceFromLast);
                        mService.requestAction(mIdListNode,
                                AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_TO_POSITION, args);
                    }
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            }
        });
    }
}