mirror of https://github.com/kurisufriend/Clover
Use structured interval types: a handler for foreground update intervals and the alarmmanager for background update intervals. Fix issue where the backoff would not work on pin watching. Start of making all database calls optionally async and in a transaction. Acquire a short wakelock while loading threads in the background. Update the notifier with peeking and remove ticker and count support. Shorten quotes and subject.multisite
parent
66d3076fd7
commit
134d745bc5
@ -0,0 +1,102 @@ |
|||||||
|
/* |
||||||
|
* Clover - 4chan browser https://github.com/Floens/Clover/
|
||||||
|
* Copyright (C) 2014 Floens |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
package org.floens.chan.core.database; |
||||||
|
|
||||||
|
import org.floens.chan.core.model.Pin; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.Callable; |
||||||
|
|
||||||
|
public class DatabasePinManager { |
||||||
|
private static final String TAG = "DatabasePinManager"; |
||||||
|
|
||||||
|
private DatabaseManager databaseManager; |
||||||
|
private DatabaseHelper helper; |
||||||
|
|
||||||
|
public DatabasePinManager(DatabaseManager databaseManager, DatabaseHelper helper) { |
||||||
|
this.databaseManager = databaseManager; |
||||||
|
this.helper = helper; |
||||||
|
} |
||||||
|
|
||||||
|
public Callable<Pin> createPin(final Pin pin) { |
||||||
|
return new Callable<Pin>() { |
||||||
|
@Override |
||||||
|
public Pin call() throws Exception { |
||||||
|
helper.loadableDao.create(pin.loadable); |
||||||
|
helper.pinDao.create(pin); |
||||||
|
return pin; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
public Callable<Void> deletePin(final Pin pin) { |
||||||
|
return new Callable<Void>() { |
||||||
|
@Override |
||||||
|
public Void call() throws Exception { |
||||||
|
helper.pinDao.delete(pin); |
||||||
|
helper.loadableDao.delete(pin.loadable); |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
public Callable<Pin> updatePin(final Pin pin) { |
||||||
|
return new Callable<Pin>() { |
||||||
|
@Override |
||||||
|
public Pin call() throws Exception { |
||||||
|
helper.pinDao.update(pin); |
||||||
|
helper.loadableDao.update(pin.loadable); |
||||||
|
return pin; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
public Callable<List<Pin>> updatePins(final List<Pin> pins) { |
||||||
|
return new Callable<List<Pin>>() { |
||||||
|
@Override |
||||||
|
public List<Pin> call() throws Exception { |
||||||
|
for (int i = 0; i < pins.size(); i++) { |
||||||
|
Pin pin = pins.get(i); |
||||||
|
helper.pinDao.update(pin); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < pins.size(); i++) { |
||||||
|
Pin pin = pins.get(i); |
||||||
|
helper.loadableDao.update(pin.loadable); |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
public Callable<List<Pin>> getPins() { |
||||||
|
return new Callable<List<Pin>>() { |
||||||
|
@Override |
||||||
|
public List<Pin> call() throws Exception { |
||||||
|
List<Pin> list = helper.pinDao.queryForAll(); |
||||||
|
for (int i = 0; i < list.size(); i++) { |
||||||
|
Pin p = list.get(i); |
||||||
|
helper.loadableDao.refresh(p.loadable); |
||||||
|
} |
||||||
|
return list; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
/* |
||||||
|
* Clover - 4chan browser https://github.com/Floens/Clover/
|
||||||
|
* Copyright (C) 2014 Floens |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
package org.floens.chan.core.receiver; |
||||||
|
|
||||||
|
import android.content.BroadcastReceiver; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.Intent; |
||||||
|
|
||||||
|
import org.floens.chan.Chan; |
||||||
|
import org.floens.chan.core.manager.WatchManager; |
||||||
|
import org.floens.chan.utils.Logger; |
||||||
|
|
||||||
|
public class WatchUpdateReceiver extends BroadcastReceiver { |
||||||
|
private static final String TAG = "WatchUpdateReceiver"; |
||||||
|
|
||||||
|
private final WatchManager watchManager; |
||||||
|
|
||||||
|
public WatchUpdateReceiver() { |
||||||
|
watchManager = Chan.getWatchManager(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onReceive(Context context, Intent intent) { |
||||||
|
watchManager.onBroadcastReceived(); |
||||||
|
} |
||||||
|
} |
@ -1,197 +0,0 @@ |
|||||||
/* |
|
||||||
* Clover - 4chan browser https://github.com/Floens/Clover/
|
|
||||||
* Copyright (C) 2014 Floens |
|
||||||
* |
|
||||||
* This program is free software: you can redistribute it and/or modify |
|
||||||
* it under the terms of the GNU General Public License as published by |
|
||||||
* the Free Software Foundation, either version 3 of the License, or |
|
||||||
* (at your option) any later version. |
|
||||||
* |
|
||||||
* This program is distributed in the hope that it will be useful, |
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
* GNU General Public License for more details. |
|
||||||
* |
|
||||||
* You should have received a copy of the GNU General Public License |
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/ |
|
||||||
package org.floens.chan.core.watch; |
|
||||||
|
|
||||||
import com.android.volley.VolleyError; |
|
||||||
|
|
||||||
import org.floens.chan.Chan; |
|
||||||
import org.floens.chan.chan.ChanLoader; |
|
||||||
import org.floens.chan.core.model.ChanThread; |
|
||||||
import org.floens.chan.core.model.Pin; |
|
||||||
import org.floens.chan.core.model.Post; |
|
||||||
import org.floens.chan.core.pool.LoaderPool; |
|
||||||
import org.floens.chan.utils.Logger; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
public class PinWatcher implements ChanLoader.ChanLoaderCallback { |
|
||||||
private static final String TAG = "PinWatcher"; |
|
||||||
|
|
||||||
private final Pin pin; |
|
||||||
private ChanLoader chanLoader; |
|
||||||
|
|
||||||
private final List<Post> posts = new ArrayList<>(); |
|
||||||
private final List<Post> quotes = new ArrayList<>(); |
|
||||||
private boolean wereNewQuotes = false; |
|
||||||
private boolean wereNewPosts = false; |
|
||||||
|
|
||||||
public PinWatcher(Pin pin) { |
|
||||||
this.pin = pin; |
|
||||||
|
|
||||||
chanLoader = LoaderPool.getInstance().obtain(pin.loadable, this); |
|
||||||
} |
|
||||||
|
|
||||||
public void destroy() { |
|
||||||
if (chanLoader != null) { |
|
||||||
LoaderPool.getInstance().release(chanLoader, this); |
|
||||||
chanLoader = null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public boolean update() { |
|
||||||
if (!pin.isError) { |
|
||||||
chanLoader.loadMoreIfTime(); |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void onViewed() { |
|
||||||
if (pin.watchNewCount >= 0) { |
|
||||||
pin.watchLastCount = pin.watchNewCount; |
|
||||||
} |
|
||||||
wereNewPosts = false; |
|
||||||
|
|
||||||
if (pin.quoteNewCount >= 0) { |
|
||||||
pin.quoteLastCount = pin.quoteNewCount; |
|
||||||
} |
|
||||||
wereNewQuotes = false; |
|
||||||
} |
|
||||||
|
|
||||||
public List<Post> getUnviewedPosts() { |
|
||||||
if (posts.size() == 0) { |
|
||||||
return posts; |
|
||||||
} else { |
|
||||||
return posts.subList(Math.max(0, posts.size() - pin.getNewPostCount()), posts.size()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public List<Post> getUnviewedQuotes() { |
|
||||||
return quotes.subList(Math.max(0, quotes.size() - pin.getNewQuoteCount()), quotes.size()); |
|
||||||
} |
|
||||||
|
|
||||||
public boolean getWereNewQuotes() { |
|
||||||
if (wereNewQuotes) { |
|
||||||
wereNewQuotes = false; |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public boolean getWereNewPosts() { |
|
||||||
if (wereNewPosts) { |
|
||||||
wereNewPosts = false; |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public long getTimeUntilNextLoad() { |
|
||||||
return chanLoader.getTimeUntilLoadMore(); |
|
||||||
} |
|
||||||
|
|
||||||
public boolean isLoading() { |
|
||||||
return chanLoader.isLoading(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onChanLoaderError(VolleyError error) { |
|
||||||
Logger.e(TAG, "PinWatcher onError"); |
|
||||||
pin.isError = true; |
|
||||||
|
|
||||||
pin.watching = false; |
|
||||||
Chan.getWatchManager().pinWatcherUpdated(pin); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onChanLoaderData(ChanThread thread) { |
|
||||||
pin.isError = false; |
|
||||||
|
|
||||||
if (pin.thumbnailUrl == null && thread.op != null && thread.op.hasImage) { |
|
||||||
pin.thumbnailUrl = thread.op.thumbnailUrl; |
|
||||||
} |
|
||||||
|
|
||||||
// Populate posts list
|
|
||||||
posts.clear(); |
|
||||||
posts.addAll(thread.posts); |
|
||||||
|
|
||||||
// Populate quotes list
|
|
||||||
quotes.clear(); |
|
||||||
|
|
||||||
// Get list of saved replies from this thread
|
|
||||||
List<Post> savedReplies = new ArrayList<>(); |
|
||||||
for (Post item : thread.posts) { |
|
||||||
// saved.title = pin.loadable.title;
|
|
||||||
|
|
||||||
if (item.isSavedReply) { |
|
||||||
savedReplies.add(item); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Now get a list of posts that have a quote to a saved reply
|
|
||||||
for (Post post : thread.posts) { |
|
||||||
for (Post saved : savedReplies) { |
|
||||||
if (post.repliesTo.contains(saved.no)) { |
|
||||||
quotes.add(post); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
boolean isFirstLoad = pin.watchNewCount < 0 || pin.quoteNewCount < 0; |
|
||||||
|
|
||||||
// If it was more than before processing
|
|
||||||
int lastWatchNewCount = pin.watchNewCount; |
|
||||||
int lastQuoteNewCount = pin.quoteNewCount; |
|
||||||
|
|
||||||
if (isFirstLoad) { |
|
||||||
pin.watchLastCount = posts.size(); |
|
||||||
pin.quoteLastCount = quotes.size(); |
|
||||||
} |
|
||||||
|
|
||||||
pin.watchNewCount = posts.size(); |
|
||||||
pin.quoteNewCount = quotes.size(); |
|
||||||
|
|
||||||
if (!isFirstLoad) { |
|
||||||
// There were new posts after processing
|
|
||||||
if (pin.watchNewCount > lastWatchNewCount) { |
|
||||||
wereNewPosts = true; |
|
||||||
} |
|
||||||
|
|
||||||
// There were new quotes after processing
|
|
||||||
if (pin.quoteNewCount > lastQuoteNewCount) { |
|
||||||
wereNewQuotes = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (Logger.debugEnabled()) { |
|
||||||
Logger.d(TAG, String.format("postlast=%d postnew=%d werenewposts=%b quotelast=%d quotenew=%d werenewquotes=%b", |
|
||||||
pin.watchLastCount, pin.watchNewCount, wereNewPosts, pin.quoteLastCount, pin.quoteNewCount, wereNewQuotes)); |
|
||||||
} |
|
||||||
|
|
||||||
if (thread.archived || thread.closed) { |
|
||||||
pin.archived = true; |
|
||||||
pin.watching = false; |
|
||||||
} |
|
||||||
|
|
||||||
Chan.getWatchManager().pinWatcherUpdated(pin); |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue