├── .editorconfig ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── ic_launcher_calculator-playstore.png │ ├── java │ └── com │ │ └── dar │ │ └── nclientv2 │ │ ├── BookmarkActivity.java │ │ ├── CommentActivity.java │ │ ├── CopyToClipboardActivity.java │ │ ├── FavoriteActivity.java │ │ ├── GalleryActivity.java │ │ ├── HistoryActivity.java │ │ ├── LocalActivity.java │ │ ├── LoginActivity.java │ │ ├── MainActivity.java │ │ ├── PINActivity.java │ │ ├── RandomActivity.java │ │ ├── SearchActivity.java │ │ ├── SettingsActivity.java │ │ ├── StatusManagerActivity.java │ │ ├── StatusViewerActivity.java │ │ ├── TagFilterActivity.java │ │ ├── ZoomActivity.java │ │ ├── adapters │ │ ├── BookmarkAdapter.java │ │ ├── CommentAdapter.java │ │ ├── FavoriteAdapter.java │ │ ├── GalleryAdapter.java │ │ ├── GenericAdapter.java │ │ ├── HistoryAdapter.java │ │ ├── ListAdapter.java │ │ ├── LocalAdapter.java │ │ ├── StatusManagerAdapter.java │ │ ├── StatusViewerAdapter.java │ │ └── TagsAdapter.java │ │ ├── api │ │ ├── InspectorV3.java │ │ ├── RandomLoader.java │ │ ├── SimpleGallery.java │ │ ├── comments │ │ │ ├── Comment.java │ │ │ ├── CommentsFetcher.java │ │ │ └── User.java │ │ ├── components │ │ │ ├── Gallery.java │ │ │ ├── GalleryData.java │ │ │ ├── GenericGallery.java │ │ │ ├── Page.java │ │ │ ├── Ranges.java │ │ │ ├── Tag.java │ │ │ └── TagList.java │ │ ├── enums │ │ │ ├── ApiRequestType.java │ │ │ ├── ImageExt.java │ │ │ ├── ImageType.java │ │ │ ├── Language.java │ │ │ ├── SortType.java │ │ │ ├── SpecialTagIds.java │ │ │ ├── TagStatus.java │ │ │ ├── TagType.java │ │ │ └── TitleType.java │ │ └── local │ │ │ ├── FakeInspector.java │ │ │ ├── LocalGallery.java │ │ │ └── LocalSortType.java │ │ ├── async │ │ ├── MetadataFetcher.java │ │ ├── ScrapeTags.java │ │ ├── VersionChecker.java │ │ ├── converters │ │ │ ├── CreatePDF.java │ │ │ └── CreateZIP.java │ │ ├── database │ │ │ ├── DatabaseHelper.java │ │ │ ├── Queries.java │ │ │ └── export │ │ │ │ ├── Exporter.java │ │ │ │ ├── Importer.java │ │ │ │ └── Manager.java │ │ └── downloader │ │ │ ├── DownloadGalleryV2.java │ │ │ ├── DownloadObserver.java │ │ │ ├── DownloadQueue.java │ │ │ ├── GalleryDownloaderManager.java │ │ │ ├── GalleryDownloaderV2.java │ │ │ └── PageChecker.java │ │ ├── components │ │ ├── CookieInterceptor.java │ │ ├── CustomCookieJar.java │ │ ├── GlideX.java │ │ ├── LocaleManager.java │ │ ├── Module.java │ │ ├── ThreadAsyncTask.java │ │ ├── activities │ │ │ ├── BaseActivity.java │ │ │ ├── CrashApplication.java │ │ │ └── GeneralActivity.java │ │ ├── classes │ │ │ ├── Bookmark.java │ │ │ ├── ConnectivityReceiver.java │ │ │ ├── CustomSSLSocketFactory.java │ │ │ ├── History.java │ │ │ ├── MultichoiceAdapter.java │ │ │ ├── MySender.java │ │ │ ├── MySenderFactory.java │ │ │ ├── Size.java │ │ │ └── integration │ │ │ │ ├── GlideGeneral.java │ │ │ │ ├── OkHttpGlideModule.java │ │ │ │ ├── OkHttpLibraryGlideModule.java │ │ │ │ ├── OkHttpStreamFetcher.java │ │ │ │ └── OkHttpUrlLoader.java │ │ ├── launcher │ │ │ ├── LauncherCalculator.java │ │ │ └── LauncherReal.java │ │ ├── status │ │ │ ├── Status.java │ │ │ └── StatusManager.java │ │ ├── views │ │ │ ├── CFTokenView.java │ │ │ ├── GeneralPreferenceFragment.java │ │ │ ├── PageSwitcher.java │ │ │ ├── RangeSelector.java │ │ │ └── ZoomFragment.java │ │ └── widgets │ │ │ ├── ChipTag.java │ │ │ ├── CustomGridLayoutManager.java │ │ │ ├── CustomImageView.java │ │ │ ├── CustomLinearLayoutManager.java │ │ │ ├── CustomSearchView.java │ │ │ ├── CustomSwipe.java │ │ │ └── TagTypePage.java │ │ ├── files │ │ ├── GalleryFolder.java │ │ └── PageFile.java │ │ ├── github │ │ └── chrisbanes │ │ │ └── photoview │ │ │ ├── Compat.java │ │ │ ├── CustomGestureDetector.java │ │ │ ├── OnGestureListener.java │ │ │ ├── OnMatrixChangedListener.java │ │ │ ├── OnOutsidePhotoTapListener.java │ │ │ ├── OnPhotoTapListener.java │ │ │ ├── OnScaleChangedListener.java │ │ │ ├── OnSingleFlingListener.java │ │ │ ├── OnViewDragListener.java │ │ │ ├── OnViewTapListener.java │ │ │ ├── PhotoView.java │ │ │ ├── PhotoViewAttacher.java │ │ │ └── Util.java │ │ ├── loginapi │ │ ├── LoadTags.java │ │ └── User.java │ │ ├── settings │ │ ├── AuthRequest.java │ │ ├── CustomInterceptor.java │ │ ├── Database.java │ │ ├── DefaultDialogs.java │ │ ├── Favorites.java │ │ ├── Global.java │ │ ├── Login.java │ │ ├── NotificationSettings.java │ │ └── TagV2.java │ │ ├── ui │ │ └── main │ │ │ ├── PlaceholderFragment.java │ │ │ └── SectionsPagerAdapter.java │ │ └── utility │ │ ├── CSRFGet.java │ │ ├── ImageDownloadUtility.java │ │ ├── IntentUtility.java │ │ ├── LogUtility.java │ │ ├── Utility.java │ │ └── network │ │ ├── ConnectivityChecker.java │ │ └── NetworkUtil.java │ └── res │ ├── drawable-anydpi-v24 │ ├── ic_archive.xml │ ├── ic_check.xml │ ├── ic_close.xml │ ├── ic_file.xml │ ├── ic_pause.xml │ └── ic_play.xml │ ├── drawable-hdpi │ ├── ic_archive.png │ ├── ic_check.png │ ├── ic_close.png │ ├── ic_file.png │ ├── ic_pause.png │ └── ic_play.png │ ├── drawable-mdpi │ ├── ic_archive.png │ ├── ic_check.png │ ├── ic_close.png │ ├── ic_file.png │ ├── ic_pause.png │ └── ic_play.png │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable-xhdpi │ ├── ic_archive.png │ ├── ic_check.png │ ├── ic_close.png │ ├── ic_file.png │ ├── ic_pause.png │ └── ic_play.png │ ├── drawable-xxhdpi │ ├── ic_archive.png │ ├── ic_check.png │ ├── ic_close.png │ ├── ic_file.png │ ├── ic_pause.png │ └── ic_play.png │ ├── drawable │ ├── ic_access_time.xml │ ├── ic_add.xml │ ├── ic_archive.xml │ ├── ic_arrow_back.xml │ ├── ic_arrow_forward.xml │ ├── ic_backspace.xml │ ├── ic_bookmark.xml │ ├── ic_bookmark_border.xml │ ├── ic_burst_mode.xml │ ├── ic_chat_bubble.xml │ ├── ic_check.xml │ ├── ic_check_circle.xml │ ├── ic_close.xml │ ├── ic_cnbw.xml │ ├── ic_content_copy.xml │ ├── ic_delete.xml │ ├── ic_exit_to_app.xml │ ├── ic_favorite.xml │ ├── ic_favorite_border.xml │ ├── ic_filter_list.xml │ ├── ic_find_in_page.xml │ ├── ic_folder.xml │ ├── ic_gbbw.xml │ ├── ic_hashtag.xml │ ├── ic_help.xml │ ├── ic_jpbw.xml │ ├── ic_keyboard_arrow_left.xml │ ├── ic_keyboard_arrow_right.xml │ ├── ic_launcher_calculator_foreground.xml │ ├── ic_launcher_foreground.xml │ ├── ic_logo.xml │ ├── ic_logo_dark.xml │ ├── ic_mode_edit.xml │ ├── ic_pause.xml │ ├── ic_pdf.xml │ ├── ic_person.xml │ ├── ic_play.xml │ ├── ic_refresh.xml │ ├── ic_rotate_90_degrees.xml │ ├── ic_save.xml │ ├── ic_search.xml │ ├── ic_select_all.xml │ ├── ic_settings.xml │ ├── ic_share.xml │ ├── ic_shuffle.xml │ ├── ic_sort.xml │ ├── ic_sort_by_alpha.xml │ ├── ic_star.xml │ ├── ic_star_border.xml │ ├── ic_view_1.xml │ ├── ic_view_2.xml │ ├── ic_view_3.xml │ ├── ic_view_4.xml │ ├── ic_void.xml │ ├── ic_world.xml │ ├── side_nav_bar_dark.xml │ ├── side_nav_bar_light.xml │ └── thumb.xml │ ├── layout-land │ └── activity_random.xml │ ├── layout │ ├── activity_bookmark.xml │ ├── activity_comment.xml │ ├── activity_gallery.xml │ ├── activity_login.xml │ ├── activity_main.xml │ ├── activity_pin.xml │ ├── activity_random.xml │ ├── activity_search.xml │ ├── activity_settings.xml │ ├── activity_status_viewer.xml │ ├── activity_tag_filter.xml │ ├── activity_zoom.xml │ ├── app_bar_gallery.xml │ ├── app_bar_main.xml │ ├── autocomplete_entry.xml │ ├── bookmark_layout.xml │ ├── cftoken_layout.xml │ ├── chip_layout.xml │ ├── chip_layout_entry.xml │ ├── comment_layout.xml │ ├── content_gallery.xml │ ├── content_main.xml │ ├── dialog_add_status.xml │ ├── entry_download_layout.xml │ ├── entry_download_layout_compact.xml │ ├── entry_history.xml │ ├── entry_layout.xml │ ├── entry_layout_single.xml │ ├── entry_status.xml │ ├── entry_tag_layout.xml │ ├── fragment_status_viewer.xml │ ├── fragment_tag_filter.xml │ ├── fragment_zoom.xml │ ├── image_void.xml │ ├── image_void_full.xml │ ├── image_void_static.xml │ ├── info_layout.xml │ ├── local_sort_type.xml │ ├── multichoice_adapter.xml │ ├── nav_header_main.xml │ ├── page_changer.xml │ ├── page_switcher.xml │ ├── range_selector.xml │ ├── related_recycler.xml │ ├── search_options.xml │ ├── search_range.xml │ ├── sub_tag_layout.xml │ ├── tags_layout.xml │ └── zoom_manager.xml │ ├── menu │ ├── activity_main_drawer.xml │ ├── download.xml │ ├── gallery.xml │ ├── history.xml │ ├── local_multichoice.xml │ ├── main.xml │ ├── menu_tag_filter.xml │ ├── menu_zoom.xml │ ├── search.xml │ └── status_viewer.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ ├── ic_launcher_calculator.xml │ └── ic_launcher_calculator_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_calculator.png │ └── ic_launcher_calculator_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_calculator.png │ └── ic_launcher_calculator_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_calculator.png │ └── ic_launcher_calculator_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_calculator.png │ └── ic_launcher_calculator_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_calculator.png │ └── ic_launcher_calculator_round.png │ ├── values-ar-rSA │ └── strings.xml │ ├── values-de-rDE │ └── strings.xml │ ├── values-es-rES │ └── strings.xml │ ├── values-fr-rFR │ └── strings.xml │ ├── values-it-rIT │ └── strings.xml │ ├── values-ja-rJP │ └── strings.xml │ ├── values-ru-rRU │ └── strings.xml │ ├── values-tr-rTR │ └── strings.xml │ ├── values-uk-rUA │ └── strings.xml │ ├── values-v19 │ └── styles.xml │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ ├── values-zh-rCN │ └── strings.xml │ ├── values-zh-rTW │ └── strings.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── ic_launcher_background.xml │ ├── ic_launcher_calculator_background.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ ├── backup_content.xml │ ├── provider_paths.xml │ ├── settings.xml │ ├── settings_column.xml │ └── settings_data.xml ├── build.gradle ├── data ├── tags.json ├── tagsPretty.json └── tagsVersion ├── fastlane └── metadata │ └── android │ ├── en-US │ ├── changelogs │ │ └── 203.txt │ ├── full_description.txt │ ├── images │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── img1.jpg │ │ │ ├── img2.jpg │ │ │ ├── img3.jpg │ │ │ └── img4.jpg │ ├── short_description.txt │ └── title.txt │ ├── fr-FR │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── it-IT │ ├── changelogs │ │ └── 203.txt │ ├── full_description.txt │ ├── images │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── img1.jpg │ │ │ ├── img2.jpg │ │ │ ├── img3.jpg │ │ │ └── img4.jpg │ ├── short_description.txt │ └── title.txt │ ├── tr-TR │ ├── changelogs │ │ └── 203.txt │ ├── full_description.txt │ ├── images │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── img1.jpg │ │ │ ├── img2.jpg │ │ │ ├── img3.jpg │ │ │ └── img4.jpg │ ├── short_description.txt │ └── title.txt │ └── zh-CN │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | liberapay: Dar9586 2 | custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CVMR2STUSVE6U'] 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Your issue may already be reported! 2 | Please search on the [issue tracker](../) before creating one. 3 | 4 | ## Expected Behavior 5 | 6 | 7 | 8 | ## Current Behavior 9 | 10 | 11 | 12 | ## Possible Solution 13 | 14 | 15 | 16 | ## Steps to Reproduce (for bugs) 17 | 18 | 19 | 1. 20 | 2. 21 | 3. 22 | 4. 23 | 24 | ## Context 25 | 26 | 27 | 28 | ## Your Environment 29 | 30 | * Version used: 31 | * Operating System version: 32 | 33 | 34 | * NHentai link (if relevant): 35 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | A similar PR may already be submitted! 2 | Please search among the [Pull request](../) before creating one. 3 | 4 | Thanks for submitting a pull request! Please provide enough information so that others can review your pull request: 5 | 6 | For more information, see the `CONTRIBUTING` guide. 7 | 8 | 9 | **Summary** 10 | 11 | 12 | 13 | This PR fixes/implements the following **bugs/features** 14 | 15 | * [ ] Bug 1 16 | * [ ] Bug 2 17 | * [ ] Feature 1 18 | * [ ] Feature 2 19 | * [ ] Breaking changes 20 | 21 | 22 | 23 | Explain the **motivation** for making this change. What existing problem does the pull request solve? 24 | 25 | 26 | 27 | **Test plan (required)** 28 | 29 | Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI. 30 | 31 | 32 | 33 | **Code formatting** 34 | 35 | 36 | 37 | **Closing issues** 38 | 39 | 40 | Fixes # 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.apk 3 | .gradle 4 | /local.properties 5 | /.idea 6 | output.json 7 | .DS_Store 8 | /build 9 | /captures 10 | /svgs 11 | /app/release 12 | /app/debug 13 | /app/schemas 14 | .externalNativeBuild 15 | /crowdin.properties 16 | 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | dist: trusty 3 | android: 4 | components: 5 | - tools 6 | - platform-tools 7 | - tools 8 | 9 | - build-tools-29.0.2 10 | 11 | - android-29 12 | 13 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | -ignorewarnings 24 | -keep class * { 25 | public private *; 26 | } 27 | #glide proguard 28 | -keep public class * implements com.bumptech.glide.module.GlideModule 29 | -keep public class * extends com.bumptech.glide.module.AppGlideModule 30 | -keep public enum com.bumptech.glide.load.ImageHeaderParser$** { 31 | **[] $VALUES; 32 | public *; 33 | } 34 | 35 | -assumenosideeffects class com.dar.nclientv2.utility.LogUtility { 36 | public static void d(...); 37 | public static void i(...); 38 | public static void e(...); 39 | } 40 | -keep public class * implements com.bumptech.glide.module.GlideModule 41 | -dontwarn com.bumptech.glide.load.resource.bitmap.VideoDecoder 42 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/ic_launcher_calculator-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/ic_launcher_calculator-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/BookmarkActivity.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2; 2 | 3 | import android.os.Bundle; 4 | import android.view.MenuItem; 5 | 6 | import androidx.appcompat.widget.Toolbar; 7 | import androidx.recyclerview.widget.RecyclerView; 8 | 9 | import com.dar.nclientv2.adapters.BookmarkAdapter; 10 | import com.dar.nclientv2.components.activities.GeneralActivity; 11 | import com.dar.nclientv2.components.widgets.CustomLinearLayoutManager; 12 | 13 | public class BookmarkActivity extends GeneralActivity { 14 | BookmarkAdapter adapter; 15 | RecyclerView recycler; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | //Global.initActivity(this); 21 | setContentView(R.layout.activity_bookmark); 22 | Toolbar toolbar = findViewById(R.id.toolbar); 23 | setSupportActionBar(toolbar); 24 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 25 | getSupportActionBar().setDisplayShowTitleEnabled(true); 26 | getSupportActionBar().setTitle(R.string.manage_bookmarks); 27 | 28 | recycler = findViewById(R.id.recycler); 29 | adapter = new BookmarkAdapter(this); 30 | recycler.setLayoutManager(new CustomLinearLayoutManager(this)); 31 | recycler.setAdapter(adapter); 32 | } 33 | 34 | @Override 35 | public boolean onOptionsItemSelected(MenuItem item) { 36 | if (item.getItemId() == android.R.id.home) { 37 | finish(); 38 | return true; 39 | } 40 | return super.onOptionsItemSelected(item); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/CopyToClipboardActivity.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2; 2 | 3 | import android.content.ClipData; 4 | import android.content.ClipboardManager; 5 | import android.content.Context; 6 | import android.net.Uri; 7 | import android.os.Bundle; 8 | import android.widget.Toast; 9 | 10 | import com.dar.nclientv2.components.activities.GeneralActivity; 11 | 12 | public class CopyToClipboardActivity extends GeneralActivity { 13 | public static void copyTextToClipboard(Context context, String text) { 14 | ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); 15 | ClipData clip = ClipData.newPlainText("text", text); 16 | if (clipboard != null) 17 | clipboard.setPrimaryClip(clip); 18 | } 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | Uri uri = getIntent().getData(); 24 | if (uri != null) { 25 | copyTextToClipboard(this, uri.toString()); 26 | Toast.makeText(this, R.string.link_copied_to_clipboard, Toast.LENGTH_SHORT).show(); 27 | } 28 | finish(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/StatusManagerActivity.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2; 2 | 3 | import android.os.Bundle; 4 | import android.view.MenuItem; 5 | 6 | import androidx.appcompat.widget.Toolbar; 7 | import androidx.recyclerview.widget.RecyclerView; 8 | 9 | import com.dar.nclientv2.adapters.StatusManagerAdapter; 10 | import com.dar.nclientv2.components.activities.GeneralActivity; 11 | import com.dar.nclientv2.components.widgets.CustomLinearLayoutManager; 12 | 13 | public class StatusManagerActivity extends GeneralActivity { 14 | 15 | StatusManagerAdapter adapter; 16 | RecyclerView recycler; 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | //Global.initActivity(this); 22 | setContentView(R.layout.activity_bookmark); 23 | Toolbar toolbar = findViewById(R.id.toolbar); 24 | setSupportActionBar(toolbar); 25 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 26 | getSupportActionBar().setDisplayShowTitleEnabled(true); 27 | getSupportActionBar().setTitle(R.string.manage_statuses); 28 | 29 | recycler = findViewById(R.id.recycler); 30 | adapter = new StatusManagerAdapter(this); 31 | recycler.setLayoutManager(new CustomLinearLayoutManager(this)); 32 | recycler.setAdapter(adapter); 33 | } 34 | 35 | @Override 36 | public boolean onOptionsItemSelected(MenuItem item) { 37 | if (item.getItemId() == android.R.id.home) { 38 | finish(); 39 | return true; 40 | } 41 | return super.onOptionsItemSelected(item); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/comments/User.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.comments; 2 | 3 | import android.net.Uri; 4 | import android.os.Parcel; 5 | import android.os.Parcelable; 6 | import android.util.JsonReader; 7 | import android.util.JsonToken; 8 | 9 | import com.dar.nclientv2.utility.Utility; 10 | 11 | import java.io.IOException; 12 | import java.util.Locale; 13 | 14 | public class User implements Parcelable { 15 | public static final Creator CREATOR = new Creator() { 16 | @Override 17 | public User createFromParcel(Parcel in) { 18 | return new User(in); 19 | } 20 | 21 | @Override 22 | public User[] newArray(int size) { 23 | return new User[size]; 24 | } 25 | }; 26 | private int id; 27 | private String username, avatarUrl; 28 | 29 | public User(JsonReader reader) throws IOException { 30 | reader.beginObject(); 31 | while (reader.peek() != JsonToken.END_OBJECT) { 32 | switch (reader.nextName()) { 33 | case "id": 34 | id = reader.nextInt(); 35 | break; 36 | case "post_date": 37 | username = reader.nextString(); 38 | break; 39 | case "avatar_url": 40 | avatarUrl = reader.nextString(); 41 | break; 42 | default: 43 | reader.skipValue(); 44 | break; 45 | } 46 | } 47 | reader.endObject(); 48 | } 49 | 50 | protected User(Parcel in) { 51 | id = in.readInt(); 52 | username = in.readString(); 53 | avatarUrl = in.readString(); 54 | } 55 | 56 | @Override 57 | public int describeContents() { 58 | return 0; 59 | } 60 | 61 | @Override 62 | public void writeToParcel(Parcel dest, int flags) { 63 | dest.writeInt(id); 64 | dest.writeString(username); 65 | dest.writeString(avatarUrl); 66 | } 67 | 68 | public int getId() { 69 | return id; 70 | } 71 | 72 | public Uri getAvatarUrl() { 73 | return Uri.parse(String.format(Locale.US, "https://i.%s/%s", Utility.getHost(), avatarUrl)); 74 | } 75 | 76 | public String getUsername() { 77 | return username; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/components/GenericGallery.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.components; 2 | 3 | import android.os.Parcelable; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.dar.nclientv2.components.classes.Size; 8 | import com.dar.nclientv2.files.GalleryFolder; 9 | import com.dar.nclientv2.utility.Utility; 10 | 11 | import java.util.Locale; 12 | 13 | public abstract class GenericGallery implements Parcelable { 14 | 15 | public abstract int getId(); 16 | 17 | public abstract Type getType(); 18 | 19 | public abstract int getPageCount(); 20 | 21 | public abstract boolean isValid(); 22 | 23 | @NonNull 24 | public abstract String getTitle(); 25 | 26 | public abstract Size getMaxSize(); 27 | 28 | public abstract Size getMinSize(); 29 | 30 | public abstract GalleryFolder getGalleryFolder(); 31 | 32 | public String sharePageUrl(int i) { 33 | return String.format(Locale.US, "https://" + Utility.getHost() + "/g/%d/%d/", getId(), i + 1); 34 | } 35 | 36 | public boolean isLocal() { 37 | return getType() == Type.LOCAL; 38 | } 39 | 40 | public abstract boolean hasGalleryData(); 41 | 42 | public abstract GalleryData getGalleryData(); 43 | 44 | public enum Type {COMPLETE, LOCAL, SIMPLE} 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/enums/ApiRequestType.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.enums; 2 | 3 | public class ApiRequestType { 4 | public static final ApiRequestType BYALL = new ApiRequestType(0, false); 5 | public static final ApiRequestType BYTAG = new ApiRequestType(1, false); 6 | public static final ApiRequestType BYSEARCH = new ApiRequestType(2, false); 7 | public static final ApiRequestType BYSINGLE = new ApiRequestType(3, true); 8 | public static final ApiRequestType RELATED = new ApiRequestType(4, false); 9 | public static final ApiRequestType FAVORITE = new ApiRequestType(5, false); 10 | public static final ApiRequestType RANDOM = new ApiRequestType(6, true); 11 | public static final ApiRequestType RANDOM_FAVORITE = new ApiRequestType(7, true); 12 | public static final ApiRequestType[] values = { 13 | BYALL, BYTAG, BYSEARCH, BYSINGLE, RELATED, FAVORITE, RANDOM, RANDOM_FAVORITE 14 | }; 15 | private final byte id; 16 | private final boolean single; 17 | 18 | private ApiRequestType(int id, boolean single) { 19 | this.id = (byte) id; 20 | this.single = single; 21 | } 22 | 23 | public byte ordinal() { 24 | return id; 25 | } 26 | 27 | public boolean isSingle() { 28 | return single; 29 | } 30 | 31 | @Override 32 | public boolean equals(Object o) { 33 | if (this == o) return true; 34 | if (o == null || getClass() != o.getClass()) return false; 35 | 36 | ApiRequestType that = (ApiRequestType) o; 37 | 38 | return id == that.id; 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | return id; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/enums/ImageExt.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.enums; 2 | 3 | public enum ImageExt { 4 | JPG("jpg"), PNG("png"), GIF("gif"); 5 | 6 | private final char firstLetter; 7 | private final String name; 8 | 9 | ImageExt(String name) { 10 | this.name = name; 11 | this.firstLetter = name.charAt(0); 12 | } 13 | 14 | public char getFirstLetter() { 15 | return firstLetter; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/enums/ImageType.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.enums; 2 | 3 | public enum ImageType { 4 | PAGE, COVER, THUMBNAIL 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/enums/Language.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.enums; 2 | 3 | public enum Language { 4 | ENGLISH, CHINESE, JAPANESE, UNKNOWN, ALL 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/enums/SortType.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.enums; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import com.dar.nclientv2.R; 6 | 7 | public enum SortType { 8 | RECENT_ALL_TIME(R.string.sort_recent, null), 9 | POPULAR_ALL_TIME(R.string.sort_popular_all_time, "popular"), 10 | POPULAR_WEEKLY(R.string.sort_popular_week, "popular-week"), 11 | POPULAR_DAILY(R.string.sort_popular_day, "popular-today"), 12 | POPULAR_MONTH(R.string.sort_popoular_month, "popular-month"); 13 | 14 | 15 | private final int nameId; 16 | @Nullable 17 | private final String urlAddition; 18 | 19 | SortType(int nameId, @Nullable String urlAddition) { 20 | this.nameId = nameId; 21 | this.urlAddition = urlAddition; 22 | } 23 | 24 | 25 | public static SortType findFromAddition(@Nullable String addition) { 26 | if (addition == null) 27 | return SortType.RECENT_ALL_TIME; 28 | 29 | for (SortType t : SortType.values()) { 30 | String url = t.getUrlAddition(); 31 | if (url != null && addition.contains(url)) { 32 | return t; 33 | } 34 | } 35 | 36 | return SortType.RECENT_ALL_TIME; 37 | } 38 | 39 | public int getNameId() { 40 | return nameId; 41 | } 42 | 43 | @Nullable 44 | public String getUrlAddition() { 45 | return urlAddition; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/enums/SpecialTagIds.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.enums; 2 | 3 | public class SpecialTagIds { 4 | public static final short LANGUAGE_JAPANESE = 6346; 5 | public static final short LANGUAGE_ENGLISH = 12227; 6 | public static final short LANGUAGE_CHINESE = 29963; 7 | public static final short INVALID_ID = -1; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/enums/TagStatus.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.enums; 2 | 3 | public enum TagStatus { 4 | DEFAULT, AVOIDED, ACCEPTED 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/enums/TitleType.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.enums; 2 | 3 | public enum TitleType { 4 | JAPANESE, PRETTY, ENGLISH 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/local/FakeInspector.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.local; 2 | 3 | import com.dar.nclientv2.LocalActivity; 4 | import com.dar.nclientv2.adapters.LocalAdapter; 5 | import com.dar.nclientv2.components.ThreadAsyncTask; 6 | import com.dar.nclientv2.utility.LogUtility; 7 | 8 | import java.io.File; 9 | import java.util.ArrayList; 10 | 11 | public class FakeInspector extends ThreadAsyncTask { 12 | private final ArrayList galleries; 13 | private final ArrayList invalidPaths; 14 | private final File folder; 15 | 16 | public FakeInspector(LocalActivity activity, File folder) { 17 | super(activity); 18 | this.folder = new File(folder, "Download"); 19 | galleries = new ArrayList<>(); 20 | invalidPaths = new ArrayList<>(); 21 | } 22 | 23 | 24 | @Override 25 | protected LocalActivity doInBackground(LocalActivity... voids) { 26 | if (!this.folder.exists()) return voids[0]; 27 | publishProgress(voids[0]); 28 | File parent = this.folder; 29 | parent.mkdirs(); 30 | File[] files = parent.listFiles(); 31 | if (files == null) return voids[0]; 32 | for (File f : files) if (f.isDirectory()) createGallery(f); 33 | for (String x : invalidPaths) LogUtility.d("Invalid path: " + x); 34 | return voids[0]; 35 | } 36 | 37 | @Override 38 | protected void onProgressUpdate(LocalActivity... values) { 39 | values[0].getRefresher().setRefreshing(true); 40 | } 41 | 42 | @Override 43 | protected void onPostExecute(LocalActivity aVoid) { 44 | aVoid.getRefresher().setRefreshing(false); 45 | aVoid.setAdapter(new LocalAdapter(aVoid, galleries)); 46 | } 47 | 48 | private void createGallery(final File file) { 49 | LocalGallery lg = new LocalGallery(file, true); 50 | if (lg.isValid()) { 51 | galleries.add(lg); 52 | } else { 53 | LogUtility.e(lg); 54 | invalidPaths.add(file.getAbsolutePath()); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/api/local/LocalSortType.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.api.local; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | public class LocalSortType { 6 | public static final byte MASK_DESCENDING = (byte) (1 << 7); //10000000 7 | private static final byte MASK_TYPE = (byte) (MASK_DESCENDING - 1); //01111111 8 | @NonNull 9 | public final Type type; 10 | public final boolean descending; 11 | 12 | public LocalSortType(@NonNull Type type, boolean ascending) { 13 | this.type = type; 14 | this.descending = ascending; 15 | } 16 | 17 | public LocalSortType(int hash) { 18 | this.type = Type.values()[(hash & MASK_TYPE) % Type.values().length]; 19 | this.descending = (hash & MASK_DESCENDING) != 0; 20 | } 21 | 22 | @Override 23 | public boolean equals(Object o) { 24 | if (this == o) return true; 25 | if (o == null || getClass() != o.getClass()) return false; 26 | 27 | LocalSortType that = (LocalSortType) o; 28 | 29 | return this.type == that.type && this.descending == that.descending; 30 | } 31 | 32 | @Override 33 | public int hashCode() { 34 | int hash = type.ordinal(); 35 | if (descending) hash |= MASK_DESCENDING; 36 | return hash; 37 | } 38 | 39 | @NonNull 40 | @Override 41 | public String toString() { 42 | return "LocalSortType{" + 43 | "type=" + type + 44 | ", descending=" + descending + 45 | ", hash=" + hashCode() + 46 | '}'; 47 | } 48 | 49 | public enum Type {TITLE, DATE, PAGE_COUNT, RANDOM} 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/async/MetadataFetcher.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.async; 2 | 3 | import android.content.Context; 4 | 5 | import com.dar.nclientv2.api.InspectorV3; 6 | import com.dar.nclientv2.api.components.Gallery; 7 | import com.dar.nclientv2.api.enums.SpecialTagIds; 8 | import com.dar.nclientv2.api.local.LocalGallery; 9 | import com.dar.nclientv2.settings.Global; 10 | 11 | import java.io.File; 12 | import java.io.FileWriter; 13 | import java.io.IOException; 14 | 15 | public class MetadataFetcher implements Runnable { 16 | private final Context context; 17 | 18 | public MetadataFetcher(Context context) { 19 | this.context = context; 20 | } 21 | 22 | @Override 23 | public void run() { 24 | File[] files = Global.DOWNLOADFOLDER.listFiles(); 25 | if (files == null) return; 26 | for (File f : files) { 27 | if (!f.isDirectory()) continue; 28 | LocalGallery lg = new LocalGallery(f, false); 29 | if (lg.getId() == SpecialTagIds.INVALID_ID || lg.hasGalleryData()) continue; 30 | InspectorV3 inspector = InspectorV3.galleryInspector(context, lg.getId(), null); 31 | inspector.run();//it is run, not start 32 | if (inspector.getGalleries() == null || inspector.getGalleries().size() == 0) 33 | continue; 34 | Gallery g = (Gallery) inspector.getGalleries().get(0); 35 | try { 36 | FileWriter writer = new FileWriter(new File(lg.getDirectory(), ".nomedia")); 37 | g.jsonWrite(writer); 38 | writer.close(); 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/async/database/export/Manager.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.async.database.export; 2 | 3 | import android.net.Uri; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.dar.nclientv2.SettingsActivity; 8 | import com.dar.nclientv2.utility.LogUtility; 9 | 10 | import java.io.IOException; 11 | 12 | public class Manager extends Thread { 13 | @NonNull 14 | private final Uri file; 15 | @NonNull 16 | private final SettingsActivity context; 17 | private final boolean export; 18 | private final Runnable end; 19 | 20 | public Manager(@NonNull Uri file, @NonNull SettingsActivity context, boolean export, Runnable end) { 21 | this.file = file; 22 | this.context = context; 23 | this.export = export; 24 | this.end = end; 25 | } 26 | 27 | 28 | @Override 29 | public void run() { 30 | try { 31 | if (export) Exporter.exportData(context, file); 32 | else Importer.importData(context, file); 33 | context.runOnUiThread(end); 34 | } catch (IOException e) { 35 | LogUtility.e(e, e); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/async/downloader/DownloadObserver.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.async.downloader; 2 | 3 | public interface DownloadObserver { 4 | void triggerStartDownload(GalleryDownloaderV2 downloader); 5 | 6 | void triggerUpdateProgress(GalleryDownloaderV2 downloader, int reach, int total); 7 | 8 | void triggerEndDownload(GalleryDownloaderV2 downloader); 9 | 10 | void triggerCancelDownload(GalleryDownloaderV2 downloader); 11 | 12 | void triggerPauseDownload(GalleryDownloaderV2 downloader); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/async/downloader/PageChecker.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.async.downloader; 2 | 3 | public class PageChecker extends Thread { 4 | @Override 5 | public void run() { 6 | for (GalleryDownloaderV2 g : DownloadQueue.getDownloaders()) 7 | if (g.hasData()) g.initDownload(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/GlideX.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.view.View; 6 | 7 | import androidx.annotation.Nullable; 8 | import androidx.fragment.app.Fragment; 9 | import androidx.fragment.app.FragmentActivity; 10 | 11 | import com.bumptech.glide.Glide; 12 | import com.bumptech.glide.RequestManager; 13 | 14 | public class GlideX { 15 | @Nullable 16 | public static Glide get(Context context) { 17 | try { 18 | return Glide.get(context); 19 | } catch (VerifyError | IllegalStateException ignore) { 20 | return null; 21 | } 22 | } 23 | 24 | @Nullable 25 | public static RequestManager with(View view) { 26 | try { 27 | return Glide.with(view); 28 | } catch (VerifyError | IllegalStateException ignore) { 29 | return null; 30 | } 31 | } 32 | 33 | @Nullable 34 | public static RequestManager with(Context context) { 35 | try { 36 | return Glide.with(context); 37 | } catch (VerifyError | IllegalStateException ignore) { 38 | return null; 39 | } 40 | } 41 | 42 | @Nullable 43 | public static RequestManager with(Fragment fragment) { 44 | try { 45 | return Glide.with(fragment); 46 | } catch (VerifyError | IllegalStateException ignore) { 47 | return null; 48 | } 49 | } 50 | 51 | @Nullable 52 | public static RequestManager with(FragmentActivity fragmentActivity) { 53 | try { 54 | return Glide.with(fragmentActivity); 55 | } catch (VerifyError | IllegalStateException ignore) { 56 | return null; 57 | } 58 | } 59 | 60 | @Nullable 61 | public static RequestManager with(Activity activity) { 62 | try { 63 | return Glide.with(activity); 64 | } catch (VerifyError | IllegalStateException ignore) { 65 | return null; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/LocaleManager.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components; 2 | 3 | import java.util.Locale; 4 | 5 | public class LocaleManager { 6 | public static final Locale[] LANGUAGES = new Locale[]{ 7 | new Locale("en"), 8 | new Locale("ar"), 9 | new Locale("de"), 10 | new Locale("es"), 11 | new Locale("fr"), 12 | new Locale("it"), 13 | new Locale("ja"), 14 | new Locale("ru"), 15 | new Locale("tr"), 16 | new Locale("uk"), 17 | new Locale("zh", "CN"), 18 | new Locale("zh", "TW"), 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/Module.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components; 2 | 3 | public class Module { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/ThreadAsyncTask.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import com.dar.nclientv2.settings.Global; 6 | 7 | public abstract class ThreadAsyncTask { 8 | 9 | private final AppCompatActivity activity; 10 | private Thread thread; 11 | public ThreadAsyncTask(AppCompatActivity activity) { 12 | this.activity = activity; 13 | } 14 | 15 | public void execute(Params... params) { 16 | thread = new AsyncThread(params); 17 | thread.start(); 18 | } 19 | 20 | protected void onPreExecute() { 21 | } 22 | 23 | protected void onPostExecute(Result result) { 24 | } 25 | 26 | protected void onProgressUpdate(Progress... values) { 27 | } 28 | 29 | protected abstract Result doInBackground(Params... params); 30 | 31 | protected final void publishProgress(Progress... values) { 32 | if (!Global.isDestroyed(activity)) 33 | activity.runOnUiThread(() -> onProgressUpdate(values)); 34 | } 35 | 36 | class AsyncThread extends Thread { 37 | 38 | Params[] params; 39 | 40 | AsyncThread(Params[] params) { 41 | this.params = params; 42 | } 43 | 44 | @Override 45 | public void run() { 46 | if (!Global.isDestroyed(activity)) 47 | activity.runOnUiThread(ThreadAsyncTask.this::onPreExecute); 48 | Result result = doInBackground(params); 49 | if (!Global.isDestroyed(activity)) 50 | activity.runOnUiThread(() -> onPostExecute(result)); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/activities/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.activities; 2 | 3 | import android.content.res.Configuration; 4 | import android.view.ViewGroup; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.recyclerview.widget.RecyclerView; 8 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; 9 | 10 | import com.dar.nclientv2.components.widgets.CustomGridLayoutManager; 11 | 12 | public abstract class BaseActivity extends GeneralActivity { 13 | protected RecyclerView recycler; 14 | protected SwipeRefreshLayout refresher; 15 | protected ViewGroup masterLayout; 16 | 17 | protected abstract int getPortraitColumnCount(); 18 | 19 | protected abstract int getLandscapeColumnCount(); 20 | 21 | 22 | public SwipeRefreshLayout getRefresher() { 23 | return refresher; 24 | } 25 | 26 | public RecyclerView getRecycler() { 27 | return recycler; 28 | } 29 | 30 | public ViewGroup getMasterLayout() { 31 | return masterLayout; 32 | } 33 | 34 | @Override 35 | public void onConfigurationChanged(@NonNull Configuration newConfig) { 36 | super.onConfigurationChanged(newConfig); 37 | if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { 38 | changeLayout(true); 39 | } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { 40 | changeLayout(false); 41 | } 42 | } 43 | 44 | protected void changeLayout(boolean landscape) { 45 | CustomGridLayoutManager manager = (CustomGridLayoutManager) recycler.getLayoutManager(); 46 | RecyclerView.Adapter adapter = recycler.getAdapter(); 47 | int count = landscape ? getLandscapeColumnCount() : getPortraitColumnCount(); 48 | int position = 0; 49 | 50 | if (manager != null) 51 | position = manager.findFirstCompletelyVisibleItemPosition(); 52 | CustomGridLayoutManager gridLayoutManager = new CustomGridLayoutManager(this, count); 53 | recycler.setLayoutManager(gridLayoutManager); 54 | recycler.setAdapter(adapter); 55 | recycler.scrollToPosition(position); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/classes/ConnectivityReceiver.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.classes; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.net.ConnectivityManager; 7 | import android.net.NetworkInfo; 8 | 9 | import com.dar.nclientv2.utility.LogUtility; 10 | 11 | public class ConnectivityReceiver extends BroadcastReceiver { 12 | 13 | @Override 14 | public void onReceive(final Context context, final Intent intent) { 15 | LogUtility.d("Is online? " + isOnline(context)); 16 | } 17 | 18 | public boolean isOnline(Context context) { 19 | 20 | ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 21 | NetworkInfo netInfo = cm.getActiveNetworkInfo(); 22 | //should check null because in airplane mode it will be null 23 | return (netInfo != null && netInfo.isConnected()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/classes/History.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.classes; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Date; 6 | import java.util.HashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | public class History { 11 | private final String value; 12 | private final Date date; 13 | 14 | public History(String value, boolean set) { 15 | if (set) { 16 | int p = value.indexOf('|'); 17 | date = new Date(Long.parseLong(value.substring(0, p))); 18 | this.value = value.substring(p + 1); 19 | } else { 20 | this.value = value; 21 | this.date = new Date(); 22 | } 23 | } 24 | 25 | public static List setToList(Set set) { 26 | List h = new ArrayList<>(set.size()); 27 | for (String s : set) h.add(new History(s, true)); 28 | Collections.sort(h, (o2, o1) -> { 29 | int o = o1.date.compareTo(o2.date); 30 | if (o == 0) o = o1.value.compareTo(o2.value); 31 | return o; 32 | }); 33 | 34 | return h; 35 | } 36 | 37 | public static Set listToSet(List list) { 38 | HashSet s = new HashSet<>(list.size()); 39 | for (History h : list) s.add(h.date.getTime() + "|" + h.value); 40 | return s; 41 | } 42 | 43 | public String getValue() { 44 | return value; 45 | } 46 | 47 | @Override 48 | public boolean equals(Object o) { 49 | if (this == o) return true; 50 | if (o == null || getClass() != o.getClass()) return false; 51 | History history = (History) o; 52 | return value.equals(history.value); 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | return value.hashCode(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/classes/MySender.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.classes; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.dar.nclientv2.settings.Global; 8 | import com.dar.nclientv2.utility.LogUtility; 9 | import com.dar.nclientv2.utility.Utility; 10 | 11 | import org.acra.data.CrashReportData; 12 | import org.acra.sender.ReportSender; 13 | import org.json.JSONException; 14 | 15 | import java.io.IOException; 16 | import java.util.Map; 17 | 18 | import okhttp3.FormBody; 19 | import okhttp3.Request; 20 | import okhttp3.RequestBody; 21 | import okhttp3.Response; 22 | 23 | public class MySender implements ReportSender { 24 | private static final String URL = "dar9586.altervista.org/php/report.php"; 25 | 26 | @Override 27 | public void send(@NonNull Context context, @NonNull CrashReportData errorContent) { 28 | Map m = errorContent.toMap(); 29 | for (Map.Entry mm : m.entrySet()) { 30 | LogUtility.e(mm.getKey() + ": " + mm.getValue()); 31 | } 32 | try { 33 | RequestBody requestBody = new FormBody.Builder().add("json", errorContent.toJSON()).build(); 34 | 35 | Request.Builder request = new Request.Builder().post(requestBody).url(Utility.PROTOCOL + URL); 36 | Response x = Global.getClient().newCall(request.build()).execute(); 37 | 38 | LogUtility.d(x.code() + x.body().string()); 39 | x.close(); 40 | } catch (JSONException | IOException e) { 41 | LogUtility.e(e.getLocalizedMessage(), e); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/classes/MySenderFactory.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.classes; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import org.acra.config.CoreConfiguration; 8 | import org.acra.sender.ReportSender; 9 | import org.acra.sender.ReportSenderFactory; 10 | 11 | public class MySenderFactory implements ReportSenderFactory { 12 | @NonNull 13 | @Override 14 | public ReportSender create(@NonNull Context context, @NonNull CoreConfiguration config) { 15 | return new MySender(); 16 | } 17 | 18 | @Override 19 | public boolean enabled(@NonNull CoreConfiguration config) { 20 | return true; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/classes/Size.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.classes; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | public class Size implements Parcelable { 7 | public static final Creator CREATOR = new Creator() { 8 | @Override 9 | public Size createFromParcel(Parcel in) { 10 | return new Size(in); 11 | } 12 | 13 | @Override 14 | public Size[] newArray(int size) { 15 | return new Size[size]; 16 | } 17 | }; 18 | private int width, height; 19 | 20 | public Size(int width, int height) { 21 | this.width = width; 22 | this.height = height; 23 | } 24 | 25 | protected Size(Parcel in) { 26 | width = in.readInt(); 27 | height = in.readInt(); 28 | } 29 | 30 | public int getWidth() { 31 | return width; 32 | } 33 | 34 | public void setWidth(int width) { 35 | this.width = width; 36 | } 37 | 38 | public int getHeight() { 39 | return height; 40 | } 41 | 42 | public void setHeight(int height) { 43 | this.height = height; 44 | } 45 | 46 | @Override 47 | public int describeContents() { 48 | return 0; 49 | } 50 | 51 | @Override 52 | public void writeToParcel(Parcel dest, int flags) { 53 | dest.writeInt(width); 54 | dest.writeInt(height); 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return "Size{" + 60 | "width=" + width + 61 | ", height=" + height + 62 | '}'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/classes/integration/GlideGeneral.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.classes.integration; 2 | 3 | import com.bumptech.glide.annotation.GlideModule; 4 | import com.bumptech.glide.module.AppGlideModule; 5 | 6 | @GlideModule 7 | public class GlideGeneral extends AppGlideModule { 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/classes/integration/OkHttpGlideModule.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.classes.integration; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.bumptech.glide.Glide; 8 | import com.bumptech.glide.GlideBuilder; 9 | import com.bumptech.glide.Registry; 10 | import com.bumptech.glide.load.model.GlideUrl; 11 | 12 | import java.io.InputStream; 13 | 14 | /** 15 | * A {@link com.bumptech.glide.module.GlideModule} implementation to replace Glide's default {@link 16 | * java.net.HttpURLConnection} based {@link com.bumptech.glide.load.model.ModelLoader} with an 17 | * OkHttp based {@link com.bumptech.glide.load.model.ModelLoader}. 18 | * 19 | *

