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