Added code to debounce filtering on the client-side so we don't send a

bunch of extra requests to the backend when searching.
This commit is contained in:
casey langen 2017-02-18 13:55:42 -08:00
parent 264f564243
commit 0fd1e0bff9
6 changed files with 100 additions and 22 deletions

View File

@ -61,7 +61,7 @@ public class AlbumBrowseActivity extends WebSocketActivityBase implements Filter
private TransportFragment transport;
private String categoryName;
private long categoryId;
private String filter = "";
private String lastFilter = "";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -97,8 +97,8 @@ public class AlbumBrowseActivity extends WebSocketActivityBase implements Filter
@Override
public void setFilter(String filter) {
this.filter = filter;
requery();
this.lastFilter = filter;
filterDebouncer.call(filter);
}
@Override
@ -122,17 +122,28 @@ public class AlbumBrowseActivity extends WebSocketActivityBase implements Filter
.request(Messages.Request.QueryAlbums)
.addOption(Messages.Key.CATEGORY, categoryName)
.addOption(Messages.Key.CATEGORY_ID, categoryId)
.addOption(Key.FILTER, filter)
.addOption(Key.FILTER, lastFilter)
.build();
wss.send(message, socketClient, (SocketMessage response) ->
adapter.setModel(response.getJsonArrayOption(Messages.Key.DATA)));
}
private final Debouncer<String> filterDebouncer = new Debouncer<String>(350) {
@Override
protected void onDebounced(String context) {
if (!isPaused()) {
requery();
}
}
};
private WebSocketService.Client socketClient = new WebSocketService.Client() {
@Override
public void onStateChanged(WebSocketService.State newState, WebSocketService.State oldState) {
if (newState == WebSocketService.State.Connected) {
filterDebouncer.call();
requery();
}
}

View File

@ -56,7 +56,7 @@ public class CategoryBrowseActivity extends WebSocketActivityBase implements Fil
private String category;
private Adapter adapter;
private String filter;
private String lastFilter;
private TransportFragment transport;
private int deepLinkType;
@ -102,8 +102,8 @@ public class CategoryBrowseActivity extends WebSocketActivityBase implements Fil
@Override
public void setFilter(String filter) {
this.filter = filter;
requery();
this.lastFilter = filter;
this.filterDebouncer.call();
}
@Override
@ -115,7 +115,7 @@ public class CategoryBrowseActivity extends WebSocketActivityBase implements Fil
final SocketMessage request = SocketMessage.Builder
.request(Messages.Request.QueryCategory)
.addOption(Messages.Key.CATEGORY, category)
.addOption(Messages.Key.FILTER, filter)
.addOption(Messages.Key.FILTER, lastFilter)
.build();
getWebSocketService().send(request, this.socketClient, (SocketMessage response) -> {
@ -126,10 +126,20 @@ public class CategoryBrowseActivity extends WebSocketActivityBase implements Fil
});
}
private final Debouncer<String> filterDebouncer = new Debouncer<String>(350) {
@Override
protected void onDebounced(String caller) {
if (!isPaused()) {
requery();
}
}
};
private WebSocketService.Client socketClient = new WebSocketService.Client() {
@Override
public void onStateChanged(WebSocketService.State newState, WebSocketService.State oldState) {
if (newState == WebSocketService.State.Connected) {
filterDebouncer.cancel();
requery();
}
}

View File

@ -0,0 +1,35 @@
package io.casey.musikcube.remote;
import android.os.Handler;
import android.os.Looper;
public abstract class Debouncer<T> {
private Handler handler = new Handler(Looper.getMainLooper());
private T t = null;
private long delay;
public Debouncer(long delay) {
this.delay = delay;
}
public void call() {
handler.removeCallbacks(deferred);
handler.postDelayed(deferred, delay);
}
public void call(T t) {
this.t = t;
handler.removeCallbacks(deferred);
handler.postDelayed(deferred, delay);
}
public void cancel() {
handler.removeCallbacks(deferred);
}
protected abstract void onDebounced(T caller);
private Runnable deferred = () -> {
onDebounced(t);
};
}

View File

@ -373,6 +373,13 @@ public class MainActivity extends WebSocketActivityBase {
}
}
private void clearUi() {
model.reset();
albumArtModel = new AlbumArtModel();
updateAlbumArt();
rebindUi();
}
private void setMetadataDisplayMode(DisplayMode mode) {
if (metadataAnim1 != null) {
metadataAnim1.cancel();
@ -547,14 +554,12 @@ public class MainActivity extends WebSocketActivityBase {
if (newState == WebSocketService.State.Connected) {
wss.send(SocketMessage.Builder.request(
Messages.Request.GetPlaybackOverview.toString()).build());
rebindUi();
}
else if (newState == WebSocketService.State.Disconnected) {
model.reset();
albumArtModel = new AlbumArtModel();
updateAlbumArt();
clearUi();
}
rebindUi();
}
@Override

View File

@ -49,7 +49,7 @@ public class TrackListActivity extends WebSocketActivityBase implements Filterab
private TransportFragment transport;
private String categoryType;
private long categoryId;
private String filter = "";
private String lastFilter = "";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -107,14 +107,15 @@ public class TrackListActivity extends WebSocketActivityBase implements Filterab
@Override
public void setFilter(String filter) {
this.filter = filter;
tracks.requery();
this.lastFilter = filter;
this.filterDebouncer.call();
}
private WebSocketService.Client socketServiceClient = new WebSocketService.Client() {
@Override
public void onStateChanged(WebSocketService.State newState, WebSocketService.State oldState) {
if (newState == WebSocketService.State.Connected) {
filterDebouncer.cancel();
tracks.requery();
}
}
@ -128,6 +129,15 @@ public class TrackListActivity extends WebSocketActivityBase implements Filterab
}
};
private final Debouncer<String> filterDebouncer = new Debouncer<String>(350) {
@Override
protected void onDebounced(String caller) {
if (!isPaused()) {
tracks.requery();
}
}
};
private View.OnClickListener onItemClickListener = (View view) -> {
int index = (Integer) view.getTag();
SocketMessage request;
@ -138,14 +148,14 @@ public class TrackListActivity extends WebSocketActivityBase implements Filterab
.addOption(Messages.Key.CATEGORY, categoryType)
.addOption(Messages.Key.ID, categoryId)
.addOption(Messages.Key.INDEX, index)
.addOption(Messages.Key.FILTER, filter)
.addOption(Messages.Key.FILTER, lastFilter)
.build();
}
else {
request = SocketMessage.Builder
.request(Messages.Request.PlayAllTracks)
.addOption(Messages.Key.INDEX, index)
.addOption(Messages.Key.FILTER, filter)
.addOption(Messages.Key.FILTER, lastFilter)
.build();
}
@ -232,7 +242,7 @@ public class TrackListActivity extends WebSocketActivityBase implements Filterab
.addOption(Messages.Key.CATEGORY, categoryType)
.addOption(Messages.Key.ID, categoryId)
.addOption(Messages.Key.COUNT_ONLY, true)
.addOption(Messages.Key.FILTER, filter)
.addOption(Messages.Key.FILTER, lastFilter)
.build();
}
@ -244,7 +254,7 @@ public class TrackListActivity extends WebSocketActivityBase implements Filterab
.addOption(Messages.Key.ID, categoryId)
.addOption(Messages.Key.OFFSET, offset)
.addOption(Messages.Key.LIMIT, limit)
.addOption(Messages.Key.FILTER, filter)
.addOption(Messages.Key.FILTER, lastFilter)
.build();
}
};
@ -256,7 +266,7 @@ public class TrackListActivity extends WebSocketActivityBase implements Filterab
public SocketMessage getRequeryMessage() {
return SocketMessage.Builder
.request(Messages.Request.QueryTracks)
.addOption(Messages.Key.FILTER, filter)
.addOption(Messages.Key.FILTER, lastFilter)
.addOption(Messages.Key.COUNT_ONLY, true)
.build();
}
@ -267,7 +277,7 @@ public class TrackListActivity extends WebSocketActivityBase implements Filterab
.request(Messages.Request.QueryTracks)
.addOption(Messages.Key.OFFSET, offset)
.addOption(Messages.Key.LIMIT, limit)
.addOption(Messages.Key.FILTER, filter)
.addOption(Messages.Key.FILTER, lastFilter)
.build();
}
};

View File

@ -7,6 +7,7 @@ import android.view.KeyEvent;
public abstract class WebSocketActivityBase extends AppCompatActivity {
private WebSocketService wss;
private boolean paused = true;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -18,12 +19,14 @@ public abstract class WebSocketActivityBase extends AppCompatActivity {
protected void onPause() {
super.onPause();
this.wss.removeClient(getWebSocketServiceClient());
this.paused = true;
}
@Override
protected void onResume() {
super.onResume();
this.wss.addClient(getWebSocketServiceClient());
this.paused = false;
}
@Override
@ -49,6 +52,10 @@ public abstract class WebSocketActivityBase extends AppCompatActivity {
return super.onKeyDown(keyCode, event);
}
protected final boolean isPaused() {
return this.paused;
}
protected final WebSocketService getWebSocketService() {
return this.wss;
}