Add an initial menu for the reader, and some minor changes.
This commit is contained in:
parent
b389db9773
commit
3c1b00435c
@ -15,7 +15,6 @@
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name=".ui.main.MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme.NoActionBar" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -60,8 +60,10 @@ public class Chapter {
|
||||
return url.hashCode();
|
||||
}
|
||||
|
||||
public static Chapter newChapter() {
|
||||
return new Chapter();
|
||||
public static Chapter create() {
|
||||
Chapter chapter = new Chapter();
|
||||
chapter.chapter_number = -1;
|
||||
return chapter;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ public class PreferencesHelper {
|
||||
prefs.edit().clear().apply();
|
||||
}
|
||||
|
||||
public boolean useFullscreenSet() {
|
||||
return prefs.getBoolean(getKey(R.string.pref_fullscreen_key), false);
|
||||
public boolean isHideStatusBarSet() {
|
||||
return prefs.getBoolean(getKey(R.string.pref_hide_status_bar_key), true);
|
||||
}
|
||||
|
||||
public int getDefaultViewer() {
|
||||
|
@ -92,9 +92,4 @@ public abstract class BaseSource {
|
||||
return builder;
|
||||
}
|
||||
|
||||
// Number of images to download at the same time. 3 by default
|
||||
protected int overrideNumberOfConcurrentPageDownloads() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -97,8 +97,7 @@ public abstract class Source extends BaseSource {
|
||||
public Observable<Page> getRemainingImageUrlsFromPageList(final List<Page> pages) {
|
||||
return Observable.from(pages)
|
||||
.filter(page -> page.getImageUrl() == null)
|
||||
.window(overrideNumberOfConcurrentPageDownloads())
|
||||
.concatMap(batchedPages -> batchedPages.concatMap(this::getImageUrlFromPage));
|
||||
.concatMap(this::getImageUrlFromPage);
|
||||
}
|
||||
|
||||
public Observable<Page> getImageUrlFromPage(final Page page) {
|
||||
|
@ -305,7 +305,7 @@ public class Batoto extends Source {
|
||||
}
|
||||
|
||||
private Chapter constructChapterFromHtmlBlock(Element chapterElement) {
|
||||
Chapter newChapter = Chapter.newChapter();
|
||||
Chapter newChapter = Chapter.create();
|
||||
|
||||
Element urlElement = chapterElement.select("a[href^=http://bato.to/reader").first();
|
||||
Element nameElement = urlElement;
|
||||
|
@ -288,7 +288,7 @@ public class Mangahere extends Source {
|
||||
}
|
||||
|
||||
private Chapter constructChapterFromHtmlBlock(Element chapterElement) {
|
||||
Chapter newChapter = Chapter.newChapter();
|
||||
Chapter newChapter = Chapter.create();
|
||||
|
||||
Element urlElement = chapterElement.select("a").first();
|
||||
Element nameElement = chapterElement.select("a").first();
|
||||
|
@ -3,6 +3,7 @@ package eu.kanade.mangafeed.ui.base.activity;
|
||||
import android.content.Context;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
|
||||
public class BaseActivity extends AppCompatActivity {
|
||||
|
||||
@ -22,7 +23,28 @@ public class BaseActivity extends AppCompatActivity {
|
||||
getSupportActionBar().setTitle(getString(titleResource));
|
||||
}
|
||||
|
||||
public void setToolbarSubtitle(String title) {
|
||||
if (getSupportActionBar() != null)
|
||||
getSupportActionBar().setSubtitle(title);
|
||||
}
|
||||
|
||||
public void setToolbarSubtitle(int titleResource) {
|
||||
if (getSupportActionBar() != null)
|
||||
getSupportActionBar().setSubtitle(getString(titleResource));
|
||||
}
|
||||
|
||||
public Context getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
}
|
@ -10,7 +10,6 @@ import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
@ -61,16 +60,6 @@ public class MangaActivity extends BaseRxActivity<MangaPresenter> {
|
||||
getPresenter().queryManga(manga_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void disableToolbarElevation() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.setElevation(0);
|
||||
|
@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
@ -18,6 +19,8 @@ import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
import eu.kanade.mangafeed.App;
|
||||
import eu.kanade.mangafeed.R;
|
||||
import eu.kanade.mangafeed.data.database.models.Chapter;
|
||||
import eu.kanade.mangafeed.data.database.models.Manga;
|
||||
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
|
||||
import eu.kanade.mangafeed.data.source.model.Page;
|
||||
import eu.kanade.mangafeed.ui.base.activity.BaseRxActivity;
|
||||
@ -34,11 +37,14 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
||||
|
||||
@Bind(R.id.page_number) TextView pageNumber;
|
||||
@Bind(R.id.reader) FrameLayout container;
|
||||
@Bind(R.id.toolbar) Toolbar toolbar;
|
||||
|
||||
@Inject PreferencesHelper prefs;
|
||||
|
||||
private BaseReader viewer;
|
||||
private boolean isFullscreen;
|
||||
private ReaderMenu readerMenu;
|
||||
|
||||
private int uiFlags;
|
||||
|
||||
private static final int LEFT_TO_RIGHT = 1;
|
||||
private static final int RIGHT_TO_LEFT = 2;
|
||||
@ -57,27 +63,19 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
||||
setContentView(R.layout.activity_reader);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
if (prefs.useFullscreenSet())
|
||||
enableFullScreen();
|
||||
setupToolbar(toolbar);
|
||||
|
||||
readerMenu = new ReaderMenu(this, prefs);
|
||||
createUiHideFlags();
|
||||
enableHardwareAcceleration();
|
||||
|
||||
viewer = getViewer();
|
||||
}
|
||||
|
||||
public void onPageListReady(List<Page> pages) {
|
||||
viewer.onPageListReady(pages);
|
||||
viewer.updatePageNumber();
|
||||
}
|
||||
|
||||
public void onPageListError() {
|
||||
finish();
|
||||
ToastUtil.showShort(this, R.string.page_list_error);
|
||||
}
|
||||
|
||||
public void onPageChanged(int currentPageIndex, int totalPages) {
|
||||
String page = (currentPageIndex + 1) + "/" + totalPages;
|
||||
pageNumber.setText(page);
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
hideSystemUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -87,42 +85,37 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
private void createUiHideFlags() {
|
||||
uiFlags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
|
||||
if (prefs.isHideStatusBarSet())
|
||||
uiFlags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
|
||||
uiFlags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
}
|
||||
|
||||
public void onChapterReady(List<Page> pages, Manga manga, Chapter chapter) {
|
||||
viewer.onPageListReady(pages);
|
||||
viewer.updatePageNumber();
|
||||
readerMenu.onChapterReady(pages.size(), manga, chapter);
|
||||
}
|
||||
|
||||
public void onChapterError() {
|
||||
finish();
|
||||
ToastUtil.showShort(this, R.string.page_list_error);
|
||||
}
|
||||
|
||||
public void onPageChanged(int currentPageIndex, int totalPages) {
|
||||
String page = (currentPageIndex + 1) + "/" + totalPages;
|
||||
pageNumber.setText(page);
|
||||
readerMenu.onPageChanged(currentPageIndex);
|
||||
}
|
||||
|
||||
public void setSelectedPage(int pageIndex) {
|
||||
viewer.setSelectedPage(pageIndex);
|
||||
}
|
||||
|
||||
public void enableFullScreen() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LOW_PROFILE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
);
|
||||
} else {
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LOW_PROFILE
|
||||
);
|
||||
}
|
||||
isFullscreen = true;
|
||||
}
|
||||
|
||||
public void disableFullscreen() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
);
|
||||
} else {
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.VISIBLE
|
||||
);
|
||||
}
|
||||
isFullscreen = false;
|
||||
public void hideSystemUI() {
|
||||
getWindow().getDecorView().setSystemUiVisibility(uiFlags);
|
||||
}
|
||||
|
||||
public void enableHardwareAcceleration() {
|
||||
@ -136,14 +129,7 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
||||
}
|
||||
|
||||
public void onCenterSingleTap() {
|
||||
toggleFullscreen();
|
||||
}
|
||||
|
||||
private void toggleFullscreen() {
|
||||
if (isFullscreen)
|
||||
disableFullscreen();
|
||||
else
|
||||
enableFullScreen();
|
||||
readerMenu.toggle();
|
||||
}
|
||||
|
||||
private BaseReader getViewer() {
|
||||
|
@ -0,0 +1,80 @@
|
||||
package eu.kanade.mangafeed.ui.reader;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
import eu.kanade.mangafeed.R;
|
||||
import eu.kanade.mangafeed.data.database.models.Chapter;
|
||||
import eu.kanade.mangafeed.data.database.models.Manga;
|
||||
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
|
||||
|
||||
public class ReaderMenu {
|
||||
|
||||
@Bind(R.id.reader_menu) RelativeLayout menu;
|
||||
@Bind(R.id.current_page) TextView currentPage;
|
||||
@Bind(R.id.page_seeker) SeekBar seekBar;
|
||||
@Bind(R.id.total_pages) TextView totalPages;
|
||||
|
||||
|
||||
private ReaderActivity activity;
|
||||
private PreferencesHelper preferences;
|
||||
private boolean showing;
|
||||
private DecimalFormat decimalFormat;
|
||||
|
||||
public ReaderMenu(ReaderActivity activity, PreferencesHelper preferences) {
|
||||
this.activity = activity;
|
||||
this.preferences = preferences;
|
||||
ButterKnife.bind(this, activity);
|
||||
|
||||
seekBar.setOnSeekBarChangeListener(new PageSeekBarChangeListener());
|
||||
decimalFormat = new DecimalFormat("#.##");
|
||||
}
|
||||
|
||||
public void toggle() {
|
||||
toggle(!showing);
|
||||
}
|
||||
|
||||
private void toggle(boolean show) {
|
||||
menu.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
showing = show;
|
||||
}
|
||||
|
||||
public void onChapterReady(int numPages, Manga manga, Chapter chapter) {
|
||||
totalPages.setText("" + numPages);
|
||||
seekBar.setMax(numPages - 1);
|
||||
|
||||
activity.setToolbarTitle(manga.title);
|
||||
activity.setToolbarSubtitle(chapter.chapter_number != -1 ?
|
||||
activity.getString(R.string.chapter_subtitle,
|
||||
decimalFormat.format(chapter.chapter_number)) :
|
||||
chapter.name);
|
||||
|
||||
}
|
||||
|
||||
public void onPageChanged(int pageIndex) {
|
||||
currentPage.setText("" + (pageIndex + 1));
|
||||
seekBar.setProgress(pageIndex);
|
||||
}
|
||||
|
||||
class PageSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
activity.setSelectedPage(progress);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
}
|
@ -66,12 +66,12 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
|
||||
start(RETRY_IMAGES);
|
||||
}),
|
||||
(view, pages) -> {
|
||||
view.onPageListReady(pages);
|
||||
view.onChapterReady(pages, manga, chapter);
|
||||
if (currentPage != 0)
|
||||
view.setSelectedPage(currentPage);
|
||||
},
|
||||
(view, error) -> {
|
||||
view.onPageListError();
|
||||
view.onChapterError();
|
||||
});
|
||||
|
||||
restartableReplay(GET_PAGE_IMAGES,
|
||||
@ -158,7 +158,7 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
|
||||
pages = Observable.from(pageList)
|
||||
.filter(page -> page.getImageUrl() != null)
|
||||
.mergeWith(source.getRemainingImageUrlsFromPageList(pageList))
|
||||
.flatMap(source::getCachedImage);
|
||||
.flatMap(source::getCachedImage, 3);
|
||||
} else {
|
||||
File chapterDir = downloadManager.getAbsoluteChapterDirectory(source, manga, chapter);
|
||||
|
||||
@ -178,7 +178,8 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
|
||||
return Observable.just(page);
|
||||
})
|
||||
.flatMap(source::getCachedImage)
|
||||
.subscribeOn(Schedulers.io());
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread());
|
||||
}
|
||||
|
||||
public void setCurrentPage(int currentPage) {
|
||||
|
@ -2,7 +2,6 @@ package eu.kanade.mangafeed.ui.setting;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
@ -32,14 +31,4 @@ public class SettingsActivity extends BaseActivity {
|
||||
if( !getFragmentManager().popBackStackImmediate() ) super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ public class ChapterRecognition {
|
||||
private static Pattern p2 = Pattern.compile("(\\d+[\\.,]?\\d*)");
|
||||
|
||||
public static void parseChapterNumber(Chapter chapter, Manga manga) {
|
||||
if (chapter.chapter_number != 0)
|
||||
if (chapter.chapter_number != -1)
|
||||
return;
|
||||
|
||||
// Remove spaces and convert to lower case
|
||||
|
@ -6,17 +6,19 @@
|
||||
<FrameLayout
|
||||
android:id="@+id/reader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent">
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="8dp"
|
||||
android:padding="4dp"
|
||||
android:layout_gravity="bottom|left"
|
||||
android:background="@color/bg_light_grey"
|
||||
android:background="@color/page_number_background"
|
||||
android:textColor="@color/black_87pc"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/page_number"/>
|
||||
|
||||
<include layout="@layout/reader_menu"/>
|
||||
|
||||
</FrameLayout>
|
43
app/src/main/res/layout/reader_menu.xml
Normal file
43
app/src/main/res/layout/reader_menu.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/reader_menu"
|
||||
android:visibility="gone">
|
||||
|
||||
<include layout="@layout/toolbar"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/reader_menu_background"
|
||||
android:layout_alignParentBottom="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current_page"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textColor="@color/light_grey"
|
||||
android:gravity="center_horizontal" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/page_seeker"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/total_pages"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textColor="@color/light_grey"
|
||||
android:gravity="center_horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
@ -17,4 +17,6 @@
|
||||
<color name="library_text_background">#E8E8E8</color>
|
||||
<color name="chapter_read_text">#909090</color>
|
||||
<color name="list_choice_pressed_bg_light">#607D8B</color>
|
||||
<color name="page_number_background">#AAE9E9E9</color>
|
||||
<color name="reader_menu_background">#333333</color>
|
||||
</resources>
|
@ -3,7 +3,7 @@
|
||||
<string name="pref_category_reader_key">pref_category_reader_key</string>
|
||||
<string name="pref_category_accounts_key">pref_category_accounts_key</string>
|
||||
<string name="pref_category_downloads_key">pref_category_downloads_key</string>
|
||||
<string name="pref_fullscreen_key">pref_fullscreen_key</string>
|
||||
<string name="pref_hide_status_bar_key">pref_hide_status_bar_key</string>
|
||||
<string name="pref_default_viewer_key">pref_default_viewer_key</string>
|
||||
<string name="pref_download_directory_key">pref_download_directory_key</string>
|
||||
<string name="pref_download_threads_key">pref_download_threads_key</string>
|
||||
|
@ -27,7 +27,7 @@
|
||||
<string name="pref_category_downloads">Downloads</string>
|
||||
|
||||
<!-- Reader section -->
|
||||
<string name="pref_fullscreen_mode">Read in fullscreen</string>
|
||||
<string name="pref_hide_status_bar">Hide status bar</string>
|
||||
<string name="pref_viewer_type">Default viewer</string>
|
||||
<string name="left_to_right_viewer">Left to right</string>
|
||||
<string name="right_to_left_viewer">Right to left</string>
|
||||
@ -75,6 +75,7 @@
|
||||
<string name="download_progress">Downloaded %1$d%%</string>
|
||||
<string name="chapter_progress">Page: %1$d</string>
|
||||
<string name="page_list_error">Error fetching page list. Is network available?</string>
|
||||
<string name="chapter_subtitle">Chapter %1$s</string>
|
||||
|
||||
<!-- Library update service notifications -->
|
||||
<string name="notification_progress">Update progress: %1$d/%2$d</string>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<CheckBoxPreference android:title="@string/pref_fullscreen_mode"
|
||||
android:key="@string/pref_fullscreen_key"
|
||||
<CheckBoxPreference android:title="@string/pref_hide_status_bar"
|
||||
android:key="@string/pref_hide_status_bar_key"
|
||||
android:defaultValue="true" />
|
||||
|
||||
<ListPreference android:title="@string/pref_viewer_type"
|
||||
|
Loading…
Reference in New Issue
Block a user