/** * Copyright 2010 Google Inc. * * 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 org.waveprotocol.wave.client.state; import org.waveprotocol.wave.model.conversation.ConversationThread; import org.waveprotocol.wave.model.util.IdentitySet; /** * Monitors the conversation for the read/unread state of blips per thread. * * For the sake of efficiency, listener events will only arrive for threads * which have been explicitly queried, either through {@link #monitor} (valid * regardless of readiness) or implicitly through {@link #getReadCount} or * {@link #getUnreadCount} (only valid when ready). This is so that * implementations don't need to maintain unnecessary state for situations such * as non-inline threads, paged-out threads, and the root thread. */ public interface ThreadReadStateMonitor { /** * Listener interface for changes to read/unread blip counts. */ interface Listener { /** * Called when the read/unread count changes for a set of threads. * Also fires when the monitor becomes ready, with the initial monitored * threads. * * With a conversation structured as follows: * * | A (10, 20) * | a * | a * \_ B (4, 16) * | b * | b * \_ C (6, 4) * | c * | c * * If a blip becomes read in C then the event will be * onReadStateChanged({A, C}) where * - getReadCount(A) = 17 (10 + 6 + 1) * - getUnreadCount(A) = 23 (20 + 4 - 1) * - getReadCount(C) = 7 (6 + 1) * - getUnreadCount(C) = 3 (4 - 1) * If a read blip is added to B then the event will be * onReadStateChanged({A, B}) where * - getReadCount(A) = 15 (10 + 4 + 1) * - getUnreadCount(A) = 36 (20 + 16) * - getReadCount(B) = 5 (4 + 1) * - getUnreadCount(B) = 16 * If an unread blip is added to A then the event will be * onReadStateChanged({A}) where * - getReadCount(A) = 10 * - getUnreadCount(A) = 21 * * And so on. * * @param threads the set of threads which have been affected by a change */ void onReadStateChanged(IdentitySet<ConversationThread> threads); } /** * Starts monitoring a thread, a valid operation before the monitor is ready. * Listener events will now include this thread when its read state changes. * * Note that querying a thread through {@link #getReadCount} or * {@link #getUnreadCount} implicitly monitors a thread, if the monitor is * ready. * * @param thread the thread to monitor */ void monitor(ConversationThread thread); /** * Stops monitoring a thread, a valid operation before the monitor is ready. * Listener events will no longer include this thread. * * @param thread the thread to stop monitoring */ void ignore(ConversationThread thread); /** * Gets the read count of a thread, and implicitly starts monitoring it. * Only valid when {@link #isReady} is true (if not, may throw an exception). * * @return the current read blip count for a thread */ int getReadCount(ConversationThread thread); /** * Gets the unread count of a thread, and implicitly starts monitoring it. * Only valid when {@link #isReady} is true (if not, may throw an exception). * * @return the current unread blip count for a thread */ int getUnreadCount(ConversationThread thread); int getTotalCount(ConversationThread thread); /** * Gets whether the monitor is ready to be queried for unread counts. If not, * {@link #getReadCount} and {@link #getUnreadCount} should throw an * exception, while all other methods are valid. * * @return whether the monitor is ready */ boolean isReady(); /** * Adds a listener to change events of monitored threads. */ void addListener(Listener listener); /** * Removes a listener to change events of monitored threads. */ void removeListener(Listener listener); }