mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-22 18:11:50 +01:00
Initial support for recent updates. #20
This commit is contained in:
parent
b9bb41164f
commit
522e900b5a
@ -27,10 +27,12 @@ import eu.kanade.tachiyomi.data.database.models.ChapterSQLiteTypeMapping;
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Manga;
|
import eu.kanade.tachiyomi.data.database.models.Manga;
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory;
|
import eu.kanade.tachiyomi.data.database.models.MangaCategory;
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategorySQLiteTypeMapping;
|
import eu.kanade.tachiyomi.data.database.models.MangaCategorySQLiteTypeMapping;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapter;
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaSQLiteTypeMapping;
|
import eu.kanade.tachiyomi.data.database.models.MangaSQLiteTypeMapping;
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaSync;
|
import eu.kanade.tachiyomi.data.database.models.MangaSync;
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaSyncSQLiteTypeMapping;
|
import eu.kanade.tachiyomi.data.database.models.MangaSyncSQLiteTypeMapping;
|
||||||
import eu.kanade.tachiyomi.data.database.resolvers.LibraryMangaGetResolver;
|
import eu.kanade.tachiyomi.data.database.resolvers.LibraryMangaGetResolver;
|
||||||
|
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterGetResolver;
|
||||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable;
|
import eu.kanade.tachiyomi.data.database.tables.CategoryTable;
|
||||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable;
|
import eu.kanade.tachiyomi.data.database.tables.ChapterTable;
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable;
|
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable;
|
||||||
@ -160,23 +162,14 @@ public class DatabaseHelper {
|
|||||||
.prepare();
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PreparedGetListOfObjects<Chapter> getChapters(long manga_id, boolean sortAToZ, boolean onlyUnread) {
|
public PreparedGetListOfObjects<MangaChapter> getRecentChapters() {
|
||||||
Query.CompleteBuilder query = Query.builder()
|
|
||||||
.table(ChapterTable.TABLE)
|
|
||||||
|
|
||||||
.orderBy(ChapterTable.COLUMN_CHAPTER_NUMBER + (sortAToZ ? " ASC" : " DESC"));
|
|
||||||
|
|
||||||
if (onlyUnread) {
|
|
||||||
query = query.where(ChapterTable.COLUMN_MANGA_ID + "=? AND " + ChapterTable.COLUMN_READ + "=?")
|
|
||||||
.whereArgs(manga_id, 0);
|
|
||||||
} else {
|
|
||||||
query = query.where(ChapterTable.COLUMN_MANGA_ID + "=?")
|
|
||||||
.whereArgs(manga_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return db.get()
|
return db.get()
|
||||||
.listOfObjects(Chapter.class)
|
.listOfObjects(MangaChapter.class)
|
||||||
.withQuery(query.build())
|
.withQuery(RawQuery.builder()
|
||||||
|
.query(MangaChapterGetResolver.RECENT_CHAPTERS_QUERY)
|
||||||
|
.observesTables(ChapterTable.TABLE)
|
||||||
|
.build())
|
||||||
|
.withGetResolver(MangaChapterGetResolver.INSTANCE)
|
||||||
.prepare();
|
.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable;
|
import eu.kanade.tachiyomi.data.database.tables.CategoryTable;
|
||||||
|
import eu.kanade.tachiyomi.data.database.tables.ChapterTable;
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable;
|
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable;
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaSyncTable;
|
import eu.kanade.tachiyomi.data.database.tables.MangaSyncTable;
|
||||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable;
|
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable;
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable;
|
||||||
|
|
||||||
public class DbOpenHelper extends SQLiteOpenHelper {
|
public class DbOpenHelper extends SQLiteOpenHelper {
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package eu.kanade.tachiyomi.data.database.models;
|
||||||
|
|
||||||
|
public class MangaChapter {
|
||||||
|
|
||||||
|
public Manga manga;
|
||||||
|
public Chapter chapter;
|
||||||
|
|
||||||
|
public MangaChapter(Manga manga, Chapter chapter) {
|
||||||
|
this.manga = manga;
|
||||||
|
this.chapter = chapter;
|
||||||
|
}
|
||||||
|
}
|
@ -5,8 +5,8 @@ import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.data.mangasync.base.MangaSyncService;
|
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaSyncTable;
|
import eu.kanade.tachiyomi.data.database.tables.MangaSyncTable;
|
||||||
|
import eu.kanade.tachiyomi.data.mangasync.base.MangaSyncService;
|
||||||
|
|
||||||
@StorIOSQLiteType(table = MangaSyncTable.TABLE)
|
@StorIOSQLiteType(table = MangaSyncTable.TABLE)
|
||||||
public class MangaSync implements Serializable {
|
public class MangaSync implements Serializable {
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package eu.kanade.tachiyomi.data.database.resolvers;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver;
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Chapter;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.ChapterStorIOSQLiteGetResolver;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapter;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaStorIOSQLiteGetResolver;
|
||||||
|
import eu.kanade.tachiyomi.data.database.tables.ChapterTable;
|
||||||
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable;
|
||||||
|
|
||||||
|
public class MangaChapterGetResolver extends DefaultGetResolver<MangaChapter> {
|
||||||
|
|
||||||
|
public static final MangaChapterGetResolver INSTANCE = new MangaChapterGetResolver();
|
||||||
|
|
||||||
|
public static final String QUERY = String.format(
|
||||||
|
"SELECT * FROM %1$s JOIN %2$s on %1$s.%3$s = %2$s.%4$s",
|
||||||
|
MangaTable.TABLE,
|
||||||
|
ChapterTable.TABLE,
|
||||||
|
MangaTable.COLUMN_ID,
|
||||||
|
ChapterTable.COLUMN_MANGA_ID);
|
||||||
|
|
||||||
|
public static final String RECENT_CHAPTERS_QUERY = String.format(
|
||||||
|
QUERY + " ORDER BY %1$s DESC LIMIT 100", ChapterTable.COLUMN_DATE_UPLOAD);
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final MangaStorIOSQLiteGetResolver mangaGetResolver;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final ChapterStorIOSQLiteGetResolver chapterGetResolver;
|
||||||
|
|
||||||
|
public MangaChapterGetResolver() {
|
||||||
|
this.mangaGetResolver = new MangaStorIOSQLiteGetResolver();
|
||||||
|
this.chapterGetResolver = new ChapterStorIOSQLiteGetResolver();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public MangaChapter mapFromCursor(@NonNull Cursor cursor) {
|
||||||
|
final Manga manga = mangaGetResolver.mapFromCursor(cursor);
|
||||||
|
final Chapter chapter = chapterGetResolver.mapFromCursor(cursor);
|
||||||
|
|
||||||
|
return new MangaChapter(manga, chapter);
|
||||||
|
}
|
||||||
|
}
|
@ -1,23 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.data.database.resolvers;
|
|
||||||
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga;
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaStorIOSQLiteGetResolver;
|
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable;
|
|
||||||
|
|
||||||
public class MangaWithUnreadGetResolver extends MangaStorIOSQLiteGetResolver {
|
|
||||||
|
|
||||||
public static final MangaWithUnreadGetResolver INSTANCE = new MangaWithUnreadGetResolver();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NonNull
|
|
||||||
public Manga mapFromCursor(@NonNull Cursor cursor) {
|
|
||||||
Manga manga = super.mapFromCursor(cursor);
|
|
||||||
int unreadColumn = cursor.getColumnIndex(MangaTable.COLUMN_UNREAD);
|
|
||||||
manga.unread = cursor.getInt(unreadColumn);
|
|
||||||
return manga;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -26,7 +26,6 @@ import eu.kanade.tachiyomi.data.source.base.Source;
|
|||||||
import eu.kanade.tachiyomi.data.source.model.Page;
|
import eu.kanade.tachiyomi.data.source.model.Page;
|
||||||
import eu.kanade.tachiyomi.event.DownloadChaptersEvent;
|
import eu.kanade.tachiyomi.event.DownloadChaptersEvent;
|
||||||
import eu.kanade.tachiyomi.util.DiskUtils;
|
import eu.kanade.tachiyomi.util.DiskUtils;
|
||||||
import eu.kanade.tachiyomi.util.DynamicConcurrentMergeOperator;
|
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
@ -14,8 +14,8 @@ import eu.kanade.tachiyomi.injection.module.AppModule;
|
|||||||
import eu.kanade.tachiyomi.injection.module.DataModule;
|
import eu.kanade.tachiyomi.injection.module.DataModule;
|
||||||
import eu.kanade.tachiyomi.ui.catalogue.CataloguePresenter;
|
import eu.kanade.tachiyomi.ui.catalogue.CataloguePresenter;
|
||||||
import eu.kanade.tachiyomi.ui.download.DownloadPresenter;
|
import eu.kanade.tachiyomi.ui.download.DownloadPresenter;
|
||||||
import eu.kanade.tachiyomi.ui.library.category.CategoryPresenter;
|
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryPresenter;
|
import eu.kanade.tachiyomi.ui.library.LibraryPresenter;
|
||||||
|
import eu.kanade.tachiyomi.ui.library.category.CategoryPresenter;
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaActivity;
|
import eu.kanade.tachiyomi.ui.manga.MangaActivity;
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaPresenter;
|
import eu.kanade.tachiyomi.ui.manga.MangaPresenter;
|
||||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersPresenter;
|
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersPresenter;
|
||||||
@ -23,6 +23,7 @@ import eu.kanade.tachiyomi.ui.manga.info.MangaInfoPresenter;
|
|||||||
import eu.kanade.tachiyomi.ui.manga.myanimelist.MyAnimeListPresenter;
|
import eu.kanade.tachiyomi.ui.manga.myanimelist.MyAnimeListPresenter;
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter;
|
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter;
|
||||||
|
import eu.kanade.tachiyomi.ui.recent.RecentChaptersPresenter;
|
||||||
import eu.kanade.tachiyomi.ui.setting.SettingsAccountsFragment;
|
import eu.kanade.tachiyomi.ui.setting.SettingsAccountsFragment;
|
||||||
import eu.kanade.tachiyomi.ui.setting.SettingsActivity;
|
import eu.kanade.tachiyomi.ui.setting.SettingsActivity;
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ public interface AppComponent {
|
|||||||
void inject(DownloadPresenter downloadPresenter);
|
void inject(DownloadPresenter downloadPresenter);
|
||||||
void inject(MyAnimeListPresenter myAnimeListPresenter);
|
void inject(MyAnimeListPresenter myAnimeListPresenter);
|
||||||
void inject(CategoryPresenter categoryPresenter);
|
void inject(CategoryPresenter categoryPresenter);
|
||||||
|
void inject(RecentChaptersPresenter recentChaptersPresenter);
|
||||||
|
|
||||||
void inject(ReaderActivity readerActivity);
|
void inject(ReaderActivity readerActivity);
|
||||||
void inject(MangaActivity mangaActivity);
|
void inject(MangaActivity mangaActivity);
|
||||||
|
@ -8,9 +8,9 @@ import dagger.Module;
|
|||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
import eu.kanade.tachiyomi.data.cache.ChapterCache;
|
import eu.kanade.tachiyomi.data.cache.ChapterCache;
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache;
|
import eu.kanade.tachiyomi.data.cache.CoverCache;
|
||||||
import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager;
|
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager;
|
import eu.kanade.tachiyomi.data.download.DownloadManager;
|
||||||
|
import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager;
|
||||||
import eu.kanade.tachiyomi.data.network.NetworkHelper;
|
import eu.kanade.tachiyomi.data.network.NetworkHelper;
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper;
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper;
|
||||||
import eu.kanade.tachiyomi.data.source.SourceManager;
|
import eu.kanade.tachiyomi.data.source.SourceManager;
|
||||||
|
@ -2,13 +2,13 @@ package eu.kanade.tachiyomi.ui.decoration;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.util.AttributeSet;
|
import android.graphics.Canvas;
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
|
||||||
import android.view.View;
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.Canvas;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
|
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.ui.base.activity.BaseActivity;
|
|||||||
import eu.kanade.tachiyomi.ui.catalogue.CatalogueFragment;
|
import eu.kanade.tachiyomi.ui.catalogue.CatalogueFragment;
|
||||||
import eu.kanade.tachiyomi.ui.download.DownloadFragment;
|
import eu.kanade.tachiyomi.ui.download.DownloadFragment;
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryFragment;
|
import eu.kanade.tachiyomi.ui.library.LibraryFragment;
|
||||||
|
import eu.kanade.tachiyomi.ui.recent.RecentChaptersFragment;
|
||||||
import eu.kanade.tachiyomi.ui.setting.SettingsActivity;
|
import eu.kanade.tachiyomi.ui.setting.SettingsActivity;
|
||||||
import icepick.State;
|
import icepick.State;
|
||||||
import nucleus.view.ViewWithPresenter;
|
import nucleus.view.ViewWithPresenter;
|
||||||
@ -71,9 +72,9 @@ public class MainActivity extends BaseActivity {
|
|||||||
new PrimaryDrawerItem()
|
new PrimaryDrawerItem()
|
||||||
.withName(R.string.label_library)
|
.withName(R.string.label_library)
|
||||||
.withIdentifier(R.id.nav_drawer_library),
|
.withIdentifier(R.id.nav_drawer_library),
|
||||||
// new PrimaryDrawerItem()
|
new PrimaryDrawerItem()
|
||||||
// .withName(R.string.recent_updates_title)
|
.withName(R.string.label_recent_updates)
|
||||||
// .withIdentifier(R.id.nav_drawer_recent_updates),
|
.withIdentifier(R.id.nav_drawer_recent_updates),
|
||||||
new PrimaryDrawerItem()
|
new PrimaryDrawerItem()
|
||||||
.withName(R.string.label_catalogues)
|
.withName(R.string.label_catalogues)
|
||||||
.withIdentifier(R.id.nav_drawer_catalogues),
|
.withIdentifier(R.id.nav_drawer_catalogues),
|
||||||
@ -95,6 +96,7 @@ public class MainActivity extends BaseActivity {
|
|||||||
setFragment(LibraryFragment.newInstance());
|
setFragment(LibraryFragment.newInstance());
|
||||||
break;
|
break;
|
||||||
case R.id.nav_drawer_recent_updates:
|
case R.id.nav_drawer_recent_updates:
|
||||||
|
setFragment(RecentChaptersFragment.newInstance());
|
||||||
break;
|
break;
|
||||||
case R.id.nav_drawer_catalogues:
|
case R.id.nav_drawer_catalogues:
|
||||||
setFragment(CatalogueFragment.newInstance());
|
setFragment(CatalogueFragment.newInstance());
|
||||||
|
@ -8,8 +8,8 @@ import android.view.MotionEvent;
|
|||||||
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterBoundariesOutListener;
|
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterBoundariesOutListener;
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterSingleTapListener;
|
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterSingleTapListener;
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerGestureListener;
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.Pager;
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.Pager;
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerGestureListener;
|
||||||
import rx.functions.Action1;
|
import rx.functions.Action1;
|
||||||
|
|
||||||
public class HorizontalPager extends ViewPager implements Pager {
|
public class HorizontalPager extends ViewPager implements Pager {
|
||||||
|
@ -7,8 +7,8 @@ import android.view.MotionEvent;
|
|||||||
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterBoundariesOutListener;
|
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterBoundariesOutListener;
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterSingleTapListener;
|
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterSingleTapListener;
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerGestureListener;
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.Pager;
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.Pager;
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerGestureListener;
|
||||||
import rx.functions.Action1;
|
import rx.functions.Action1;
|
||||||
|
|
||||||
public class VerticalPager extends VerticalViewPagerImpl implements Pager {
|
public class VerticalPager extends VerticalViewPagerImpl implements Pager {
|
||||||
|
@ -0,0 +1,102 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.recent;
|
||||||
|
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
||||||
|
import eu.kanade.tachiyomi.R;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapter;
|
||||||
|
|
||||||
|
public class RecentChaptersAdapter extends FlexibleAdapter<RecyclerView.ViewHolder, Object> {
|
||||||
|
|
||||||
|
private RecentChaptersFragment fragment;
|
||||||
|
|
||||||
|
private static final int CHAPTER = 0;
|
||||||
|
private static final int SECTION = 1;
|
||||||
|
|
||||||
|
public RecentChaptersAdapter(RecentChaptersFragment fragment) {
|
||||||
|
this.fragment = fragment;
|
||||||
|
setHasStableIds(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
Object item = getItem(position);
|
||||||
|
if (item instanceof MangaChapter)
|
||||||
|
return ((MangaChapter) item).chapter.id;
|
||||||
|
else
|
||||||
|
return item.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItems(List<Object> items) {
|
||||||
|
mItems = items;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDataSet(String param) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return getItem(position) instanceof MangaChapter ? CHAPTER : SECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||||
|
View v;
|
||||||
|
switch (viewType) {
|
||||||
|
case CHAPTER:
|
||||||
|
v = inflater.inflate(R.layout.item_recent_chapter, parent, false);
|
||||||
|
return new RecentChaptersHolder(v, this, fragment);
|
||||||
|
case SECTION:
|
||||||
|
v = inflater.inflate(R.layout.item_recent_chapter_section, parent, false);
|
||||||
|
return new SectionViewHolder(v);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||||
|
switch (holder.getItemViewType()) {
|
||||||
|
case CHAPTER:
|
||||||
|
final MangaChapter chapter = (MangaChapter) getItem(position);
|
||||||
|
((RecentChaptersHolder) holder).onSetValues(chapter);
|
||||||
|
break;
|
||||||
|
case SECTION:
|
||||||
|
final Date date = (Date) getItem(position);
|
||||||
|
((SectionViewHolder) holder).onSetValues(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
//When user scrolls this bind the correct selection status
|
||||||
|
holder.itemView.setActivated(isSelected(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecentChaptersFragment getFragment() {
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SectionViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
private TextView view;
|
||||||
|
|
||||||
|
public SectionViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
this.view = (TextView) view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSetValues(Date date) {
|
||||||
|
String s = DateFormat.getDateFormat(view.getContext()).format(date);
|
||||||
|
view.setText(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.recent;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import butterknife.Bind;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import eu.kanade.tachiyomi.R;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapter;
|
||||||
|
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
|
||||||
|
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment;
|
||||||
|
import eu.kanade.tachiyomi.ui.decoration.DividerItemDecoration;
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
|
||||||
|
import nucleus.factory.RequiresPresenter;
|
||||||
|
|
||||||
|
@RequiresPresenter(RecentChaptersPresenter.class)
|
||||||
|
public class RecentChaptersFragment extends BaseRxFragment<RecentChaptersPresenter> implements FlexibleViewHolder.OnListItemClickListener {
|
||||||
|
|
||||||
|
@Bind(R.id.chapter_list) RecyclerView recyclerView;
|
||||||
|
|
||||||
|
private RecentChaptersAdapter adapter;
|
||||||
|
|
||||||
|
public static RecentChaptersFragment newInstance() {
|
||||||
|
return new RecentChaptersFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
View view = inflater.inflate(R.layout.fragment_recent_chapters, container, false);
|
||||||
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
|
// Init RecyclerView and adapter
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||||
|
recyclerView.addItemDecoration(new DividerItemDecoration(ContextCompat.getDrawable(
|
||||||
|
getContext(), R.drawable.line_divider)));
|
||||||
|
recyclerView.setHasFixedSize(true);
|
||||||
|
adapter = new RecentChaptersAdapter(this);
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
|
setToolbarTitle(R.string.label_recent_updates);
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onNextMangaChapters(List<Object> chapters) {
|
||||||
|
adapter.setItems(chapters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onListItemClick(int position) {
|
||||||
|
Object item = adapter.getItem(position);
|
||||||
|
if (item instanceof MangaChapter) {
|
||||||
|
openChapter((MangaChapter) item);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onListItemLongClick(int position) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void openChapter(MangaChapter chapter) {
|
||||||
|
getPresenter().onOpenChapter(chapter);
|
||||||
|
Intent intent = ReaderActivity.newIntent(getActivity());
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.recent;
|
||||||
|
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import butterknife.Bind;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import eu.kanade.tachiyomi.R;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapter;
|
||||||
|
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
|
||||||
|
|
||||||
|
public class RecentChaptersHolder extends FlexibleViewHolder {
|
||||||
|
|
||||||
|
@Bind(R.id.chapter_title) TextView chapterTitle;
|
||||||
|
@Bind(R.id.manga_title) TextView mangaTitle;
|
||||||
|
|
||||||
|
private final int readColor;
|
||||||
|
private final int unreadColor;
|
||||||
|
|
||||||
|
public RecentChaptersHolder(View view, RecentChaptersAdapter adapter, OnListItemClickListener onListItemClickListener) {
|
||||||
|
super(view, adapter, onListItemClickListener);
|
||||||
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
|
readColor = ContextCompat.getColor(view.getContext(), R.color.hint_text);
|
||||||
|
unreadColor = ContextCompat.getColor(view.getContext(), R.color.primary_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSetValues(MangaChapter item) {
|
||||||
|
chapterTitle.setText(item.chapter.name);
|
||||||
|
mangaTitle.setText(item.manga.title);
|
||||||
|
|
||||||
|
if (item.chapter.read) {
|
||||||
|
chapterTitle.setTextColor(readColor);
|
||||||
|
mangaTitle.setTextColor(readColor);
|
||||||
|
} else {
|
||||||
|
chapterTitle.setTextColor(unreadColor);
|
||||||
|
mangaTitle.setTextColor(unreadColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.recent;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import de.greenrobot.event.EventBus;
|
||||||
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaChapter;
|
||||||
|
import eu.kanade.tachiyomi.data.source.SourceManager;
|
||||||
|
import eu.kanade.tachiyomi.data.source.base.Source;
|
||||||
|
import eu.kanade.tachiyomi.event.ReaderEvent;
|
||||||
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
|
||||||
|
import rx.Observable;
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
|
||||||
|
public class RecentChaptersPresenter extends BasePresenter<RecentChaptersFragment> {
|
||||||
|
|
||||||
|
@Inject DatabaseHelper db;
|
||||||
|
@Inject SourceManager sourceManager;
|
||||||
|
|
||||||
|
private static final int GET_RECENT_CHAPTERS = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedState) {
|
||||||
|
super.onCreate(savedState);
|
||||||
|
|
||||||
|
restartableLatestCache(GET_RECENT_CHAPTERS,
|
||||||
|
this::getRecentChaptersObservable,
|
||||||
|
RecentChaptersFragment::onNextMangaChapters);
|
||||||
|
|
||||||
|
if (savedState == null)
|
||||||
|
start(GET_RECENT_CHAPTERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Observable<List<Object>> getRecentChaptersObservable() {
|
||||||
|
return db.getRecentChapters().createObservable()
|
||||||
|
// group chapters by the date they were fetched on a ordered map
|
||||||
|
.flatMap(recents -> Observable.from(recents)
|
||||||
|
.toMultimap(
|
||||||
|
recent -> getMapKey(recent.chapter.date_fetch),
|
||||||
|
recent -> recent,
|
||||||
|
() -> new TreeMap<>((d1, d2) -> d2.compareTo(d1))))
|
||||||
|
// add every day and all its chapters to a single list
|
||||||
|
.map(recents -> {
|
||||||
|
List<Object> items = new ArrayList<>();
|
||||||
|
for (Map.Entry<Date, Collection<MangaChapter>> recent : recents.entrySet()) {
|
||||||
|
items.add(recent.getKey());
|
||||||
|
items.addAll(recent.getValue());
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
})
|
||||||
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date getMapKey(long date) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(new Date(date));
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
cal.set(Calendar.MINUTE, 0);
|
||||||
|
cal.set(Calendar.SECOND, 0);
|
||||||
|
cal.set(Calendar.MILLISECOND, 0);
|
||||||
|
return cal.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onOpenChapter(MangaChapter item) {
|
||||||
|
Source source = sourceManager.get(item.manga.source);
|
||||||
|
EventBus.getDefault().postSticky(new ReaderEvent(source, item.manga, item.chapter));
|
||||||
|
}
|
||||||
|
}
|
@ -12,8 +12,8 @@ import java.util.List;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.App;
|
import eu.kanade.tachiyomi.App;
|
||||||
import eu.kanade.tachiyomi.data.mangasync.base.MangaSyncService;
|
|
||||||
import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager;
|
import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager;
|
||||||
|
import eu.kanade.tachiyomi.data.mangasync.base.MangaSyncService;
|
||||||
import eu.kanade.tachiyomi.data.source.SourceManager;
|
import eu.kanade.tachiyomi.data.source.SourceManager;
|
||||||
import eu.kanade.tachiyomi.data.source.base.Source;
|
import eu.kanade.tachiyomi.data.source.base.Source;
|
||||||
import eu.kanade.tachiyomi.widget.preference.MangaSyncLoginDialog;
|
import eu.kanade.tachiyomi.widget.preference.MangaSyncLoginDialog;
|
||||||
|
18
app/src/main/res/layout/fragment_recent_chapters.xml
Normal file
18
app/src/main/res/layout/fragment_recent_chapters.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/chapter_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:descendantFocusability="blocksDescendants"
|
||||||
|
android:background="@color/white"
|
||||||
|
tools:listitem="@layout/item_recent_chapter">
|
||||||
|
|
||||||
|
</android.support.v7.widget.RecyclerView>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
47
app/src/main/res/layout/item_recent_chapter.xml
Normal file
47
app/src/main/res/layout/item_recent_chapter.xml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="?android:attr/listPreferredItemHeight"
|
||||||
|
android:background="@drawable/selector_chapter_light">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
|
||||||
|
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="30dp"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/manga_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
|
android:singleLine="true"
|
||||||
|
tools:text="My manga"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/chapter_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
android:maxLines="1"
|
||||||
|
tools:text="Title"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
14
app/src/main/res/layout/item_recent_chapter_section.xml
Normal file
14
app/src/main/res/layout/item_recent_chapter_section.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingLeft="24dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textColor="@color/colorAccent"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:id="@+id/section_text"
|
||||||
|
android:textStyle="bold" />
|
Loading…
Reference in New Issue
Block a user