diff options
author | desperateCoder <echotodevnull@gmail.com> | 2020-06-27 21:36:33 +0300 |
---|---|---|
committer | desperateCoder <echotodevnull@gmail.com> | 2020-06-27 21:36:33 +0300 |
commit | 76d6e3d5697428b3297a7be03b107a03e74dc8ab (patch) | |
tree | b7c719f1e36324b6f93c0ef485e8e81300433de9 /app/src/main/java/it/niedermann/nextcloud/deck/persistence | |
parent | 01490b471994923f629c3c1894226d232d1667de (diff) |
first (not yet working) try
Diffstat (limited to 'app/src/main/java/it/niedermann/nextcloud/deck/persistence')
4 files changed, 163 insertions, 40 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java index 59de21fe3..735436f64 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java @@ -8,6 +8,7 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import androidx.core.util.Pair; import androidx.lifecycle.LiveData; +import androidx.lifecycle.MediatorLiveData; import androidx.lifecycle.MutableLiveData; import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; @@ -48,7 +49,10 @@ import it.niedermann.nextcloud.deck.model.ocs.user.OcsUser; import it.niedermann.nextcloud.deck.model.ocs.user.OcsUserList; import it.niedermann.nextcloud.deck.persistence.sync.adapters.ServerAdapter; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DataBaseAdapter; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.WrappedLiveData; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.extrawurst.Debouncer; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.extrawurst.UserSearchLiveData; import it.niedermann.nextcloud.deck.persistence.sync.helpers.DataPropagationHelper; import it.niedermann.nextcloud.deck.persistence.sync.helpers.SyncHelper; import it.niedermann.nextcloud.deck.persistence.sync.helpers.providers.AbstractSyncDataProvider; @@ -342,30 +346,6 @@ public class SyncManager { } catch (OfflineException e) { callback.onError(e); } - - serverAdapter.getAllOcsUsers(new IResponseCallback<OcsUserList>(callback.getAccount()) { - @Override - public void onResponse(OcsUserList response) { - Long accountId = callback.getAccount().getId(); - for (String ocsUserName : response) { - User existingUser = dataBaseAdapter.getUserByUidDirectly(accountId, ocsUserName); - if (existingUser == null) { - // we don't know this user, lets get some details... - serverAdapter.getOcsUserDetails(ocsUserName, new IResponseCallback<OcsUser>(callback.getAccount()) { - @Override - public void onResponse(OcsUser response) { - User newUser = new User(); - newUser.setStatus(DBStatus.UP_TO_DATE.getId()); - newUser.setPrimaryKey(ocsUserName); - newUser.setUid(ocsUserName); - newUser.setDisplayname(response.getDisplayName()); - dataBaseAdapter.createUser(accountId, newUser); - } - }); - } - } - } - }); }); } @@ -1146,16 +1126,10 @@ public class SyncManager { public LiveData<List<Label>> findProposalsForLabelsToAssign(final long accountId, final long boardId, long notAssignedToLocalCardId) { return dataBaseAdapter.findProposalsForLabelsToAssign(accountId, boardId, notAssignedToLocalCardId); } - public LiveData<List<Label>> findProposalsForLabelsToAssign(final long accountId, final long boardId) { return findProposalsForLabelsToAssign(accountId, boardId, -1L); } - // TODO Difference to getFullBoardByid() ??? I think those methods are equal, we should drop one of them. - public LiveData<FullBoard> getFullBoard(Long accountId, Long localId) { - return dataBaseAdapter.getFullBoardById(accountId, localId); - } - public LiveData<User> getUserByLocalId(long accountId, long localId) { return dataBaseAdapter.getUserByLocalId(accountId, localId); } @@ -1172,8 +1146,8 @@ public class SyncManager { return dataBaseAdapter.searchUserByUidOrDisplayName(accountId, boardId, notYetAssignedToLocalCardId, searchTerm); } - public LiveData<List<User>> searchUserByUidOrDisplayNameForACL(final long accountId, final long notYetAssignedInACL, final String searchTerm) { - return dataBaseAdapter.searchUserByUidOrDisplayNameForACL(accountId, notYetAssignedInACL, searchTerm); + public UserSearchLiveData searchUserByUidOrDisplayNameForACL() { + return new UserSearchLiveData(dataBaseAdapter, serverAdapter); } public LiveData<Board> getBoard(long accountId, long remoteId) { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java index 4f41173e9..50110c20e 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java @@ -39,7 +39,6 @@ import it.niedermann.nextcloud.deck.model.full.FullStack; import it.niedermann.nextcloud.deck.model.ocs.Capabilities; import it.niedermann.nextcloud.deck.model.ocs.comment.DeckComment; import it.niedermann.nextcloud.deck.model.ocs.comment.OcsComment; -import it.niedermann.nextcloud.deck.model.ocs.user.OcsUser; import it.niedermann.nextcloud.deck.model.ocs.user.OcsUserList; import it.niedermann.nextcloud.deck.model.propagation.CardUpdate; import it.niedermann.nextcloud.deck.model.propagation.Reorder; @@ -153,14 +152,9 @@ public class ServerAdapter { ensureInternetConnection(); RequestHelper.request(provider, () -> provider.getNextcloudAPI().getCapabilities(), responseCallback); } - public void getAllOcsUsers(IResponseCallback<OcsUserList> responseCallback) { + public void searchUser(String searchTerm, IResponseCallback<OcsUserList> responseCallback) { ensureInternetConnection(); - RequestHelper.request(provider, () -> provider.getNextcloudAPI().getAllUsers(), responseCallback); - } - - public void getOcsUserDetails(String ocsUserName, IResponseCallback<OcsUser> responseCallback) { - ensureInternetConnection(); - RequestHelper.request(provider, () -> provider.getNextcloudAPI().getUserDetails(ocsUserName), responseCallback); + RequestHelper.request(provider, () -> provider.getNextcloudAPI().searchUser(searchTerm), responseCallback); } public void getActivitiesForCard(long cardId, IResponseCallback<List<it.niedermann.nextcloud.deck.model.ocs.Activity>> responseCallback) { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/Debouncer.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/Debouncer.java new file mode 100644 index 000000000..fca4ca369 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/Debouncer.java @@ -0,0 +1,75 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.extrawurst; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class Debouncer <T> { + private final ScheduledExecutorService sched = Executors.newScheduledThreadPool(1); + private final ConcurrentHashMap<T, TimerTask> delayedMap = new ConcurrentHashMap<T, TimerTask>(); + private final Callback<T> callback; + private final int interval; + + public Debouncer(Callback<T> c, int interval) { + this.callback = c; + this.interval = interval; + } + + public void call(T key) { + TimerTask task = new TimerTask(key); + + TimerTask prev; + do { + prev = delayedMap.putIfAbsent(key, task); + if (prev == null) + sched.schedule(task, interval, TimeUnit.MILLISECONDS); + // Exit only if new task was added to map, or existing task was extended successfully + } while (prev != null && !prev.extend()); + } + + public void terminate() { + sched.shutdownNow(); + } + + public interface Callback<T> { + void call(T key); + } + + // The task that wakes up when the wait time elapses + private class TimerTask implements Runnable { + private final T key; + private long dueTime; + private final Object lock = new Object(); + + public TimerTask(T key) { + this.key = key; + extend(); + } + + public boolean extend() { + synchronized (lock) { + if (dueTime < 0) // Task has been shutdown + return false; + dueTime = System.currentTimeMillis() + interval; + return true; + } + } + + public void run() { + synchronized (lock) { + long remaining = dueTime - System.currentTimeMillis(); + if (remaining > 0) { // Re-schedule task + sched.schedule(this, remaining, TimeUnit.MILLISECONDS); + } else { // Mark as terminated and invoke callback + dueTime = -1; + try { + callback.call(key); + } finally { + delayedMap.remove(key); + } + } + } + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/UserSearchLiveData.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/UserSearchLiveData.java new file mode 100644 index 000000000..41d451e2f --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/UserSearchLiveData.java @@ -0,0 +1,80 @@ +package it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.extrawurst; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MediatorLiveData; + +import java.util.ArrayList; +import java.util.List; + +import it.niedermann.nextcloud.deck.api.IResponseCallback; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.model.enums.DBStatus; +import it.niedermann.nextcloud.deck.model.ocs.user.OcsUser; +import it.niedermann.nextcloud.deck.model.ocs.user.OcsUserList; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.ServerAdapter; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DataBaseAdapter; + +public class UserSearchLiveData extends MediatorLiveData<List<User>> implements Debouncer.Callback<Long> { + + private static final int DEBOUNCE_TIME = 300; // ms + private DataBaseAdapter db; + private ServerAdapter server; + private List<User> foundInDB; + long accountId; + String searchTerm; + long notYetAssignedInACL; + private Debouncer<Long> debouncer = new Debouncer<>(this, DEBOUNCE_TIME); + + public UserSearchLiveData(DataBaseAdapter db, ServerAdapter server) { + this.db = db; + this.server = server; + } + + public UserSearchLiveData search(long accountId, long notYetAssignedInACL, String searchTerm) { + this.accountId = accountId; + this.searchTerm = searchTerm; + this.notYetAssignedInACL = notYetAssignedInACL; + new Thread(() -> debouncer.call(notYetAssignedInACL)).start(); + return this; + } + + + @Override + public void call(Long key) { + if (key!=notYetAssignedInACL){ + return; + } + LiveData<List<User>> dbLiveData = db.searchUserByUidOrDisplayNameForACL(accountId, notYetAssignedInACL, searchTerm); + addSource(dbLiveData, changedData -> { + foundInDB = changedData; + postValue(changedData); + } + ); + + Account account = db.getAccountByIdDirectly(accountId); + server.searchUser(searchTerm, new IResponseCallback<OcsUserList>(account) { + @Override + public void onResponse(OcsUserList response) { + if (response == null || response.getUsers().isEmpty()){ + return; + } + List<User> allFound = new ArrayList<>(); + allFound.addAll(foundInDB); + for (OcsUser user : response.getUsers()) { + User existingUser = db.getUserByUidDirectly(accountId, user.getId()); + if (existingUser == null) { + User newUser = new User(); + newUser.setStatus(DBStatus.UP_TO_DATE.getId()); + newUser.setPrimaryKey(user.getId()); + newUser.setUid(user.getId()); + newUser.setDisplayname(user.getDisplayName()); + db.createUser(accountId, newUser); + allFound.add(newUser); + } + } + postValue(allFound); + } + }); + } +} |