Add state holder for message activity
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
package com.github.gotify.messages.provider;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.github.gotify.Utils;
|
||||
import com.github.gotify.api.Api;
|
||||
import com.github.gotify.client.ApiClient;
|
||||
import com.github.gotify.client.ApiException;
|
||||
import com.github.gotify.client.api.TokenApi;
|
||||
import com.github.gotify.client.model.Application;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ApplicationHolder {
|
||||
private List<Application> state;
|
||||
private Runnable onUpdate;
|
||||
private Activity activity;
|
||||
private ApiClient client;
|
||||
|
||||
public ApplicationHolder(Activity activity, ApiClient client) {
|
||||
this.activity = activity;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void requestIfMissing() {
|
||||
if (state == null) {
|
||||
request();
|
||||
}
|
||||
}
|
||||
|
||||
public void request() {
|
||||
TokenApi tokenApi = new TokenApi(client);
|
||||
Api.withLogging(tokenApi::getAppsAsync)
|
||||
.handleInUIThread(activity, this::onReceiveApps, this::onFailedApps);
|
||||
}
|
||||
|
||||
private void onReceiveApps(List<Application> apps) {
|
||||
state = apps;
|
||||
onUpdate.run();
|
||||
}
|
||||
|
||||
private void onFailedApps(ApiException e) {
|
||||
Utils.showSnackBar(activity, "Could not request applications, see logs.");
|
||||
}
|
||||
|
||||
public List<Application> get() {
|
||||
return state == null ? Collections.emptyList() : state;
|
||||
}
|
||||
|
||||
public void onUpdate(Runnable runnable) {
|
||||
this.onUpdate = runnable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.github.gotify.messages.provider;
|
||||
|
||||
import com.github.gotify.client.api.MessageApi;
|
||||
import com.github.gotify.client.model.Message;
|
||||
import com.github.gotify.client.model.PagedMessages;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MessageFacade {
|
||||
private final ApplicationHolder applicationHolder;
|
||||
private final MessageRequester requester;
|
||||
private final MessageStateHolder state;
|
||||
private final MessageImageCombiner combiner;
|
||||
|
||||
public MessageFacade(MessageApi api, ApplicationHolder applicationHolder) {
|
||||
this.applicationHolder = applicationHolder;
|
||||
this.requester = new MessageRequester(api);
|
||||
this.combiner = new MessageImageCombiner();
|
||||
this.state = new MessageStateHolder();
|
||||
}
|
||||
|
||||
public List<MessageWithImage> get(Integer appId) {
|
||||
return combiner.combine(state.state(appId).messages, applicationHolder.get());
|
||||
}
|
||||
|
||||
public void addMessages(List<Message> messages) {
|
||||
for (Message message : messages) {
|
||||
state.newMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public List<MessageWithImage> loadMore(Integer appId) {
|
||||
MessageState state = this.state.state(appId);
|
||||
if (state.hasNext || !state.loaded) {
|
||||
PagedMessages pagedMessages = requester.loadMore(state);
|
||||
this.state.newMessages(appId, pagedMessages);
|
||||
}
|
||||
return get(appId);
|
||||
}
|
||||
|
||||
public List<MessageWithImage> getOrLoadMore(Integer appId) {
|
||||
MessageState state = this.state.state(appId);
|
||||
if (state.loaded) {
|
||||
return get(appId);
|
||||
}
|
||||
return loadMore(appId);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.state.clear();
|
||||
}
|
||||
|
||||
public int getLastReceivedMessage() {
|
||||
return state.getLastReceivedMessage();
|
||||
}
|
||||
|
||||
public void delete(Message message) {
|
||||
this.requester.asyncRemoveMessage(message);
|
||||
this.state.removeMessage(message);
|
||||
}
|
||||
|
||||
public boolean deleteAll(Integer appId) {
|
||||
boolean success = this.requester.deleteAll(appId);
|
||||
this.state.deleteAll(appId);
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean canLoadMore(Integer appId) {
|
||||
return state.state(appId).hasNext;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.github.gotify.messages.provider;
|
||||
|
||||
import com.github.gotify.client.model.Application;
|
||||
import com.github.gotify.client.model.Message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
class MessageImageCombiner {
|
||||
|
||||
List<MessageWithImage> combine(List<Message> messages, List<Application> applications) {
|
||||
Map<Integer, String> appIdToImage = appIdToImage(applications);
|
||||
|
||||
List<MessageWithImage> result = new ArrayList<>();
|
||||
|
||||
for (Message message : messages) {
|
||||
MessageWithImage messageWithImage = new MessageWithImage();
|
||||
|
||||
messageWithImage.message = message;
|
||||
messageWithImage.image = appIdToImage.get(message.getAppid());
|
||||
|
||||
result.add(messageWithImage);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<Integer, String> appIdToImage(List<Application> applications) {
|
||||
Map<Integer, String> map = new HashMap<>();
|
||||
for (Application app : applications) {
|
||||
map.put(app.getId(), app.getImage());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.github.gotify.messages.provider;
|
||||
|
||||
import com.github.gotify.api.Api;
|
||||
import com.github.gotify.client.ApiException;
|
||||
import com.github.gotify.client.api.MessageApi;
|
||||
import com.github.gotify.client.model.Message;
|
||||
import com.github.gotify.client.model.PagedMessages;
|
||||
import com.github.gotify.log.Log;
|
||||
|
||||
class MessageRequester {
|
||||
private static final Integer LIMIT = 100;
|
||||
private MessageApi messageApi;
|
||||
|
||||
MessageRequester(MessageApi messageApi) {
|
||||
this.messageApi = messageApi;
|
||||
}
|
||||
|
||||
PagedMessages loadMore(MessageState state) {
|
||||
try {
|
||||
Log.i("Loading more messages for " + state.appId);
|
||||
if (MessageState.ALL_MESSAGES == state.appId) {
|
||||
return messageApi.getMessages(LIMIT, state.nextSince);
|
||||
} else {
|
||||
return messageApi.getAppMessages(state.appId, LIMIT, state.nextSince);
|
||||
}
|
||||
} catch (ApiException apiException) {
|
||||
Log.e("failed requesting messages", apiException);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void asyncRemoveMessage(Message message) {
|
||||
Log.i("Removing message with id " + message.getId());
|
||||
Api.<Void>withLogging((cb) -> messageApi.deleteMessageAsync(message.getId(), cb))
|
||||
.handle((a) -> {}, (e) -> {});
|
||||
}
|
||||
|
||||
boolean deleteAll(Integer appId) {
|
||||
try {
|
||||
Log.i("Deleting all messages for " + appId);
|
||||
if (MessageState.ALL_MESSAGES == appId) {
|
||||
messageApi.deleteMessages();
|
||||
} else {
|
||||
messageApi.deleteAppMessages(appId);
|
||||
}
|
||||
return true;
|
||||
} catch (ApiException e) {
|
||||
Log.e("Could not delete messages", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.github.gotify.messages.provider;
|
||||
|
||||
import com.github.gotify.client.model.Message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MessageState {
|
||||
public static final int ALL_MESSAGES = -1;
|
||||
|
||||
int appId;
|
||||
boolean loaded;
|
||||
boolean hasNext;
|
||||
int nextSince = 0;
|
||||
List<Message> messages = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.github.gotify.messages.provider;
|
||||
|
||||
import com.github.gotify.client.model.Message;
|
||||
import com.github.gotify.client.model.PagedMessages;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class MessageStateHolder {
|
||||
private int lastReceivedMessage = -1;
|
||||
private Map<Integer, MessageState> states = new HashMap<>();
|
||||
|
||||
synchronized void clear() {
|
||||
states = new HashMap<>();
|
||||
}
|
||||
|
||||
synchronized void newMessages(Integer appId, PagedMessages pagedMessages) {
|
||||
MessageState state = state(appId);
|
||||
|
||||
if (!state.loaded && pagedMessages.getMessages().size() > 0) {
|
||||
lastReceivedMessage =
|
||||
Math.max(pagedMessages.getMessages().get(0).getId(), lastReceivedMessage);
|
||||
}
|
||||
|
||||
state.loaded = true;
|
||||
state.messages.addAll(pagedMessages.getMessages());
|
||||
state.hasNext = pagedMessages.getPaging().getNext() != null;
|
||||
state.nextSince = pagedMessages.getPaging().getSince();
|
||||
state.appId = appId;
|
||||
states.put(appId, state);
|
||||
}
|
||||
|
||||
synchronized void newMessage(Message message) {
|
||||
MessageState allMessages = state(MessageState.ALL_MESSAGES);
|
||||
MessageState appMessages = state(message.getAppid());
|
||||
|
||||
if (allMessages.loaded) {
|
||||
allMessages.messages.add(0, message);
|
||||
}
|
||||
|
||||
if (appMessages.loaded) {
|
||||
appMessages.messages.add(0, message);
|
||||
}
|
||||
|
||||
lastReceivedMessage = message.getId();
|
||||
}
|
||||
|
||||
synchronized MessageState state(Integer appId) {
|
||||
MessageState state = states.get(appId);
|
||||
if (state == null) {
|
||||
return emptyState(appId);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
void deleteAll(Integer appId) {
|
||||
clear();
|
||||
MessageState state = state(appId);
|
||||
state.loaded = true;
|
||||
states.put(appId, state);
|
||||
}
|
||||
|
||||
private MessageState emptyState(Integer appId) {
|
||||
MessageState emptyState = new MessageState();
|
||||
emptyState.loaded = false;
|
||||
emptyState.hasNext = false;
|
||||
emptyState.nextSince = 0;
|
||||
emptyState.appId = appId;
|
||||
return emptyState;
|
||||
}
|
||||
|
||||
synchronized int getLastReceivedMessage() {
|
||||
return lastReceivedMessage;
|
||||
}
|
||||
|
||||
void removeMessage(Message message) {
|
||||
MessageState allMessages = state(MessageState.ALL_MESSAGES);
|
||||
MessageState appMessages = state(message.getAppid());
|
||||
|
||||
if (allMessages.loaded) {
|
||||
allMessages.messages.remove(message);
|
||||
}
|
||||
|
||||
if (appMessages.loaded) {
|
||||
appMessages.messages.remove(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.github.gotify.messages.provider;
|
||||
|
||||
import com.github.gotify.client.model.Message;
|
||||
|
||||
public class MessageWithImage {
|
||||
public Message message;
|
||||
public String image;
|
||||
}
|
||||
Reference in New Issue
Block a user