If you're using gradle, you can include this module simply by depending on the aar, the module 20 | * will be merged in by manifest merger. For other build systems or for more more information, see 21 | * {@link com.bumptech.glide.module.GlideModule}. 22 | * 23 | * @deprecated Replaced by {@link OkHttpLibraryGlideModule} for Applications that use Glide's 24 | * annotations. 25 | */ 26 | @Deprecated 27 | public class OkHttpGlideModule implements com.bumptech.glide.module.GlideModule { 28 | @Override 29 | public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) { 30 | // Do nothing. 31 | } 32 | 33 | @Override 34 | public void registerComponents(Context context, Glide glide, Registry registry) { 35 | registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/classes/integration/OkHttpLibraryGlideModule.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.classes.integration; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.bumptech.glide.Glide; 8 | import com.bumptech.glide.Registry; 9 | import com.bumptech.glide.annotation.GlideModule; 10 | import com.bumptech.glide.load.model.GlideUrl; 11 | import com.bumptech.glide.module.AppGlideModule; 12 | import com.bumptech.glide.module.LibraryGlideModule; 13 | 14 | import java.io.InputStream; 15 | 16 | /** 17 | * Registers OkHttp related classes via Glide's annotation processor. 18 | * 19 | *

For Applications that depend on this library and include an {@link AppGlideModule} and Glide's 20 | * annotation processor, this class will be automatically included. 21 | */ 22 | @GlideModule 23 | public final class OkHttpLibraryGlideModule extends LibraryGlideModule { 24 | @Override 25 | public void registerComponents( 26 | @NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) { 27 | registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/launcher/LauncherCalculator.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.launcher; 2 | 3 | public class LauncherCalculator { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/launcher/LauncherReal.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.launcher; 2 | 3 | public class LauncherReal { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/status/Status.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.status; 2 | 3 | import android.graphics.Color; 4 | 5 | public class Status { 6 | public final int color; 7 | public final String name; 8 | 9 | Status(int color, String name) { 10 | this.color = Color.argb(0x7f, Color.red(color), Color.green(color), Color.blue(color)); 11 | this.name = name; 12 | } 13 | 14 | public int opaqueColor() { 15 | return color | 0xff000000; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/status/StatusManager.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.status; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import com.dar.nclientv2.async.database.Queries; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | public class StatusManager { 13 | public static final String DEFAULT_STATUS = "None"; 14 | private static HashMap statusMap = new HashMap<>(); 15 | 16 | public static Status getByName(String name) { 17 | return statusMap.get(name); 18 | } 19 | 20 | public static Status add(String name, int color) { 21 | return add(new Status(color, name)); 22 | } 23 | 24 | static Status add(Status status) { 25 | Queries.StatusTable.insert(status); 26 | statusMap.put(status.name, status); 27 | return status; 28 | } 29 | 30 | public static void remove(Status status) { 31 | Queries.StatusTable.remove(status.name); 32 | statusMap.remove(status.name); 33 | } 34 | 35 | public static List getNames() { 36 | List st = new ArrayList<>(statusMap.keySet()); 37 | Collections.sort(st, String::compareToIgnoreCase); 38 | st.remove(DEFAULT_STATUS); 39 | //st.add(0,DEFAULT_STATUS); 40 | return st; 41 | } 42 | 43 | public static List toList() { 44 | ArrayList statuses = new ArrayList<>(statusMap.values()); 45 | Collections.sort(statuses, (o1, o2) -> o1.name.compareToIgnoreCase(o2.name)); 46 | statuses.remove(getByName(DEFAULT_STATUS)); 47 | return statuses; 48 | } 49 | 50 | public static Status updateStatus(@Nullable Status oldStatus, String newName, int newColor) { 51 | if (oldStatus == null) 52 | return add(newName, newColor); 53 | Status newStatus = new Status(newColor, newName); 54 | Queries.StatusTable.update(oldStatus, newStatus); 55 | statusMap.remove(oldStatus.name); 56 | statusMap.put(newStatus.name, newStatus); 57 | return newStatus; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/widgets/CustomGridLayoutManager.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.widgets; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.recyclerview.widget.GridLayoutManager; 6 | 7 | public class CustomGridLayoutManager extends GridLayoutManager { 8 | 9 | public CustomGridLayoutManager(Context context, int spanCount) { 10 | super(context, Math.max(1, spanCount)); 11 | } 12 | 13 | public CustomGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { 14 | super(context, Math.max(1, spanCount), orientation, reverseLayout); 15 | } 16 | 17 | @Override 18 | public boolean supportsPredictiveItemAnimations() { 19 | return false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/widgets/CustomImageView.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.widgets; 2 | 3 | import android.content.Context; 4 | import android.graphics.Matrix; 5 | import android.graphics.drawable.Drawable; 6 | import android.util.AttributeSet; 7 | 8 | import androidx.annotation.Nullable; 9 | import androidx.appcompat.widget.AppCompatImageView; 10 | 11 | public class CustomImageView extends AppCompatImageView { 12 | 13 | public CustomImageView(Context context) { 14 | super(context); 15 | } 16 | 17 | public CustomImageView(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | } 20 | 21 | public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) { 22 | super(context, attrs, defStyleAttr); 23 | } 24 | 25 | @Override 26 | public void setImageDrawable(@Nullable Drawable drawable) { 27 | super.setImageDrawable(drawable); 28 | invalidate(); 29 | } 30 | 31 | 32 | @Override 33 | protected boolean setFrame(int l, int t, int r, int b) { 34 | final Matrix matrix = getImageMatrix(); 35 | float scale; 36 | final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight(); 37 | final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom(); 38 | final int drawableWidth = getDrawable().getIntrinsicWidth(); 39 | final int drawableHeight = getDrawable().getIntrinsicHeight(); 40 | 41 | if (drawableWidth * viewHeight > drawableHeight * viewWidth) { 42 | scale = (float) viewHeight / (float) drawableHeight; 43 | } else { 44 | scale = (float) viewWidth / (float) drawableWidth; 45 | } 46 | 47 | matrix.setScale(scale, scale); 48 | setImageMatrix(matrix); 49 | 50 | return super.setFrame(l, t, r, b); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/widgets/CustomLinearLayoutManager.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.widgets; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.recyclerview.widget.LinearLayoutManager; 6 | 7 | 8 | public class CustomLinearLayoutManager extends LinearLayoutManager { 9 | public CustomLinearLayoutManager(Context context) { 10 | super(context); 11 | } 12 | 13 | 14 | @Override 15 | public boolean supportsPredictiveItemAnimations() { 16 | return false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/widgets/CustomSearchView.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.widgets; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import androidx.appcompat.widget.SearchView; 7 | 8 | public class CustomSearchView extends SearchView { 9 | private SearchView.SearchAutoComplete mSearchSrcTextView; 10 | 11 | public CustomSearchView(Context context) { 12 | super(context); 13 | } 14 | 15 | public CustomSearchView(Context context, AttributeSet attrs) { 16 | super(context, attrs); 17 | } 18 | 19 | public CustomSearchView(Context context, AttributeSet attrs, int defStyleAttr) { 20 | super(context, attrs, defStyleAttr); 21 | } 22 | 23 | @Override 24 | public void setOnQueryTextListener(OnQueryTextListener listener) { 25 | super.setOnQueryTextListener(listener); 26 | mSearchSrcTextView = this.findViewById(androidx.appcompat.R.id.search_src_text); 27 | mSearchSrcTextView.setOnEditorActionListener((textView, i, keyEvent) -> { 28 | if (listener != null) { 29 | listener.onQueryTextSubmit(getQuery().toString()); 30 | } 31 | return true; 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/components/widgets/CustomSwipe.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.components.widgets; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.Nullable; 8 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; 9 | 10 | import com.dar.nclientv2.utility.LogUtility; 11 | 12 | public class CustomSwipe extends SwipeRefreshLayout { 13 | public CustomSwipe(@NonNull Context context) { 14 | super(context); 15 | } 16 | 17 | public CustomSwipe(@NonNull Context context, @Nullable AttributeSet attrs) { 18 | super(context, attrs); 19 | } 20 | 21 | @Override 22 | public void setEnabled(boolean refreshing) { 23 | try { 24 | throw new Exception(); 25 | } catch (Exception e) { 26 | LogUtility.e("NEW VALUE: " + refreshing + ",," + e.getLocalizedMessage(), e); 27 | } 28 | super.setRefreshing(refreshing); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/Compat.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2011, 2012 Chris Banes. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package com.dar.nclientv2.github.chrisbanes.photoview; 17 | 18 | import android.annotation.TargetApi; 19 | import android.os.Build.VERSION; 20 | import android.os.Build.VERSION_CODES; 21 | import android.view.View; 22 | 23 | class Compat { 24 | 25 | private static final int SIXTY_FPS_INTERVAL = 1000 / 60; 26 | 27 | public static void postOnAnimation(View view, Runnable runnable) { 28 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { 29 | postOnAnimationJellyBean(view, runnable); 30 | } else { 31 | view.postDelayed(runnable, SIXTY_FPS_INTERVAL); 32 | } 33 | } 34 | 35 | @TargetApi(16) 36 | private static void postOnAnimationJellyBean(View view, Runnable runnable) { 37 | view.postOnAnimation(runnable); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/OnGestureListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2011, 2012 Chris Banes. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package com.dar.nclientv2.github.chrisbanes.photoview; 17 | 18 | interface OnGestureListener { 19 | 20 | void onDrag(float dx, float dy); 21 | 22 | void onFling(float startX, float startY, float velocityX, 23 | float velocityY); 24 | 25 | void onScale(float scaleFactor, float focusX, float focusY); 26 | 27 | void onScale(float scaleFactor, float focusX, float focusY, float dx, float dy); 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/OnMatrixChangedListener.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.github.chrisbanes.photoview; 2 | 3 | import android.graphics.RectF; 4 | 5 | /** 6 | * Interface definition for a callback to be invoked when the internal Matrix has changed for 7 | * this View. 8 | */ 9 | public interface OnMatrixChangedListener { 10 | 11 | /** 12 | * Callback for when the Matrix displaying the Drawable has changed. This could be because 13 | * the View's bounds have changed, or the user has zoomed. 14 | * 15 | * @param rect - Rectangle displaying the Drawable's new bounds. 16 | */ 17 | void onMatrixChanged(RectF rect); 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/OnOutsidePhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.github.chrisbanes.photoview; 2 | 3 | import android.widget.ImageView; 4 | 5 | /** 6 | * Callback when the user tapped outside of the photo 7 | */ 8 | public interface OnOutsidePhotoTapListener { 9 | 10 | /** 11 | * The outside of the photo has been tapped 12 | */ 13 | void onOutsidePhotoTap(ImageView imageView); 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/OnPhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.github.chrisbanes.photoview; 2 | 3 | import android.widget.ImageView; 4 | 5 | /** 6 | * A callback to be invoked when the Photo is tapped with a single 7 | * tap. 8 | */ 9 | public interface OnPhotoTapListener { 10 | 11 | /** 12 | * A callback to receive where the user taps on a photo. You will only receive a callback if 13 | * the user taps on the actual photo, tapping on 'whitespace' will be ignored. 14 | * 15 | * @param view ImageView the user tapped. 16 | * @param x where the user tapped from the of the Drawable, as percentage of the 17 | * Drawable width. 18 | * @param y where the user tapped from the top of the Drawable, as percentage of the 19 | * Drawable height. 20 | */ 21 | void onPhotoTap(ImageView view, float x, float y); 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/OnScaleChangedListener.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.github.chrisbanes.photoview; 2 | 3 | 4 | /** 5 | * Interface definition for callback to be invoked when attached ImageView scale changes 6 | */ 7 | public interface OnScaleChangedListener { 8 | 9 | /** 10 | * Callback for when the scale changes 11 | * 12 | * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in) 13 | * @param focusX focal point X position 14 | * @param focusY focal point Y position 15 | */ 16 | void onScaleChange(float scaleFactor, float focusX, float focusY); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/OnSingleFlingListener.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.github.chrisbanes.photoview; 2 | 3 | import android.view.MotionEvent; 4 | 5 | /** 6 | * A callback to be invoked when the ImageView is flung with a single 7 | * touch 8 | */ 9 | public interface OnSingleFlingListener { 10 | 11 | /** 12 | * A callback to receive where the user flings on a ImageView. You will receive a callback if 13 | * the user flings anywhere on the view. 14 | * 15 | * @param e1 MotionEvent the user first touch. 16 | * @param e2 MotionEvent the user last touch. 17 | * @param velocityX distance of user's horizontal fling. 18 | * @param velocityY distance of user's vertical fling. 19 | */ 20 | boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/OnViewDragListener.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.github.chrisbanes.photoview; 2 | 3 | /** 4 | * Interface definition for a callback to be invoked when the photo is experiencing a drag event 5 | */ 6 | public interface OnViewDragListener { 7 | 8 | /** 9 | * Callback for when the photo is experiencing a drag event. This cannot be invoked when the 10 | * user is scaling. 11 | * 12 | * @param dx The change of the coordinates in the x-direction 13 | * @param dy The change of the coordinates in the y-direction 14 | */ 15 | void onDrag(float dx, float dy); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/OnViewTapListener.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.github.chrisbanes.photoview; 2 | 3 | import android.view.View; 4 | 5 | public interface OnViewTapListener { 6 | 7 | /** 8 | * A callback to receive where the user taps on a ImageView. You will receive a callback if 9 | * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored. 10 | * 11 | * @param view - View the user tapped. 12 | * @param x - where the user tapped from the left of the View. 13 | * @param y - where the user tapped from the top of the View. 14 | */ 15 | void onViewTap(View view, float x, float y); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/github/chrisbanes/photoview/Util.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.github.chrisbanes.photoview; 2 | 3 | import android.view.MotionEvent; 4 | import android.widget.ImageView; 5 | 6 | class Util { 7 | 8 | static void checkZoomLevels(float minZoom, float midZoom, 9 | float maxZoom) { 10 | if (minZoom >= midZoom) { 11 | throw new IllegalArgumentException( 12 | "Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value"); 13 | } else if (midZoom >= maxZoom) { 14 | throw new IllegalArgumentException( 15 | "Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value"); 16 | } 17 | } 18 | 19 | static boolean hasDrawable(ImageView imageView) { 20 | return imageView.getDrawable() != null; 21 | } 22 | 23 | static boolean isSupportedScaleType(final ImageView.ScaleType scaleType) { 24 | if (scaleType == null) { 25 | return false; 26 | } 27 | switch (scaleType) { 28 | case MATRIX: 29 | throw new IllegalStateException("Matrix scale type is not supported"); 30 | } 31 | return true; 32 | } 33 | 34 | static int getPointerIndex(int action) { 35 | return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/settings/AuthRequest.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.settings; 2 | 3 | import com.dar.nclientv2.utility.CSRFGet; 4 | 5 | import java.nio.charset.Charset; 6 | 7 | import okhttp3.Callback; 8 | import okhttp3.FormBody; 9 | import okhttp3.Request; 10 | import okhttp3.RequestBody; 11 | 12 | public class AuthRequest extends Thread { 13 | public static final RequestBody EMPTY_BODY = new FormBody.Builder(Charset.defaultCharset()).build(); 14 | private final String referer, url; 15 | private final Callback callback; 16 | private String method; 17 | private RequestBody body; 18 | 19 | public AuthRequest(String referer, String url, Callback callback) { 20 | this.referer = referer; 21 | this.url = url; 22 | this.callback = callback; 23 | } 24 | 25 | public AuthRequest setMethod(String method, RequestBody body) { 26 | this.method = method; 27 | this.body = body; 28 | return this; 29 | } 30 | 31 | @Override 32 | public void run() { 33 | new CSRFGet(token -> { 34 | Global.client.newCall(new Request.Builder().url(url) 35 | .addHeader("Referer", referer) 36 | .addHeader("X-CSRFToken", token) 37 | .addHeader("X-Requested-With", "XMLHttpRequest") 38 | .method(method, body) 39 | .build()).enqueue(callback); 40 | }, referer).start(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/settings/Database.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.settings; 2 | 3 | import android.database.sqlite.SQLiteDatabase; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.dar.nclientv2.async.database.Queries; 8 | import com.dar.nclientv2.utility.LogUtility; 9 | 10 | public class Database { 11 | @NonNull 12 | private static SQLiteDatabase database; 13 | 14 | @NonNull 15 | public static SQLiteDatabase getDatabase() { 16 | return database; 17 | } 18 | 19 | public static void setDatabase(SQLiteDatabase database) { 20 | Database.database = database; 21 | LogUtility.d("SETTED database" + database); 22 | setDBForTables(database); 23 | Queries.StatusTable.initStatuses(); 24 | } 25 | 26 | private static void setDBForTables(SQLiteDatabase database) { 27 | Queries.setDb(database); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/settings/Favorites.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.settings; 2 | 3 | import com.dar.nclientv2.api.components.Gallery; 4 | import com.dar.nclientv2.api.components.GenericGallery; 5 | import com.dar.nclientv2.async.database.Queries; 6 | 7 | public class Favorites { 8 | 9 | 10 | public static boolean addFavorite(Gallery gallery) { 11 | Queries.FavoriteTable.addFavorite(gallery); 12 | return true; 13 | } 14 | 15 | public static boolean removeFavorite(GenericGallery gallery) { 16 | Queries.FavoriteTable.removeFavorite(gallery.getId()); 17 | return true; 18 | } 19 | 20 | public static boolean isFavorite(GenericGallery gallery) { 21 | if (gallery == null || !gallery.isValid()) return false; 22 | return Queries.FavoriteTable.isFavorite(gallery.getId()); 23 | } 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/ui/main/SectionsPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.ui.main; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | import androidx.fragment.app.Fragment; 6 | import androidx.viewpager2.adapter.FragmentStateAdapter; 7 | 8 | import com.dar.nclientv2.StatusViewerActivity; 9 | import com.dar.nclientv2.async.database.Queries; 10 | import com.dar.nclientv2.components.status.StatusManager; 11 | 12 | import java.util.List; 13 | import java.util.Locale; 14 | 15 | /** 16 | * A [FragmentPagerAdapter] that returns a fragment corresponding to 17 | * one of the sections/tabs/pages. 18 | */ 19 | public class SectionsPagerAdapter extends FragmentStateAdapter { 20 | List statuses; 21 | 22 | public SectionsPagerAdapter(StatusViewerActivity context) { 23 | super(context.getSupportFragmentManager(), context.getLifecycle()); 24 | statuses = StatusManager.getNames(); 25 | } 26 | 27 | @Nullable 28 | public CharSequence getPageTitle(int position) { 29 | String status = statuses.get(position); 30 | int count = Queries.StatusMangaTable.getCountPerStatus(status); 31 | return String.format(Locale.US, "%s - %d", status, count); 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public Fragment createFragment(int position) { 37 | return PlaceholderFragment.newInstance(statuses.get(position)); 38 | } 39 | 40 | @Override 41 | public int getItemCount() { 42 | return statuses.size(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/utility/CSRFGet.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.utility; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import com.dar.nclientv2.settings.Global; 6 | 7 | import java.io.IOException; 8 | 9 | import okhttp3.Request; 10 | 11 | public class CSRFGet extends Thread { 12 | @Nullable 13 | private final Response response; 14 | private final String url; 15 | 16 | public CSRFGet(@Nullable Response response, String url) { 17 | this.response = response; 18 | this.url = url; 19 | } 20 | 21 | @Override 22 | public void run() { 23 | try { 24 | assert Global.getClient() != null; 25 | okhttp3.Response response = Global.getClient().newCall(new Request.Builder().url(url).build()).execute(); 26 | if (response.body() == null) throw new NullPointerException("Error retrieving url"); 27 | String token = response.body().string(); 28 | token = token.substring(token.lastIndexOf("csrf_token")); 29 | token = token.substring(token.indexOf('"') + 1); 30 | token = token.substring(0, token.indexOf('"')); 31 | if (this.response != null) this.response.onResponse(token); 32 | } catch (Exception e) { 33 | if (response != null) response.onError(e); 34 | } 35 | } 36 | 37 | public interface Response { 38 | void onResponse(String token) throws IOException; 39 | 40 | default void onError(Exception e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/utility/IntentUtility.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.utility; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | 6 | public class IntentUtility extends Intent { 7 | public static String PACKAGE_NAME; 8 | 9 | public static void startAnotherActivity(Activity activity, Intent intent) { 10 | activity.runOnUiThread(() -> activity.startActivity(intent)); 11 | } 12 | 13 | public static void endActivity(Activity activity) { 14 | activity.runOnUiThread(activity::finish); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/utility/LogUtility.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.utility; 2 | 3 | import android.util.Log; 4 | 5 | import java.util.Arrays; 6 | 7 | public class LogUtility { 8 | public static final String LOGTAG = "NCLIENTLOG"; 9 | 10 | public static void d(Object... message) { 11 | if (message == null) return; 12 | if (message.length == 1) Log.d(LogUtility.LOGTAG, "" + message[0]); 13 | else Log.d(LogUtility.LOGTAG, Arrays.toString(message)); 14 | } 15 | 16 | public static void d(Object message, Throwable throwable) { 17 | if (message == null) message = ""; 18 | Log.d(LogUtility.LOGTAG, message.toString(), throwable); 19 | } 20 | 21 | public static void i(Object... message) { 22 | if (message == null) return; 23 | if (message.length == 1) Log.i(LogUtility.LOGTAG, "" + message[0]); 24 | else Log.i(LogUtility.LOGTAG, Arrays.toString(message)); 25 | } 26 | 27 | public static void i(Object message, Throwable throwable) { 28 | if (message == null) message = ""; 29 | Log.i(LogUtility.LOGTAG, message.toString(), throwable); 30 | } 31 | 32 | public static void e(Object... message) { 33 | if (message == null) return; 34 | if (message.length == 1) Log.e(LogUtility.LOGTAG, "" + message[0]); 35 | else Log.e(LogUtility.LOGTAG, Arrays.toString(message)); 36 | } 37 | 38 | public static void e(Object message, Throwable throwable) { 39 | if (message == null) message = ""; 40 | Log.e(LogUtility.LOGTAG, message.toString(), throwable); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/dar/nclientv2/utility/network/ConnectivityChecker.java: -------------------------------------------------------------------------------- 1 | package com.dar.nclientv2.utility.network; 2 | 3 | import android.content.Context; 4 | 5 | import java.io.IOException; 6 | import java.net.InetSocketAddress; 7 | import java.net.Socket; 8 | import java.net.SocketAddress; 9 | 10 | public class ConnectivityChecker extends Thread { 11 | private final Context context; 12 | 13 | public ConnectivityChecker(Context context) { 14 | this.context = context; 15 | } 16 | 17 | @Override 18 | public void run() { 19 | 20 | } 21 | 22 | public boolean isOnline() { 23 | try { 24 | int timeoutMs = 1500; 25 | Socket sock = new Socket(); 26 | SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53); 27 | 28 | sock.connect(sockaddr, timeoutMs); 29 | sock.close(); 30 | 31 | return true; 32 | } catch (IOException e) { 33 | return false; 34 | } 35 | } 36 | 37 | public interface ConnectionResult { 38 | void isConnected(); 39 | 40 | void isDisconnected(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-anydpi-v24/ic_archive.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-anydpi-v24/ic_check.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-anydpi-v24/ic_close.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-anydpi-v24/ic_file.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-anydpi-v24/ic_pause.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-anydpi-v24/ic_play.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-hdpi/ic_archive.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-hdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-hdpi/ic_close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-hdpi/ic_file.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-hdpi/ic_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-hdpi/ic_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-mdpi/ic_archive.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-mdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-mdpi/ic_close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-mdpi/ic_file.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-mdpi/ic_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-mdpi/ic_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xhdpi/ic_archive.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xhdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xhdpi/ic_close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xhdpi/ic_file.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xhdpi/ic_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xhdpi/ic_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xxhdpi/ic_archive.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xxhdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xxhdpi/ic_close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xxhdpi/ic_file.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xxhdpi/ic_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar9586/NClientV2/d418226f423bb61312a35840dea4ce685b5cc213/app/src/main/res/drawable-xxhdpi/ic_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_access_time.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_archive.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_back.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_forward.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_backspace.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bookmark.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bookmark_border.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_burst_mode.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chat_bubble.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_circle.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_close.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_content_copy.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_exit_to_app.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_favorite.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_favorite_border.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_list.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_find_in_page.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_folder.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_hashtag.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_help.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_jpbw.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_arrow_left.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_arrow_right.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_calculator_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_logo.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 16 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_logo_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 16 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_mode_edit.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pause.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pdf.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_person.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_rotate_90_degrees.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_save.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_select_all.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_shuffle.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sort.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sort_by_alpha.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_star.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_star_border.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_view_1.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_view_2.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 17 | 22 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_view_3.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_view_4.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_void.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_world.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar_dark.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar_light.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_bookmark.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_gallery.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 24 | 25 | 29 | 30 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_status_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_tag_filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/app_bar_gallery.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/app_bar_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/autocomplete_entry.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/cftoken_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |