Search now actually searches, yay

This commit is contained in:
Grishka
2022-03-31 17:49:54 +03:00
parent fa9112e117
commit c60bc253e5
27 changed files with 1046 additions and 122 deletions

View File

@@ -14,13 +14,17 @@ import org.joinmastodon.android.BuildConfig;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.api.requests.notifications.GetNotifications;
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Hashtag;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.SearchResult;
import org.joinmastodon.android.model.Status;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.function.Consumer;
import androidx.annotation.Nullable;
import me.grishka.appkit.api.Callback;
@@ -29,7 +33,7 @@ import me.grishka.appkit.utils.WorkerThread;
public class CacheController{
private static final String TAG="CacheController";
private static final int DB_VERSION=1;
private static final int DB_VERSION=2;
private static final WorkerThread databaseThread=new WorkerThread("databaseThread");
private static final Handler uiHandler=new Handler(Looper.getMainLooper());
@@ -91,24 +95,16 @@ public class CacheController{
}
private void putHomeTimeline(List<Status> posts, boolean clear){
cancelDelayedClose();
databaseThread.postRunnable(()->{
try{
SQLiteDatabase db=getOrOpenDatabase();
if(clear)
db.delete("home_timeline", null, null);
ContentValues values=new ContentValues(2);
for(Status s:posts){
values.put("id", s.id);
values.put("json", MastodonAPIController.gson.toJson(s));
db.insertWithOnConflict("home_timeline", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
}catch(SQLiteException x){
Log.w(TAG, x);
}finally{
closeDelayed();
runOnDbThread((db)->{
if(clear)
db.delete("home_timeline", null, null);
ContentValues values=new ContentValues(2);
for(Status s:posts){
values.put("id", s.id);
values.put("json", MastodonAPIController.gson.toJson(s));
db.insertWithOnConflict("home_timeline", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
}, 0);
});
}
public void getNotifications(String maxID, int count, boolean onlyMentions, boolean forceReload, Callback<List<Notification>> callback){
@@ -157,26 +153,46 @@ public class CacheController{
}
private void putNotifications(List<Notification> notifications, boolean onlyMentions, boolean clear){
cancelDelayedClose();
databaseThread.postRunnable(()->{
try{
SQLiteDatabase db=getOrOpenDatabase();
String table=onlyMentions ? "notifications_mentions" : "notifications_all";
if(clear)
db.delete(table, null, null);
ContentValues values=new ContentValues(3);
for(Notification n:notifications){
values.put("id", n.id);
values.put("json", MastodonAPIController.gson.toJson(n));
values.put("type", n.type.ordinal());
db.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
}catch(SQLiteException x){
Log.w(TAG, x);
}finally{
closeDelayed();
runOnDbThread((db)->{
String table=onlyMentions ? "notifications_mentions" : "notifications_all";
if(clear)
db.delete(table, null, null);
ContentValues values=new ContentValues(3);
for(Notification n:notifications){
values.put("id", n.id);
values.put("json", MastodonAPIController.gson.toJson(n));
values.put("type", n.type.ordinal());
db.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
}, 0);
});
}
public void getRecentSearches(Consumer<List<SearchResult>> callback){
runOnDbThread((db)->{
try(Cursor cursor=db.query("recent_searches", new String[]{"json"}, null, null, null, null, "time DESC")){
List<SearchResult> results=new ArrayList<>();
while(cursor.moveToNext()){
SearchResult result=MastodonAPIController.gson.fromJson(cursor.getString(0), SearchResult.class);
result.postprocess();
results.add(result);
}
uiHandler.post(()->callback.accept(results));
}
});
}
public void putRecentSearch(SearchResult result){
runOnDbThread((db)->{
ContentValues values=new ContentValues(4);
values.put("id", result.getID());
values.put("json", MastodonAPIController.gson.toJson(result));
values.put("time", (int)(System.currentTimeMillis()/1000));
db.insertWithOnConflict("recent_searches", null, values, SQLiteDatabase.CONFLICT_REPLACE);
});
}
public void clearRecentSearches(){
runOnDbThread((db)->db.delete("recent_searches", null, null));
}
private void closeDelayed(){
@@ -204,6 +220,26 @@ public class CacheController{
return db.getWritableDatabase();
}
private void runOnDbThread(DatabaseRunnable r){
runOnDbThread(r, null);
}
private void runOnDbThread(DatabaseRunnable r, Consumer<Exception> onError){
cancelDelayedClose();
databaseThread.postRunnable(()->{
try{
SQLiteDatabase db=getOrOpenDatabase();
r.run(db);
}catch(SQLiteException|IOException x){
Log.w(TAG, x);
if(onError!=null)
onError.accept(x);
}finally{
closeDelayed();
}
}, 0);
}
private class DatabaseHelper extends SQLiteOpenHelper{
public DatabaseHelper(){
@@ -232,11 +268,28 @@ public class CacheController{
`flags` INTEGER NOT NULL DEFAULT 0,
`type` INTEGER NOT NULL
)""");
createRecentSearchesTable(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
if(oldVersion==1){
createRecentSearchesTable(db);
}
}
private void createRecentSearchesTable(SQLiteDatabase db){
db.execSQL("""
CREATE TABLE `recent_searches` (
`id` VARCHAR(50) NOT NULL PRIMARY KEY,
`json` TEXT NOT NULL,
`time` INTEGER NOT NULL
)""");
}
}
@FunctionalInterface
private interface DatabaseRunnable{
void run(SQLiteDatabase db) throws IOException;
}
}

View File

@@ -4,11 +4,13 @@ import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.SearchResults;
public class GetSearchResults extends MastodonAPIRequest<SearchResults>{
public GetSearchResults(String query, Type type){
public GetSearchResults(String query, Type type, boolean resolve){
super(HttpMethod.GET, "/search", SearchResults.class);
addQueryParameter("q", query);
if(type!=null)
addQueryParameter("type", type.name().toLowerCase());
if(resolve)
addQueryParameter("resolve", "true");
}
@Override