Skip to content

Commit

Permalink
Moved issue filters/bookmarks to SQLite
Browse files Browse the repository at this point in the history
Fixed backing out of a filtered list
Fixed small tests
  • Loading branch information
Meisolsson committed Apr 11, 2020
1 parent 8c93d04 commit fdf08d2
Show file tree
Hide file tree
Showing 17 changed files with 382 additions and 55 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ dependencies {
kapt 'com.google.auto.factory:auto-factory:1.0-beta7'

implementation 'com.github.meisolsson:githubsdk:0.7.0'
implementation "com.squareup.moshi:moshi:1.9.2"
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'com.xwray:groupie:2.3.0'
implementation 'com.xwray:groupie-kotlin-android-extensions:2.3.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.junit.Before;
import org.junit.Rule;

import java.util.UUID;

/**
* Tests of {@link EditIssuesFilterActivity}
*/
Expand All @@ -35,7 +37,7 @@ public class EditIssuesFilterActivityTest {
@Before
public void setUp() {
Repository repo = InfoUtils.createRepoFromData("owner", "name");
IssueFilter filter = new IssueFilter(repo);
IssueFilter filter = new IssueFilter(repo, UUID.randomUUID().toString());
activityTestRule.launchActivity(EditIssuesFilterActivity.Companion.createIntent(filter));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import com.meisolsson.githubsdk.model.User;
import org.junit.Test;

import java.util.UUID;

import static junit.framework.Assert.assertFalse;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
Expand All @@ -41,13 +43,13 @@ public void testEqualFilter() {
.id(1L)
.build();

IssueFilter filter1 = new IssueFilter(repo);
IssueFilter filter1 = new IssueFilter(repo, UUID.randomUUID().toString());

assertFalse(filter1.equals(null));
assertFalse(filter1.equals(""));
assertTrue(filter1.equals(filter1));

IssueFilter filter2 = new IssueFilter(repo);
IssueFilter filter2 = new IssueFilter(repo, UUID.randomUUID().toString());
assertEquals(filter1, filter2);
assertEquals(filter1.hashCode(), filter2.hashCode());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package com.github.pockethub.android
import android.app.Application
import android.content.Context
import com.github.pockethub.android.Database.Companion.Schema
import com.meisolsson.githubsdk.core.ServiceGenerator
import com.meisolsson.githubsdk.model.IssueState
import com.squareup.sqldelight.ColumnAdapter
import com.squareup.sqldelight.android.AndroidSqliteDriver
import dagger.Binds
import dagger.Module
Expand All @@ -21,7 +24,16 @@ internal abstract class ApplicationModule {
@Provides
fun provideDatabase(context: Context?): Database {
val driver = AndroidSqliteDriver(Schema, context!!, "cache.db")
return Database(driver)
return Database(driver, Milestones.Adapter(object : ColumnAdapter<IssueState, String> {
var adapter = ServiceGenerator.moshi.adapter<IssueState>(IssueState::class.java)
override fun decode(databaseValue: String): IssueState {
return adapter.fromJsonValue(databaseValue)!!
}

override fun encode(value: IssueState): String {
return adapter.toJsonValue(value) as String
}
}))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,12 @@

import android.os.Parcel;
import android.os.Parcelable;

import com.meisolsson.githubsdk.model.Label;
import com.meisolsson.githubsdk.model.Milestone;
import com.meisolsson.githubsdk.model.Repository;
import com.meisolsson.githubsdk.model.User;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

import static java.lang.String.CASE_INSENSITIVE_ORDER;

Expand Down Expand Up @@ -143,12 +136,11 @@ public class IssueFilter implements Parcelable, Cloneable, Comparator<Label> {
*/
public static final String SORT_COMMENTS = "comments";

/** serialVersionUID */
private static final long serialVersionUID = 7310646589186299063L;

private final Repository repository;

private List<Label> labels;
private final String id;

private List<Label> labels = new ArrayList<>();

private Milestone milestone;

Expand All @@ -165,14 +157,16 @@ public class IssueFilter implements Parcelable, Cloneable, Comparator<Label> {
*
* @param repository
*/
public IssueFilter(final Repository repository) {
public IssueFilter(final Repository repository, String id) {
this.id = id;
this.repository = repository;
open = true;
direction = DIRECTION_DESCENDING;
sortType = SORT_CREATED;
}

protected IssueFilter(Parcel in) {
id = in.readString();
repository = in.readParcelable(Repository.class.getClassLoader());
labels = new ArrayList<>();
in.readList(labels, Label.class.getClassLoader());
Expand Down Expand Up @@ -479,6 +473,7 @@ public int describeContents() {

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeParcelable(repository, flags);
dest.writeList(labels);
dest.writeParcelable(milestone, flags);
Expand All @@ -487,4 +482,8 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeString(direction);
dest.writeString(sortType);
}

public String getId() {
return id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;

import com.github.pockethub.android.GetFilterLabels;
import com.github.pockethub.android.GetFilters;
import com.github.pockethub.android.RequestReader;
import com.github.pockethub.android.RequestWriter;
import com.github.pockethub.android.Users;
import com.github.pockethub.android.core.issue.IssueFilter;
import com.meisolsson.githubsdk.model.Label;
import com.meisolsson.githubsdk.model.Milestone;
import com.meisolsson.githubsdk.model.Permissions;
import com.meisolsson.githubsdk.model.Repository;
import com.meisolsson.githubsdk.model.User;
import io.reactivex.Single;
Expand All @@ -32,9 +39,7 @@
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
Expand Down Expand Up @@ -185,13 +190,93 @@ public List<Repository> getRepos(final User user, boolean forceReload)
*
* @return non-null but possibly empty collection of issue filters
*/
public Collection<IssueFilter> getIssueFilters() {
final File cache = new File(root, "issue_filters.ser");
Collection<IssueFilter> cached = read(cache);
if (cached != null) {
return cached;
public List<IssueFilter> getIssueFilters() {
List<GetFilters> filters = dbCache.database.getIssue_filterQueries()
.getFilters()
.executeAsList();

List<IssueFilter> issueFilters = new ArrayList<>();

for (GetFilters f : filters) {
Users owner = dbCache.database.getOrganizationsQueries().selectUser(f.getOwnerId()).executeAsOne();

Repository.Builder builder = Repository.builder()
.id(f.getRepoId())
.name(f.getName())
.owner(
User.builder()
.id(owner.getId())
.login(owner.getLogin())
.name(owner.getName())
.avatarUrl(owner.getAvatarurl())
.build()
)
.isPrivate(f.getPrivate())
.isFork(f.getFork())
.description(f.getDescription())
.forksCount(f.getForks())
.watchersCount(f.getWatchers())
.language(f.getLanguage())
.hasIssues(f.getHasIssues())
.mirrorUrl(f.getMirrorUrl())
.permissions(
Permissions.builder()
.admin(f.getPermissions_admin())
.pull(f.getPermissions_pull())
.push(f.getPermissions_push())
.build()
);

if (f.getOrgId() != null) {
Users org = dbCache.database.getOrganizationsQueries().selectUser(f.getOrgId()).executeAsOne();
builder.organization(
User.builder()
.id(org.getId())
.login(org.getLogin())
.name(org.getName())
.avatarUrl(org.getAvatarurl())
.build()
);
}

Repository repo = builder.build();
IssueFilter filter = new IssueFilter(repo, f.getId());
if (f.getLogin() != null) {
filter.setAssignee(
User.builder()
.id(f.getId__())
.name(f.getName_())
.login(f.getLogin())
.avatarUrl(f.getAvatarurl())
.build()
);
}

if (f.getMilestone_id() != null) {
filter.setMilestone(Milestone.builder().id(f.getMilestone_id()).build());
}

filter.setDirection(f.getDirection());
filter.setOpen(f.getOpen());
filter.setSortType(f.getSort_type());

List<GetFilterLabels> filterLabels = dbCache.database.getIssue_filterQueries()
.getFilterLabels(filter.getId())
.executeAsList();

for (GetFilterLabels filterLabel : filterLabels) {
filter.addLabel(
Label.builder()
.name(filterLabel.getName())
.color(filterLabel.getColor())
.build()
);
}

issueFilters.add(filter);
}
return Collections.emptyList();

return issueFilters;
}

/**
Expand All @@ -203,18 +288,67 @@ public Collection<IssueFilter> getIssueFilters() {
* @param filter
*/
public Single<IssueFilter> addIssueFilter(final IssueFilter filter) {
return Single.fromCallable(() -> {
final File cache = new File(root, "issue_filters.ser");
Collection<IssueFilter> filters = read(cache);
if (filters == null) {
filters = new HashSet<>();
}
if (filters.add(filter)) {
write(cache, filters);
}
Repository repo = filter.getRepository();
dbCache.getDatabase().getRepositoriesQueries().replaceRepo(
repo.id(),
repo.name(),
repo.organization() != null ? repo.organization().id() : null,
repo.owner().id(),
repo.isPrivate(),
repo.isFork(),
repo.description(),
repo.forksCount(),
repo.watchersCount(),
repo.language(),
repo.hasIssues(),
repo.mirrorUrl(),
repo.permissions().admin(),
repo.permissions().pull(),
repo.permissions().push()
);

for (Label label : filter.getLabels()) {
dbCache.database.getIssue_filterQueries().insertOrReplaceLabel(
repo.id(),
label.name(),
label.color()
);
dbCache.database.getIssue_filterQueries().insertOrReplaceIssueFilterLabel(
filter.getId(),
repo.id(),
label.name()
);
}

return filter;
});
if (filter.getMilestone() != null) {
dbCache.database.getIssue_filterQueries().insertOrReplaceMilestone(
repo.id(),
filter.getMilestone().title(),
filter.getMilestone().state(),
filter.getMilestone().id(),
filter.getMilestone().number().longValue()
);
}

if (filter.getAssignee() != null) {
dbCache.database.getOrganizationsQueries().replaceUser(
filter.getAssignee().id(),
filter.getAssignee().login(),
filter.getAssignee().name(),
filter.getAssignee().avatarUrl()
);
}

dbCache.database.getIssue_filterQueries().insertOrReplaceIssueFilter(
filter.getId(),
repo.id(),
filter.getMilestone() != null ? filter.getMilestone().id() : null,
filter.getAssignee() != null ? filter.getAssignee().id() : null,
filter.isOpen(),
filter.getDirection(),
filter.getSortType()
);
return Single.just(filter);
}

/**
Expand All @@ -226,14 +360,15 @@ public Single<IssueFilter> addIssueFilter(final IssueFilter filter) {
* @param filter
*/
public Single<IssueFilter> removeIssueFilter(IssueFilter filter) {
return Single.fromCallable(() -> {
final File cache = new File(root, "issue_filters.ser");
Collection<IssueFilter> filters = read(cache);
if (filters != null && filters.remove(filter)) {
write(cache, filters);
}
dbCache.database.getIssue_filterQueries().removeIssueFilter(filter.getId());
for (Label label : filter.getLabels()) {
dbCache.database.getIssue_filterQueries().removeIssueFilterLabel(
filter.getId(),
filter.getRepository().id(),
label.name()
);
}

return filter;
}).doOnError( e -> Log.d(TAG, "Exception removing issue filter", e));
return Single.just(filter);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class OrganizationRepositories(

for (repo in repos) {
val owner = repo.owner()
database.repositoriesQueries.insertRepo(
database.repositoriesQueries.replaceRepo(
repo.id(),
repo.name(),
org.id(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
for (account in allGitHubAccounts) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
accountManager.removeAccountExplicitly(account)
startLoginActivity()
} else {
accountManager.removeAccount(account, { bundle -> startLoginActivity() }, null)
}
Expand Down
Loading

0 comments on commit fdf08d2

Please sign in to comment.