mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-07 19:27:25 +01:00
Merge pull request #91 from NoodleMage/change_cover
Can now manually set cover pictures. #79
This commit is contained in:
commit
38bb0b61d4
@ -130,12 +130,15 @@ dependencies {
|
|||||||
compile('com.mikepenz:materialdrawer:4.6.4@aar') {
|
compile('com.mikepenz:materialdrawer:4.6.4@aar') {
|
||||||
transitive = true
|
transitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Google material icons SVG.
|
||||||
compile 'com.mikepenz:google-material-typeface:2.1.0.1.original@aar'
|
compile 'com.mikepenz:google-material-typeface:2.1.0.1.original@aar'
|
||||||
|
|
||||||
compile('com.github.afollestad.material-dialogs:core:0.8.5.3@aar') {
|
compile('com.github.afollestad.material-dialogs:core:0.8.5.3@aar') {
|
||||||
transitive = true
|
transitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
testCompile 'org.assertj:assertj-core:2.3.0'
|
testCompile 'org.assertj:assertj-core:2.3.0'
|
||||||
testCompile "org.mockito:mockito-core:$MOCKITO_VERSION"
|
testCompile "org.mockito:mockito-core:$MOCKITO_VERSION"
|
||||||
|
@ -11,6 +11,7 @@ import com.bumptech.glide.load.model.GlideUrl;
|
|||||||
import com.bumptech.glide.load.model.LazyHeaders;
|
import com.bumptech.glide.load.model.LazyHeaders;
|
||||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||||
import com.bumptech.glide.request.target.SimpleTarget;
|
import com.bumptech.glide.request.target.SimpleTarget;
|
||||||
|
import com.bumptech.glide.signature.StringSignature;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -119,7 +120,7 @@ public class CoverCache {
|
|||||||
* @param source the cover image.
|
* @param source the cover image.
|
||||||
* @throws IOException exception returned
|
* @throws IOException exception returned
|
||||||
*/
|
*/
|
||||||
private void copyToLocalCache(String thumbnailUrl, File source) throws IOException {
|
public void copyToLocalCache(String thumbnailUrl, File source) throws IOException {
|
||||||
// Create cache directory if needed.
|
// Create cache directory if needed.
|
||||||
createCacheDir();
|
createCacheDir();
|
||||||
|
|
||||||
@ -200,11 +201,12 @@ public class CoverCache {
|
|||||||
* @param imageView imageView where picture should be displayed.
|
* @param imageView imageView where picture should be displayed.
|
||||||
* @param file file to load. Must exist!.
|
* @param file file to load. Must exist!.
|
||||||
*/
|
*/
|
||||||
private void loadFromCache(ImageView imageView, File file) {
|
public void loadFromCache(ImageView imageView, File file) {
|
||||||
Glide.with(context)
|
Glide.with(context)
|
||||||
.load(file)
|
.load(file)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.RESULT)
|
.diskCacheStrategy(DiskCacheStrategy.RESULT)
|
||||||
.centerCrop()
|
.centerCrop()
|
||||||
|
.signature(new StringSignature(String.valueOf(file.lastModified())))
|
||||||
.into(imageView);
|
.into(imageView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,6 @@ public interface AppComponent {
|
|||||||
void inject(LibraryUpdateService libraryUpdateService);
|
void inject(LibraryUpdateService libraryUpdateService);
|
||||||
void inject(DownloadService downloadService);
|
void inject(DownloadService downloadService);
|
||||||
void inject(UpdateMangaSyncService updateMangaSyncService);
|
void inject(UpdateMangaSyncService updateMangaSyncService);
|
||||||
|
|
||||||
Application application();
|
Application application();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
110
app/src/main/java/eu/kanade/tachiyomi/io/IOHandler.java
Normal file
110
app/src/main/java/eu/kanade/tachiyomi/io/IOHandler.java
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package eu.kanade.tachiyomi.io;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.provider.DocumentsContract;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class IOHandler {
|
||||||
|
/**
|
||||||
|
* Get full filepath of build in Android File picker.
|
||||||
|
* If Google Drive (or other Cloud service) throw exception and download before loading
|
||||||
|
*/
|
||||||
|
public static String getFilePath(Uri uri, ContentResolver resolver, Context context) {
|
||||||
|
try {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
String filePath = "";
|
||||||
|
String wholeID = DocumentsContract.getDocumentId(uri);
|
||||||
|
|
||||||
|
//Ugly work around. In sdk version Kitkat or higher external getDocumentId request will have no content://
|
||||||
|
if (wholeID.split(":").length == 1)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
// Split at colon, use second item in the array
|
||||||
|
String id = wholeID.split(":")[1];
|
||||||
|
|
||||||
|
String[] column = {MediaStore.Images.Media.DATA};
|
||||||
|
|
||||||
|
// where id is equal to
|
||||||
|
String sel = MediaStore.Images.Media._ID + "=?";
|
||||||
|
|
||||||
|
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||||
|
column, sel, new String[]{id}, null);
|
||||||
|
|
||||||
|
int columnIndex = cursor != null ? cursor.getColumnIndex(column[0]) : 0;
|
||||||
|
|
||||||
|
if (cursor != null ? cursor.moveToFirst() : false) {
|
||||||
|
filePath = cursor.getString(columnIndex);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
return filePath;
|
||||||
|
} else {
|
||||||
|
String[] fields = {MediaStore.Images.Media.DATA};
|
||||||
|
|
||||||
|
Cursor cursor = resolver.query(uri, fields, null, null, null);
|
||||||
|
|
||||||
|
if (cursor == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
cursor.moveToFirst();
|
||||||
|
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
|
||||||
|
cursor.close();
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
//This exception is thrown when Google Drive. Try to download file
|
||||||
|
return downloadMediaAndReturnPath(uri, resolver, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTempFilename(Context context) throws IOException {
|
||||||
|
File outputDir = context.getCacheDir();
|
||||||
|
File outputFile = File.createTempFile("temp_cover", "0", outputDir);
|
||||||
|
return outputFile.getAbsolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String downloadMediaAndReturnPath(Uri uri, ContentResolver resolver, Context context) {
|
||||||
|
if (uri == null) return null;
|
||||||
|
FileInputStream input = null;
|
||||||
|
FileOutputStream output = null;
|
||||||
|
try {
|
||||||
|
ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r");
|
||||||
|
FileDescriptor fd = pfd != null ? pfd.getFileDescriptor() : null;
|
||||||
|
input = new FileInputStream(fd);
|
||||||
|
|
||||||
|
String tempFilename = getTempFilename(context);
|
||||||
|
output = new FileOutputStream(tempFilename);
|
||||||
|
|
||||||
|
int read;
|
||||||
|
byte[] bytes = new byte[4096];
|
||||||
|
while ((read = input.read(bytes)) != -1) {
|
||||||
|
output.write(bytes, 0, read);
|
||||||
|
}
|
||||||
|
return tempFilename;
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
} finally {
|
||||||
|
if (input != null) try {
|
||||||
|
input.close();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
if (output != null) try {
|
||||||
|
output.close();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,11 @@
|
|||||||
package eu.kanade.tachiyomi.ui.manga.info;
|
package eu.kanade.tachiyomi.ui.manga.info;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -10,6 +15,11 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.bumptech.glide.load.model.LazyHeaders;
|
import com.bumptech.glide.load.model.LazyHeaders;
|
||||||
|
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
|
||||||
|
import com.mikepenz.iconics.IconicsDrawable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
@ -17,14 +27,16 @@ import eu.kanade.tachiyomi.R;
|
|||||||
import eu.kanade.tachiyomi.data.cache.CoverCache;
|
import eu.kanade.tachiyomi.data.cache.CoverCache;
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga;
|
import eu.kanade.tachiyomi.data.database.models.Manga;
|
||||||
import eu.kanade.tachiyomi.data.source.base.Source;
|
import eu.kanade.tachiyomi.data.source.base.Source;
|
||||||
|
import eu.kanade.tachiyomi.io.IOHandler;
|
||||||
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment;
|
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment;
|
||||||
|
import eu.kanade.tachiyomi.util.ToastUtil;
|
||||||
import nucleus.factory.RequiresPresenter;
|
import nucleus.factory.RequiresPresenter;
|
||||||
|
|
||||||
@RequiresPresenter(MangaInfoPresenter.class)
|
@RequiresPresenter(MangaInfoPresenter.class)
|
||||||
public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
|
public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
|
||||||
|
|
||||||
|
private static final int REQUEST_IMAGE_OPEN = 101;
|
||||||
@Bind(R.id.swipe_refresh) SwipeRefreshLayout swipeRefresh;
|
@Bind(R.id.swipe_refresh) SwipeRefreshLayout swipeRefresh;
|
||||||
|
|
||||||
@Bind(R.id.manga_artist) TextView artist;
|
@Bind(R.id.manga_artist) TextView artist;
|
||||||
@Bind(R.id.manga_author) TextView author;
|
@Bind(R.id.manga_author) TextView author;
|
||||||
@Bind(R.id.manga_chapters) TextView chapterCount;
|
@Bind(R.id.manga_chapters) TextView chapterCount;
|
||||||
@ -33,9 +45,8 @@ public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
|
|||||||
@Bind(R.id.manga_source) TextView source;
|
@Bind(R.id.manga_source) TextView source;
|
||||||
@Bind(R.id.manga_summary) TextView description;
|
@Bind(R.id.manga_summary) TextView description;
|
||||||
@Bind(R.id.manga_cover) ImageView cover;
|
@Bind(R.id.manga_cover) ImageView cover;
|
||||||
|
|
||||||
@Bind(R.id.action_favorite) Button favoriteBtn;
|
@Bind(R.id.action_favorite) Button favoriteBtn;
|
||||||
|
@Bind(R.id.fab_edit) FloatingActionButton fabEdit;
|
||||||
|
|
||||||
public static MangaInfoFragment newInstance() {
|
public static MangaInfoFragment newInstance() {
|
||||||
return new MangaInfoFragment();
|
return new MangaInfoFragment();
|
||||||
@ -54,9 +65,20 @@ public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
|
|||||||
View view = inflater.inflate(R.layout.fragment_manga_info, container, false);
|
View view = inflater.inflate(R.layout.fragment_manga_info, container, false);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
favoriteBtn.setOnClickListener(v -> {
|
//Create edit drawable with size 24dp (google guidelines)
|
||||||
getPresenter().toggleFavorite();
|
IconicsDrawable edit = new IconicsDrawable(this.getContext())
|
||||||
});
|
.icon(GoogleMaterial.Icon.gmd_edit)
|
||||||
|
.color(ContextCompat.getColor(this.getContext(), R.color.white))
|
||||||
|
.sizeDp(24);
|
||||||
|
|
||||||
|
// Update image of fab buttons
|
||||||
|
fabEdit.setImageDrawable(edit);
|
||||||
|
|
||||||
|
// Set listener.
|
||||||
|
fabEdit.setOnClickListener(v -> MangaInfoFragment.this.selectImage());
|
||||||
|
|
||||||
|
favoriteBtn.setOnClickListener(v -> getPresenter().toggleFavorite());
|
||||||
|
|
||||||
swipeRefresh.setOnRefreshListener(this::fetchMangaFromSource);
|
swipeRefresh.setOnRefreshListener(this::fetchMangaFromSource);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
@ -71,6 +93,12 @@ public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the info of the manga
|
||||||
|
*
|
||||||
|
* @param manga manga object containing information about manga
|
||||||
|
* @param mangaSource the source of the manga
|
||||||
|
*/
|
||||||
private void setMangaInfo(Manga manga, Source mangaSource) {
|
private void setMangaInfo(Manga manga, Source mangaSource) {
|
||||||
artist.setText(manga.artist);
|
artist.setText(manga.artist);
|
||||||
author.setText(manga.author);
|
author.setText(manga.author);
|
||||||
@ -99,7 +127,7 @@ public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
|
|||||||
chapterCount.setText(String.valueOf(count));
|
chapterCount.setText(String.valueOf(count));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFavoriteText(boolean isFavorite) {
|
private void setFavoriteText(boolean isFavorite) {
|
||||||
favoriteBtn.setText(!isFavorite ? R.string.add_to_library : R.string.remove_from_library);
|
favoriteBtn.setText(!isFavorite ? R.string.add_to_library : R.string.remove_from_library);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +136,45 @@ public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
|
|||||||
getPresenter().fetchMangaFromSource();
|
getPresenter().fetchMangaFromSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void selectImage() {
|
||||||
|
if (getPresenter().getManga().favorite) {
|
||||||
|
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setType("image/*");
|
||||||
|
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||||
|
startActivityForResult(Intent.createChooser(intent,
|
||||||
|
getString(R.string.file_select_cover)), REQUEST_IMAGE_OPEN);
|
||||||
|
} else {
|
||||||
|
ToastUtil.showShort(getContext(), R.string.notification_first_add_to_library);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
if (requestCode == REQUEST_IMAGE_OPEN) {
|
||||||
|
// Get the file's content URI from the incoming Intent
|
||||||
|
Uri selectedImageUri = data.getData();
|
||||||
|
|
||||||
|
// Convert to absolute path to prevent FileNotFoundException
|
||||||
|
String result = IOHandler.getFilePath(selectedImageUri, this.getContext().getContentResolver(), this.getContext());
|
||||||
|
|
||||||
|
// Get file from filepath
|
||||||
|
File picture = new File(result != null ? result : "");
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Update cover to selected file
|
||||||
|
getPresenter().editCoverWithLocalFile(picture, cover);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onFetchMangaDone() {
|
public void onFetchMangaDone() {
|
||||||
setRefreshing(false);
|
setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package eu.kanade.tachiyomi.ui.manga.info;
|
package eu.kanade.tachiyomi.ui.manga.info;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -19,17 +23,42 @@ import rx.schedulers.Schedulers;
|
|||||||
|
|
||||||
public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
||||||
|
|
||||||
@Inject DatabaseHelper db;
|
/**
|
||||||
@Inject SourceManager sourceManager;
|
* The id of the restartable.
|
||||||
@Inject CoverCache coverCache;
|
*/
|
||||||
|
|
||||||
protected Source source;
|
|
||||||
private Manga manga;
|
|
||||||
private int count = -1;
|
|
||||||
|
|
||||||
private static final int GET_MANGA = 1;
|
private static final int GET_MANGA = 1;
|
||||||
|
/**
|
||||||
|
* The id of the restartable.
|
||||||
|
*/
|
||||||
private static final int GET_CHAPTER_COUNT = 2;
|
private static final int GET_CHAPTER_COUNT = 2;
|
||||||
|
/**
|
||||||
|
* The id of the restartable.
|
||||||
|
*/
|
||||||
private static final int FETCH_MANGA_INFO = 3;
|
private static final int FETCH_MANGA_INFO = 3;
|
||||||
|
/**
|
||||||
|
* Source information
|
||||||
|
*/
|
||||||
|
protected Source source;
|
||||||
|
/**
|
||||||
|
* Used to connect to database
|
||||||
|
*/
|
||||||
|
@Inject DatabaseHelper db;
|
||||||
|
/**
|
||||||
|
* Used to connect to different manga sources
|
||||||
|
*/
|
||||||
|
@Inject SourceManager sourceManager;
|
||||||
|
/**
|
||||||
|
* Used to connect to cache
|
||||||
|
*/
|
||||||
|
@Inject CoverCache coverCache;
|
||||||
|
/**
|
||||||
|
* Selected manga information
|
||||||
|
*/
|
||||||
|
private Manga manga;
|
||||||
|
/**
|
||||||
|
* Count of chapters
|
||||||
|
*/
|
||||||
|
private int count = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedState) {
|
protected void onCreate(Bundle savedState) {
|
||||||
@ -39,22 +68,29 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
|||||||
onProcessRestart();
|
onProcessRestart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update manga cache
|
||||||
restartableLatestCache(GET_MANGA,
|
restartableLatestCache(GET_MANGA,
|
||||||
() -> Observable.just(manga),
|
() -> Observable.just(manga),
|
||||||
(view, manga) -> view.onNextManga(manga, source));
|
(view, manga) -> view.onNextManga(manga, source));
|
||||||
|
|
||||||
|
// Update chapter count
|
||||||
restartableLatestCache(GET_CHAPTER_COUNT,
|
restartableLatestCache(GET_CHAPTER_COUNT,
|
||||||
() -> Observable.just(count),
|
() -> Observable.just(count),
|
||||||
MangaInfoFragment::setChapterCount);
|
MangaInfoFragment::setChapterCount);
|
||||||
|
|
||||||
|
// Fetch manga info from source
|
||||||
restartableFirst(FETCH_MANGA_INFO,
|
restartableFirst(FETCH_MANGA_INFO,
|
||||||
this::fetchMangaObs,
|
this::fetchMangaObs,
|
||||||
(view, manga) -> view.onFetchMangaDone(),
|
(view, manga) -> view.onFetchMangaDone(),
|
||||||
(view, error) -> view.onFetchMangaError());
|
(view, error) -> view.onFetchMangaError());
|
||||||
|
|
||||||
|
// onEventMainThread receives an event thanks to this line.
|
||||||
registerForStickyEvents();
|
registerForStickyEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when savedState not null
|
||||||
|
*/
|
||||||
private void onProcessRestart() {
|
private void onProcessRestart() {
|
||||||
stop(GET_MANGA);
|
stop(GET_MANGA);
|
||||||
stop(GET_CHAPTER_COUNT);
|
stop(GET_CHAPTER_COUNT);
|
||||||
@ -82,6 +118,9 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch manga info from source
|
||||||
|
*/
|
||||||
public void fetchMangaFromSource() {
|
public void fetchMangaFromSource() {
|
||||||
if (isUnsubscribed(FETCH_MANGA_INFO)) {
|
if (isUnsubscribed(FETCH_MANGA_INFO)) {
|
||||||
start(FETCH_MANGA_INFO);
|
start(FETCH_MANGA_INFO);
|
||||||
@ -107,6 +146,16 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
|||||||
refreshManga();
|
refreshManga();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update cover with local file
|
||||||
|
*/
|
||||||
|
public void editCoverWithLocalFile(File file, ImageView imageView) throws IOException {
|
||||||
|
if (manga.favorite) {
|
||||||
|
coverCache.copyToLocalCache(manga.thumbnail_url, file);
|
||||||
|
coverCache.loadFromCache(imageView, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onMangaFavoriteChange(boolean isFavorite) {
|
private void onMangaFavoriteChange(boolean isFavorite) {
|
||||||
if (isFavorite) {
|
if (isFavorite) {
|
||||||
coverCache.save(manga.thumbnail_url, source.getGlideHeaders());
|
coverCache.save(manga.thumbnail_url, source.getGlideHeaders());
|
||||||
@ -115,8 +164,12 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Manga getManga() {
|
||||||
|
return manga;
|
||||||
|
}
|
||||||
|
|
||||||
// Used to refresh the view
|
// Used to refresh the view
|
||||||
private void refreshManga() {
|
protected void refreshManga() {
|
||||||
start(GET_MANGA);
|
start(GET_MANGA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -16,8 +17,8 @@
|
|||||||
<android.support.v4.widget.SwipeRefreshLayout
|
<android.support.v4.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/swipe_refresh"
|
android:id="@+id/swipe_refresh"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:orientation="vertical"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -252,10 +253,29 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
</android.support.v4.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:gravity="bottom">
|
||||||
|
|
||||||
|
<android.support.design.widget.FloatingActionButton
|
||||||
|
android:id="@+id/fab_edit"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|right"
|
||||||
|
android:layout_margin="@dimen/fab_margin"
|
||||||
|
app:backgroundTint="@color/colorPrimary"
|
||||||
|
app:layout_behavior="eu.kanade.tachiyomi.ui.base.fab.ScrollAwareFABBehavior"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
@ -11,6 +11,7 @@
|
|||||||
<color name="primary">@color/colorPrimary</color>
|
<color name="primary">@color/colorPrimary</color>
|
||||||
<color name="primary_dark">@color/colorPrimaryDark</color>
|
<color name="primary_dark">@color/colorPrimaryDark</color>
|
||||||
<color name="primary_light">@color/colorPrimaryLight</color>
|
<color name="primary_light">@color/colorPrimaryLight</color>
|
||||||
|
<color name="color_ripple">#E9F1FF</color>
|
||||||
|
|
||||||
<color name="divider">@color/md_light_dividers</color>
|
<color name="divider">@color/md_light_dividers</color>
|
||||||
|
|
||||||
|
@ -205,5 +205,9 @@
|
|||||||
<string name="notification_no_new_chapters">No new chapters found</string>
|
<string name="notification_no_new_chapters">No new chapters found</string>
|
||||||
<string name="notification_new_chapters">New chapters found for:</string>
|
<string name="notification_new_chapters">New chapters found for:</string>
|
||||||
<string name="notification_manga_update_failed">Failed to update manga:</string>
|
<string name="notification_manga_update_failed">Failed to update manga:</string>
|
||||||
|
<string name="notification_first_add_to_library">Please add the manga to your library before doing this</string>
|
||||||
|
|
||||||
|
<!-- File Picker Titles -->
|
||||||
|
<string name="file_select_cover">Select cover image</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user