diff --git a/app/build.gradle b/app/build.gradle index 1bddbeb9..97bc914a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -60,4 +60,5 @@ dependencies { // fastadapter requires androidx after 3.2.9 implementation 'com.mikepenz:fastadapter:3.2.9' implementation 'com.mikepenz:fastadapter-commons:3.2.9' + implementation "com.mikepenz:materialdrawer:6.0.9" } diff --git a/app/src/main/java/com/readrops/app/activities/MainActivity.java b/app/src/main/java/com/readrops/app/activities/MainActivity.java index d1d79c08..aafae8a3 100644 --- a/app/src/main/java/com/readrops/app/activities/MainActivity.java +++ b/app/src/main/java/com/readrops/app/activities/MainActivity.java @@ -30,7 +30,14 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader; import com.bumptech.glide.util.ViewPreloadSizeProvider; import com.github.clans.fab.FloatingActionMenu; +import com.mikepenz.materialdrawer.Drawer; +import com.mikepenz.materialdrawer.DrawerBuilder; +import com.mikepenz.materialdrawer.model.ExpandableBadgeDrawerItem; +import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; +import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; +import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import com.readrops.app.database.entities.Feed; +import com.readrops.app.database.entities.Folder; import com.readrops.app.views.MainItemListAdapter; import com.readrops.app.viewmodels.MainViewModel; import com.readrops.app.R; @@ -43,6 +50,7 @@ import com.readrops.app.utils.ParsingResult; import org.joda.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.TreeMap; @@ -50,19 +58,20 @@ import io.reactivex.Observer; import io.reactivex.SingleObserver; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; +import io.reactivex.observers.DisposableSingleObserver; import io.reactivex.schedulers.Schedulers; public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener { public static final String TAG = MainActivity.class.getSimpleName(); public static final int ADD_FEED_REQUEST = 1; + public static final int MANAGE_FEEDS_REQUEST = 2; private RecyclerView recyclerView; private MainItemListAdapter adapter; private SwipeRefreshLayout refreshLayout; - private NavigationView navigationView; - private DrawerLayout drawerLayout; + private Drawer drawer; private FloatingActionMenu actionMenu; private List newItems; @@ -85,28 +94,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou Toolbar toolbar = findViewById(R.id.toolbar_main); setSupportActionBar(toolbar); - drawerLayout = findViewById(R.id.drawer_layout); - ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_nav_drawer, R.string.close_nav_drawer); - drawerLayout.addDrawerListener(toggle); - toggle.syncState(); - actionMenu = findViewById(R.id.fab_menu); - - navigationView = findViewById(R.id.nav_view); - navigationView.setNavigationItemSelectedListener((menuItem) -> { - menuItem.setChecked(true); - drawerLayout.closeDrawers(); - - switch (menuItem.getItemId()) { - case R.id.to_read: - break; - case R.id.non_read_articles: - break; - } - - return true; - }); - viewModel = ViewModelProviders.of(this).get(MainViewModel.class); itemsMap = new TreeMap<>(LocalDateTime::compareTo); @@ -127,25 +115,80 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou syncProgressBar = findViewById(R.id.sync_progress_bar); feedCount = 0; - initRecyclerView(); + + drawer = new DrawerBuilder() + .withActivity(this) + .withToolbar(toolbar) + .withShowDrawerOnFirstLaunch(true) + .build(); + + updateDrawerFeeds(); } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - drawerLayout.openDrawer(GravityCompat.START); - return true; + private void updateDrawerFeeds() { + viewModel.getFoldersWithFeeds() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new DisposableSingleObserver>>() { + @Override + public void onSuccess(HashMap> folderListHashMap) { + populateDrawer(folderListHashMap); + } + + @Override + public void onError(Throwable e) { + + } + }); + } + + private void populateDrawer(HashMap> folderListHashMap) { + drawer.removeAllItems(); + List feedsWithoutFolder = new ArrayList<>(); + + for (Folder folder : folderListHashMap.keySet()) { + if (folder.getId() != 1) { + ExpandableBadgeDrawerItem badgeDrawerItem = new ExpandableBadgeDrawerItem() + .withName(folder.getName()) + .withIdentifier(folder.getId()) + .withIcon(getDrawable(R.drawable.ic_folder_grey)); + + List secondaryDrawerItems = new ArrayList<>(); + + for (Feed feed : folderListHashMap.get(folder)) { + SecondaryDrawerItem secondaryDrawerItem = new SecondaryDrawerItem() + .withName(feed.getName()) + .withIdentifier(feed.getId()); + + secondaryDrawerItems.add(secondaryDrawerItem); + } + + if (secondaryDrawerItems.size() > 0) { + badgeDrawerItem.withSubItems(secondaryDrawerItems); + drawer.addItem(badgeDrawerItem); + } + } else { // no folder case + for (Feed feed : folderListHashMap.get(folder)) { + SecondaryDrawerItem primaryDrawerItem = new SecondaryDrawerItem() + .withName(feed.getName()) + .withIdentifier(feed.getId()); + + feedsWithoutFolder.add(primaryDrawerItem); + } + } } - return super.onOptionsItemSelected(item); + // work-around as MaterialDrawer doesn't accept an item list + for (SecondaryDrawerItem primaryDrawerItem : feedsWithoutFolder) { + drawer.addItem(primaryDrawerItem); + } } @Override public void onBackPressed() { - if (drawerLayout.isDrawerOpen(GravityCompat.START)) - drawerLayout.closeDrawers(); + if (drawer.isDrawerOpen()) + drawer.closeDrawer(); else super.onBackPressed(); } @@ -242,7 +285,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou }); } - public void displayAddFeedDialog(View view) { + public void openAddFeedActivity(View view) { actionMenu.close(true); Intent intent = new Intent(this, AddFeedActivity.class); @@ -253,12 +296,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou actionMenu.close(true); Intent intent = new Intent(this, ManageFeedsActivity.class); - startActivity(intent); - } - - public void insertNewFeed(ParsingResult result) { - refreshLayout.setRefreshing(true); - viewModel.addFeed(result); + startActivityForResult(intent, MANAGE_FEEDS_REQUEST); } @Override @@ -271,6 +309,8 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou feedNb = feeds.size(); sync(feeds); } + } else if (requestCode == MANAGE_FEEDS_REQUEST) { + updateDrawerFeeds(); } super.onActivityResult(requestCode, resultCode, data); diff --git a/app/src/main/java/com/readrops/app/database/dao/FeedDao.java b/app/src/main/java/com/readrops/app/database/dao/FeedDao.java index 428007c6..797349d5 100644 --- a/app/src/main/java/com/readrops/app/database/dao/FeedDao.java +++ b/app/src/main/java/com/readrops/app/database/dao/FeedDao.java @@ -36,6 +36,9 @@ public interface FeedDao { @Query("Select * from Feed Where url = :feedUrl") Feed getFeedByUrl(String feedUrl); + @Query("Select * from Feed Where folder_id = :folderId") + List getFeedsByFolder(int folderId); + @Query("Update Feed set etag = :etag, last_modified = :lastModified Where id = :feedId") void updateHeaders(String etag, String lastModified, int feedId); diff --git a/app/src/main/java/com/readrops/app/database/dao/FolderDao.java b/app/src/main/java/com/readrops/app/database/dao/FolderDao.java index 0e147d27..eb2982b2 100644 --- a/app/src/main/java/com/readrops/app/database/dao/FolderDao.java +++ b/app/src/main/java/com/readrops/app/database/dao/FolderDao.java @@ -16,6 +16,9 @@ public interface FolderDao { @Query("Select * from Folder Order By name ASC") LiveData> getAllFolders(); + @Query("Select * from Folder Order By name ASC") + List getFolders(); + @Insert long insert(Folder folder); diff --git a/app/src/main/java/com/readrops/app/repositories/LocalFeedRepository.java b/app/src/main/java/com/readrops/app/repositories/LocalFeedRepository.java index c9fdbe58..97b46b4c 100644 --- a/app/src/main/java/com/readrops/app/repositories/LocalFeedRepository.java +++ b/app/src/main/java/com/readrops/app/repositories/LocalFeedRepository.java @@ -3,6 +3,7 @@ package com.readrops.app.repositories; import android.accounts.NetworkErrorException; import android.app.Application; import android.arch.lifecycle.LiveData; +import android.support.annotation.Nullable; import com.readrops.app.database.entities.Folder; import com.readrops.app.database.pojo.FeedWithFolder; @@ -53,7 +54,7 @@ public class LocalFeedRepository extends ARepository { } @Override - public Observable sync(List feeds) { + public Observable sync(@Nullable List feeds) { return Observable.create(emitter -> { List feedList; diff --git a/app/src/main/java/com/readrops/app/viewmodels/MainViewModel.java b/app/src/main/java/com/readrops/app/viewmodels/MainViewModel.java index 2dca2247..5ca25b6d 100644 --- a/app/src/main/java/com/readrops/app/viewmodels/MainViewModel.java +++ b/app/src/main/java/com/readrops/app/viewmodels/MainViewModel.java @@ -5,11 +5,14 @@ import android.arch.lifecycle.AndroidViewModel; import android.arch.lifecycle.LiveData; import android.support.annotation.NonNull; +import com.readrops.app.database.Database; import com.readrops.app.database.entities.Feed; +import com.readrops.app.database.entities.Folder; import com.readrops.app.database.pojo.ItemWithFeed; import com.readrops.app.repositories.LocalFeedRepository; import com.readrops.app.utils.ParsingResult; +import java.util.HashMap; import java.util.List; import io.reactivex.Observable; @@ -19,13 +22,14 @@ public class MainViewModel extends AndroidViewModel { private LiveData> itemsWithFeed; private LocalFeedRepository repository; + private Database db; public MainViewModel(@NonNull Application application) { super(application); repository = new LocalFeedRepository(application); - itemsWithFeed = repository.getItemsWithFeed(); + db = Database.getInstance(application); } public LiveData> getItemsWithFeed() { @@ -43,4 +47,18 @@ public class MainViewModel extends AndroidViewModel { public Single getFeedCount() { return repository.getFeedCount(); } + + public Single>> getFoldersWithFeeds() { + return Single.create(emitter -> { + List folders = db.folderDao().getFolders(); + HashMap> foldersWithFeeds = new HashMap<>(); + + for (Folder folder : folders) { + List feeds = db.feedDao().getFeedsByFolder(folder.getId()); + foldersWithFeeds.put(folder, feeds); + } + + emitter.onSuccess(foldersWithFeeds); + }); + } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 07f3fa93..c679b873 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,8 +1,7 @@ - @@ -13,19 +12,13 @@ android:animateLayoutChanges="true" android:orientation="vertical"> - + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> - - - - - - - \ No newline at end of file + \ No newline at end of file