diff options
264 files changed, 18957 insertions, 5618 deletions
diff --git a/app/build.gradle b/app/build.gradle index b8a1164a..053f0f7f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ android { applicationId "ml.docilealligator.infinityforreddit" minSdkVersion 21 targetSdkVersion 30 - versionCode 63 - versionName "4.3.0-beta3" + versionCode 80 + versionName "5.0.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { annotationProcessorOptions { @@ -43,21 +43,21 @@ android { dependencies { /** AndroidX **/ implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'androidx.biometric:biometric:1.2.0-alpha01' + implementation 'androidx.biometric:biometric:1.2.0-alpha03' implementation 'androidx.browser:browser:1.3.0' implementation 'androidx.cardview:cardview:1.0.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.constraintlayout:constraintlayout:2.1.0-beta02' implementation 'androidx.legacy:legacy-support-v4:1.0.0' def lifecycleVersion = "2.2.0" implementation "androidx.lifecycle:lifecycle-livedata:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycleVersion" annotationProcessor "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" - implementation 'androidx.paging:paging-runtime:2.1.2' + implementation 'androidx.paging:paging-runtime:3.0.0' implementation 'androidx.preference:preference:1.1.1' - def roomVersion = "2.2.6" + def roomVersion = "2.3.0" implementation "androidx.room:room-runtime:$roomVersion" annotationProcessor "androidx.room:room-compiler:$roomVersion" - implementation 'androidx.work:work-runtime:2.4.0' + implementation 'androidx.work:work-runtime:2.5.0' implementation 'com.google.android.material:material:1.3.0-rc01' implementation "androidx.viewpager2:viewpager2:1.1.0-alpha01" @@ -79,16 +79,16 @@ dependencies { // Reactive stuff for event and async related implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' - implementation 'io.reactivex.rxjava2:rxjava:2.2.20' + implementation 'io.reactivex.rxjava2:rxjava:2.2.21' // HTTP clients def retrofitVersion = "2.9.0" implementation "com.squareup.retrofit2:retrofit:$retrofitVersion" implementation "com.squareup.retrofit2:converter-scalars:$retrofitVersion" - implementation 'com.squareup.okhttp3:okhttp:4.2.2' + implementation 'com.squareup.okhttp3:okhttp:4.9.1' // Dependency injection - def daggerVersion = "2.30.1" + def daggerVersion = "2.34" implementation "com.google.dagger:dagger:$daggerVersion" annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" @@ -120,7 +120,7 @@ dependencies { /**** User Interface (frontend) ****/ //Image loading - def glideVersion = "4.11.0" + def glideVersion = "4.12.0" implementation "com.github.bumptech.glide:glide:$glideVersion" annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion" implementation 'jp.wasabeef:glide-transformations:4.3.0' @@ -167,15 +167,17 @@ dependencies { // RecyclerView fast scrolling implementation 'me.zhanghai.android.fastscroll:library:1.1.5' - // Crash screen - implementation 'com.melegy.redscreenofdeath:red-screen-of-death:0.1.2' - implementation 'net.lingala.zip4j:zip4j:2.7.0' implementation 'org.apache.commons:commons-io:1.3.2' implementation "androidx.startup:startup-runtime:1.0.0" implementation 'com.github.FunkyMuse:Crashy:1.1.0' + //implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + //annotationProcessor "androidx.lifecycle:compiler:2.2.0" + + implementation 'androidx.palette:palette:1.0.0' + /**** Builds and flavors ****/ // debugImplementation because LeakCanary should only run in debug builds. diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 97dc80d3..d610fb2f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,7 +18,9 @@ android:maxSdkVersion="22" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> - <uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission-sdk-23 + android:name="android.permission.WRITE_EXTERNAL_STORAGE" + android:maxSdkVersion="28" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> @@ -32,7 +34,33 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true" tools:replace="android:label"> - <activity android:name=".activities.AnonymousSubscriptionsActivity" + <activity android:name=".activities.WikiActivity" + android:label="@string/wiki_activity_label" + android:parentActivityName=".activities.MainActivity" + android:theme="@style/AppTheme.Slidable" /> + <activity + android:name=".activities.TrendingActivity" + android:label="@string/trending_activity_label" + android:parentActivityName=".activities.MainActivity" + android:theme="@style/AppTheme.Slidable" /> + <activity + android:name=".activities.PostGalleryActivity" + android:label="@string/post_gallery_activity_label" + android:parentActivityName=".activities.MainActivity" + android:theme="@style/AppTheme.NoActionBar" + android:windowSoftInputMode="adjustResize" /> + <activity + android:name=".activities.RPANActivity" + android:configChanges="orientation|screenSize|layoutDirection" + android:label="@string/rpan_activity_label" + android:parentActivityName=".activities.MainActivity" + android:theme="@style/AppTheme.TranslucentStatusBar" + android:windowSoftInputMode="adjustPan" /> + <activity + android:name=".activities.LockScreenActivity" + android:theme="@style/AppTheme.NoActionBar" /> + <activity + android:name=".activities.AnonymousSubscriptionsActivity" android:label="@string/subscriptions" android:parentActivityName=".activities.MainActivity" android:theme="@style/AppTheme.NoActionBar" /> @@ -393,7 +421,8 @@ <activity android:name=".activities.ViewPostDetailActivity" android:parentActivityName=".activities.MainActivity" - android:theme="@style/AppTheme.Slidable" /> + android:theme="@style/AppTheme.Slidable" + android:windowSoftInputMode="adjustPan" /> <activity android:name=".activities.ViewSubredditDetailActivity" android:parentActivityName=".activities.MainActivity" @@ -426,6 +455,9 @@ android:name=".services.SubmitPostService" android:enabled="true" android:exported="false" /> + <service + android:name=".services.MaterialYouService" + android:exported="false" /> </application> </manifest>
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index b0506a82..2fc08bd9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -21,15 +21,18 @@ import ml.docilealligator.infinityforreddit.activities.FullMarkdownActivity; import ml.docilealligator.infinityforreddit.activities.GiveAwardActivity; import ml.docilealligator.infinityforreddit.activities.InboxActivity; import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.LockScreenActivity; import ml.docilealligator.infinityforreddit.activities.LoginActivity; import ml.docilealligator.infinityforreddit.activities.MainActivity; import ml.docilealligator.infinityforreddit.activities.MultiredditSelectionActivity; -import ml.docilealligator.infinityforreddit.activities.PostFilterUsageListingActivity; import ml.docilealligator.infinityforreddit.activities.PostFilterPreferenceActivity; +import ml.docilealligator.infinityforreddit.activities.PostFilterUsageListingActivity; +import ml.docilealligator.infinityforreddit.activities.PostGalleryActivity; import ml.docilealligator.infinityforreddit.activities.PostImageActivity; import ml.docilealligator.infinityforreddit.activities.PostLinkActivity; import ml.docilealligator.infinityforreddit.activities.PostTextActivity; import ml.docilealligator.infinityforreddit.activities.PostVideoActivity; +import ml.docilealligator.infinityforreddit.activities.RPANActivity; import ml.docilealligator.infinityforreddit.activities.ReportActivity; import ml.docilealligator.infinityforreddit.activities.RulesActivity; import ml.docilealligator.infinityforreddit.activities.SearchActivity; @@ -45,6 +48,7 @@ import ml.docilealligator.infinityforreddit.activities.SubredditMultiselectionAc import ml.docilealligator.infinityforreddit.activities.SubredditSelectionActivity; import ml.docilealligator.infinityforreddit.activities.SubscribedThingListingActivity; import ml.docilealligator.infinityforreddit.activities.SuicidePreventionActivity; +import ml.docilealligator.infinityforreddit.activities.TrendingActivity; import ml.docilealligator.infinityforreddit.activities.ViewImageOrGifActivity; import ml.docilealligator.infinityforreddit.activities.ViewImgurMediaActivity; import ml.docilealligator.infinityforreddit.activities.ViewMultiRedditDetailActivity; @@ -55,6 +59,7 @@ import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivi import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.activities.ViewVideoActivity; import ml.docilealligator.infinityforreddit.activities.WebViewActivity; +import ml.docilealligator.infinityforreddit.activities.WikiActivity; import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment; import ml.docilealligator.infinityforreddit.fragments.FollowedUsersListingFragment; @@ -68,10 +73,12 @@ import ml.docilealligator.infinityforreddit.fragments.UserListingFragment; import ml.docilealligator.infinityforreddit.fragments.ViewImgurImageFragment; import ml.docilealligator.infinityforreddit.fragments.ViewImgurVideoFragment; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; +import ml.docilealligator.infinityforreddit.fragments.ViewRPANBroadcastFragment; import ml.docilealligator.infinityforreddit.fragments.ViewRedditGalleryImageOrGifFragment; import ml.docilealligator.infinityforreddit.fragments.ViewRedditGalleryVideoFragment; import ml.docilealligator.infinityforreddit.services.DownloadMediaService; import ml.docilealligator.infinityforreddit.services.DownloadRedditVideoService; +import ml.docilealligator.infinityforreddit.services.MaterialYouService; import ml.docilealligator.infinityforreddit.services.SubmitPostService; import ml.docilealligator.infinityforreddit.settings.AdvancedPreferenceFragment; import ml.docilealligator.infinityforreddit.settings.CrashReportsFragment; @@ -263,4 +270,20 @@ public interface AppComponent { void inject(CrashReportsFragment crashReportsFragment); void inject(AnonymousSubscriptionsActivity anonymousSubscriptionsActivity); + + void inject(LockScreenActivity lockScreenActivity); + + void inject(MaterialYouService materialYouService); + + void inject(RPANActivity rpanActivity); + + void inject(ViewRPANBroadcastFragment viewRPANBroadcastFragment); + + void inject(PostGalleryActivity postGalleryActivity); + + void inject(TrendingActivity trendingActivity); + + void inject(WikiActivity wikiActivity); + + void inject(Infinity infinity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java index 845f1b49..49120eca 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java @@ -44,7 +44,7 @@ class AppModule { @Provides @Named("oauth") @Singleton - Retrofit provideOauthRetrofit(OkHttpClient okHttpClient) { + Retrofit provideOauthRetrofit(@Named("default") OkHttpClient okHttpClient) { return new Retrofit.Builder() .baseUrl(APIUtils.OAUTH_API_BASE_URI) .client(okHttpClient) @@ -153,6 +153,18 @@ class AppModule { } @Provides + @Named("strapi") + @Singleton + Retrofit providestrapiRetrofit(@Named("default") OkHttpClient okHttpClient) { + return new Retrofit.Builder() + .baseUrl(APIUtils.STRAPI_BASE_URI) + .client(okHttpClient) + .addConverterFactory(ScalarsConverterFactory.create()) + .build(); + } + + @Provides + @Named("default") @Singleton OkHttpClient provideOkHttpClient(@Named("no_oauth") Retrofit retrofit, RedditDataRoomDatabase accountRoomDatabase, @Named("current_account") SharedPreferences currentAccountSharedPreferences) { @@ -166,6 +178,17 @@ class AppModule { } @Provides + @Named("rpan") + @Singleton + OkHttpClient provideRPANOkHttpClient() { + return new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .build(); + } + + @Provides @Singleton RedditDataRoomDatabase provideRedditDataRoomDatabase() { return RedditDataRoomDatabase.getDatabase(mApplication); @@ -254,6 +277,12 @@ class AppModule { } @Provides + @Named("post_details") + SharedPreferences providePostDetailsSharedPreferences() { + return mApplication.getSharedPreferences(SharedPreferencesUtils.POST_DETAILS_SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE); + } + + @Provides @Singleton CustomThemeWrapper provideCustomThemeWrapper(@Named("light_theme") SharedPreferences lightThemeSharedPreferences, @Named("dark_theme") SharedPreferences darkThemeSharedPreferences, @@ -263,10 +292,15 @@ class AppModule { @Provides @Singleton - ExoCreator provideExoCreator() { - SimpleCache cache = new SimpleCache(new File(mApplication.getCacheDir(), "/toro_cache"), + SimpleCache provideSimpleCache() { + return new SimpleCache(new File(mApplication.getCacheDir(), "/exoplayer"), new LeastRecentlyUsedCacheEvictor(200 * 1024 * 1024), new ExoDatabaseProvider(mApplication)); - Config config = new Config.Builder(mApplication).setMediaSourceBuilder(MediaSourceBuilder.LOOPING).setCache(cache) + } + + @Provides + @Singleton + ExoCreator provideExoCreator(SimpleCache simpleCache) { + Config config = new Config.Builder(mApplication).setMediaSourceBuilder(MediaSourceBuilder.LOOPING).setCache(simpleCache) .build(); return ToroExo.with(mApplication).getCreator(config); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchGfycatOrRedgifsVideoLinks.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchGfycatOrRedgifsVideoLinks.java index 1fc8960c..19dc8a9c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchGfycatOrRedgifsVideoLinks.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchGfycatOrRedgifsVideoLinks.java @@ -1,12 +1,14 @@ package ml.docilealligator.infinityforreddit; -import android.os.AsyncTask; +import android.os.Handler; import androidx.annotation.NonNull; import org.json.JSONException; import org.json.JSONObject; +import java.util.concurrent.Executor; + import ml.docilealligator.infinityforreddit.apis.GfycatAPI; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import retrofit2.Call; @@ -16,8 +18,6 @@ import retrofit2.Retrofit; public class FetchGfycatOrRedgifsVideoLinks { private FetchGfycatOrRedgifsVideoLinksListener fetchGfycatOrRedgifsVideoLinksListener; - private ParseGfycatVideoLinksAsyncTask parseGfycatVideoLinksAsyncTask; - Retrofit gfycatRetrofit; Call<String> gfycatCall; public interface FetchGfycatOrRedgifsVideoLinksListener { @@ -29,13 +29,14 @@ public class FetchGfycatOrRedgifsVideoLinks { this.fetchGfycatOrRedgifsVideoLinksListener = fetchGfycatOrRedgifsVideoLinksListener; } - public static void fetchGfycatOrRedgifsVideoLinks(Retrofit gfycatRetrofit, String gfycatId, + public static void fetchGfycatOrRedgifsVideoLinks(Executor executor, Handler handler, Retrofit gfycatRetrofit, + String gfycatId, FetchGfycatOrRedgifsVideoLinksListener fetchGfycatOrRedgifsVideoLinksListener) { gfycatRetrofit.create(GfycatAPI.class).getGfycatData(gfycatId).enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { if (response.isSuccessful()) { - new ParseGfycatVideoLinksAsyncTask(response.body(), fetchGfycatOrRedgifsVideoLinksListener).execute(); + parseGfycatVideoLinks(executor, handler, response.body(), fetchGfycatOrRedgifsVideoLinksListener); } else { fetchGfycatOrRedgifsVideoLinksListener.failed(response.code()); } @@ -48,7 +49,8 @@ public class FetchGfycatOrRedgifsVideoLinks { }); } - public void fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(Retrofit gfycatRetrofit, Retrofit redgifsRetrofit, + public void fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(Executor executor, Handler handler, + Retrofit gfycatRetrofit, Retrofit redgifsRetrofit, String gfycatId, boolean isGfycatVideo, boolean automaticallyTryRedgifs) { gfycatCall = (isGfycatVideo ? gfycatRetrofit : redgifsRetrofit).create(GfycatAPI.class).getGfycatData(gfycatId); @@ -56,11 +58,11 @@ public class FetchGfycatOrRedgifsVideoLinks { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { if (response.isSuccessful()) { - parseGfycatVideoLinksAsyncTask = new ParseGfycatVideoLinksAsyncTask(response.body(), fetchGfycatOrRedgifsVideoLinksListener); - parseGfycatVideoLinksAsyncTask.execute(); + parseGfycatVideoLinks(executor, handler, response.body(), fetchGfycatOrRedgifsVideoLinksListener); } else { if (response.code() == 404 && isGfycatVideo && automaticallyTryRedgifs) { - fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(gfycatRetrofit, redgifsRetrofit, gfycatId, false, false); + fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(executor, handler, gfycatRetrofit, + redgifsRetrofit, gfycatId, false, false); } else { fetchGfycatOrRedgifsVideoLinksListener.failed(response.code()); } @@ -78,60 +80,33 @@ public class FetchGfycatOrRedgifsVideoLinks { if (gfycatCall != null && !gfycatCall.isCanceled()) { gfycatCall.cancel(); } - if (parseGfycatVideoLinksAsyncTask != null && !parseGfycatVideoLinksAsyncTask.isCancelled()) { - parseGfycatVideoLinksAsyncTask.cancel(true); - } } - private static class ParseGfycatVideoLinksAsyncTask extends AsyncTask<Void, Void, Void> { - - private String response; - private String webm; - private String mp4; - private boolean parseFailed = false; - private FetchGfycatOrRedgifsVideoLinksListener fetchGfycatOrRedgifsVideoLinksListener; - - ParseGfycatVideoLinksAsyncTask(String response, FetchGfycatOrRedgifsVideoLinksListener fetchGfycatOrRedgifsVideoLinksListener) { - this.response = response; - this.fetchGfycatOrRedgifsVideoLinksListener = fetchGfycatOrRedgifsVideoLinksListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject jsonObject = new JSONObject(response); - mp4 = jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).has(JSONUtils.MP4_URL_KEY) ? - jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).getString(JSONUtils.MP4_URL_KEY) - : jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY) + private static void parseGfycatVideoLinks(Executor executor, Handler handler, String response, + FetchGfycatOrRedgifsVideoLinksListener fetchGfycatOrRedgifsVideoLinksListener) { + try { + JSONObject jsonObject = new JSONObject(response); + String mp4 = jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).has(JSONUtils.MP4_URL_KEY) ? + jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).getString(JSONUtils.MP4_URL_KEY) + : jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY) + .getJSONObject(JSONUtils.CONTENT_URLS_KEY) + .getJSONObject(JSONUtils.MP4_KEY) + .getString(JSONUtils.URL_KEY); + String webm; + if (jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).has(JSONUtils.WEBM_URL_KEY)) { + webm = jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).getString(JSONUtils.WEBM_URL_KEY); + } else if (jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).getJSONObject(JSONUtils.CONTENT_URLS_KEY).has(JSONUtils.WEBM_KEY)) { + webm = jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY) .getJSONObject(JSONUtils.CONTENT_URLS_KEY) - .getJSONObject(JSONUtils.MP4_KEY) + .getJSONObject(JSONUtils.WEBM_KEY) .getString(JSONUtils.URL_KEY); - if (jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).has(JSONUtils.WEBM_URL_KEY)) { - webm = jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).getString(JSONUtils.WEBM_URL_KEY); - } else if (jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY).getJSONObject(JSONUtils.CONTENT_URLS_KEY).has(JSONUtils.WEBM_KEY)) { - webm = jsonObject.getJSONObject(JSONUtils.GFY_ITEM_KEY) - .getJSONObject(JSONUtils.CONTENT_URLS_KEY) - .getJSONObject(JSONUtils.WEBM_KEY) - .getString(JSONUtils.URL_KEY); - } else { - webm = mp4; - } - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - fetchGfycatOrRedgifsVideoLinksListener.failed(-1); } else { - fetchGfycatOrRedgifsVideoLinksListener.success(webm, mp4); + webm = mp4; } + handler.post(() -> fetchGfycatOrRedgifsVideoLinksListener.success(webm, mp4)); + } catch (JSONException e) { + e.printStackTrace(); + handler.post(() -> fetchGfycatOrRedgifsVideoLinksListener.failed(-1)); } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java index 69f0fa58..e1f9c5e7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java @@ -1,6 +1,6 @@ package ml.docilealligator.infinityforreddit; -import android.os.AsyncTask; +import android.os.Handler; import androidx.annotation.NonNull; @@ -9,6 +9,7 @@ import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; +import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.utils.JSONUtils; @@ -24,25 +25,25 @@ public class FetchRules { void failed(); } - public static void fetchRules(Retrofit retrofit, String subredditName, FetchRulesListener fetchRulesListener) { - + public static void fetchRules(Executor executor, Handler handler, Retrofit retrofit, String subredditName, + FetchRulesListener fetchRulesListener) { RedditAPI api = retrofit.create(RedditAPI.class); Call<String> rulesCall = api.getRules(subredditName); rulesCall.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { if (response.isSuccessful()) { - new ParseRulesAsyncTask(response.body(), new ParseRulesAsyncTask.ParseRulesAsyncTaskListener() { + parseRules(executor, handler, response.body(), new FetchRulesListener() { @Override - public void parseSuccessful(ArrayList<Rule> rules) { + public void success(ArrayList<Rule> rules) { fetchRulesListener.success(rules); } @Override - public void parseFailed() { + public void failed() { fetchRulesListener.failed(); } - }).execute(); + }); } else { fetchRulesListener.failed(); } @@ -55,17 +56,9 @@ public class FetchRules { }); } - private static class ParseRulesAsyncTask extends AsyncTask<Void, ArrayList<Rule>, ArrayList<Rule>> { - private String response; - private ParseRulesAsyncTask.ParseRulesAsyncTaskListener parseRulesAsyncTaskListener; - - ParseRulesAsyncTask(String response, ParseRulesAsyncTask.ParseRulesAsyncTaskListener parseRulesAsyncTaskListener) { - this.response = response; - this.parseRulesAsyncTaskListener = parseRulesAsyncTaskListener; - } - - @Override - protected ArrayList<Rule> doInBackground(Void... voids) { + private static void parseRules(Executor executor, Handler handler, String response, + FetchRulesListener fetchRulesListener) { + executor.execute(() -> { try { JSONArray rulesArray = new JSONObject(response).getJSONArray(JSONUtils.RULES_KEY); ArrayList<Rule> rules = new ArrayList<>(); @@ -77,26 +70,11 @@ public class FetchRules { } rules.add(new Rule(shortName, description)); } - return rules; + handler.post(() -> fetchRulesListener.success(rules)); } catch (JSONException e) { e.printStackTrace(); + handler.post(fetchRulesListener::failed); } - return null; - } - - @Override - protected void onPostExecute(ArrayList<Rule> rules) { - if (rules != null) { - parseRulesAsyncTaskListener.parseSuccessful(rules); - } else { - parseRulesAsyncTaskListener.parseFailed(); - } - } - - interface ParseRulesAsyncTaskListener { - void parseSuccessful(ArrayList<Rule> rules); - - void parseFailed(); - } + }); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java index 274d1ad7..1c7c7649 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java @@ -1,37 +1,101 @@ package ml.docilealligator.infinityforreddit; +import android.app.Activity; import android.app.Application; +import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.os.Bundle; +import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.lifecycle.LifecycleObserver; import com.evernote.android.state.StateSaver; import com.livefront.bridge.Bridge; import com.livefront.bridge.SavedStateHandler; import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; import ml.docilealligator.infinityforreddit.broadcastreceivers.NetworkWifiStatusReceiver; +import ml.docilealligator.infinityforreddit.broadcastreceivers.WallpaperChangeReceiver; import ml.docilealligator.infinityforreddit.events.ChangeNetworkStatusEvent; +import ml.docilealligator.infinityforreddit.events.ToggleSecureModeEvent; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; -public class Infinity extends Application { +public class Infinity extends Application implements LifecycleObserver { private AppComponent mAppComponent; private NetworkWifiStatusReceiver mNetworkWifiStatusReceiver; + //private boolean lock = false; + private boolean isSecureMode; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; @Override public void onCreate() { super.onCreate(); - //RedScreenOfDeath.init(this); - mAppComponent = DaggerAppComponent.builder() .appModule(new AppModule(this)) .build(); + mAppComponent.inject(this); + + isSecureMode = mSharedPreferences.getBoolean(SharedPreferencesUtils.SECURE_MODE, false); + + registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { + @Override + public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) { + if (isSecureMode) { + activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); + } + } + + @Override + public void onActivityStarted(@NonNull Activity activity) { + + } + + @Override + public void onActivityResumed(@NonNull Activity activity) { + /*if (lock && !(activity instanceof LockScreenActivity)) { + lock = false; + Intent intent = new Intent(activity, LockScreenActivity.class); + activity.startActivity(intent); + }*/ + } + + @Override + public void onActivityPaused(@NonNull Activity activity) { + + } + + @Override + public void onActivityStopped(@NonNull Activity activity) { + + } + + @Override + public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) { + + } + + @Override + public void onActivityDestroyed(@NonNull Activity activity) { + + } + }); + + //ProcessLifecycleOwner.get().getLifecycle().addObserver(this); + Bridge.initialize(getApplicationContext(), new SavedStateHandler() { @Override public void saveInstanceState(@NonNull Object target, @NonNull Bundle state) { @@ -46,12 +110,31 @@ public class Infinity extends Application { EventBus.builder().addIndex(new EventBusIndex()).installDefaultEventBus(); + EventBus.getDefault().register(this); + mNetworkWifiStatusReceiver = new NetworkWifiStatusReceiver(() -> EventBus.getDefault().post(new ChangeNetworkStatusEvent(Utils.getConnectedNetwork(getApplicationContext())))); registerReceiver(mNetworkWifiStatusReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); + + registerReceiver(new WallpaperChangeReceiver(), new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED)); + } + + /*@OnLifecycleEvent(Lifecycle.Event.ON_START) + public void appInForeground() { + lock = true; } + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) + public void appInBackground(){ + + }*/ + public AppComponent getAppComponent() { return mAppComponent; } + + @Subscribe + public void onToggleSecureModeEvent(ToggleSecureModeEvent secureModeEvent) { + isSecureMode = secureModeEvent.isSecureMode; + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RPANBroadcast.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RPANBroadcast.java new file mode 100644 index 00000000..d7c936c2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RPANBroadcast.java @@ -0,0 +1,236 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.Parcel; +import android.os.Parcelable; + +import ml.docilealligator.infinityforreddit.utils.APIUtils; + +public class RPANBroadcast implements Parcelable { + + public int upvotes; + public int downvotes; + public int uniqueWatchers; + public int continuousWatchers; + public int totalContinuousWatchers; + public boolean chatDisabled; + public double broadcastTime; + public double estimatedRemainingTime; + + public RPANPost rpanPost; + public RPANStream rpanStream; + + public RPANBroadcast(int upvotes, int downvotes, int uniqueWatchers, int continuousWatchers, + int totalContinuousWatchers, boolean chatDisabled, double broadcastTime, + double estimatedRemainingTime, RPANPost rpanPost, RPANStream rpanStream) { + this.upvotes = upvotes; + this.downvotes = downvotes; + this.uniqueWatchers = uniqueWatchers; + this.continuousWatchers = continuousWatchers; + this.totalContinuousWatchers = totalContinuousWatchers; + this.chatDisabled = chatDisabled; + this.broadcastTime = broadcastTime; + this.estimatedRemainingTime = estimatedRemainingTime; + this.rpanPost = rpanPost; + this.rpanStream = rpanStream; + } + + protected RPANBroadcast(Parcel in) { + upvotes = in.readInt(); + downvotes = in.readInt(); + uniqueWatchers = in.readInt(); + continuousWatchers = in.readInt(); + totalContinuousWatchers = in.readInt(); + chatDisabled = in.readByte() != 0; + broadcastTime = in.readDouble(); + estimatedRemainingTime = in.readDouble(); + rpanPost = in.readParcelable(RPANPost.class.getClassLoader()); + rpanStream = in.readParcelable(RPANStream.class.getClassLoader()); + } + + public static final Creator<RPANBroadcast> CREATOR = new Creator<RPANBroadcast>() { + @Override + public RPANBroadcast createFromParcel(Parcel in) { + return new RPANBroadcast(in); + } + + @Override + public RPANBroadcast[] newArray(int size) { + return new RPANBroadcast[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeInt(upvotes); + parcel.writeInt(downvotes); + parcel.writeInt(uniqueWatchers); + parcel.writeInt(continuousWatchers); + parcel.writeInt(totalContinuousWatchers); + parcel.writeByte((byte) (chatDisabled ? 1 : 0)); + parcel.writeDouble(broadcastTime); + parcel.writeDouble(estimatedRemainingTime); + parcel.writeParcelable(rpanPost, i); + parcel.writeParcelable(rpanStream, i); + } + + public static class RPANPost implements Parcelable { + public String fullname; + public String title; + public String subredditName; + public String subredditIconUrl; + public String username; + public int postScore; + public String voteState; + public double upvoteRatio; + public String postPermalink; + public String rpanUrl; + public boolean isNsfw; + public boolean isLocked; + public boolean isArchived; + public boolean isSpoiler; + public String suggestedCommentSort; + public String liveCommentsWebsocketUrl; + + public RPANPost(String fullname, String title, String subredditName, String subredditIconUrl, String username, + int postScore, String voteState, double upvoteRatio, String postPermalink, String rpanUrl, + boolean isNsfw, boolean isLocked, boolean isArchived, boolean isSpoiler, + String suggestedCommentSort, String liveCommentsWebsocketUrl) { + this.fullname = fullname; + this.title = title; + this.subredditName = subredditName; + this.subredditIconUrl = subredditIconUrl; + this.username = username; + this.postScore = postScore; + this.voteState = voteState; + this.upvoteRatio = upvoteRatio; + this.postPermalink = APIUtils.API_BASE_URI + postPermalink; + this.rpanUrl = rpanUrl; + this.isNsfw = isNsfw; + this.isLocked = isLocked; + this.isArchived = isArchived; + this.isSpoiler = isSpoiler; + this.suggestedCommentSort = suggestedCommentSort; + this.liveCommentsWebsocketUrl = liveCommentsWebsocketUrl; + } + + protected RPANPost(Parcel in) { + fullname = in.readString(); + title = in.readString(); + subredditName = in.readString(); + subredditIconUrl = in.readString(); + username = in.readString(); + postScore = in.readInt(); + voteState = in.readString(); + upvoteRatio = in.readDouble(); + postPermalink = in.readString(); + rpanUrl = in.readString(); + isNsfw = in.readByte() != 0; + isLocked = in.readByte() != 0; + isArchived = in.readByte() != 0; + isSpoiler = in.readByte() != 0; + suggestedCommentSort = in.readString(); + liveCommentsWebsocketUrl = in.readString(); + } + + public static final Creator<RPANPost> CREATOR = new Creator<RPANPost>() { + @Override + public RPANPost createFromParcel(Parcel in) { + return new RPANPost(in); + } + + @Override + public RPANPost[] newArray(int size) { + return new RPANPost[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(fullname); + parcel.writeString(title); + parcel.writeString(subredditName); + parcel.writeString(subredditIconUrl); + parcel.writeString(username); + parcel.writeInt(postScore); + parcel.writeString(voteState); + parcel.writeDouble(upvoteRatio); + parcel.writeString(postPermalink); + parcel.writeString(rpanUrl); + parcel.writeByte((byte) (isNsfw ? 1 : 0)); + parcel.writeByte((byte) (isLocked ? 1 : 0)); + parcel.writeByte((byte) (isArchived ? 1 : 0)); + parcel.writeByte((byte) (isSpoiler ? 1 : 0)); + parcel.writeString(suggestedCommentSort); + parcel.writeString(liveCommentsWebsocketUrl); + } + } + + public static class RPANStream implements Parcelable { + public String streamId; + public String hlsUrl; + public String thumbnail; + public int width; + public int height; + public long publishAt; + public String state; + + public RPANStream(String streamId, String hlsUrl, String thumbnail, int width, int height, long publishAt, + String state) { + this.streamId = streamId; + this.hlsUrl = hlsUrl; + this.thumbnail = thumbnail; + this.width = width; + this.height = height; + this.publishAt = publishAt; + this.state = state; + } + + protected RPANStream(Parcel in) { + streamId = in.readString(); + hlsUrl = in.readString(); + thumbnail = in.readString(); + width = in.readInt(); + height = in.readInt(); + publishAt = in.readLong(); + state = in.readString(); + } + + public static final Creator<RPANStream> CREATOR = new Creator<RPANStream>() { + @Override + public RPANStream createFromParcel(Parcel in) { + return new RPANStream(in); + } + + @Override + public RPANStream[] newArray(int size) { + return new RPANStream[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(streamId); + parcel.writeString(hlsUrl); + parcel.writeString(thumbnail); + parcel.writeInt(width); + parcel.writeInt(height); + parcel.writeLong(publishAt); + parcel.writeString(state); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RPANComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RPANComment.java new file mode 100644 index 00000000..077031bf --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RPANComment.java @@ -0,0 +1,15 @@ +package ml.docilealligator.infinityforreddit; + +public class RPANComment { + public String author; + public String authorIconImage; + public String content; + public long createdUTC; + + public RPANComment(String author, String authorIconImage, String content, long createdUTC) { + this.author = author; + this.authorIconImage = authorIconImage; + this.content = content; + this.createdUTC = createdUTC; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java index f190a9fb..480adf81 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java @@ -211,7 +211,7 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE custom_themes" - + " ADD COLUMN link_color INTEGER DEFAULT " + Color.parseColor("#FF4081") + " NOT NULL"); + + " ADD COLUMN link_color INTEGER DEFAULT " + Color.parseColor("#FF1868") + " NOT NULL"); database.execSQL("ALTER TABLE custom_themes" + " ADD COLUMN received_message_text_color INTEGER DEFAULT " + Color.parseColor("#FFFFFF") + " NOT NULL"); database.execSQL("ALTER TABLE custom_themes" diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditGalleryPayload.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditGalleryPayload.java new file mode 100644 index 00000000..ef91d6d9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditGalleryPayload.java @@ -0,0 +1,96 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; + +public class RedditGalleryPayload { + @SerializedName("sr") + public String subredditName; + @SerializedName("submit_type") + public String submitType; + @SerializedName("api_type") + public String apiType = "json"; + @SerializedName("show_error_list") + public boolean showErrorList = true; + public String title; + @SerializedName("spoiler") + public boolean isSpoiler; + @SerializedName("nsfw") + public boolean isNSFW; + public String kind = "self"; + @SerializedName("original_content") + public boolean originalContent = false; + @SerializedName("post_to_twitter") + public boolean postToTwitter = false; + public boolean sendReplies; + @SerializedName("validate_on_submit") + public boolean validateOnSubmit = true; + @SerializedName("flair_id") + public String flairId; + @SerializedName("flair_text") + public String flairText; + public ArrayList<Item> items; + + public RedditGalleryPayload(String subredditName, String submitType, String title, + boolean isSpoiler, boolean isNSFW, boolean sendReplies, Flair flair, ArrayList<Item> items) { + this.subredditName = subredditName; + this.submitType = submitType; + this.title = title; + this.isSpoiler = isSpoiler; + this.isNSFW = isNSFW; + this.sendReplies = sendReplies; + if (flair != null) { + flairId = flair.getId(); + flairText = flair.getText(); + } + this.items = items; + } + + public static class Item implements Parcelable { + public String caption; + @SerializedName("outbound_url") + public String outboundUrl; + @SerializedName("media_id") + public String mediaId; + + public Item(String caption, String outboundUrl, String mediaId) { + this.caption = caption; + this.outboundUrl = outboundUrl; + this.mediaId = mediaId; + } + + protected Item(Parcel in) { + caption = in.readString(); + outboundUrl = in.readString(); + mediaId = in.readString(); + } + + public static final Creator<Item> CREATOR = new Creator<Item>() { + @Override + public Item createFromParcel(Parcel in) { + return new Item(in); + } + + @Override + public Item[] newArray(int size) { + return new Item[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(caption); + parcel.writeString(outboundUrl); + parcel.writeString(mediaId); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/TrendingSearch.java b/app/src/main/java/ml/docilealligator/infinityforreddit/TrendingSearch.java new file mode 100644 index 00000000..f0afc541 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/TrendingSearch.java @@ -0,0 +1,54 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.post.Post; + +public class TrendingSearch implements Parcelable { + public String queryString; + public String displayString; + public String title; + public ArrayList<Post.Preview> previews; + + public TrendingSearch(String queryString, String displayString, String title, ArrayList<Post.Preview> previews) { + this.queryString = queryString; + this.displayString = displayString; + this.title = title; + this.previews = previews; + } + + protected TrendingSearch(Parcel in) { + queryString = in.readString(); + displayString = in.readString(); + title = in.readString(); + previews = in.createTypedArrayList(Post.Preview.CREATOR); + } + + public static final Creator<TrendingSearch> CREATOR = new Creator<TrendingSearch>() { + @Override + public TrendingSearch createFromParcel(Parcel in) { + return new TrendingSearch(in); + } + + @Override + public TrendingSearch[] newArray(int size) { + return new TrendingSearch[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(queryString); + parcel.writeString(displayString); + parcel.writeString(title); + parcel.writeTypedList(previews); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/UploadImageEnabledActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/UploadImageEnabledActivity.java new file mode 100644 index 00000000..aecde88f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/UploadImageEnabledActivity.java @@ -0,0 +1,7 @@ +package ml.docilealligator.infinityforreddit; + +public interface UploadImageEnabledActivity { + void uploadImage(); + void captureImage(); + void insertImageUrl(UploadedImage uploadedImage); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/UploadedImage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/UploadedImage.java new file mode 100644 index 00000000..e3d28734 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/UploadedImage.java @@ -0,0 +1,42 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.Parcel; +import android.os.Parcelable; + +public class UploadedImage implements Parcelable { + public String imageName; + public String imageUrl; + + public UploadedImage(String imageName, String imageUrl) { + this.imageName = imageName; + this.imageUrl = imageUrl; + } + + protected UploadedImage(Parcel in) { + imageName = in.readString(); + imageUrl = in.readString(); + } + + public static final Creator<UploadedImage> CREATOR = new Creator<UploadedImage>() { + @Override + public UploadedImage createFromParcel(Parcel in) { + return new UploadedImage(in); + } + + @Override + public UploadedImage[] newArray(int size) { + return new UploadedImage[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(imageName); + parcel.writeString(imageUrl); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/account/Account.java b/app/src/main/java/ml/docilealligator/infinityforreddit/account/Account.java index 6232c94d..246c3c05 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/account/Account.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/account/Account.java @@ -3,6 +3,7 @@ package ml.docilealligator.infinityforreddit.account; import androidx.annotation.NonNull; import androidx.room.ColumnInfo; import androidx.room.Entity; +import androidx.room.Ignore; import androidx.room.PrimaryKey; @Entity(tableName = "accounts") @@ -26,6 +27,11 @@ public class Account { @ColumnInfo(name = "is_current_user") private boolean isCurrentUser; + @Ignore + public static Account getAnonymousAccount() { + return new Account("-", null, null, null, null, null, 0, false); + } + public Account(@NonNull String accountName, String accessToken, String refreshToken, String code, String profileImageUrl, String bannerImageUrl, int karma, boolean isCurrentUser) { this.accountName = accountName; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountDao.java index 721dea6f..fcd824a1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountDao.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountDao.java @@ -16,9 +16,6 @@ public interface AccountDao { @Query("SELECT EXISTS (SELECT 1 FROM accounts WHERE username = '-')") boolean isAnonymousAccountInserted(); - @Query("INSERT INTO accounts(username, karma, is_current_user) VALUES('-', 0, 0)") - void insertAnonymousAccount(); - @Query("SELECT * FROM accounts WHERE username != '-'") List<Account> getAllAccounts(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java index 74dbe822..a244fafe 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java @@ -1,11 +1,15 @@ package ml.docilealligator.infinityforreddit.activities; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.provider.MediaStore; import android.text.Spanned; import android.text.util.Linkify; import android.view.Menu; @@ -20,7 +24,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.core.content.FileProvider; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; @@ -31,6 +35,11 @@ import org.commonmark.ext.gfm.tables.TableBlock; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.concurrent.Executor; + import javax.inject.Inject; import javax.inject.Named; @@ -48,17 +57,21 @@ import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.UploadImageEnabledActivity; +import ml.docilealligator.infinityforreddit.UploadedImage; import ml.docilealligator.infinityforreddit.adapters.MarkdownBottomBarRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UploadedImagesBottomSheetFragment; import ml.docilealligator.infinityforreddit.comment.Comment; import ml.docilealligator.infinityforreddit.comment.SendComment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; -public class CommentActivity extends BaseActivity { +public class CommentActivity extends BaseActivity implements UploadImageEnabledActivity { public static final String EXTRA_COMMENT_PARENT_TEXT_KEY = "ECPTK"; public static final String EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY = "ECPTMK"; @@ -70,6 +83,10 @@ public class CommentActivity extends BaseActivity { public static final String EXTRA_IS_REPLYING_KEY = "EIRK"; public static final String RETURN_EXTRA_COMMENT_DATA_KEY = "RECDK"; public static final int WRITE_COMMENT_REQUEST_CODE = 1; + private static final int PICK_IMAGE_REQUEST_CODE = 100; + private static final int CAPTURE_IMAGE_REQUEST_CODE = 200; + private static final int MARKDOWN_PREVIEW_REQUEST_CODE = 300; + private static final String UPLOADED_IMAGES_STATE = "UIS"; @BindView(R.id.coordinator_layout_comment_activity) CoordinatorLayout coordinatorLayout; @@ -91,6 +108,9 @@ public class CommentActivity extends BaseActivity { @Named("oauth") Retrofit mOauthRetrofit; @Inject + @Named("upload_media") + Retrofit mUploadMediaRetrofit; + @Inject @Named("default") SharedPreferences mSharedPreferences; @Inject @@ -98,6 +118,8 @@ public class CommentActivity extends BaseActivity { SharedPreferences mCurrentAccountSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; private String mAccessToken; private String parentFullname; private int parentDepth; @@ -105,6 +127,9 @@ public class CommentActivity extends BaseActivity { private boolean isSubmitting = false; private boolean isReplying; private int markdownColor; + private Uri capturedImageUri; + private ArrayList<UploadedImage> uploadedImages = new ArrayList<>(); + private Menu mMenu; @Override protected void onCreate(Bundle savedInstanceState) { @@ -216,7 +241,7 @@ public class CommentActivity extends BaseActivity { .tableLayout(R.layout.adapter_table_block, R.id.table_layout) .textLayoutIsRoot(R.layout.view_table_entry_cell))) .build(); - contentMarkdownRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + contentMarkdownRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this)); contentMarkdownRecyclerView.setAdapter(markwonAdapter); markwonAdapter.setMarkdown(postBodyMarkwon, parentBodyMarkdown); markwonAdapter.notifyDataSetChanged(); @@ -231,12 +256,32 @@ public class CommentActivity extends BaseActivity { setSupportActionBar(toolbar); - MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, commentEditText, item); + if (savedInstanceState != null) { + uploadedImages = savedInstanceState.getParcelableArrayList(UPLOADED_IMAGES_STATE); + } + + MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( + mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { + @Override + public void onClick(int item) { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( + CommentActivity.this, commentEditText, item); + } + + @Override + public void onUploadImage() { + Utils.hideKeyboard(CommentActivity.this); + UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); + Bundle arguments = new Bundle(); + arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, + uploadedImages); + fragment.setArguments(arguments); + fragment.show(getSupportFragmentManager(), fragment.getTag()); + } }); - markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, - LinearLayoutManager.HORIZONTAL, false)); + markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, + LinearLayoutManagerBugFixed.HORIZONTAL, false)); markdownBottomBarRecyclerView.setAdapter(adapter); commentEditText.requestFocus(); @@ -247,6 +292,12 @@ public class CommentActivity extends BaseActivity { } @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelableArrayList(UPLOADED_IMAGES_STATE, uploadedImages); + } + + @Override public SharedPreferences getDefaultSharedPreferences() { return mSharedPreferences; } @@ -280,6 +331,7 @@ public class CommentActivity extends BaseActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.comment_activity, menu); + mMenu = menu; applyMenuItemTheme(menu); return true; } @@ -293,60 +345,70 @@ public class CommentActivity extends BaseActivity { } else if (itemId == R.id.action_preview_comment_activity) { Intent intent = new Intent(this, FullMarkdownActivity.class); intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, commentEditText.getText().toString()); - startActivity(intent); + intent.putExtra(FullMarkdownActivity.EXTRA_SUBMIT_POST, true); + startActivityForResult(intent, MARKDOWN_PREVIEW_REQUEST_CODE); } else if (itemId == R.id.action_send_comment_activity) { - if (!isSubmitting) { - isSubmitting = true; - if (commentEditText.getText() == null || commentEditText.getText().toString().equals("")) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.comment_content_required, Snackbar.LENGTH_SHORT).show(); - return true; - } + sendComment(item); + return true; + } + + return false; + } + + public void sendComment(@Nullable MenuItem item) { + if (!isSubmitting) { + isSubmitting = true; + if (commentEditText.getText() == null || commentEditText.getText().toString().equals("")) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.comment_content_required, Snackbar.LENGTH_SHORT).show(); + return; + } + if (item != null) { item.setEnabled(false); item.getIcon().setAlpha(130); - Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_comment, Snackbar.LENGTH_INDEFINITE); - sendingSnackbar.show(); - - SendComment.sendComment(commentEditText.getText().toString(), parentFullname, parentDepth, - getResources().getConfiguration().locale, mOauthRetrofit, - mAccessToken, - new SendComment.SendCommentListener() { - @Override - public void sendCommentSuccess(Comment comment) { - isSubmitting = false; + } + Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_comment, Snackbar.LENGTH_INDEFINITE); + sendingSnackbar.show(); + + SendComment.sendComment(mExecutor, new Handler(), commentEditText.getText().toString(), + parentFullname, parentDepth, mOauthRetrofit, mAccessToken, + new SendComment.SendCommentListener() { + @Override + public void sendCommentSuccess(Comment comment) { + isSubmitting = false; + if (item != null) { item.setEnabled(true); item.getIcon().setAlpha(255); - Toast.makeText(CommentActivity.this, R.string.send_comment_success, Toast.LENGTH_SHORT).show(); - Intent returnIntent = new Intent(); - returnIntent.putExtra(RETURN_EXTRA_COMMENT_DATA_KEY, comment); - returnIntent.putExtra(EXTRA_PARENT_FULLNAME_KEY, parentFullname); - if (isReplying) { - returnIntent.putExtra(EXTRA_PARENT_POSITION_KEY, parentPosition); - } - setResult(RESULT_OK, returnIntent); - finish(); } + Toast.makeText(CommentActivity.this, R.string.send_comment_success, Toast.LENGTH_SHORT).show(); + Intent returnIntent = new Intent(); + returnIntent.putExtra(RETURN_EXTRA_COMMENT_DATA_KEY, comment); + returnIntent.putExtra(EXTRA_PARENT_FULLNAME_KEY, parentFullname); + if (isReplying) { + returnIntent.putExtra(EXTRA_PARENT_POSITION_KEY, parentPosition); + } + setResult(RESULT_OK, returnIntent); + finish(); + } - @Override - public void sendCommentFailed(@Nullable String errorMessage) { - isSubmitting = false; - sendingSnackbar.dismiss(); + @Override + public void sendCommentFailed(@Nullable String errorMessage) { + isSubmitting = false; + sendingSnackbar.dismiss(); + if (item != null) { item.setEnabled(true); item.getIcon().setAlpha(255); + } - if (errorMessage == null || !errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.send_comment_failed, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_SHORT).show(); - } + if (errorMessage == null || !errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.send_comment_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_SHORT).show(); } - }); - } - return true; + } + }); } - - return false; } private void promptAlertDialog(int titleResId, int messageResId) { @@ -360,6 +422,26 @@ public class CommentActivity extends BaseActivity { } @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == PICK_IMAGE_REQUEST_CODE) { + if (data == null) { + Toast.makeText(CommentActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show(); + return; + } + Utils.uploadImageToReddit(this, mExecutor, mOauthRetrofit, mUploadMediaRetrofit, + mAccessToken, commentEditText, coordinatorLayout, data.getData(), uploadedImages); + } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { + Utils.uploadImageToReddit(this, mExecutor, mOauthRetrofit, mUploadMediaRetrofit, + mAccessToken, commentEditText, coordinatorLayout, capturedImageUri, uploadedImages); + } else if (requestCode == MARKDOWN_PREVIEW_REQUEST_CODE) { + sendComment(mMenu == null ? null : mMenu.findItem(R.id.action_send_comment_activity)); + } + } + } + + @Override public void onBackPressed() { if (isSubmitting) { promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_comment_detail); @@ -382,4 +464,37 @@ public class CommentActivity extends BaseActivity { public void onAccountSwitchEvent(SwitchAccountEvent event) { finish(); } + + @Override + public void uploadImage() { + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, + getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); + } + + @Override + public void captureImage() { + Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + try { + capturedImageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", + File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); + pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri); + startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); + } catch (IOException ex) { + Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show(); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void insertImageUrl(UploadedImage uploadedImage) { + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")", + 0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java index 9f9207e5..144898bb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java @@ -1,5 +1,7 @@ package ml.docilealligator.infinityforreddit.activities; +import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN; + import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -17,7 +19,6 @@ import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.app.ActivityCompat; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; @@ -37,6 +38,9 @@ import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.adapters.CustomThemeListingRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.asynctasks.ChangeThemeName; import ml.docilealligator.infinityforreddit.asynctasks.DeleteTheme; @@ -48,13 +52,8 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeViewModel; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; -import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN; - public class CustomThemeListingActivity extends BaseActivity implements CustomThemeOptionsBottomSheetFragment.CustomThemeOptionsBottomSheetFragmentListener, CreateThemeBottomSheetFragment.SelectBaseThemeBottomSheetFragmentListener { @@ -110,7 +109,6 @@ public class CustomThemeListingActivity extends BaseActivity implements CustomThemeListingRecyclerViewAdapter adapter = new CustomThemeListingRecyclerViewAdapter(this, CustomThemeWrapper.getPredefinedThemes(this)); recyclerView.setAdapter(adapter); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemePreviewActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemePreviewActivity.java index dbd40c31..e3d232e6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemePreviewActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemePreviewActivity.java @@ -1,5 +1,10 @@ package ml.docilealligator.infinityforreddit.activities; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; + import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.content.res.Configuration; @@ -43,22 +48,18 @@ import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeSettingsItem; +import ml.docilealligator.infinityforreddit.customviews.ViewPagerBugFixed; import ml.docilealligator.infinityforreddit.font.ContentFontStyle; import ml.docilealligator.infinityforreddit.font.FontStyle; import ml.docilealligator.infinityforreddit.font.TitleFontStyle; import ml.docilealligator.infinityforreddit.fragments.ThemePreviewCommentsFragment; import ml.docilealligator.infinityforreddit.fragments.ThemePreviewPostsFragment; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; - public class CustomThemePreviewActivity extends AppCompatActivity { public static final String EXTRA_CUSTOM_THEME_SETTINGS_ITEMS = "ECTSI"; @@ -66,7 +67,7 @@ public class CustomThemePreviewActivity extends AppCompatActivity { @BindView(R.id.coordinator_layout_theme_preview_activity) CoordinatorLayout coordinatorLayout; @BindView(R.id.view_pager_theme_preview_activity) - ViewPager viewPager; + ViewPagerBugFixed viewPager; @BindView(R.id.appbar_layout_theme_preview_activity) AppBarLayout appBarLayout; @BindView(R.id.collapsing_toolbar_layout_theme_preview_activity) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeThemeActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeThemeActivity.java index fc238c34..989eb34f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeThemeActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeThemeActivity.java @@ -12,7 +12,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; @@ -104,8 +103,6 @@ public class CustomizeThemeActivity extends BaseActivity { setTitle(R.string.customize_theme_activity_create_theme_label); } - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - if (savedInstanceState != null) { customThemeSettingsItems = savedInstanceState.getParcelableArrayList(CUSTOM_THEME_SETTINGS_ITEMS_STATE); themeName = savedInstanceState.getString(THEME_NAME_STATE); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java index 07c0c2af..e46f581b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java @@ -1,10 +1,14 @@ package ml.docilealligator.infinityforreddit.activities; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; import android.view.Menu; import android.view.MenuItem; import android.view.inputmethod.InputMethodManager; @@ -12,8 +16,10 @@ import android.widget.EditText; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.FileProvider; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -24,20 +30,28 @@ import com.google.android.material.snackbar.Snackbar; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.UploadImageEnabledActivity; +import ml.docilealligator.infinityforreddit.UploadedImage; import ml.docilealligator.infinityforreddit.adapters.MarkdownBottomBarRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UploadedImagesBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -46,15 +60,20 @@ import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; -public class EditCommentActivity extends BaseActivity { +public class EditCommentActivity extends BaseActivity implements UploadImageEnabledActivity { public static final String EXTRA_CONTENT = "EC"; public static final String EXTRA_FULLNAME = "EF"; public static final String EXTRA_POSITION = "EP"; - public static final String EXTRA_EDITED_COMMENT_CONTENT = "EECC"; public static final String EXTRA_EDITED_COMMENT_POSITION = "EECP"; + private static final int PICK_IMAGE_REQUEST_CODE = 100; + private static final int CAPTURE_IMAGE_REQUEST_CODE = 200; + private static final int MARKDOWN_PREVIEW_REQUEST_CODE = 300; + + private static final String UPLOADED_IMAGES_STATE = "UIS"; + @BindView(R.id.coordinator_layout_edit_comment_activity) CoordinatorLayout coordinatorLayout; @BindView(R.id.appbar_layout_edit_comment_activity) @@ -69,6 +88,9 @@ public class EditCommentActivity extends BaseActivity { @Named("oauth") Retrofit mOauthRetrofit; @Inject + @Named("upload_media") + Retrofit mUploadMediaRetrofit; + @Inject @Named("default") SharedPreferences mSharedPreferences; @Inject @@ -76,10 +98,14 @@ public class EditCommentActivity extends BaseActivity { SharedPreferences mCurrentAccountSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; private String mFullName; private String mAccessToken; private String mCommentContent; private boolean isSubmitting = false; + private Uri capturedImageUri; + private ArrayList<UploadedImage> uploadedImages = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -109,11 +135,31 @@ public class EditCommentActivity extends BaseActivity { mCommentContent = getIntent().getStringExtra(EXTRA_CONTENT); contentEditText.setText(mCommentContent); - MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); + if (savedInstanceState != null) { + uploadedImages = savedInstanceState.getParcelableArrayList(UPLOADED_IMAGES_STATE); + } + + MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( + mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { + @Override + public void onClick(int item) { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( + EditCommentActivity.this, contentEditText, item); + } + + @Override + public void onUploadImage() { + Utils.hideKeyboard(EditCommentActivity.this); + UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); + Bundle arguments = new Bundle(); + arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, + uploadedImages); + fragment.setArguments(arguments); + fragment.show(getSupportFragmentManager(), fragment.getTag()); + } }); - markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, + markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, LinearLayoutManager.HORIZONTAL, false)); markdownBottomBarRecyclerView.setAdapter(adapter); @@ -162,47 +208,10 @@ public class EditCommentActivity extends BaseActivity { if (item.getItemId() == R.id.action_preview_edit_comment_activity) { Intent intent = new Intent(this, FullMarkdownActivity.class); intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); - startActivity(intent); + intent.putExtra(FullMarkdownActivity.EXTRA_SUBMIT_POST, true); + startActivityForResult(intent, MARKDOWN_PREVIEW_REQUEST_CODE); } else if (item.getItemId() == R.id.action_send_edit_comment_activity) { - if (!isSubmitting) { - isSubmitting = true; - - Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); - - String content = contentEditText.getText().toString(); - - Map<String, String> params = new HashMap<>(); - params.put(APIUtils.THING_ID_KEY, mFullName); - params.put(APIUtils.TEXT_KEY, content); - - mOauthRetrofit.create(RedditAPI.class) - .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) - .enqueue(new Callback<String>() { - @Override - public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { - isSubmitting = false; - if (response.isSuccessful()) { - Toast.makeText(EditCommentActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); - - Intent returnIntent = new Intent(); - returnIntent.putExtra(EXTRA_EDITED_COMMENT_CONTENT, Utils.modifyMarkdown(content)); - returnIntent.putExtra(EXTRA_EDITED_COMMENT_POSITION, getIntent().getExtras().getInt(EXTRA_POSITION)); - setResult(RESULT_OK, returnIntent); - - finish(); - } else { - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } - } - - @Override - public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } - }); - - } + editComment(); return true; } else if (item.getItemId() == android.R.id.home) { onBackPressed(); @@ -211,17 +220,85 @@ public class EditCommentActivity extends BaseActivity { return false; } + private void editComment() { + if (!isSubmitting) { + isSubmitting = true; + + Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); + + String content = contentEditText.getText().toString(); + + Map<String, String> params = new HashMap<>(); + params.put(APIUtils.THING_ID_KEY, mFullName); + params.put(APIUtils.TEXT_KEY, content); + + mOauthRetrofit.create(RedditAPI.class) + .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + isSubmitting = false; + if (response.isSuccessful()) { + Toast.makeText(EditCommentActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); + + Intent returnIntent = new Intent(); + returnIntent.putExtra(EXTRA_EDITED_COMMENT_CONTENT, Utils.modifyMarkdown(content)); + returnIntent.putExtra(EXTRA_EDITED_COMMENT_POSITION, getIntent().getExtras().getInt(EXTRA_POSITION)); + setResult(RESULT_OK, returnIntent); + + finish(); + } else { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } + }); + + } + } + private void promptAlertDialog(int titleResId, int messageResId) { new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(titleResId) .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) + .setPositiveButton(R.string.discard_dialog_button, (dialogInterface, i) -> finish()) .setNegativeButton(R.string.no, null) .show(); } @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == PICK_IMAGE_REQUEST_CODE) { + if (data == null) { + Toast.makeText(EditCommentActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show(); + return; + } + Utils.uploadImageToReddit(this, mExecutor, mOauthRetrofit, mUploadMediaRetrofit, + mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages); + } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { + Utils.uploadImageToReddit(this, mExecutor, mOauthRetrofit, mUploadMediaRetrofit, + mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages); + } else if (requestCode == MARKDOWN_PREVIEW_REQUEST_CODE) { + editComment(); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelableArrayList(UPLOADED_IMAGES_STATE, uploadedImages); + } + + @Override public void onBackPressed() { if (isSubmitting) { promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_comment_detail); @@ -244,4 +321,37 @@ public class EditCommentActivity extends BaseActivity { public void onAccountSwitchEvent(SwitchAccountEvent event) { finish(); } + + @Override + public void uploadImage() { + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, + getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); + } + + @Override + public void captureImage() { + Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + try { + capturedImageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", + File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); + pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri); + startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); + } catch (IOException ex) { + Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show(); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void insertImageUrl(UploadedImage uploadedImage) { + int start = Math.max(contentEditText.getSelectionStart(), 0); + int end = Math.max(contentEditText.getSelectionEnd(), 0); + contentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")", + 0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java index 5c8ea02f..21e1418d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java @@ -1,10 +1,14 @@ package ml.docilealligator.infinityforreddit.activities; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -14,9 +18,10 @@ import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.core.content.FileProvider; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; @@ -27,33 +32,48 @@ import com.r0adkll.slidr.Slidr; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.UploadImageEnabledActivity; +import ml.docilealligator.infinityforreddit.UploadedImage; import ml.docilealligator.infinityforreddit.adapters.MarkdownBottomBarRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UploadedImagesBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; -public class EditPostActivity extends BaseActivity { +public class EditPostActivity extends BaseActivity implements UploadImageEnabledActivity { public static final String EXTRA_TITLE = "ET"; public static final String EXTRA_CONTENT = "EC"; public static final String EXTRA_FULLNAME = "EF"; + private static final int PICK_IMAGE_REQUEST_CODE = 100; + private static final int CAPTURE_IMAGE_REQUEST_CODE = 200; + private static final int MARKDOWN_PREVIEW_REQUEST_CODE = 300; + + private static final String UPLOADED_IMAGES_STATE = "UIS"; + @BindView(R.id.coordinator_layout_edit_post_activity) CoordinatorLayout coordinatorLayout; @BindView(R.id.appbar_layout_edit_post_activity) @@ -72,6 +92,9 @@ public class EditPostActivity extends BaseActivity { @Named("oauth") Retrofit mOauthRetrofit; @Inject + @Named("upload_media") + Retrofit mUploadMediaRetrofit; + @Inject @Named("default") SharedPreferences mSharedPreferences; @Inject @@ -79,10 +102,14 @@ public class EditPostActivity extends BaseActivity { SharedPreferences mCurrentAccountSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; private String mFullName; private String mAccessToken; private String mPostContent; private boolean isSubmitting = false; + private Uri capturedImageUri; + private ArrayList<UploadedImage> uploadedImages = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -117,12 +144,32 @@ public class EditPostActivity extends BaseActivity { mPostContent = getIntent().getStringExtra(EXTRA_CONTENT); contentEditText.setText(mPostContent); - MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); + if (savedInstanceState != null) { + uploadedImages = savedInstanceState.getParcelableArrayList(UPLOADED_IMAGES_STATE); + } + + MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( + mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { + @Override + public void onClick(int item) { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( + EditPostActivity.this, contentEditText, item); + } + + @Override + public void onUploadImage() { + Utils.hideKeyboard(EditPostActivity.this); + UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); + Bundle arguments = new Bundle(); + arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, + uploadedImages); + fragment.setArguments(arguments); + fragment.show(getSupportFragmentManager(), fragment.getTag()); + } }); - markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, - LinearLayoutManager.HORIZONTAL, false)); + markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, + LinearLayoutManagerBugFixed.HORIZONTAL, false)); markdownBottomBarRecyclerView.setAdapter(adapter); contentEditText.requestFocus(); @@ -172,37 +219,10 @@ public class EditPostActivity extends BaseActivity { if (item.getItemId() == R.id.action_preview_edit_post_activity) { Intent intent = new Intent(this, FullMarkdownActivity.class); intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); - startActivity(intent); + intent.putExtra(FullMarkdownActivity.EXTRA_SUBMIT_POST, true); + startActivityForResult(intent, MARKDOWN_PREVIEW_REQUEST_CODE); } else if (item.getItemId() == R.id.action_send_edit_post_activity) { - if (!isSubmitting) { - isSubmitting = true; - - Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); - - Map<String, String> params = new HashMap<>(); - params.put(APIUtils.THING_ID_KEY, mFullName); - params.put(APIUtils.TEXT_KEY, contentEditText.getText().toString()); - - mOauthRetrofit.create(RedditAPI.class) - .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) - .enqueue(new Callback<String>() { - @Override - public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { - isSubmitting = false; - Toast.makeText(EditPostActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); - Intent returnIntent = new Intent(); - setResult(RESULT_OK, returnIntent); - finish(); - } - - @Override - public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } - }); - - } + editPost(); return true; } else if (item.getItemId() == android.R.id.home) { onBackPressed(); @@ -211,11 +231,69 @@ public class EditPostActivity extends BaseActivity { return false; } + private void editPost() { + if (!isSubmitting) { + isSubmitting = true; + + Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); + + Map<String, String> params = new HashMap<>(); + params.put(APIUtils.THING_ID_KEY, mFullName); + params.put(APIUtils.TEXT_KEY, contentEditText.getText().toString()); + + mOauthRetrofit.create(RedditAPI.class) + .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + isSubmitting = false; + Toast.makeText(EditPostActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); + Intent returnIntent = new Intent(); + setResult(RESULT_OK, returnIntent); + finish(); + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } + }); + + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == PICK_IMAGE_REQUEST_CODE) { + if (data == null) { + Toast.makeText(EditPostActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show(); + return; + } + Utils.uploadImageToReddit(this, mExecutor, mOauthRetrofit, mUploadMediaRetrofit, + mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages); + } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { + Utils.uploadImageToReddit(this, mExecutor, mOauthRetrofit, mUploadMediaRetrofit, + mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages); + } else if (requestCode == MARKDOWN_PREVIEW_REQUEST_CODE) { + editPost(); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelableArrayList(UPLOADED_IMAGES_STATE, uploadedImages); + } + private void promptAlertDialog(int titleResId, int messageResId) { new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(titleResId) .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) + .setPositiveButton(R.string.discard_dialog_button, (dialogInterface, i) -> finish()) .setNegativeButton(R.string.no, null) .show(); @@ -244,4 +322,37 @@ public class EditPostActivity extends BaseActivity { public void onAccountSwitchEvent(SwitchAccountEvent event) { finish(); } + + @Override + public void uploadImage() { + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, + getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); + } + + @Override + public void captureImage() { + Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + try { + capturedImageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", + File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); + pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri); + startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); + } catch (IOException ex) { + Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show(); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void insertImageUrl(UploadedImage uploadedImage) { + int start = Math.max(contentEditText.getSelectionStart(), 0); + int end = Math.max(contentEditText.getSelectionEnd(), 0); + contentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")", + 0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FetchRandomSubredditOrPostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FetchRandomSubredditOrPostActivity.java index d73e195c..365209b1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FetchRandomSubredditOrPostActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FetchRandomSubredditOrPostActivity.java @@ -3,9 +3,12 @@ package ml.docilealligator.infinityforreddit.activities; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Handler; import android.widget.RelativeLayout; import android.widget.Toast; +import java.util.concurrent.Executor; + import javax.inject.Inject; import javax.inject.Named; @@ -32,6 +35,8 @@ public class FetchRandomSubredditOrPostActivity extends BaseActivity { SharedPreferences mSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; private boolean isCanceled = false; @Override @@ -44,7 +49,7 @@ public class FetchRandomSubredditOrPostActivity extends BaseActivity { int option = getIntent().getIntExtra(EXTRA_RANDOM_OPTION, RandomBottomSheetFragment.RANDOM_SUBREDDIT); - FetchPost.fetchRandomPost(mRetrofit, option == RandomBottomSheetFragment.RANDOM_NSFW_SUBREDDIT + FetchPost.fetchRandomPost(mExecutor, new Handler(), mRetrofit, option == RandomBottomSheetFragment.RANDOM_NSFW_SUBREDDIT || option == RandomBottomSheetFragment.RANDOM_NSFW_POST, new FetchPost.FetchRandomPostListener() { @Override public void fetchRandomPostSuccess(String postId, String subredditName) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredPostsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredPostsActivity.java index e14e8499..4d2ff01f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredPostsActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredPostsActivity.java @@ -62,6 +62,7 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec public static final String EXTRA_NAME = "ESN"; public static final String EXTRA_QUERY = "EQ"; + public static final String EXTRA_TRENDING_SOURCE = "ETS"; public static final String EXTRA_FILTER = "EF"; public static final String EXTRA_CONTAIN_FLAIR = "ECF"; public static final String EXTRA_POST_TYPE = "EPT"; @@ -312,6 +313,7 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec } else if (postType == PostDataSource.TYPE_SEARCH) { bundle.putString(PostFragment.EXTRA_NAME, name); bundle.putString(PostFragment.EXTRA_QUERY, getIntent().getStringExtra(EXTRA_QUERY)); + bundle.putString(PostFragment.EXTRA_TRENDING_SOURCE, getIntent().getStringExtra(EXTRA_TRENDING_SOURCE)); } mFragment.setArguments(bundle); getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_filtered_posts_activity, mFragment).commit(); @@ -359,81 +361,81 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_sort_filtered_thing_activity: - switch (postType) { - case PostDataSource.TYPE_FRONT_PAGE: - SortTypeBottomSheetFragment bestSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle bestBundle = new Bundle(); - bestBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, false); - bestSortTypeBottomSheetFragment.setArguments(bestBundle); - bestSortTypeBottomSheetFragment.show(getSupportFragmentManager(), bestSortTypeBottomSheetFragment.getTag()); - break; - case PostDataSource.TYPE_SEARCH: - SearchPostSortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment = new SearchPostSortTypeBottomSheetFragment(); - Bundle searchBundle = new Bundle(); - searchPostSortTypeBottomSheetFragment.setArguments(searchBundle); - searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag()); - break; - case PostDataSource.TYPE_SUBREDDIT: - if (name.equals("popular") || name.equals("all")) { - SortTypeBottomSheetFragment popularAndAllSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle popularBundle = new Bundle(); - popularBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - popularAndAllSortTypeBottomSheetFragment.setArguments(popularBundle); - popularAndAllSortTypeBottomSheetFragment.show(getSupportFragmentManager(), popularAndAllSortTypeBottomSheetFragment.getTag()); - } else { - SortTypeBottomSheetFragment subredditSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle subredditSheetBundle = new Bundle(); - subredditSheetBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - subredditSortTypeBottomSheetFragment.setArguments(subredditSheetBundle); - subredditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), subredditSortTypeBottomSheetFragment.getTag()); - } - break; - case PostDataSource.TYPE_MULTI_REDDIT: - SortTypeBottomSheetFragment multiRedditSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle multiRedditBundle = new Bundle(); - multiRedditBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - multiRedditSortTypeBottomSheetFragment.setArguments(multiRedditBundle); - multiRedditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), multiRedditSortTypeBottomSheetFragment.getTag()); - break; - case PostDataSource.TYPE_USER: - UserThingSortTypeBottomSheetFragment userThingSortTypeBottomSheetFragment = new UserThingSortTypeBottomSheetFragment(); - userThingSortTypeBottomSheetFragment.show(getSupportFragmentManager(), userThingSortTypeBottomSheetFragment.getTag()); - } - return true; - case R.id.action_refresh_filtered_thing_activity: - if (mMenu != null) { - mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity).setTitle(R.string.action_start_lazy_mode); - } - if (mFragment instanceof FragmentCommunicator) { - ((FragmentCommunicator) mFragment).refresh(); - } - return true; - case R.id.action_lazy_mode_filtered_thing_activity: - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity); - if (isInLazyMode) { - ((FragmentCommunicator) mFragment).stopLazyMode(); - isInLazyMode = false; - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } else { - if (((FragmentCommunicator) mFragment).startLazyMode()) { - isInLazyMode = true; - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + finish(); + return true; + } else if (itemId == R.id.action_sort_filtered_thing_activity) { + switch (postType) { + case PostDataSource.TYPE_FRONT_PAGE: + SortTypeBottomSheetFragment bestSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle bestBundle = new Bundle(); + bestBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, false); + bestSortTypeBottomSheetFragment.setArguments(bestBundle); + bestSortTypeBottomSheetFragment.show(getSupportFragmentManager(), bestSortTypeBottomSheetFragment.getTag()); + break; + case PostDataSource.TYPE_SEARCH: + SearchPostSortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment = new SearchPostSortTypeBottomSheetFragment(); + Bundle searchBundle = new Bundle(); + searchPostSortTypeBottomSheetFragment.setArguments(searchBundle); + searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag()); + break; + case PostDataSource.TYPE_SUBREDDIT: + if (name.equals("popular") || name.equals("all")) { + SortTypeBottomSheetFragment popularAndAllSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle popularBundle = new Bundle(); + popularBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + popularAndAllSortTypeBottomSheetFragment.setArguments(popularBundle); + popularAndAllSortTypeBottomSheetFragment.show(getSupportFragmentManager(), popularAndAllSortTypeBottomSheetFragment.getTag()); + } else { + SortTypeBottomSheetFragment subredditSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle subredditSheetBundle = new Bundle(); + subredditSheetBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + subredditSortTypeBottomSheetFragment.setArguments(subredditSheetBundle); + subredditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), subredditSortTypeBottomSheetFragment.getTag()); } + break; + case PostDataSource.TYPE_MULTI_REDDIT: + SortTypeBottomSheetFragment multiRedditSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle multiRedditBundle = new Bundle(); + multiRedditBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + multiRedditSortTypeBottomSheetFragment.setArguments(multiRedditBundle); + multiRedditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), multiRedditSortTypeBottomSheetFragment.getTag()); + break; + case PostDataSource.TYPE_USER: + UserThingSortTypeBottomSheetFragment userThingSortTypeBottomSheetFragment = new UserThingSortTypeBottomSheetFragment(); + userThingSortTypeBottomSheetFragment.show(getSupportFragmentManager(), userThingSortTypeBottomSheetFragment.getTag()); + } + return true; + } else if (itemId == R.id.action_refresh_filtered_thing_activity) { + if (mMenu != null) { + mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity).setTitle(R.string.action_start_lazy_mode); + } + if (mFragment != null) { + ((FragmentCommunicator) mFragment).refresh(); + } + return true; + } else if (itemId == R.id.action_lazy_mode_filtered_thing_activity) { + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity); + if (isInLazyMode) { + ((FragmentCommunicator) mFragment).stopLazyMode(); + isInLazyMode = false; + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } else { + if (((FragmentCommunicator) mFragment).startLazyMode()) { + isInLazyMode = true; + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); } - return true; - case R.id.action_change_post_layout_filtered_post_activity: - PostLayoutBottomSheetFragment postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; + } + return true; + } else if (itemId == R.id.action_change_post_layout_filtered_post_activity) { + PostLayoutBottomSheetFragment postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; } return false; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java index 312fe6cd..9eb9fb86 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java @@ -1,5 +1,6 @@ package ml.docilealligator.infinityforreddit.activities; +import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; @@ -11,6 +12,7 @@ import android.text.Spanned; import android.text.TextPaint; import android.text.style.ClickableSpan; import android.text.util.Linkify; +import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; @@ -20,15 +22,15 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; import com.r0adkll.slidr.Slidr; import com.r0adkll.slidr.model.SlidrInterface; import org.commonmark.ext.gfm.tables.TableBlock; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -51,20 +53,21 @@ import io.noties.markwon.recycler.table.TableEntryPlugin; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; public class FullMarkdownActivity extends BaseActivity { public static final String EXTRA_COMMENT_MARKDOWN = "ECM"; public static final String EXTRA_IS_NSFW = "EIN"; + public static final String EXTRA_SUBMIT_POST = "ESP"; @BindView(R.id.coordinator_layout_comment_full_markdown_activity) CoordinatorLayout coordinatorLayout; @BindView(R.id.appbar_layout_comment_full_markdown_activity) AppBarLayout appBarLayout; - @BindView(R.id.collapsing_toolbar_layout_comment_full_markdown_activity) - CollapsingToolbarLayout collapsingToolbarLayout; @BindView(R.id.toolbar_comment_full_markdown_activity) Toolbar toolbar; @BindView(R.id.content_markdown_view_comment_full_markdown_activity) @@ -85,6 +88,8 @@ public class FullMarkdownActivity extends BaseActivity { ButterKnife.bind(this); + EventBus.getDefault().register(this); + applyCustomTheme(); setSupportActionBar(toolbar); @@ -112,7 +117,7 @@ public class FullMarkdownActivity extends BaseActivity { window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } adjustToolbar(toolbar); - markdownRecyclerView.setPadding(0, 0, 0, getNavBarHeight()); + markdownRecyclerView.setPadding(markdownRecyclerView.getPaddingLeft(), 0, markdownRecyclerView.getPaddingRight(), getNavBarHeight()); } } @@ -212,7 +217,7 @@ public class FullMarkdownActivity extends BaseActivity { .tableLayout(R.layout.adapter_table_block, R.id.table_layout) .textLayoutIsRoot(R.layout.view_table_entry_cell))) .build(); - LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { + LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { @Override public void onScrolledLeft() { if (mSlidrInterface != null) { @@ -234,10 +239,26 @@ public class FullMarkdownActivity extends BaseActivity { } @Override + public boolean onCreateOptionsMenu(Menu menu) { + if (getIntent().getBooleanExtra(EXTRA_SUBMIT_POST, false)) { + getMenuInflater().inflate(R.menu.full_markdown_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + return false; + } + + @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == android.R.id.home) { finish(); return true; + } else if (item.getItemId() == R.id.action_send_full_markdown_activity) { + Intent returnIntent = new Intent(); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + return true; } return false; @@ -258,4 +279,17 @@ public class FullMarkdownActivity extends BaseActivity { coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + if (!getClass().getName().equals(event.excludeActivityClassName)) { + finish(); + } + } }
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/GiveAwardActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/GiveAwardActivity.java index a3cc4cdb..98e1b604 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/GiveAwardActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/GiveAwardActivity.java @@ -17,7 +17,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; @@ -39,6 +38,7 @@ import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.adapters.AwardRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.award.GiveAward; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import retrofit2.Retrofit; @@ -162,7 +162,7 @@ public class GiveAwardActivity extends BaseActivity { .setNegativeButton(R.string.no, null) .show(); }); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this)); recyclerView.setAdapter(adapter); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/InboxActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/InboxActivity.java index 78fdc00f..2437103f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/InboxActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/InboxActivity.java @@ -9,9 +9,9 @@ import android.os.Handler; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.Toast; @@ -20,15 +20,17 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentPagerAdapter; -import androidx.viewpager.widget.ViewPager; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; import com.google.android.material.textfield.TextInputEditText; import com.r0adkll.slidr.Slidr; import com.r0adkll.slidr.model.SlidrInterface; @@ -80,7 +82,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf @BindView(R.id.tab_layout_inbox_activity) TabLayout tabLayout; @BindView(R.id.view_pager_inbox_activity) - ViewPager viewPager; + ViewPager2 viewPager2; @BindView(R.id.fab_inbox_activity) FloatingActionButton fab; @Inject @@ -100,6 +102,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf Executor mExecutor; private SlidrInterface mSlidrInterface; private SectionsPagerAdapter sectionsPagerAdapter; + private FragmentManager fragmentManager; private String mAccessToken; private String mAccountName; private String mNewAccountName; @@ -152,6 +155,8 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf setSupportActionBar(mToolbar); setToolbarGoToTop(mToolbar); + fragmentManager = getSupportFragmentManager(); + mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); @@ -162,7 +167,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf } getCurrentAccountAndFetchMessage(savedInstanceState); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){ + viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { fab.show(); @@ -177,6 +182,18 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class); + pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString()); + startActivity(pmIntent); + return true; + } + return false; + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.choose_a_user) .setView(rootView) @@ -250,8 +267,8 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf } private void bindView(Bundle savedInstanceState) { - sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + sectionsPagerAdapter = new SectionsPagerAdapter(this); + viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { if (position == 0) { @@ -261,12 +278,23 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf } } }); - viewPager.setAdapter(sectionsPagerAdapter); - viewPager.setOffscreenPageLimit(2); - tabLayout.setupWithViewPager(viewPager); + viewPager2.setAdapter(sectionsPagerAdapter); + viewPager2.setOffscreenPageLimit(2); + new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { + switch (position) { + case 0: + tab.setText(R.string.notifications); + break; + case 1: + tab.setText(R.string.messages); + break; + } + }).attach(); if (savedInstanceState == null && getIntent().getBooleanExtra(EXTRA_VIEW_MESSAGE, false)) { - viewPager.setCurrentItem(1); + viewPager2.setCurrentItem(1, false); } + + fixViewPager2Sensitivity(viewPager2); } @Override @@ -376,17 +404,44 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf fab.hide(); } - private class SectionsPagerAdapter extends FragmentPagerAdapter { - private InboxFragment tab1; - private InboxFragment tab2; + private class SectionsPagerAdapter extends FragmentStateAdapter { - public SectionsPagerAdapter(@NonNull FragmentManager fm) { - super(fm, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + SectionsPagerAdapter(FragmentActivity fa) { + super(fa); + } + + @Nullable + private Fragment getCurrentFragment() { + if (viewPager2 == null || fragmentManager == null) { + return null; + } + return fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); + } + + void refresh() { + InboxFragment fragment = (InboxFragment) getCurrentFragment(); + if (fragment != null) { + fragment.refresh(); + } + } + + void goBackToTop() { + InboxFragment fragment = (InboxFragment) getCurrentFragment(); + if (fragment != null) { + fragment.goBackToTop(); + } + } + + void readAllMessages() { + InboxFragment fragment = (InboxFragment) getCurrentFragment(); + if (fragment != null) { + fragment.markAllMessagesRead(); + } } @NonNull @Override - public Fragment getItem(int position) { + public Fragment createFragment(int position) { if (position == 0) { InboxFragment fragment = new InboxFragment(); Bundle bundle = new Bundle(); @@ -405,62 +460,8 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf } @Override - public int getCount() { + public int getItemCount() { return 2; } - - @Nullable - @Override - public CharSequence getPageTitle(int position) { - if (position == 0) { - return getString(R.string.notifications); - } - - return getString(R.string.messages); - } - - @NonNull - @Override - public Object instantiateItem(@NonNull ViewGroup container, int position) { - Fragment fragment = (Fragment) super.instantiateItem(container, position); - if (position == 0) { - tab1 = (InboxFragment) fragment; - } else if (position == 1) { - tab2 = (InboxFragment) fragment; - } - - return fragment; - } - - void refresh() { - if (viewPager.getCurrentItem() == 0) { - if (tab1 != null) { - tab1.refresh(); - } - } else if (viewPager.getCurrentItem() == 1 && tab2 != null) { - tab2.refresh(); - } - } - - void goBackToTop() { - if (viewPager.getCurrentItem() == 0) { - if (tab1 != null) { - tab1.goBackToTop(); - } - } else if (viewPager.getCurrentItem() == 1) { - if (tab2 != null) { - tab2.goBackToTop(); - } - } - } - - void readAllMessages() { - if (tab1 != null) { - tab1.markAllMessagesRead(); - } - if (tab2 != null) { - tab2.markAllMessagesRead(); - } - } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java index 7f834f48..a6596edb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java @@ -48,6 +48,8 @@ public class LinkResolverActivity extends AppCompatActivity { private static final String IMGUR_GALLERY_PATTERN = "/gallery/\\w+/?"; private static final String IMGUR_ALBUM_PATTERN = "/(album|a)/\\w+/?"; private static final String IMGUR_IMAGE_PATTERN = "/\\w+/?"; + private static final String RPAN_BROADCAST_PATTERN = "/rpan/r/[\\w-]+/\\w+/?\\w+/?"; + private static final String WIKI_PATTERN = "/[rR]/[\\w-]+/(wiki|w)/?\\w+"; @Inject @Named("default") @@ -117,7 +119,19 @@ public class LinkResolverActivity extends AppCompatActivity { List<String> segments = uri.getPathSegments(); if (authority != null) { - if (authority.equals("v.redd.it")) { + if (authority.equals("reddit-uploaded-media.s3-accelerate.amazonaws.com")) { + String unescapedUrl = uri.toString().replace("%2F", "/"); + int lastSlashIndex = unescapedUrl.lastIndexOf("/"); + if (lastSlashIndex < 0 || lastSlashIndex == unescapedUrl.length() - 1) { + deepLinkError(uri); + return; + } + String id = unescapedUrl.substring(lastSlashIndex + 1); + Intent intent = new Intent(this, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, uri.toString()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, id + ".jpg"); + startActivity(intent); + } else if (authority.equals("v.redd.it")) { Intent intent = new Intent(this, ViewVideoActivity.class); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_V_REDD_IT); intent.putExtra(ViewVideoActivity.EXTRA_V_REDD_IT_URL, uri.toString()); @@ -158,6 +172,10 @@ public class LinkResolverActivity extends AppCompatActivity { } else { deepLinkError(uri); } + } else if (path.matches(WIKI_PATTERN)) { + Intent intent = new Intent(this, WikiActivity.class); + intent.putExtra(WikiActivity.EXTRA_SUBREDDIT_NAME, segments.get(1)); + startActivity(intent); } else if (path.matches(SUBREDDIT_PATTERN)) { Intent intent = new Intent(this, ViewSubredditDetailActivity.class); intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3)); @@ -186,6 +204,10 @@ public class LinkResolverActivity extends AppCompatActivity { intent.putExtra(ViewSubredditDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); startActivity(intent); + } else if (path.matches(RPAN_BROADCAST_PATTERN)) { + Intent intent = new Intent(this, RPANActivity.class); + intent.putExtra(RPANActivity.EXTRA_RPAN_BROADCAST_FULLNAME_OR_ID, path.substring(path.lastIndexOf('/') + 1)); + startActivity(intent); } else if (authority.equals("redd.it") && path.matches(REDD_IT_POST_PATTERN)) { Intent intent = new Intent(this, ViewPostDetailActivity.class); intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1)); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LockScreenActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LockScreenActivity.java new file mode 100644 index 00000000..3ba73440 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LockScreenActivity.java @@ -0,0 +1,83 @@ +package ml.docilealligator.infinityforreddit.activities; + +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; +import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; + +import android.content.SharedPreferences; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.biometric.BiometricManager; +import androidx.biometric.BiometricPrompt; +import androidx.core.content.ContextCompat; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; + +public class LockScreenActivity extends BaseActivity { + + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_look_screen); + + applyCustomTheme(); + + BiometricManager biometricManager = BiometricManager.from(this); + if (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) { + Executor executor = ContextCompat.getMainExecutor(this); + BiometricPrompt biometricPrompt = new BiometricPrompt(this, + executor, new BiometricPrompt.AuthenticationCallback() { + @Override + public void onAuthenticationSucceeded( + @NonNull BiometricPrompt.AuthenticationResult result) { + super.onAuthenticationSucceeded(result); + finish(); + } + }); + + BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() + .setTitle(getString(R.string.unlock_account_section)) + .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) + .build(); + + biometricPrompt.authenticate(promptInfo); + } else { + finish(); + } + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + + } + + @Override + public void onBackPressed() { } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java index 89c95efa..55522aa9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java @@ -1,5 +1,8 @@ package ml.docilealligator.infinityforreddit.activities; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; + import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -9,6 +12,8 @@ import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.text.Editable; +import android.text.TextWatcher; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; @@ -16,6 +21,7 @@ import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.ImageView; import android.widget.LinearLayout; @@ -33,8 +39,8 @@ import androidx.drawerlayout.widget.DrawerLayout; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.widget.ViewPager2; @@ -79,6 +85,8 @@ import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; import ml.docilealligator.infinityforreddit.account.AccountViewModel; import ml.docilealligator.infinityforreddit.adapters.NavigationDrawerRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.adapters.SubredditAutocompleteRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.asynctasks.InsertSubscribedThings; import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccount; import ml.docilealligator.infinityforreddit.asynctasks.SwitchToAnonymousMode; @@ -89,6 +97,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.RandomBottomShe import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTypeBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.ChangeConfirmToExitEvent; import ml.docilealligator.infinityforreddit.events.ChangeDisableSwipingBetweenTabsEvent; import ml.docilealligator.infinityforreddit.events.ChangeLockBottomAppBarEvent; @@ -99,23 +108,27 @@ import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.fragments.PostFragment; import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.MultiRedditViewModel; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.PostDataSource; import ml.docilealligator.infinityforreddit.readpost.InsertReadPost; +import ml.docilealligator.infinityforreddit.subreddit.ParseSubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditViewModel; import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; import ml.docilealligator.infinityforreddit.user.FetchUserData; import ml.docilealligator.infinityforreddit.user.UserData; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; import retrofit2.Retrofit; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; - public class MainActivity extends BaseActivity implements SortTypeSelectionCallback, PostTypeBottomSheetFragment.PostTypeSelectionCallback, PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface, FABMoreOptionsBottomSheetFragment.FABOptionSelectionCallback, @@ -168,6 +181,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb ImageView option4BottomAppBar; @BindView(R.id.fab_main_activity) FloatingActionButton fab; + MultiRedditViewModel multiRedditViewModel; SubscribedSubredditViewModel subscribedSubredditViewModel; AccountViewModel accountViewModel; @Inject @@ -210,6 +224,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb private SectionsPagerAdapter sectionsPagerAdapter; private AppBarLayout.LayoutParams params; private NavigationDrawerRecyclerViewAdapter adapter; + private Call<String> subredditAutocompleteCall; private String mAccessToken; private String mAccountName; private boolean mFetchUserInfoSuccess = false; @@ -223,6 +238,8 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb private boolean mConfirmToExit; private boolean mLockBottomAppBar; private boolean mDisableSwipingBetweenTabs; + private boolean mShowFavoriteMultiReddits; + private boolean mShowMultiReddits; private boolean mShowFavoriteSubscribedSubreddits; private boolean mShowSubscribedSubreddits; private int fabOption; @@ -300,7 +317,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); - showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); + showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, true); mConfirmToExit = mSharedPreferences.getBoolean(SharedPreferencesUtils.CONFIRM_TO_EXIT, false); mLockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); mDisableSwipingBetweenTabs = mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false); @@ -745,6 +762,10 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } else if (stringId == R.string.multi_reddit) { intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); + } else if (stringId == R.string.rpan) { + intent = new Intent(MainActivity.this, RPANActivity.class); + } else if (stringId == R.string.trending) { + intent = new Intent(MainActivity.this, TrendingActivity.class); } else if (stringId == R.string.upvoted) { intent = new Intent(MainActivity.this, AccountPostsActivity.class); intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_UPVOTED); @@ -826,19 +847,21 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } }); adapter.setInboxCount(inboxCount); - navDrawerRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + navDrawerRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this)); navDrawerRecyclerView.setAdapter(adapter); int tabCount = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_COUNT, 3); + mShowFavoriteMultiReddits = mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_MULTIREDDITS, false); + mShowMultiReddits = mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_MULTIREDDITS, false); mShowFavoriteSubscribedSubreddits = mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, false); mShowSubscribedSubreddits = mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, false); - sectionsPagerAdapter = new SectionsPagerAdapter(this, tabCount, - mShowFavoriteSubscribedSubreddits, mShowSubscribedSubreddits); + sectionsPagerAdapter = new SectionsPagerAdapter(this, tabCount, mShowFavoriteMultiReddits, + mShowMultiReddits, mShowFavoriteSubscribedSubreddits, mShowSubscribedSubreddits); viewPager2.setAdapter(sectionsPagerAdapter); viewPager2.setOffscreenPageLimit(1); viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs); if (mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, true)) { - if (mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) { + if (mShowFavoriteMultiReddits || mShowMultiReddits || mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) { tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); } else { tabLayout.setTabMode(TabLayout.MODE_FIXED); @@ -868,13 +891,26 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb tab.setText(mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE, getString(R.string.all))); break; } - if (position >= tabCount && (mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) && sectionsPagerAdapter != null) { - List<SubscribedSubredditData> favoriteSubscribedSubreddits = sectionsPagerAdapter.favoriteSubscribedSubreddits; - List<SubscribedSubredditData> subscribedSubreddits = sectionsPagerAdapter.subscribedSubreddits; - if (position - tabCount < favoriteSubscribedSubreddits.size()) { - tab.setText(favoriteSubscribedSubreddits.get(position - tabCount).getName()); - } else if (position - tabCount - favoriteSubscribedSubreddits.size() < subscribedSubreddits.size()) { - tab.setText(subscribedSubreddits.get(position - tabCount - favoriteSubscribedSubreddits.size()).getName()); + if (position >= tabCount && (mShowFavoriteMultiReddits || mShowMultiReddits || + mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) + && sectionsPagerAdapter != null) { + if (position - tabCount < sectionsPagerAdapter.favoriteMultiReddits.size()) { + tab.setText(sectionsPagerAdapter.favoriteMultiReddits.get(position - tabCount).getName()); + } else if (position - tabCount - sectionsPagerAdapter.favoriteMultiReddits.size() < sectionsPagerAdapter.multiReddits.size()) { + tab.setText(sectionsPagerAdapter.multiReddits.get(position - tabCount + - sectionsPagerAdapter.favoriteMultiReddits.size()).getName()); + } else if (position - tabCount - sectionsPagerAdapter.favoriteMultiReddits.size() + - sectionsPagerAdapter.multiReddits.size() < sectionsPagerAdapter.favoriteSubscribedSubreddits.size()) { + tab.setText(sectionsPagerAdapter.favoriteSubscribedSubreddits.get(position - tabCount + - sectionsPagerAdapter.favoriteMultiReddits.size() + - sectionsPagerAdapter.multiReddits.size()).getName()); + } else if (position - tabCount - sectionsPagerAdapter.favoriteMultiReddits.size() + - sectionsPagerAdapter.multiReddits.size() + - sectionsPagerAdapter.favoriteSubscribedSubreddits.size() < sectionsPagerAdapter.subscribedSubreddits.size()) { + tab.setText(sectionsPagerAdapter.subscribedSubreddits.get(position - tabCount + - sectionsPagerAdapter.favoriteMultiReddits.size() + - sectionsPagerAdapter.multiReddits.size() + - sectionsPagerAdapter.favoriteSubscribedSubreddits.size()).getName()); } } } @@ -900,6 +936,25 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb loadSubscriptions(); + multiRedditViewModel = new ViewModelProvider(this, new MultiRedditViewModel.Factory(getApplication(), + mRedditDataRoomDatabase, mAccountName)) + .get(MultiRedditViewModel.class); + + multiRedditViewModel.getAllFavoriteMultiReddits().observe(this, multiReddits -> { + if (mShowFavoriteMultiReddits && sectionsPagerAdapter != null) { + sectionsPagerAdapter.setFavoriteMultiReddits(multiReddits); + } + }); + + multiRedditViewModel.getAllMultiReddits().observe(this, new Observer<List<MultiReddit>>() { + @Override + public void onChanged(List<MultiReddit> multiReddits) { + if (mShowMultiReddits && sectionsPagerAdapter != null) { + sectionsPagerAdapter.setMultiReddits(multiReddits); + } + } + }); + subscribedSubredditViewModel = new ViewModelProvider(this, new SubscribedSubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName)) .get(SubscribedSubredditViewModel.class); @@ -1173,6 +1228,10 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb case PostTypeBottomSheetFragment.TYPE_VIDEO: intent = new Intent(MainActivity.this, PostVideoActivity.class); startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_GALLERY: + intent = new Intent(MainActivity.this, PostGalleryActivity.class); + startActivity(intent); } } @@ -1250,7 +1309,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb adapter.setShowAvatarOnTheRightInTheNavigationDrawer(event.showAvatarOnTheRightInTheNavigationDrawer); int previousPosition = -1; if (navDrawerRecyclerView.getLayoutManager() != null) { - previousPosition = ((LinearLayoutManager) navDrawerRecyclerView.getLayoutManager()).findFirstVisibleItemPosition(); + previousPosition = ((LinearLayoutManagerBugFixed) navDrawerRecyclerView.getLayoutManager()).findFirstVisibleItemPosition(); } RecyclerView.LayoutManager layoutManager = navDrawerRecyclerView.getLayoutManager(); @@ -1332,11 +1391,80 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb private void goToSubreddit() { View rootView = getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, coordinatorLayout, false); TextInputEditText thingEditText = rootView.findViewById(R.id.text_input_edit_text_go_to_thing_edit_text); - thingEditText.requestFocus(); + RecyclerView recyclerView = rootView.findViewById(R.id.recycler_view_go_to_thing_edit_text); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + SubredditAutocompleteRecyclerViewAdapter adapter = new SubredditAutocompleteRecyclerViewAdapter( + this, mCustomThemeWrapper, subredditData -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent intent = new Intent(MainActivity.this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditData.getName()); + startActivity(intent); + }); + recyclerView.setAdapter(adapter); + + thingEditText.requestFocus(); if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); + subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); + startActivity(subredditIntent); + return true; + } + return false; + }); + + boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false); + thingEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + if (subredditAutocompleteCall != null) { + subredditAutocompleteCall.cancel(); + } + subredditAutocompleteCall = mOauthRetrofit.create(RedditAPI.class).subredditAutocomplete(APIUtils.getOAuthHeader(mAccessToken), + editable.toString(), nsfw); + subredditAutocompleteCall.enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + ParseSubredditData.parseSubredditListingData(response.body(), nsfw, new ParseSubredditData.ParseSubredditListingDataListener() { + @Override + public void onParseSubredditListingDataSuccess(ArrayList<SubredditData> subredditData, String after) { + adapter.setSubreddits(subredditData); + } + + @Override + public void onParseSubredditListingDataFail() { + + } + }); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + + } + }); + } + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.go_to_subreddit) .setView(rootView) @@ -1349,7 +1477,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); startActivity(subredditIntent); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) .setOnDismissListener(dialogInterface -> { if (imm != null) { imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); @@ -1366,6 +1498,18 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent userIntent = new Intent(this, ViewUserDetailActivity.class); + userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); + startActivity(userIntent); + return true; + } + return false; + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.go_to_user) .setView(rootView) @@ -1378,7 +1522,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); startActivity(userIntent); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) .setOnDismissListener(dialogInterface -> { if (imm != null) { imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); @@ -1409,16 +1557,26 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb private class SectionsPagerAdapter extends FragmentStateAdapter { int tabCount; + boolean showFavoriteMultiReddits; + boolean showMultiReddits; boolean showFavoriteSubscribedSubreddits; boolean showSubscribedSubreddits; + List<MultiReddit> favoriteMultiReddits; + List<MultiReddit> multiReddits; List<SubscribedSubredditData> favoriteSubscribedSubreddits; List<SubscribedSubredditData> subscribedSubreddits; - SectionsPagerAdapter(FragmentActivity fa, int tabCount, boolean showFavoriteSubscribedSubreddits, boolean showSubscribedSubreddits) { + SectionsPagerAdapter(FragmentActivity fa, int tabCount, boolean showFavoriteMultiReddits, + boolean showMultiReddits, boolean showFavoriteSubscribedSubreddits, + boolean showSubscribedSubreddits) { super(fa); this.tabCount = tabCount; + favoriteMultiReddits = new ArrayList<>(); + multiReddits = new ArrayList<>(); favoriteSubscribedSubreddits = new ArrayList<>(); subscribedSubreddits = new ArrayList<>(); + this.showFavoriteMultiReddits = showFavoriteMultiReddits; + this.showMultiReddits = showMultiReddits; this.showFavoriteSubscribedSubreddits = showFavoriteSubscribedSubreddits; this.showSubscribedSubreddits = showSubscribedSubreddits; } @@ -1463,17 +1621,38 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb String name = mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME, ""); return generatePostFragment(postType, name); } else { + if (showFavoriteMultiReddits) { + if (position >= tabCount && position - tabCount < favoriteMultiReddits.size()) { + int postType = SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT; + String name = favoriteMultiReddits.get(position - tabCount).getPath(); + return generatePostFragment(postType, name); + } + } + + if (showMultiReddits) { + if (position >= tabCount && position - tabCount - favoriteMultiReddits.size() < multiReddits.size()) { + int postType = SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT; + String name = multiReddits.get(position - tabCount - favoriteMultiReddits.size()).getPath(); + return generatePostFragment(postType, name); + } + } + if (showFavoriteSubscribedSubreddits) { - if (position >= tabCount && position - tabCount < favoriteSubscribedSubreddits.size()) { + if (position >= tabCount && position - tabCount - favoriteMultiReddits.size() + - multiReddits.size() < favoriteSubscribedSubreddits.size()) { int postType = SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT; - String name = favoriteSubscribedSubreddits.get(position - tabCount).getName(); + String name = favoriteSubscribedSubreddits.get(position - tabCount + - favoriteMultiReddits.size() + - multiReddits.size()).getName(); return generatePostFragment(postType, name); } } if (showSubscribedSubreddits) { - if (position >= tabCount && position - tabCount - favoriteSubscribedSubreddits.size() < subscribedSubreddits.size()) { + if (position >= tabCount && position - tabCount - favoriteMultiReddits.size() + - multiReddits.size() - favoriteSubscribedSubreddits.size() < subscribedSubreddits.size()) { int postType = SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT; - String name = subscribedSubreddits.get(position - tabCount - favoriteSubscribedSubreddits.size()).getName(); + String name = subscribedSubreddits.get(position - tabCount - favoriteMultiReddits.size() + - multiReddits.size() - favoriteSubscribedSubreddits.size()).getName(); return generatePostFragment(postType, name); } } @@ -1483,6 +1662,16 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } } + public void setFavoriteMultiReddits(List<MultiReddit> favoriteMultiReddits) { + this.favoriteMultiReddits = favoriteMultiReddits; + notifyDataSetChanged(); + } + + public void setMultiReddits(List<MultiReddit> multiReddits) { + this.multiReddits = multiReddits; + notifyDataSetChanged(); + } + public void setFavoriteSubscribedSubreddits(List<SubscribedSubredditData> favoriteSubscribedSubreddits) { this.favoriteSubscribedSubreddits = favoriteSubscribedSubreddits; notifyDataSetChanged(); @@ -1583,7 +1772,8 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb if (mAccessToken == null) { return 3; } - return tabCount + favoriteSubscribedSubreddits.size() + subscribedSubreddits.size(); + return tabCount + favoriteMultiReddits.size() + multiReddits.size() + + favoriteSubscribedSubreddits.size() + subscribedSubreddits.size(); } @Nullable diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostFilterPreferenceActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostFilterPreferenceActivity.java index e64bf21e..4ed7534d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostFilterPreferenceActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostFilterPreferenceActivity.java @@ -36,6 +36,8 @@ import ml.docilealligator.infinityforreddit.postfilter.PostFilterViewModel; public class PostFilterPreferenceActivity extends BaseActivity { public static final String EXTRA_POST = "EP"; + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + public static final String EXTRA_USER_NAME = "EUN"; @BindView(R.id.coordinator_layout_post_filter_preference_activity) CoordinatorLayout coordinatorLayout; @@ -76,26 +78,36 @@ public class PostFilterPreferenceActivity extends BaseActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); Post post = getIntent().getParcelableExtra(EXTRA_POST); + String subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + String username = getIntent().getStringExtra(EXTRA_USER_NAME); fab.setOnClickListener(view -> { - if (post == null) { + if (post != null) { + showPostFilterOptions(post, null); + } else if (subredditName != null) { + excludeSubredditInFilter(subredditName, null); + } else if (username != null) { + excludeUserInFilter(username, null); + } else { Intent intent = new Intent(PostFilterPreferenceActivity.this, CustomizePostFilterActivity.class); intent.putExtra(CustomizePostFilterActivity.EXTRA_FROM_SETTINGS, true); startActivity(intent); - } else { - showPostFilterOptions(post, null); } }); adapter = new PostFilterRecyclerViewAdapter(postFilter -> { - if (post == null) { + if (post != null) { + showPostFilterOptions(post, postFilter); + } else if (subredditName != null) { + excludeSubredditInFilter(subredditName, postFilter); + } else if (username != null) { + excludeUserInFilter(username, postFilter); + } else { PostFilterOptionsBottomSheetFragment postFilterOptionsBottomSheetFragment = new PostFilterOptionsBottomSheetFragment(); Bundle bundle = new Bundle(); bundle.putParcelable(PostFilterOptionsBottomSheetFragment.EXTRA_POST_FILTER, postFilter); postFilterOptionsBottomSheetFragment.setArguments(bundle); postFilterOptionsBottomSheetFragment.show(getSupportFragmentManager(), postFilterOptionsBottomSheetFragment.getTag()); - } else { - showPostFilterOptions(post, postFilter); } }); @@ -145,6 +157,24 @@ public class PostFilterPreferenceActivity extends BaseActivity { .show(); } + public void excludeSubredditInFilter(String subredditName, PostFilter postFilter) { + Intent intent = new Intent(this, CustomizePostFilterActivity.class); + intent.putExtra(CustomizePostFilterActivity.EXTRA_EXCLUDE_SUBREDDIT, subredditName); + if (postFilter != null) { + intent.putExtra(CustomizePostFilterActivity.EXTRA_POST_FILTER, postFilter); + } + startActivity(intent); + } + + public void excludeUserInFilter(String username, PostFilter postFilter) { + Intent intent = new Intent(this, CustomizePostFilterActivity.class); + intent.putExtra(CustomizePostFilterActivity.EXTRA_EXCLUDE_USER, username); + if (postFilter != null) { + intent.putExtra(CustomizePostFilterActivity.EXTRA_POST_FILTER, postFilter); + } + startActivity(intent); + } + public void editPostFilter(PostFilter postFilter) { Intent intent = new Intent(PostFilterPreferenceActivity.this, CustomizePostFilterActivity.class); intent.putExtra(CustomizePostFilterActivity.EXTRA_POST_FILTER, postFilter); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostGalleryActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostGalleryActivity.java new file mode 100644 index 00000000..8edb4516 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostGalleryActivity.java @@ -0,0 +1,709 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.provider.MediaStore; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.switchmaterial.SwitchMaterial; +import com.google.gson.Gson; +import com.libRG.CustomTextView; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.json.JSONException; +import org.json.JSONObject; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.RedditGalleryPayload; +import ml.docilealligator.infinityforreddit.adapters.RedditGallerySubmissionRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIcon; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SelectOrCaptureImageBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SubmitGalleryPostEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.services.SubmitPostService; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.UploadImageUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class PostGalleryActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { + + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + + private static final String SUBREDDIT_NAME_STATE = "SNS"; + private static final String SUBREDDIT_ICON_STATE = "SIS"; + private static final String SUBREDDIT_SELECTED_STATE = "SSS"; + private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; + private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; + private static final String IS_POSTING_STATE = "IPS"; + private static final String FLAIR_STATE = "FS"; + private static final String IS_SPOILER_STATE = "ISS"; + private static final String IS_NSFW_STATE = "INS"; + private static final String REDDIT_GALLERY_IMAGE_INFO_STATE = "RGIIS"; + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + private static final int PICK_IMAGE_REQUEST_CODE = 1; + private static final int CAPTURE_IMAGE_REQUEST_CODE = 2; + + @BindView(R.id.coordinator_layout_post_gallery_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_post_gallery_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_post_gallery_activity) + Toolbar toolbar; + @BindView(R.id.subreddit_icon_gif_image_view_post_gallery_activity) + GifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_post_gallery_activity) + TextView subredditNameTextView; + @BindView(R.id.rules_button_post_gallery_activity) + MaterialButton rulesButton; + @BindView(R.id.divider_1_post_gallery_activity) + View divider1; + @BindView(R.id.flair_custom_text_view_post_gallery_activity) + CustomTextView flairTextView; + @BindView(R.id.spoiler_custom_text_view_post_gallery_activity) + CustomTextView spoilerTextView; + @BindView(R.id.nsfw_custom_text_view_post_gallery_activity) + CustomTextView nsfwTextView; + @BindView(R.id.divider_2_post_gallery_activity) + View divider2; + @BindView(R.id.receive_post_reply_notifications_linear_layout_post_gallery_activity) + LinearLayout receivePostReplyNotificationsLinearLayout; + @BindView(R.id.receive_post_reply_notifications_text_view_post_gallery_activity) + TextView receivePostReplyNotificationsTextView; + @BindView(R.id.receive_post_reply_notifications_switch_material_post_gallery_activity) + SwitchMaterial receivePostReplyNotificationsSwitchMaterial; + @BindView(R.id.divider_3_post_gallery_activity) + View divider3; + @BindView(R.id.post_title_edit_text_post_gallery_activity) + EditText titleEditText; + @BindView(R.id.divider_4_post_gallery_activity) + View divider4; + @BindView(R.id.images_recycler_view_post_gallery_activity) + RecyclerView imagesRecyclerView; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("upload_media") + Retrofit mUploadMediaRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences mCurrentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + private ArrayList<RedditGallerySubmissionRecyclerViewAdapter.RedditGalleryImageInfo> redditGalleryImageInfoList; + private String mAccessToken; + private String mAccountName; + private String iconUrl; + private String subredditName; + private boolean subredditSelected = false; + private boolean subredditIsUser; + private boolean loadSubredditIconSuccessful = true; + private boolean isPosting; + private int primaryTextColor; + private int flairBackgroundColor; + private int flairTextColor; + private int spoilerBackgroundColor; + private int spoilerTextColor; + private int nsfwBackgroundColor; + private int nsfwTextColor; + private Flair flair; + private boolean isSpoiler = false; + private boolean isNSFW = false; + private Resources resources; + private Menu mMemu; + private RequestManager mGlide; + private FlairBottomSheetFragment flairSelectionBottomSheetFragment; + private Snackbar mPostingSnackbar; + private RedditGallerySubmissionRecyclerViewAdapter adapter; + private Uri imageUri; + private boolean isUploading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_post_gallery); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mGlide = Glide.with(this); + + mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); + + resources = getResources(); + + mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); + mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); + + adapter = new RedditGallerySubmissionRecyclerViewAdapter(this, mCustomThemeWrapper, new RedditGallerySubmissionRecyclerViewAdapter.ItemClickListener() { + @Override + public void onAddImageClicked() { + if (!isUploading) { + SelectOrCaptureImageBottomSheetFragment fragment = new SelectOrCaptureImageBottomSheetFragment(); + fragment.show(getSupportFragmentManager(), fragment.getTag()); + } else { + Snackbar.make(coordinatorLayout, R.string.please_wait_image_is_uploading, Snackbar.LENGTH_SHORT).show(); + } + } + }); + imagesRecyclerView.setAdapter(adapter); + Resources resources = getResources(); + int nColumns = resources.getBoolean(R.bool.isTablet) || resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 3 : 2; + ((GridLayoutManager) imagesRecyclerView.getLayoutManager()).setSpanCount(nColumns); + imagesRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() { + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { + GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams(); + + int spanIndex = layoutParams.getSpanIndex(); + + int offset = (int) (Utils.convertDpToPixel(16, PostGalleryActivity.this)); + int halfOffset = offset / 2; + + if (nColumns == 2) { + if (spanIndex == 0) { + outRect.set(halfOffset, 0, halfOffset, offset); + } else { + outRect.set(halfOffset, 0, halfOffset, offset); + } + } else if (nColumns == 3) { + if (spanIndex == 0) { + outRect.set(halfOffset, 0, halfOffset, offset); + } else if (spanIndex == 1) { + outRect.set(halfOffset, 0, halfOffset, offset); + } else { + outRect.set(halfOffset, 0, halfOffset, offset); + } + } + } + }); + + if (savedInstanceState != null) { + subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); + iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); + subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); + subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); + loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); + isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); + flair = savedInstanceState.getParcelable(FLAIR_STATE); + isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); + isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); + redditGalleryImageInfoList = savedInstanceState.getParcelableArrayList(REDDIT_GALLERY_IMAGE_INFO_STATE); + if (redditGalleryImageInfoList != null && !redditGalleryImageInfoList.isEmpty()) { + if (redditGalleryImageInfoList.get(redditGalleryImageInfoList.size() - 1).payload == null) { + imageUri = Uri.parse(redditGalleryImageInfoList.get(redditGalleryImageInfoList.size() - 1).imageUrlString); + uploadImage(); + } + } + adapter.setRedditGalleryImageInfoList(redditGalleryImageInfoList); + + if (subredditName != null) { + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + if (!loadSubredditIconSuccessful) { + loadSubredditIcon(); + } + } + displaySubredditIcon(); + + if (isPosting) { + mPostingSnackbar.show(); + } + + if (flair != null) { + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + if (isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + } + if (isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + } + } else { + isPosting = false; + + if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { + loadSubredditIconSuccessful = false; + subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + subredditSelected = true; + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + loadSubredditIcon(); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + subredditNameTextView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + rulesButton.setOnClickListener(view -> { + if (subredditName == null) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(this, RulesActivity.class); + if (subredditIsUser) { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); + } + startActivity(intent); + } + }); + + flairTextView.setOnClickListener(view -> { + if (flair == null) { + flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); + flairSelectionBottomSheetFragment.setArguments(bundle); + flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); + } else { + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + }); + + spoilerTextView.setOnClickListener(view -> { + if (!isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + isSpoiler = true; + } else { + spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + spoilerTextView.setTextColor(primaryTextColor); + isSpoiler = false; + } + }); + + nsfwTextView.setOnClickListener(view -> { + if (!isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + isNSFW = true; + } else { + nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + nsfwTextView.setTextColor(primaryTextColor); + isNSFW = false; + } + }); + + receivePostReplyNotificationsLinearLayout.setOnClickListener(view -> { + receivePostReplyNotificationsSwitchMaterial.performClick(); + }); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + subredditNameTextView.setTextColor(secondaryTextColor); + rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); + rulesButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + receivePostReplyNotificationsTextView.setTextColor(primaryTextColor); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + divider3.setBackgroundColor(dividerColor); + divider4.setBackgroundColor(dividerColor); + flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); + flairTextColor = mCustomThemeWrapper.getFlairTextColor(); + spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); + spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); + nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); + nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); + flairTextView.setTextColor(primaryTextColor); + spoilerTextView.setTextColor(primaryTextColor); + nsfwTextView.setTextColor(primaryTextColor); + titleEditText.setTextColor(primaryTextColor); + titleEditText.setHintTextColor(secondaryTextColor); + } + + public void selectImage() { + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, resources.getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); + } + + public void captureImage() { + Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + try { + imageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", + File.createTempFile("temp_img", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); + pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); + startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); + } catch (IOException ex) { + Snackbar.make(coordinatorLayout, R.string.error_creating_temp_file, Snackbar.LENGTH_SHORT).show(); + } catch (ActivityNotFoundException e) { + Snackbar.make(coordinatorLayout, R.string.no_camera_available, Snackbar.LENGTH_SHORT).show(); + } + } + + private void uploadImage() { + Handler handler = new Handler(); + isUploading = true; + mExecutor.execute(() -> { + try { + Bitmap resource = Glide.with(PostGalleryActivity.this).asBitmap().load(imageUri).submit().get(); + String response = UploadImageUtils.uploadImage(mOauthRetrofit, mUploadMediaRetrofit, mAccessToken, resource, true); + String mediaId = new JSONObject(response).getJSONObject(JSONUtils.ASSET_KEY).getString(JSONUtils.ASSET_ID_KEY); + handler.post(() -> { + adapter.setImageAsUploaded(mediaId); + isUploading = false; + }); + } catch (ExecutionException | InterruptedException e) { + e.printStackTrace(); + handler.post(() -> { + adapter.removeFailedToUploadImage(); + Snackbar.make(coordinatorLayout, R.string.get_image_bitmap_failed, Snackbar.LENGTH_LONG).show(); + isUploading = false; + }); + } catch (XmlPullParserException | JSONException | IOException e) { + e.printStackTrace(); + handler.post(() -> { + adapter.removeFailedToUploadImage(); + Snackbar.make(coordinatorLayout, R.string.upload_image_failed, Snackbar.LENGTH_LONG).show(); + isUploading = false; + }); + } + }); + } + + private void displaySubredditIcon() { + if (iconUrl != null && !iconUrl.equals("")) { + mGlide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + private void loadSubredditIcon() { + LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { + iconUrl = iconImageUrl; + displaySubredditIcon(); + loadSubredditIconSuccessful = true; + }); + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.discard_dialog_button, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.post_gallery_activity, menu); + applyMenuItemTheme(menu); + mMemu = menu; + if (isPosting) { + mMemu.findItem(R.id.action_send_post_gallery_activity).setEnabled(false); + mMemu.findItem(R.id.action_send_post_gallery_activity).getIcon().setAlpha(130); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + return true; + } else { + if (!titleEditText.getText().toString().equals("") || redditGalleryImageInfoList != null) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + return true; + } + } + finish(); + return true; + } else if (itemId == R.id.action_send_post_gallery_activity) { + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (redditGalleryImageInfoList == null || redditGalleryImageInfoList.isEmpty()) { + Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (redditGalleryImageInfoList.get(redditGalleryImageInfoList.size() - 1).payload == null) { + Snackbar.make(coordinatorLayout, R.string.please_wait_image_is_uploading, Snackbar.LENGTH_LONG).show(); + return true; + } + + isPosting = true; + + item.setEnabled(false); + item.getIcon().setAlpha(130); + + mPostingSnackbar.show(); + + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } + + Intent intent = new Intent(this, SubmitPostService.class); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_GALLERY); + ArrayList<RedditGalleryPayload.Item> items = new ArrayList<>(); + for (RedditGallerySubmissionRecyclerViewAdapter.RedditGalleryImageInfo i : redditGalleryImageInfoList) { + items.add(i.payload); + } + RedditGalleryPayload payload = new RedditGalleryPayload(subredditName, subredditIsUser ? "profile" : "subreddit", + titleEditText.getText().toString(), isSpoiler, isNSFW, receivePostReplyNotificationsSwitchMaterial.isChecked(), + flair, items); + intent.putExtra(SubmitPostService.EXTRA_REDDIT_GALLERY_PAYLOAD, new Gson().toJson(payload)); + + ContextCompat.startForegroundService(this, intent); + + return true; + } + + return false; + } + + @Override + public void onBackPressed() { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + } else { + if (!titleEditText.getText().toString().equals("") || redditGalleryImageInfoList != null) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } else { + finish(); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(SUBREDDIT_NAME_STATE, subredditName); + outState.putString(SUBREDDIT_ICON_STATE, iconUrl); + outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); + outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); + outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); + outState.putBoolean(IS_POSTING_STATE, isPosting); + outState.putParcelable(FLAIR_STATE, flair); + outState.putBoolean(IS_SPOILER_STATE, isSpoiler); + outState.putBoolean(IS_NSFW_STATE, isNSFW); + redditGalleryImageInfoList = adapter.getRedditGalleryImageInfoList(); + outState.putParcelableArrayList(REDDIT_GALLERY_IMAGE_INFO_STATE, redditGalleryImageInfoList); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); + iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + subredditSelected = true; + subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); + + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + displaySubredditIcon(); + + flairTextView.setVisibility(View.VISIBLE); + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + } else if (requestCode == PICK_IMAGE_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + if (data == null) { + Snackbar.make(coordinatorLayout, R.string.error_getting_image, Snackbar.LENGTH_SHORT).show(); + return; + } + + imageUri = data.getData(); + adapter.addImage(imageUri.toString()); + uploadImage(); + } + } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + adapter.addImage(imageUri.toString()); + uploadImage(); + } + } + } + + @Override + protected void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + } + + @Override + public void flairSelected(Flair flair) { + this.flair = flair; + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onSubmitGalleryPostEvent(SubmitGalleryPostEvent submitGalleryPostEvent) { + isPosting = false; + mPostingSnackbar.dismiss(); + if (submitGalleryPostEvent.postSuccess) { + Intent intent = new Intent(this, LinkResolverActivity.class); + intent.setData(Uri.parse(submitGalleryPostEvent.postUrl)); + startActivity(intent); + finish(); + } else { + mMemu.findItem(R.id.action_send_post_gallery_activity).setEnabled(true); + mMemu.findItem(R.id.action_send_post_gallery_activity).getIcon().setAlpha(255); + if (submitGalleryPostEvent.errorMessage == null || submitGalleryPostEvent.errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, submitGalleryPostEvent.errorMessage.substring(0, 1).toUpperCase() + + submitGalleryPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); + } + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java index cbab1914..acf5034d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java @@ -1,8 +1,8 @@ package ml.docilealligator.infinityforreddit.activities; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.ColorStateList; import android.content.res.Resources; import android.net.Uri; import android.os.Build; @@ -13,9 +13,9 @@ import android.provider.MediaStore; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; @@ -30,9 +30,11 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.RequestManager; import com.bumptech.glide.request.RequestOptions; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.button.MaterialButton; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.switchmaterial.SwitchMaterial; import com.libRG.CustomTextView; import org.greenrobot.eventbus.EventBus; @@ -93,7 +95,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF @BindView(R.id.subreddit_name_text_view_post_image_activity) TextView subredditNameTextView; @BindView(R.id.rules_button_post_image_activity) - Button rulesButton; + MaterialButton rulesButton; @BindView(R.id.divider_1_post_image_activity) View divider1; @BindView(R.id.flair_custom_text_view_post_image_activity) @@ -104,10 +106,18 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF CustomTextView nsfwTextView; @BindView(R.id.divider_2_post_image_activity) View divider2; - @BindView(R.id.post_title_edit_text_post_image_activity) - EditText titleEditText; + @BindView(R.id.receive_post_reply_notifications_linear_layout_post_image_activity) + LinearLayout receivePostReplyNotificationsLinearLayout; + @BindView(R.id.receive_post_reply_notifications_text_view_post_image_activity) + TextView receivePostReplyNotificationsTextView; + @BindView(R.id.receive_post_reply_notifications_switch_material_post_image_activity) + SwitchMaterial receivePostReplyNotificationsSwitchMaterial; @BindView(R.id.divider_3_post_image_activity) View divider3; + @BindView(R.id.post_title_edit_text_post_image_activity) + EditText titleEditText; + @BindView(R.id.divider_4_post_image_activity) + View divider4; @BindView(R.id.select_image_constraint_layout_post_image_activity) ConstraintLayout constraintLayout; @BindView(R.id.capture_fab_post_image_activity) @@ -331,18 +341,20 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF } }); + receivePostReplyNotificationsLinearLayout.setOnClickListener(view -> { + receivePostReplyNotificationsSwitchMaterial.performClick(); + }); + captureFab.setOnClickListener(view -> { Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - if (pictureIntent.resolveActivity(getPackageManager()) != null) { - try { - imageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", - File.createTempFile("temp_img", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); - pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); - startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); - } catch (IOException ex) { - Snackbar.make(coordinatorLayout, R.string.error_creating_temp_file, Snackbar.LENGTH_SHORT).show(); - } - } else { + try { + imageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", + File.createTempFile("temp_img", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); + pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); + startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); + } catch (IOException ex) { + Snackbar.make(coordinatorLayout, R.string.error_creating_temp_file, Snackbar.LENGTH_SHORT).show(); + } catch (ActivityNotFoundException e) { Snackbar.make(coordinatorLayout, R.string.no_camera_available, Snackbar.LENGTH_SHORT).show(); } }); @@ -380,12 +392,14 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); subredditNameTextView.setTextColor(secondaryTextColor); rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + rulesButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + receivePostReplyNotificationsTextView.setTextColor(primaryTextColor); int dividerColor = mCustomThemeWrapper.getDividerColor(); divider1.setBackgroundColor(dividerColor); divider2.setBackgroundColor(dividerColor); divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + divider4.setBackgroundColor(dividerColor); flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); flairTextColor = mCustomThemeWrapper.getFlairTextColor(); spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); @@ -435,7 +449,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(titleResId) .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) + .setPositiveButton(R.string.discard_dialog_button, (dialogInterface, i) -> finish()) .setNegativeButton(R.string.no, null) .show(); @@ -455,68 +469,69 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - return true; - } else { - if (!titleEditText.getText().toString().equals("") || imageUri != null) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - return true; - } - } - finish(); + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); return true; - case R.id.action_send_post_image_activity: - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + } else { + if (!titleEditText.getText().toString().equals("") || imageUri != null) { + promptAlertDialog(R.string.discard, R.string.discard_detail); return true; } + } + finish(); + return true; + } else if (itemId == R.id.action_send_post_image_activity) { + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); - return true; - } + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } - if (imageUri == null) { - Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); - return true; - } + if (imageUri == null) { + Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); + return true; + } - isPosting = true; + isPosting = true; - item.setEnabled(false); - item.getIcon().setAlpha(130); + item.setEnabled(false); + item.getIcon().setAlpha(130); - mPostingSnackbar.show(); + mPostingSnackbar.show(); - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } - Intent intent = new Intent(this, SubmitPostService.class); - intent.setData(imageUri); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - String mimeType = getContentResolver().getType(imageUri); - if (mimeType != null && mimeType.contains("gif")) { - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_VIDEO); - } else { - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_IMAGE); - } - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + Intent intent = new Intent(this, SubmitPostService.class); + intent.setData(imageUri); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_RECEIVE_POST_REPLY_NOTIFICATIONS, receivePostReplyNotificationsSwitchMaterial.isChecked()); + String mimeType = getContentResolver().getType(imageUri); + if (mimeType != null && mimeType.contains("gif")) { + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_VIDEO); + } else { + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_IMAGE); + } + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - ContextCompat.startForegroundService(this, intent); + ContextCompat.startForegroundService(this, intent); - return true; + return true; } return false; @@ -631,7 +646,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF } @Subscribe - public void onSubmitVideoOrGifPostEvent(SubmitVideoOrGifPostEvent submitVideoOrGifPostEvent) { + public void onSubmitGifPostEvent(SubmitVideoOrGifPostEvent submitVideoOrGifPostEvent) { isPosting = false; mPostingSnackbar.dismiss(); mMemu.findItem(R.id.action_send_post_image_activity).setEnabled(true); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostLinkActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostLinkActivity.java index ab1852bc..8ce97d55 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostLinkActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostLinkActivity.java @@ -2,7 +2,6 @@ package ml.docilealligator.infinityforreddit.activities; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.ColorStateList; import android.content.res.Resources; import android.os.Build; import android.os.Bundle; @@ -10,8 +9,8 @@ import android.os.Handler; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.Button; import android.widget.EditText; +import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -28,6 +27,7 @@ import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.button.MaterialButton; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.switchmaterial.SwitchMaterial; import com.libRG.CustomTextView; import org.greenrobot.eventbus.EventBus; @@ -89,19 +89,27 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr @BindView(R.id.subreddit_name_text_view_post_link_activity) TextView subredditNameTextView; @BindView(R.id.rules_button_post_link_activity) - Button rulesButton; + MaterialButton rulesButton; @BindView(R.id.divider_1_post_link_activity) View divider1; @BindView(R.id.divider_2_post_link_activity) View divider2; - @BindView(R.id.divider_3_post_link_activity) - View divider3; + @BindView(R.id.divider_4_post_link_activity) + View divider4; @BindView(R.id.flair_custom_text_view_post_link_activity) CustomTextView flairTextView; @BindView(R.id.spoiler_custom_text_view_post_link_activity) CustomTextView spoilerTextView; @BindView(R.id.nsfw_custom_text_view_post_link_activity) CustomTextView nsfwTextView; + @BindView(R.id.receive_post_reply_notifications_linear_layout_post_link_activity) + LinearLayout receivePostReplyNotificationsLinearLayout; + @BindView(R.id.receive_post_reply_notifications_text_view_post_link_activity) + TextView receivePostReplyNotificationsTextView; + @BindView(R.id.receive_post_reply_notifications_switch_material_post_link_activity) + SwitchMaterial receivePostReplyNotificationsSwitchMaterial; + @BindView(R.id.divider_3_post_link_activity) + View divider3; @BindView(R.id.post_title_edit_text_post_link_activity) EditText titleEditText; @BindView(R.id.suggest_title_button_post_link_activity) @@ -310,6 +318,10 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr } }); + receivePostReplyNotificationsLinearLayout.setOnClickListener(view -> { + receivePostReplyNotificationsSwitchMaterial.performClick(); + }); + suggestTitleButton.setOnClickListener(view -> { Toast.makeText(this, R.string.please_wait, Toast.LENGTH_SHORT).show(); String url = linkEditText.getText().toString().trim(); @@ -354,12 +366,14 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); subredditNameTextView.setTextColor(secondaryTextColor); rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + rulesButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + receivePostReplyNotificationsTextView.setTextColor(primaryTextColor); int dividerColor = mCustomThemeWrapper.getDividerColor(); divider1.setBackgroundColor(dividerColor); divider2.setBackgroundColor(dividerColor); divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + divider4.setBackgroundColor(dividerColor); flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); flairTextColor = mCustomThemeWrapper.getFlairTextColor(); spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); @@ -404,7 +418,7 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(titleResId) .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> finish()) + .setPositiveButton(R.string.discard_dialog_button, (dialogInterface, i) -> finish()) .setNegativeButton(R.string.no, null) .show(); } @@ -475,6 +489,7 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_RECEIVE_POST_REPLY_NOTIFICATIONS, receivePostReplyNotificationsSwitchMaterial.isChecked()); intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TEXT_OR_LINK); ContextCompat.startForegroundService(this, intent); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java index 7d93fef7..a03f7355 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java @@ -1,24 +1,29 @@ package ml.docilealligator.infinityforreddit.activities; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.ColorStateList; import android.content.res.Resources; +import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.os.Handler; +import android.provider.MediaStore; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.Button; import android.widget.EditText; +import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -26,13 +31,18 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.RequestManager; import com.bumptech.glide.request.RequestOptions; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.button.MaterialButton; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.switchmaterial.SwitchMaterial; import com.libRG.CustomTextView; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; import java.util.concurrent.Executor; import javax.inject.Inject; @@ -45,19 +55,25 @@ import ml.docilealligator.infinityforreddit.Flair; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.UploadImageEnabledActivity; +import ml.docilealligator.infinityforreddit.UploadedImage; import ml.docilealligator.infinityforreddit.adapters.MarkdownBottomBarRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIcon; import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UploadedImagesBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.SubmitTextOrLinkPostEvent; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.services.SubmitPostService; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; import pl.droidsonroids.gif.GifImageView; import retrofit2.Retrofit; -public class PostTextActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { +public class PostTextActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback, + UploadImageEnabledActivity { static final String EXTRA_SUBREDDIT_NAME = "ESN"; static final String EXTRA_CONTENT = "EC"; @@ -71,8 +87,12 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr private static final String FLAIR_STATE = "FS"; private static final String IS_SPOILER_STATE = "ISS"; private static final String IS_NSFW_STATE = "INS"; + private static final String UPLOADED_IMAGES_STATE = "UIS"; private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + private static final int PICK_IMAGE_REQUEST_CODE = 100; + private static final int CAPTURE_IMAGE_REQUEST_CODE = 200; + private static final int MARKDOWN_PREVIEW_REQUEST_CODE = 300; @BindView(R.id.coordinator_layout_post_text_activity) CoordinatorLayout coordinatorLayout; @@ -80,12 +100,12 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr AppBarLayout appBarLayout; @BindView(R.id.toolbar_post_text_activity) Toolbar toolbar; - @BindView(R.id.subreddit_icon_gif_image_view_search_activity) + @BindView(R.id.subreddit_icon_gif_image_view_post_text_activity) GifImageView iconGifImageView; - @BindView(R.id.subreddit_name_text_view_search_activity) + @BindView(R.id.subreddit_name_text_view_post_text_activity) TextView subredditNameTextView; @BindView(R.id.rules_button_post_text_activity) - Button rulesButton; + MaterialButton rulesButton; @BindView(R.id.divider_1_post_text_activity) View divider1; @BindView(R.id.flair_custom_text_view_post_text_activity) @@ -96,10 +116,18 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr CustomTextView nsfwTextView; @BindView(R.id.divider_2_post_text_activity) View divider2; - @BindView(R.id.post_title_edit_text_post_text_activity) - EditText titleEditText; + @BindView(R.id.receive_post_reply_notifications_linear_layout_post_text_activity) + LinearLayout receivePostReplyNotificationsLinearLayout; + @BindView(R.id.receive_post_reply_notifications_text_view_post_text_activity) + TextView receivePostReplyNotificationsTextView; + @BindView(R.id.receive_post_reply_notifications_switch_material_post_text_activity) + SwitchMaterial receivePostReplyNotificationsSwitchMaterial; @BindView(R.id.divider_3_post_text_activity) View divider3; + @BindView(R.id.post_title_edit_text_post_text_activity) + EditText titleEditText; + @BindView(R.id.divider_4_post_text_activity) + View divider4; @BindView(R.id.post_text_content_edit_text_post_text_activity) EditText contentEditText; @BindView(R.id.markdown_bottom_bar_recycler_view_post_text_activity) @@ -111,6 +139,9 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr @Named("oauth") Retrofit mOauthRetrofit; @Inject + @Named("upload_media") + Retrofit mUploadMediaRetrofit; + @Inject RedditDataRoomDatabase mRedditDataRoomDatabase; @Inject @Named("default") @@ -144,6 +175,8 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr private RequestManager mGlide; private FlairBottomSheetFragment flairSelectionBottomSheetFragment; private Snackbar mPostingSnackbar; + private Uri capturedImageUri; + private ArrayList<UploadedImage> uploadedImages = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -186,6 +219,7 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr flair = savedInstanceState.getParcelable(FLAIR_STATE); isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); + uploadedImages = savedInstanceState.getParcelableArrayList(UPLOADED_IMAGES_STATE); if (subredditName != null) { subredditNameTextView.setTextColor(primaryTextColor); @@ -310,11 +344,31 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr } }); - MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); + receivePostReplyNotificationsLinearLayout.setOnClickListener(view -> { + receivePostReplyNotificationsSwitchMaterial.performClick(); + }); + + MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( + mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { + @Override + public void onClick(int item) { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( + PostTextActivity.this, contentEditText, item); + } + + @Override + public void onUploadImage() { + Utils.hideKeyboard(PostTextActivity.this); + UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); + Bundle arguments = new Bundle(); + arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, + uploadedImages); + fragment.setArguments(arguments); + fragment.show(getSupportFragmentManager(), fragment.getTag()); + } }); - markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, + markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, LinearLayoutManager.HORIZONTAL, false)); markdownBottomBarRecyclerView.setAdapter(adapter); } @@ -336,12 +390,14 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); subredditNameTextView.setTextColor(secondaryTextColor); rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + rulesButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + receivePostReplyNotificationsTextView.setTextColor(primaryTextColor); int dividerColor = mCustomThemeWrapper.getDividerColor(); divider1.setBackgroundColor(dividerColor); divider2.setBackgroundColor(dividerColor); divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + divider4.setBackgroundColor(dividerColor); flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); flairTextColor = mCustomThemeWrapper.getFlairTextColor(); spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); @@ -384,9 +440,9 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(titleResId) .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) + .setPositiveButton(R.string.discard_dialog_button, (dialogInterface, i) -> finish()) - .setNegativeButton(R.string.no, null) + .setNegativeButton(R.string.cancel, null) .show(); } @@ -420,48 +476,55 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr } else if (itemId == R.id.action_preview_post_text_activity) { Intent intent = new Intent(this, FullMarkdownActivity.class); intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); - startActivity(intent); + intent.putExtra(FullMarkdownActivity.EXTRA_SUBMIT_POST, true); + startActivityForResult(intent, MARKDOWN_PREVIEW_REQUEST_CODE); } else if (itemId == R.id.action_send_post_text_activity) { - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - return true; - } + submitPost(item); + return true; + } - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); - return true; - } + return false; + } - isPosting = true; + private void submitPost(MenuItem item) { + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return; + } - item.setEnabled(false); - item.getIcon().setAlpha(130); + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return; + } - mPostingSnackbar.show(); + isPosting = true; - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } + if (item != null) { + item.setEnabled(false); + item.getIcon().setAlpha(130); + } - Intent intent = new Intent(this, SubmitPostService.class); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_CONTENT, contentEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_SELF); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TEXT_OR_LINK); - ContextCompat.startForegroundService(this, intent); + mPostingSnackbar.show(); - return true; + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); } - return false; + Intent intent = new Intent(this, SubmitPostService.class); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_CONTENT, contentEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_SELF); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_RECEIVE_POST_REPLY_NOTIFICATIONS, receivePostReplyNotificationsSwitchMaterial.isChecked()); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TEXT_OR_LINK); + ContextCompat.startForegroundService(this, intent); } @Override @@ -489,13 +552,14 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr outState.putParcelable(FLAIR_STATE, flair); outState.putBoolean(IS_SPOILER_STATE, isSpoiler); outState.putBoolean(IS_NSFW_STATE, isNSFW); + outState.putParcelableArrayList(UPLOADED_IMAGES_STATE, uploadedImages); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { - if (resultCode == RESULT_OK) { + if (resultCode == RESULT_OK) { + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); subredditSelected = true; @@ -510,8 +574,22 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr flairTextView.setTextColor(primaryTextColor); flairTextView.setText(getString(R.string.flair)); flair = null; + + } else if (requestCode == PICK_IMAGE_REQUEST_CODE) { + if (data == null) { + Toast.makeText(PostTextActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show(); + return; + } + Utils.uploadImageToReddit(this, mExecutor, mOauthRetrofit, mUploadMediaRetrofit, + mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages); + } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { + Utils.uploadImageToReddit(this, mExecutor, mOauthRetrofit, mUploadMediaRetrofit, + mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages); + } else if (requestCode == MARKDOWN_PREVIEW_REQUEST_CODE) { + submitPost(mMenu.findItem(R.id.action_send_post_text_activity)); } } + } @Override @@ -554,4 +632,37 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr } } } + + @Override + public void uploadImage() { + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, + getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); + } + + @Override + public void captureImage() { + Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + try { + capturedImageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", + File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); + pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri); + startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); + } catch (IOException ex) { + Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show(); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void insertImageUrl(UploadedImage uploadedImage) { + int start = Math.max(contentEditText.getSelectionStart(), 0); + int end = Math.max(contentEditText.getSelectionEnd(), 0); + contentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")", + 0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostVideoActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostVideoActivity.java index 420477ff..109d10d3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostVideoActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostVideoActivity.java @@ -2,7 +2,6 @@ package ml.docilealligator.infinityforreddit.activities; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.ColorStateList; import android.content.res.Resources; import android.net.Uri; import android.os.Build; @@ -12,8 +11,8 @@ import android.provider.MediaStore; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.Button; import android.widget.EditText; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; @@ -35,9 +34,11 @@ import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.util.Util; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.button.MaterialButton; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.switchmaterial.SwitchMaterial; import com.libRG.CustomTextView; import org.greenrobot.eventbus.EventBus; @@ -95,7 +96,7 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF @BindView(R.id.subreddit_name_text_view_post_video_activity) TextView subredditNameTextView; @BindView(R.id.rules_button_post_video_activity) - Button rulesButton; + MaterialButton rulesButton; @BindView(R.id.divider_1_post_video_activity) View divider1; @BindView(R.id.flair_custom_text_view_post_video_activity) @@ -106,10 +107,18 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF CustomTextView nsfwTextView; @BindView(R.id.divider_2_post_video_activity) View divider2; - @BindView(R.id.post_title_edit_text_post_video_activity) - EditText titleEditText; + @BindView(R.id.receive_post_reply_notifications_linear_layout_post_video_activity) + LinearLayout receivePostReplyNotificationsLinearLayout; + @BindView(R.id.receive_post_reply_notifications_text_view_post_video_activity) + TextView receivePostReplyNotificationsTextView; + @BindView(R.id.receive_post_reply_notifications_switch_material_post_video_activity) + SwitchMaterial receivePostReplyNotificationsSwitchMaterial; @BindView(R.id.divider_3_post_video_activity) View divider3; + @BindView(R.id.post_title_edit_text_post_video_activity) + EditText titleEditText; + @BindView(R.id.divider_4_post_video_activity) + View divider4; @BindView(R.id.select_video_constraint_layout_post_video_activity) ConstraintLayout constraintLayout; @BindView(R.id.capture_fab_post_video_activity) @@ -345,6 +354,10 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF } }); + receivePostReplyNotificationsLinearLayout.setOnClickListener(view -> { + receivePostReplyNotificationsSwitchMaterial.performClick(); + }); + captureFab.setOnClickListener(view -> { Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); if (takeVideoIntent.resolveActivity(getPackageManager()) != null) { @@ -386,12 +399,14 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); subredditNameTextView.setTextColor(secondaryTextColor); rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + rulesButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + receivePostReplyNotificationsTextView.setTextColor(primaryTextColor); int dividerColor = mCustomThemeWrapper.getDividerColor(); divider1.setBackgroundColor(dividerColor); divider2.setBackgroundColor(dividerColor); divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + divider4.setBackgroundColor(dividerColor); flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); flairTextColor = mCustomThemeWrapper.getFlairTextColor(); spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); @@ -444,7 +459,7 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(titleResId) .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> finish()) + .setPositiveButton(R.string.discard_dialog_button, (dialogInterface, i) -> finish()) .setNegativeButton(R.string.no, null) .show(); } @@ -463,63 +478,64 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - return true; - } else { - if (!titleEditText.getText().toString().equals("") || videoUri != null) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - return true; - } - } - finish(); + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); return true; - case R.id.action_send_post_video_activity: - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (videoUri == null) { - Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); + } else { + if (!titleEditText.getText().toString().equals("") || videoUri != null) { + promptAlertDialog(R.string.discard, R.string.discard_detail); return true; } + } + finish(); + return true; + } else if (itemId == R.id.action_send_post_video_activity) { + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } - isPosting = true; + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } - item.setEnabled(false); - item.getIcon().setAlpha(130); + if (videoUri == null) { + Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); + return true; + } - mPostingSnackbar.show(); + isPosting = true; - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } + item.setEnabled(false); + item.getIcon().setAlpha(130); - Intent intent = new Intent(this, SubmitPostService.class); - intent.setData(videoUri); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_VIDEO); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + mPostingSnackbar.show(); - ContextCompat.startForegroundService(this, intent); + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } - return true; + Intent intent = new Intent(this, SubmitPostService.class); + intent.setData(videoUri); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_RECEIVE_POST_REPLY_NOTIFICATIONS, receivePostReplyNotificationsSwitchMaterial.isChecked()); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_VIDEO); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + ContextCompat.startForegroundService(this, intent); + + return true; } return false; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RPANActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RPANActivity.java new file mode 100644 index 00000000..d99511ac --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RPANActivity.java @@ -0,0 +1,412 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.media.AudioManager; +import android.os.Bundle; +import android.os.Handler; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import com.evernote.android.state.State; +import com.google.android.material.snackbar.Snackbar; +import com.livefront.bridge.Bridge; + +import org.greenrobot.eventbus.EventBus; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RPANBroadcast; +import ml.docilealligator.infinityforreddit.apis.Strapi; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.font.ContentFontFamily; +import ml.docilealligator.infinityforreddit.font.ContentFontStyle; +import ml.docilealligator.infinityforreddit.font.FontFamily; +import ml.docilealligator.infinityforreddit.font.FontStyle; +import ml.docilealligator.infinityforreddit.font.TitleFontFamily; +import ml.docilealligator.infinityforreddit.font.TitleFontStyle; +import ml.docilealligator.infinityforreddit.fragments.ViewRPANBroadcastFragment; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class RPANActivity extends AppCompatActivity { + + public static final String EXTRA_RPAN_BROADCAST_FULLNAME_OR_ID = "ERBFOI"; + + @BindView(R.id.coordinator_layout_rpan_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.view_pager_2_rpan_activity) + ViewPager2 viewPager2; + @BindView(R.id.progress_bar_rpan_activity) + ProgressBar progressBar; + @Inject + @Named("strapi") + Retrofit strapiRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + @State + ArrayList<RPANBroadcast> rpanBroadcasts; + @State + String nextCursor; + private SectionsPagerAdapter sectionsPagerAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + getTheme().applyStyle(R.style.Theme_Normal, true); + + getTheme().applyStyle(FontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(TitleFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(ContentFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(FontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(TitleFontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); + + setContentView(R.layout.activity_rpanactivity); + + setVolumeControlStream(AudioManager.STREAM_MUSIC); + + Bridge.restoreInstanceState(this, savedInstanceState); + + ButterKnife.bind(this); + + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00000000"))); + + if (rpanBroadcasts == null) { + loadRPANVideos(); + } else { + initializeViewPager(); + } + } + + private void loadRPANVideos() { + String rpanBroadcastFullNameOrId = getIntent().getStringExtra(EXTRA_RPAN_BROADCAST_FULLNAME_OR_ID); + if (rpanBroadcastFullNameOrId == null) { + strapiRetrofit.create(Strapi.class).getAllBroadcasts().enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + progressBar.setVisibility(View.GONE); + if (response.isSuccessful()) { + parseRPANBroadcasts(response.body()); + } else { + try { + ResponseBody responseBody = response.errorBody(); + if (responseBody != null) { + JSONObject errorObject = new JSONObject(responseBody.string()); + String errorMessage = errorObject.getString(JSONUtils.DATA_KEY); + if (!errorMessage.isEmpty() && !errorMessage.equals("null")) { + Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show(); + } else { + Toast.makeText(RPANActivity.this, + R.string.load_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(RPANActivity.this, + R.string.load_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show(); + } + } catch (IOException | JSONException e) { + e.printStackTrace(); + Toast.makeText(RPANActivity.this, + R.string.load_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show(); + } + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + progressBar.setVisibility(View.GONE); + Toast.makeText(RPANActivity.this, + R.string.load_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show(); + } + }); + } else { + strapiRetrofit.create(Strapi.class).getRPANBroadcast(rpanBroadcastFullNameOrId).enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + progressBar.setVisibility(View.GONE); + if (response.isSuccessful()) { + Handler handler = new Handler(); + mExecutor.execute(() -> { + try { + rpanBroadcasts = new ArrayList<>(); + rpanBroadcasts.add(parseSingleRPANBroadcast(new JSONObject(response.body()).getJSONObject(JSONUtils.DATA_KEY))); + handler.post(() -> initializeViewPager()); + } catch (JSONException e) { + e.printStackTrace(); + handler.post(() -> Toast.makeText(RPANActivity.this, + R.string.parse_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show()); + } + }); + } else { + try { + ResponseBody responseBody = response.errorBody(); + if (responseBody != null) { + JSONObject errorObject = new JSONObject(responseBody.string()); + String errorMessage = errorObject.getString(JSONUtils.DATA_KEY); + if (!errorMessage.isEmpty() && !errorMessage.equals("null")) { + Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show(); + } else { + Toast.makeText(RPANActivity.this, + R.string.load_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(RPANActivity.this, + R.string.load_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show(); + } + } catch (IOException | JSONException e) { + e.printStackTrace(); + Toast.makeText(RPANActivity.this, + R.string.load_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show(); + } + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + progressBar.setVisibility(View.GONE); + Toast.makeText(RPANActivity.this, + R.string.load_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + private void parseRPANBroadcasts(String response) { + Handler handler = new Handler(); + mExecutor.execute(() -> { + try { + ArrayList<RPANBroadcast> rpanBroadcasts = new ArrayList<>(); + JSONObject responseObject = new JSONObject(response); + String nextCursor = responseObject.getString(JSONUtils.NEXT_CURSOR_KEY); + + JSONArray dataArray = responseObject.getJSONArray(JSONUtils.DATA_KEY); + for (int i = 0; i < dataArray.length(); i++) { + try { + JSONObject singleData = dataArray.getJSONObject(i); + rpanBroadcasts.add(parseSingleRPANBroadcast(singleData)); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + handler.post(() -> { + RPANActivity.this.rpanBroadcasts = rpanBroadcasts; + RPANActivity.this.nextCursor = nextCursor; + + initializeViewPager(); + }); + } catch (JSONException e) { + e.printStackTrace(); + handler.post(() -> Toast.makeText(RPANActivity.this, + R.string.parse_rpan_broadcasts_failed, Toast.LENGTH_SHORT).show()); + } + }); + } + + private RPANBroadcast parseSingleRPANBroadcast(JSONObject singleData) throws JSONException { + JSONObject rpanPostObject = singleData.getJSONObject(JSONUtils.POST_KEY); + RPANBroadcast.RPANPost rpanPost = new RPANBroadcast.RPANPost( + rpanPostObject.getString(JSONUtils.ID_KEY), + rpanPostObject.getString(JSONUtils.TITLE_KEY), + rpanPostObject.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.NAME_KEY), + rpanPostObject.getJSONObject(JSONUtils.SUBREDDIT_KEY).getJSONObject(JSONUtils.STYLES_KEY).getString(JSONUtils.ICON_KEY), + rpanPostObject.getJSONObject(JSONUtils.AUTHOR_INFO_KEY).getString(JSONUtils.NAME_KEY), + rpanPostObject.getInt(JSONUtils.SCORE_KEY), + rpanPostObject.getString(JSONUtils.VOTE_STATE_KEY), + rpanPostObject.getDouble(JSONUtils.UPVOTE_RATIO_CAMEL_CASE_KEY), + rpanPostObject.getString(JSONUtils.PERMALINK_KEY), + rpanPostObject.getJSONObject(JSONUtils.OUTBOUND_LINK_KEY).getString(JSONUtils.URL_KEY), + rpanPostObject.getBoolean(JSONUtils.IS_NSFW_KEY), + rpanPostObject.getBoolean(JSONUtils.IS_LOCKED_KEY), + rpanPostObject.getBoolean(JSONUtils.IS_ARCHIVED_KEY), + rpanPostObject.getBoolean(JSONUtils.IS_SPOILER), + rpanPostObject.getString(JSONUtils.SUGGESTED_COMMENT_SORT_CAMEL_CASE_KEY), + rpanPostObject.getString(JSONUtils.LIVE_COMMENTS_WEBSOCKET_KEY) + ); + + JSONObject rpanStreamObject = singleData.getJSONObject(JSONUtils.STREAM_KEY); + RPANBroadcast.RPANStream rpanStream = new RPANBroadcast.RPANStream( + rpanStreamObject.getString(JSONUtils.STREAM_ID_KEY), + rpanStreamObject.getString(JSONUtils.HLS_URL_KEY), + rpanStreamObject.getString(JSONUtils.THUMBNAIL_KEY), + rpanStreamObject.getInt(JSONUtils.WIDTH_KEY), + rpanStreamObject.getInt(JSONUtils.HEIGHT_KEY), + rpanStreamObject.getLong(JSONUtils.PUBLISH_AT_KEY), + rpanStreamObject.getString(JSONUtils.STATE_KEY) + ); + + return new RPANBroadcast( + singleData.getInt(JSONUtils.UPVOTES_KEY), + singleData.getInt(JSONUtils.DOWNVOTES_KEY), + singleData.getInt(JSONUtils.UNIQUE_WATCHERS_KEY), + singleData.getInt(JSONUtils.CONTINUOUS_WATCHERS_KEY), + singleData.getInt(JSONUtils.TOTAL_CONTINUOUS_WATCHERS_KEY), + singleData.getBoolean(JSONUtils.CHAT_DISABLED_KEY), + singleData.getDouble(JSONUtils.BROADCAST_TIME_KEY), + singleData.getDouble(JSONUtils.ESTIMATED_REMAINING_TIME_KEY), + rpanPost, + rpanStream + ); + } + + private void initializeViewPager() { + sectionsPagerAdapter = new SectionsPagerAdapter(this); + viewPager2.setAdapter(sectionsPagerAdapter); + viewPager2.setOffscreenPageLimit(3); + fixViewPager2Sensitivity(viewPager2); + } + + private void fixViewPager2Sensitivity(ViewPager2 viewPager2) { + try { + Field recyclerViewField = ViewPager2.class.getDeclaredField("mRecyclerView"); + recyclerViewField.setAccessible(true); + + RecyclerView recyclerView = (RecyclerView) recyclerViewField.get(viewPager2); + + Field touchSlopField = RecyclerView.class.getDeclaredField("mTouchSlop"); + touchSlopField.setAccessible(true); + + Object touchSlopBox = touchSlopField.get(recyclerView); + if (touchSlopBox != null) { + int touchSlop = (int) touchSlopBox; + touchSlopField.set(recyclerView, touchSlop * 4); + } + } catch (NoSuchFieldException | IllegalAccessException ignore) {} + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.rpan_activity, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } else if (item.getItemId() == R.id.action_share_rpan_link_rpan_activity) { + if (rpanBroadcasts != null) { + int position = viewPager2.getCurrentItem(); + if (position >= 0 && position < rpanBroadcasts.size()) { + shareLink(rpanBroadcasts.get(position).rpanPost.rpanUrl); + return true; + } + } + } else if (item.getItemId() == R.id.action_share_post_link_rpan_activity) { + if (rpanBroadcasts != null) { + int position = viewPager2.getCurrentItem(); + if (position >= 0 && position < rpanBroadcasts.size()) { + shareLink(rpanBroadcasts.get(position).rpanPost.postPermalink); + return true; + } + } + } + return false; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + private void shareLink(String link) { + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, link); + startActivity(Intent.createChooser(intent, getString(R.string.share))); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.no_activity_found_for_share, Toast.LENGTH_SHORT).show(); + } + } + + private class SectionsPagerAdapter extends FragmentStateAdapter { + + public SectionsPagerAdapter(FragmentActivity fa) { + super(fa); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + ViewRPANBroadcastFragment fragment = new ViewRPANBroadcastFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelable(ViewRPANBroadcastFragment.EXTRA_RPAN_BROADCAST, rpanBroadcasts.get(position)); + fragment.setArguments(bundle); + return fragment; + } + + @Nullable + private Fragment getCurrentFragment() { + if (viewPager2 == null || getSupportFragmentManager() == null) { + return null; + } + return getSupportFragmentManager().findFragmentByTag("f" + viewPager2.getCurrentItem()); + } + + @Override + public int getItemCount() { + return rpanBroadcasts == null ? 0 : rpanBroadcasts.size(); + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ReportActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ReportActivity.java index 0c88bcb4..4b8f9b38 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ReportActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ReportActivity.java @@ -3,6 +3,7 @@ package ml.docilealligator.infinityforreddit.activities; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; @@ -10,7 +11,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; @@ -18,6 +18,7 @@ import com.google.android.material.snackbar.Snackbar; import com.r0adkll.slidr.Slidr; import java.util.ArrayList; +import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; @@ -67,6 +68,8 @@ public class ReportActivity extends BaseActivity { RedditDataRoomDatabase mRedditDataRoomDatabase; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; private String mAccessToken; private String mFullname; private String mSubredditName; @@ -113,11 +116,10 @@ public class ReportActivity extends BaseActivity { } else { mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, ReportReason.getGeneralReasons(this)); } - recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(mAdapter); if (rulesReasons == null) { - FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + FetchRules.fetchRules(mExecutor, new Handler(), mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { @Override public void success(ArrayList<Rule> rules) { mAdapter.setRules(ReportReason.convertRulesToReasons(rules)); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RulesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RulesActivity.java index 0e3021e9..ca687cf1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RulesActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RulesActivity.java @@ -4,6 +4,7 @@ import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.view.MenuItem; import android.view.View; import android.view.Window; @@ -14,7 +15,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; @@ -24,6 +24,7 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import java.util.ArrayList; +import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; @@ -64,6 +65,8 @@ public class RulesActivity extends BaseActivity { SharedPreferences mSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; private String mSubredditName; private RulesRecyclerViewAdapter mAdapter; @@ -115,13 +118,10 @@ public class RulesActivity extends BaseActivity { mSubredditName = getIntent().getExtras().getString(EXTRA_SUBREDDIT_NAME); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper); recyclerView.setAdapter(mAdapter); - //fetchRules(); - - FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + FetchRules.fetchRules(mExecutor, new Handler(), mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { @Override public void success(ArrayList<Rule> rules) { progressBar.setVisibility(View.GONE); @@ -159,46 +159,6 @@ public class RulesActivity extends BaseActivity { errorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); } - /*private void fetchRules() { - progressBar.setVisibility(View.VISIBLE); - errorTextView.setVisibility(View.GONE); - - RedditAPI api = mRetrofit.create(RedditAPI.class); - Call<String> rulesCall = api.getRules(mSubredditName); - rulesCall.enqueue(new Callback<String>() { - @Override - public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { - if (response.isSuccessful()) { - new ParseRulesAsyncTask(response.body(), new ParseRulesAsyncTask.ParseRulesAsyncTaskListener() { - @Override - public void parseSuccessful(ArrayList<Rule> rules) { - progressBar.setVisibility(View.GONE); - if (rules == null || rules.size() == 0) { - errorTextView.setVisibility(View.VISIBLE); - errorTextView.setText(R.string.no_rule); - errorTextView.setOnClickListener(view -> { - }); - } - mAdapter.changeDataset(rules); - } - - @Override - public void parseFailed() { - displayError(); - } - }).execute(); - } else { - displayError(); - } - } - - @Override - public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { - displayError(); - } - }); - }*/ - private void displayError() { progressBar.setVisibility(View.GONE); errorTextView.setVisibility(View.VISIBLE); @@ -206,7 +166,7 @@ public class RulesActivity extends BaseActivity { errorTextView.setOnClickListener(view -> { progressBar.setVisibility(View.VISIBLE); errorTextView.setVisibility(View.GONE); - FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + FetchRules.fetchRules(mExecutor, new Handler(), mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { @Override public void success(ArrayList<Rule> rules) { progressBar.setVisibility(View.GONE); @@ -247,49 +207,4 @@ public class RulesActivity extends BaseActivity { public void onAccountSwitchEvent(SwitchAccountEvent event) { finish(); } - - /*private static class ParseRulesAsyncTask extends AsyncTask<Void, ArrayList<Rule>, ArrayList<Rule>> { - private String response; - private ParseRulesAsyncTaskListener parseRulesAsyncTaskListener; - - ParseRulesAsyncTask(String response, ParseRulesAsyncTaskListener parseRulesAsyncTaskListener) { - this.response = response; - this.parseRulesAsyncTaskListener = parseRulesAsyncTaskListener; - } - - @Override - protected ArrayList<Rule> doInBackground(Void... voids) { - try { - JSONArray rulesArray = new JSONObject(response).getJSONArray(JSONUtils.RULES_KEY); - ArrayList<Rule> rules = new ArrayList<>(); - for (int i = 0; i < rulesArray.length(); i++) { - String shortName = rulesArray.getJSONObject(i).getString(JSONUtils.SHORT_NAME_KEY); - String description = null; - if (rulesArray.getJSONObject(i).has(JSONUtils.DESCRIPTION_KEY)) { - description = Utils.modifyMarkdown(rulesArray.getJSONObject(i).getString(JSONUtils.DESCRIPTION_KEY)); - } - rules.add(new Rule(shortName, description)); - } - return rules; - } catch (JSONException e) { - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(ArrayList<Rule> rules) { - if (rules != null) { - parseRulesAsyncTaskListener.parseSuccessful(rules); - } else { - parseRulesAsyncTaskListener.parseFailed(); - } - } - - interface ParseRulesAsyncTaskListener { - void parseSuccessful(ArrayList<Rule> rules); - - void parseFailed(); - } - }*/ } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchActivity.java index cd6c2c5c..66369953 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchActivity.java @@ -18,7 +18,6 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.ferfalk.simplesearchview.SimpleSearchView; @@ -28,6 +27,8 @@ import com.r0adkll.slidr.Slidr; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.util.ArrayList; + import javax.inject.Inject; import javax.inject.Named; @@ -37,12 +38,21 @@ import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.adapters.SearchActivityRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.adapters.SubredditAutocompleteRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.recentsearchquery.DeleteRecentSearchQuery; import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQuery; import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQueryViewModel; +import ml.docilealligator.infinityforreddit.subreddit.ParseSubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; public class SearchActivity extends BaseActivity { @@ -83,11 +93,12 @@ public class SearchActivity extends BaseActivity { TextView subredditNameTextView; @BindView(R.id.divider_search_activity) View divider; - @BindView(R.id.recent_summary_text_view_search_activity) - TextView recentSummaryTextView; @BindView(R.id.recycler_view_search_activity) RecyclerView recyclerView; @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject RedditDataRoomDatabase mRedditDataRoomDatabase; @Inject @Named("default") @@ -96,14 +107,20 @@ public class SearchActivity extends BaseActivity { @Named("current_account") SharedPreferences mCurrentAccountSharedPreferences; @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject CustomThemeWrapper mCustomThemeWrapper; private String mAccountName; + private String mAccessToken; private String query; private String subredditName; private boolean subredditIsUser; private boolean searchOnlySubreddits; private boolean searchOnlyUsers; private SearchActivityRecyclerViewAdapter adapter; + private SubredditAutocompleteRecyclerViewAdapter subredditAutocompleteRecyclerViewAdapter; + private Call<String> subredditAutocompleteCall; RecentSearchQueryViewModel mRecentSearchQueryViewModel; @Override @@ -159,6 +176,31 @@ public class SearchActivity extends BaseActivity { } }); + mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); + mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); + boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false); + + subredditAutocompleteRecyclerViewAdapter = new SubredditAutocompleteRecyclerViewAdapter(this, + mCustomThemeWrapper, subredditData -> { + if (searchOnlySubreddits) { + Intent returnIntent = new Intent(); + if (getIntent().getBooleanExtra(EXTRA_IS_MULTI_SELECTION, false)) { + ArrayList<String> subredditNameList = new ArrayList<>(); + subredditNameList.add(subredditData.getName()); + returnIntent.putStringArrayListExtra(RETURN_EXTRA_SELECTED_SUBREDDIT_NAMES, subredditNameList); + } else { + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, subredditData.getName()); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, subredditData.getIconUrl()); + } + setResult(Activity.RESULT_OK, returnIntent); + } else { + Intent intent = new Intent(SearchActivity.this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditData.getName()); + startActivity(intent); + } + finish(); + }); + simpleSearchView.setOnQueryTextListener(new SimpleSearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { @@ -168,6 +210,38 @@ public class SearchActivity extends BaseActivity { @Override public boolean onQueryTextChange(String newText) { + if (!newText.isEmpty()) { + if (subredditAutocompleteCall != null) { + subredditAutocompleteCall.cancel(); + } + subredditAutocompleteCall = mOauthRetrofit.create(RedditAPI.class).subredditAutocomplete(APIUtils.getOAuthHeader(mAccessToken), + newText, nsfw); + subredditAutocompleteCall.enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + ParseSubredditData.parseSubredditListingData(response.body(), nsfw, new ParseSubredditData.ParseSubredditListingDataListener() { + @Override + public void onParseSubredditListingDataSuccess(ArrayList<SubredditData> subredditData, String after) { + subredditAutocompleteRecyclerViewAdapter.setSubreddits(subredditData); + recyclerView.setAdapter(subredditAutocompleteRecyclerViewAdapter); + } + + @Override + public void onParseSubredditListingDataFail() { + + } + }); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + + } + }); + return true; + } return false; } @@ -177,8 +251,6 @@ public class SearchActivity extends BaseActivity { } }); - mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); - if (savedInstanceState != null) { subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); @@ -227,7 +299,6 @@ public class SearchActivity extends BaseActivity { }); recyclerView.setVisibility(View.VISIBLE); recyclerView.setNestedScrollingEnabled(false); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); if (mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SEARCH_HISTORY, true)) { @@ -238,10 +309,8 @@ public class SearchActivity extends BaseActivity { mRecentSearchQueryViewModel.getAllRecentSearchQueries().observe(this, recentSearchQueries -> { if (recentSearchQueries != null && !recentSearchQueries.isEmpty()) { divider.setVisibility(View.VISIBLE); - recentSummaryTextView.setVisibility(View.VISIBLE); } else { divider.setVisibility(View.GONE); - recentSummaryTextView.setVisibility(View.GONE); } adapter.setRecentSearchQueries(recentSearchQueries); }); @@ -309,7 +378,6 @@ public class SearchActivity extends BaseActivity { searchInTextView.setTextColor(colorAccent); subredditNameTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); divider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); - recentSummaryTextView.setTextColor(colorAccent); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java index 5ca8a554..f2096b97 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java @@ -5,12 +5,15 @@ import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import androidx.annotation.NonNull; @@ -20,6 +23,7 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.widget.ViewPager2; @@ -35,6 +39,8 @@ import com.r0adkll.slidr.model.SlidrInterface; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.util.ArrayList; + import javax.inject.Inject; import javax.inject.Named; @@ -48,6 +54,8 @@ import ml.docilealligator.infinityforreddit.RecyclerViewContentScrollingInterfac import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.adapters.SubredditAutocompleteRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.bottomsheetfragments.FABMoreOptionsBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostTypeBottomSheetFragment; @@ -63,14 +71,23 @@ import ml.docilealligator.infinityforreddit.fragments.SubredditListingFragment; import ml.docilealligator.infinityforreddit.fragments.UserListingFragment; import ml.docilealligator.infinityforreddit.post.PostDataSource; import ml.docilealligator.infinityforreddit.recentsearchquery.InsertRecentSearchQuery; +import ml.docilealligator.infinityforreddit.subreddit.ParseSubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; public class SearchResultActivity extends BaseActivity implements SortTypeSelectionCallback, PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface, FABMoreOptionsBottomSheetFragment.FABOptionSelectionCallback, RandomBottomSheetFragment.RandomOptionSelectionCallback, PostTypeBottomSheetFragment.PostTypeSelectionCallback, RecyclerViewContentScrollingInterface { - static final String EXTRA_QUERY = "QK"; + + static final String EXTRA_QUERY = "EQ"; + static final String EXTRA_TRENDING_SOURCE = "ETS"; static final String EXTRA_SUBREDDIT_NAME = "ESN"; private static final String INSERT_SEARCH_QUERY_SUCCESS_STATE = "ISQSS"; @@ -87,6 +104,9 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect @BindView(R.id.fab_search_result_activity) FloatingActionButton fab; @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject RedditDataRoomDatabase mRedditDataRoomDatabase; @Inject @Named("default") @@ -108,6 +128,7 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect SharedPreferences mCurrentAccountSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; + private Call<String> subredditAutocompleteCall; private String mAccessToken; private String mAccountName; private String mQuery; @@ -543,11 +564,79 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect private void goToSubreddit() { View rootView = getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, coordinatorLayout, false); TextInputEditText thingEditText = rootView.findViewById(R.id.text_input_edit_text_go_to_thing_edit_text); + RecyclerView recyclerView = rootView.findViewById(R.id.recycler_view_go_to_thing_edit_text); thingEditText.requestFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + SubredditAutocompleteRecyclerViewAdapter adapter = new SubredditAutocompleteRecyclerViewAdapter( + this, mCustomThemeWrapper, subredditData -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent intent = new Intent(SearchResultActivity.this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditData.getName()); + startActivity(intent); + }); + recyclerView.setAdapter(adapter); if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); + subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); + startActivity(subredditIntent); + return true; + } + return false; + }); + + boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false); + thingEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + if (subredditAutocompleteCall != null) { + subredditAutocompleteCall.cancel(); + } + subredditAutocompleteCall = mOauthRetrofit.create(RedditAPI.class).subredditAutocomplete(APIUtils.getOAuthHeader(mAccessToken), + editable.toString(), nsfw); + subredditAutocompleteCall.enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + ParseSubredditData.parseSubredditListingData(response.body(), nsfw, new ParseSubredditData.ParseSubredditListingDataListener() { + @Override + public void onParseSubredditListingDataSuccess(ArrayList<SubredditData> subredditData, String after) { + adapter.setSubreddits(subredditData); + } + + @Override + public void onParseSubredditListingDataFail() { + + } + }); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + + } + }); + } + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.go_to_subreddit) .setView(rootView) @@ -560,7 +649,11 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); startActivity(subredditIntent); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) .setOnDismissListener(dialogInterface -> { if (imm != null) { imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); @@ -577,6 +670,18 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent userIntent = new Intent(this, ViewUserDetailActivity.class); + userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); + startActivity(userIntent); + return true; + } + return false; + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.go_to_user) .setView(rootView) @@ -589,7 +694,11 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); startActivity(userIntent); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) .setOnDismissListener(dialogInterface -> { if (imm != null) { imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); @@ -625,6 +734,10 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect case PostTypeBottomSheetFragment.TYPE_VIDEO: intent = new Intent(this, PostVideoActivity.class); startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_GALLERY: + intent = new Intent(this, PostGalleryActivity.class); + startActivity(intent); } } @@ -661,6 +774,7 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SEARCH); bundle.putString(PostFragment.EXTRA_NAME, mSubredditName); bundle.putString(PostFragment.EXTRA_QUERY, mQuery); + bundle.putString(PostFragment.EXTRA_TRENDING_SOURCE, getIntent().getStringExtra(EXTRA_TRENDING_SOURCE)); bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); mFragment.setArguments(bundle); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectUserFlairActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectUserFlairActivity.java index 84db322c..f9a7460e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectUserFlairActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectUserFlairActivity.java @@ -13,7 +13,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; @@ -36,6 +35,7 @@ import ml.docilealligator.infinityforreddit.SelectUserFlair; import ml.docilealligator.infinityforreddit.UserFlair; import ml.docilealligator.infinityforreddit.adapters.UserFlairRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import retrofit2.Retrofit; @@ -63,7 +63,7 @@ public class SelectUserFlairActivity extends BaseActivity implements ActivityToo SharedPreferences mCurrentAccountSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; private boolean mNullAccessToken = false; private String mAccessToken; private String mAccountName; @@ -170,7 +170,7 @@ public class SelectUserFlairActivity extends BaseActivity implements ActivityToo .show(); } }); - mLinearLayoutManager = new LinearLayoutManager(SelectUserFlairActivity.this); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(SelectUserFlairActivity.this); recyclerView.setLayoutManager(mLinearLayoutManager); recyclerView.setAdapter(mAdapter); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectedSubredditsAndUsersActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectedSubredditsAndUsersActivity.java index cfc30dcf..38502fd4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectedSubredditsAndUsersActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectedSubredditsAndUsersActivity.java @@ -11,7 +11,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; @@ -31,6 +30,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.SelectSubreddit import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; public class SelectedSubredditsAndUsersActivity extends BaseActivity implements ActivityToolbarInterface { @@ -56,7 +56,7 @@ public class SelectedSubredditsAndUsersActivity extends BaseActivity implements SharedPreferences mSharedPreferences; @Inject CustomThemeWrapper mCustomThemeWrapper; - private LinearLayoutManager linearLayoutManager; + private LinearLayoutManagerBugFixed linearLayoutManager; private SelectedSubredditsRecyclerViewAdapter adapter; private ArrayList<String> subreddits; @@ -88,7 +88,7 @@ public class SelectedSubredditsAndUsersActivity extends BaseActivity implements } adapter = new SelectedSubredditsRecyclerViewAdapter(mCustomThemeWrapper, subreddits); - linearLayoutManager = new LinearLayoutManager(this); + linearLayoutManager = new LinearLayoutManagerBugFixed(this); recyclerView.setLayoutManager(linearLayoutManager); recyclerView.setAdapter(adapter); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubmitCrosspostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubmitCrosspostActivity.java index 7e97c0a6..d6c5e68f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubmitCrosspostActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubmitCrosspostActivity.java @@ -2,7 +2,6 @@ package ml.docilealligator.infinityforreddit.activities; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; @@ -12,10 +11,10 @@ import android.os.Handler; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.Button; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; @@ -32,8 +31,10 @@ import com.bumptech.glide.request.transition.Transition; import com.davemorrissey.labs.subscaleview.ImageSource; import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.button.MaterialButton; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.switchmaterial.SwitchMaterial; import com.libRG.CustomTextView; import org.greenrobot.eventbus.EventBus; @@ -91,7 +92,7 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom @BindView(R.id.subreddit_name_text_view_submit_crosspost_activity) TextView subredditNameTextView; @BindView(R.id.rules_button_submit_crosspost_activity) - Button rulesButton; + MaterialButton rulesButton; @BindView(R.id.divider_1_submit_crosspost_activity) View divider1; @BindView(R.id.flair_custom_text_view_submit_crosspost_activity) @@ -102,10 +103,18 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom CustomTextView nsfwTextView; @BindView(R.id.divider_2_submit_crosspost_activity) View divider2; - @BindView(R.id.post_title_edit_text_submit_crosspost_activity) - EditText titleEditText; + @BindView(R.id.receive_post_reply_notifications_linear_layout_submit_crosspost_activity) + LinearLayout receivePostReplyNotificationsLinearLayout; + @BindView(R.id.receive_post_reply_notifications_text_view_submit_crosspost_activity) + TextView receivePostReplyNotificationsTextView; + @BindView(R.id.receive_post_reply_notifications_switch_material_submit_crosspost_activity) + SwitchMaterial receivePostReplyNotificationsSwitchMaterial; @BindView(R.id.divider_3_submit_crosspost_activity) View divider3; + @BindView(R.id.post_title_edit_text_submit_crosspost_activity) + EditText titleEditText; + @BindView(R.id.divider_4_submit_crosspost_activity) + View divider4; @BindView(R.id.post_content_text_view_submit_crosspost_activity) TextView contentTextView; @BindView(R.id.frame_layout_submit_crosspost_activity) @@ -360,6 +369,10 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom isNSFW = false; } }); + + receivePostReplyNotificationsLinearLayout.setOnClickListener(view -> { + receivePostReplyNotificationsSwitchMaterial.performClick(); + }); } @Nullable @@ -389,12 +402,14 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); subredditNameTextView.setTextColor(secondaryTextColor); rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + rulesButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + receivePostReplyNotificationsTextView.setTextColor(primaryTextColor); int dividerColor = mCustomThemeWrapper.getDividerColor(); divider1.setBackgroundColor(dividerColor); divider2.setBackgroundColor(dividerColor); divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + divider4.setBackgroundColor(dividerColor); flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); flairTextColor = mCustomThemeWrapper.getFlairTextColor(); spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); @@ -457,61 +472,62 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - return true; - } else { - if (!titleEditText.getText().toString().equals("")) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - return true; - } - } - finish(); + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); return true; - case R.id.action_send_submit_crosspost_activity: - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + } else { + if (!titleEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); return true; } + } + finish(); + return true; + } else if (itemId == R.id.action_send_submit_crosspost_activity) { + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } - isPosting = true; + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } - item.setEnabled(false); - item.getIcon().setAlpha(130); + isPosting = true; - mPostingSnackbar.show(); + item.setEnabled(false); + item.getIcon().setAlpha(130); - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } + mPostingSnackbar.show(); - Intent intent = new Intent(this, SubmitPostService.class); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - if (post.isCrosspost()) { - intent.putExtra(SubmitPostService.EXTRA_CONTENT, "t3_" + post.getCrosspostParentId()); - } else { - intent.putExtra(SubmitPostService.EXTRA_CONTENT, post.getFullName()); - } - intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_CROSSPOST); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_CROSSPOST); - ContextCompat.startForegroundService(this, intent); + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } - return true; + Intent intent = new Intent(this, SubmitPostService.class); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + if (post.isCrosspost()) { + intent.putExtra(SubmitPostService.EXTRA_CONTENT, "t3_" + post.getCrosspostParentId()); + } else { + intent.putExtra(SubmitPostService.EXTRA_CONTENT, post.getFullName()); + } + intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_CROSSPOST); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_RECEIVE_POST_REPLY_NOTIFICATIONS, receivePostReplyNotificationsSwitchMaterial.isChecked()); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_CROSSPOST); + ContextCompat.startForegroundService(this, intent); + + return true; } return false; @@ -588,7 +604,7 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom } @Subscribe - public void onSubmitTextPostEvent(SubmitCrosspostEvent submitCrosspostEvent) { + public void onSubmitCrosspostEvent(SubmitCrosspostEvent submitCrosspostEvent) { isPosting = false; mPostingSnackbar.dismiss(); if (submitCrosspostEvent.postSuccess) { @@ -597,8 +613,8 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom startActivity(intent); finish(); } else { - mMenu.findItem(R.id.action_send_post_text_activity).setEnabled(true); - mMenu.findItem(R.id.action_send_post_text_activity).getIcon().setAlpha(255); + mMenu.findItem(R.id.action_send_submit_crosspost_activity).setEnabled(true); + mMenu.findItem(R.id.action_send_submit_crosspost_activity).getIcon().setAlpha(255); if (submitCrosspostEvent.errorMessage == null || submitCrosspostEvent.errorMessage.equals("")) { Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); } else { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditMultiselectionActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditMultiselectionActivity.java index 69b83579..f2d00212 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditMultiselectionActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditMultiselectionActivity.java @@ -19,7 +19,6 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -41,6 +40,7 @@ import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.adapters.SubredditMultiselectionRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditViewModel; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import retrofit2.Retrofit; @@ -83,7 +83,7 @@ public class SubredditMultiselectionActivity extends BaseActivity implements Act public SubscribedSubredditViewModel mSubscribedSubredditViewModel; private String mAccessToken; private String mAccountName; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; private SubredditMultiselectionRecyclerViewAdapter mAdapter; private RequestManager mGlide; @@ -142,7 +142,7 @@ public class SubredditMultiselectionActivity extends BaseActivity implements Act } private void bindView() { - mLinearLayoutManager = new LinearLayoutManager(this); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(this); mRecyclerView.setLayoutManager(mLinearLayoutManager); mAdapter = new SubredditMultiselectionRecyclerViewAdapter(this, mCustomThemeWrapper); mRecyclerView.setAdapter(mAdapter); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubscribedThingListingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubscribedThingListingActivity.java index e5b2e225..0d33b2a8 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubscribedThingListingActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubscribedThingListingActivity.java @@ -47,6 +47,7 @@ import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.asynctasks.InsertMultireddit; import ml.docilealligator.infinityforreddit.asynctasks.InsertSubscribedThings; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.ViewPagerBugFixed; import ml.docilealligator.infinityforreddit.events.GoBackToMainPageEvent; import ml.docilealligator.infinityforreddit.events.RefreshMultiRedditsEvent; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; @@ -77,7 +78,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti @BindView(R.id.tab_layout_subscribed_thing_listing_activity) TabLayout tabLayout; @BindView(R.id.view_pager_subscribed_thing_listing_activity) - ViewPager viewPager; + ViewPagerBugFixed viewPager; @BindView(R.id.fab_subscribed_thing_listing_activity) FloatingActionButton fab; @Inject @@ -211,7 +212,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti tabLayout.setupWithViewPager(viewPager); if (showMultiReddits) { - viewPager.setCurrentItem(2); + viewPager.setCurrentItem(2, false); } loadSubscriptions(false); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/TrendingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/TrendingActivity.java new file mode 100644 index 00000000..ca1a5887 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/TrendingActivity.java @@ -0,0 +1,328 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.util.DisplayMetrics; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.TrendingSearch; +import ml.docilealligator.infinityforreddit.adapters.TrendingSearchRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.post.ParsePost; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class TrendingActivity extends BaseActivity { + + private static final String TRENDING_SEARCHES_STATE = "TSS"; + + @BindView(R.id.coordinator_layout_trending_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.collapsing_toolbar_layout_trending_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.appbar_layout_trending_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_trending_activity) + Toolbar toolbar; + @BindView(R.id.swipe_refresh_layout_trending_activity) + SwipeRefreshLayout swipeRefreshLayout; + @BindView(R.id.recycler_view_trending_activity) + RecyclerView recyclerView; + @BindView(R.id.fetch_trending_search_linear_layout_trending_activity) + LinearLayout errorLinearLayout; + @BindView(R.id.fetch_trending_search_image_view_trending_activity) + ImageView errorImageView; + @BindView(R.id.fetch_trending_search_text_view_trending_activity) + TextView errorTextView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences mCurrentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + private String mAccessToken; + private String mAccountName; + private boolean isRefreshing = false; + private ArrayList<TrendingSearch> trendingSearches; + private TrendingSearchRecyclerViewAdapter adapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_trending); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + + int navBarResourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + if (navBarResourceId > 0) { + recyclerView.setPadding(0, 0, 0, recyclerView.getPaddingBottom() + getResources().getDimensionPixelSize(navBarResourceId)); + } + } + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); + mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); + + DisplayMetrics displayMetrics = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); + int windowWidth = displayMetrics.widthPixels; + + String dataSavingModeString = mSharedPreferences.getString(SharedPreferencesUtils.DATA_SAVING_MODE, SharedPreferencesUtils.DATA_SAVING_MODE_OFF); + boolean dataSavingMode = false; + if (dataSavingModeString.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ALWAYS)) { + dataSavingMode = true; + } else if (dataSavingModeString.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA)) { + int networkType = Utils.getConnectedNetwork(this); + dataSavingMode = networkType == Utils.NETWORK_TYPE_CELLULAR; + } + boolean disableImagePreview = mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false); + adapter = new TrendingSearchRecyclerViewAdapter(this, mCustomThemeWrapper, windowWidth, + dataSavingMode, disableImagePreview, new TrendingSearchRecyclerViewAdapter.ItemClickListener() { + @Override + public void onClick(TrendingSearch trendingSearch) { + Intent intent = new Intent(TrendingActivity.this, SearchResultActivity.class); + intent.putExtra(SearchResultActivity.EXTRA_QUERY, trendingSearch.queryString); + intent.putExtra(SearchResultActivity.EXTRA_TRENDING_SOURCE, "trending"); + startActivity(intent); + } + }); + recyclerView.setAdapter(adapter); + + swipeRefreshLayout.setEnabled(mSharedPreferences.getBoolean(SharedPreferencesUtils.PULL_TO_REFRESH, true)); + swipeRefreshLayout.setOnRefreshListener(this::fetchTrendingSearches); + + if (savedInstanceState != null) { + trendingSearches = savedInstanceState.getParcelableArrayList(TRENDING_SEARCHES_STATE); + } + if (trendingSearches != null) { + adapter.setTrendingSearches(trendingSearches); + } else { + fetchTrendingSearches(); + } + } + + private void fetchTrendingSearches() { + if (isRefreshing) { + return; + } + isRefreshing = true; + + errorLinearLayout.setVisibility(View.GONE); + Glide.with(this).clear(errorImageView); + swipeRefreshLayout.setRefreshing(true); + trendingSearches = null; + adapter.setTrendingSearches(null); + Handler handler = new Handler(); + mOauthRetrofit.create(RedditAPI.class).getTrendingSearches(APIUtils.getOAuthHeader(mAccessToken)).enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + mExecutor.execute(() -> { + try { + JSONArray trendingSearchesArray = new JSONObject(response.body()).getJSONArray(JSONUtils.TRENDING_SEARCHES_KEY); + ArrayList<TrendingSearch> trendingSearchList = new ArrayList<>(); + for (int i = 0; i < trendingSearchesArray.length(); i++) { + try { + JSONObject trendingSearchObject = trendingSearchesArray.getJSONObject(i); + String queryString = trendingSearchObject.getString(JSONUtils.QUERY_STRING_KEY); + String displayString = trendingSearchObject.getString(JSONUtils.DISPLAY_STRING_KEY); + JSONArray childrenWithOnlyOneChild = trendingSearchObject + .getJSONObject(JSONUtils.RESULTS_KEY) + .getJSONObject(JSONUtils.DATA_KEY) + .getJSONArray(JSONUtils.CHILDREN_KEY); + if (childrenWithOnlyOneChild.length() > 0) { + Post post = ParsePost.parseBasicData(childrenWithOnlyOneChild.getJSONObject(0) + .getJSONObject(JSONUtils.DATA_KEY)); + + trendingSearchList.add(new TrendingSearch(queryString, displayString, + post.getTitle(), post.getPreviews())); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + handler.post(() -> { + trendingSearches = trendingSearchList; + swipeRefreshLayout.setRefreshing(false); + adapter.setTrendingSearches(trendingSearches); + isRefreshing = false; + }); + } catch (JSONException e) { + e.printStackTrace(); + handler.post(() -> { + swipeRefreshLayout.setRefreshing(false); + showErrorView(R.string.error_parse_trending_search); + isRefreshing = false; + }); + } + }); + } else { + handler.post(() -> { + swipeRefreshLayout.setRefreshing(false); + showErrorView(R.string.error_fetch_trending_search); + isRefreshing = false; + }); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + handler.post(() -> { + swipeRefreshLayout.setRefreshing(false); + showErrorView(R.string.error_fetch_trending_search); + isRefreshing = false; + }); + } + }); + } + + private void showErrorView(int stringId) { + errorLinearLayout.setVisibility(View.VISIBLE); + Glide.with(this).load(R.drawable.error_image).into(errorImageView); + errorTextView.setText(stringId); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.trending_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } else if (item.getItemId() == R.id.action_refresh_trending_activity) { + fetchTrendingSearches(); + return true; + } + + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelableArrayList(TRENDING_SEARCHES_STATE, trendingSearches); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + swipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); + swipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); + errorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImageOrGifActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImageOrGifActivity.java index e82ea47a..9602da8b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImageOrGifActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImageOrGifActivity.java @@ -12,11 +12,14 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.text.Html; +import android.text.Spanned; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -42,6 +45,7 @@ import com.github.piasy.biv.loader.ImageLoader; import com.github.piasy.biv.loader.glide.GlideImageLoader; import com.github.piasy.biv.view.BigImageView; import com.github.piasy.biv.view.GlideImageViewFactory; +import com.google.android.material.bottomappbar.BottomAppBar; import com.r0adkll.slidr.Slidr; import com.r0adkll.slidr.model.SlidrConfig; import com.r0adkll.slidr.model.SlidrPosition; @@ -85,6 +89,16 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa BigImageView mImageView; @BindView(R.id.load_image_error_linear_layout_view_image_or_gif_activity) LinearLayout mLoadErrorLinearLayout; + @BindView(R.id.bottom_navigation_view_image_or_gif_activity) + BottomAppBar bottomAppBar; + @BindView(R.id.title_text_view_view_image_or_gif_activity) + TextView titleTextView; + @BindView(R.id.download_image_view_view_image_or_gif_activity) + ImageView downloadImageView; + @BindView(R.id.share_image_view_view_image_or_gif_activity) + ImageView shareImageView; + @BindView(R.id.wallpaper_image_view_view_image_or_gif_activity) + ImageView wallpaperImageView; @Inject @Named("default") SharedPreferences mSharedPreferences; @@ -130,12 +144,9 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa ButterKnife.bind(this); - ActionBar actionBar = getSupportActionBar(); - Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); - actionBar.setHomeAsUpIndicator(upArrow); - actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); - - Slidr.attach(this, new SlidrConfig.Builder().position(SlidrPosition.VERTICAL).distanceThreshold(0.125f).build()); + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_VERTICALLY_TO_GO_BACK_FROM_MEDIA, true)) { + Slidr.attach(this, new SlidrConfig.Builder().position(SlidrPosition.VERTICAL).distanceThreshold(0.125f).build()); + } glide = Glide.with(this); @@ -149,10 +160,44 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa String postTitle = intent.getStringExtra(EXTRA_POST_TITLE_KEY); mSubredditName = intent.getStringExtra(EXTRA_SUBREDDIT_OR_USERNAME_KEY); + boolean useBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER, false); if (postTitle != null) { - setTitle(Html.fromHtml(String.format("<small>%s</small>", postTitle))); + Spanned title = Html.fromHtml(String.format("<small>%s</small>", postTitle)); + if (useBottomAppBar) { + titleTextView.setText(title); + } else { + setTitle(title); + } } else { - setTitle(""); + if (!useBottomAppBar) { + setTitle(""); + } + } + + if (useBottomAppBar) { + getSupportActionBar().hide(); + bottomAppBar.setVisibility(View.VISIBLE); + downloadImageView.setOnClickListener(view -> { + if (isDownloading) { + return; + } + isDownloading = true; + requestPermissionAndDownload(); + }); + shareImageView.setOnClickListener(view -> { + if (isGif) + shareGif(); + else + shareImage(); + }); + wallpaperImageView.setOnClickListener(view -> { + setWallpaper(); + }); + } else { + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); } mLoadErrorLinearLayout.setOnClickListener(view -> { @@ -168,6 +213,9 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); isActionBarHidden = false; + if (useBottomAppBar) { + bottomAppBar.setVisibility(View.VISIBLE); + } } else { getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE @@ -177,6 +225,9 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE); isActionBarHidden = true; + if (useBottomAppBar) { + bottomAppBar.setVisibility(View.GONE); + } } }); @@ -285,26 +336,8 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa if (isDownloading) { return false; } - isDownloading = true; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (ContextCompat.checkSelfPermission(this, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } - + requestPermissionAndDownload(); return true; } else if (itemId == R.id.action_share_view_image_or_gif_activity) { if (isGif) @@ -313,31 +346,32 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa shareImage(); return true; } else if (itemId == R.id.action_set_wallpaper_view_image_or_gif_activity) { - if (!isGif) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); - setAsWallpaperBottomSheetFragment.show(getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); - } else { - WallpaperSetter.set(mExecutor, new Handler(), mImageUrl, WallpaperSetter.BOTH_SCREENS, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - } + setWallpaper(); return true; } return false; } + private void requestPermissionAndDownload() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + if (ContextCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + } + private void download() { isDownloading = false; @@ -431,6 +465,28 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa }).submit(); } + private void setWallpaper() { + if (!isGif) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); + setAsWallpaperBottomSheetFragment.show(getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); + } else { + WallpaperSetter.set(mExecutor, new Handler(), mImageUrl, WallpaperSetter.BOTH_SCREENS, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + } + } + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImgurMediaActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImgurMediaActivity.java index 10866770..8aab0011 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImgurMediaActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImgurMediaActivity.java @@ -36,7 +36,13 @@ import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ImgurMedia; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; +import ml.docilealligator.infinityforreddit.WallpaperSetter; import ml.docilealligator.infinityforreddit.apis.ImgurAPI; +import ml.docilealligator.infinityforreddit.customviews.ViewPagerBugFixed; import ml.docilealligator.infinityforreddit.font.ContentFontFamily; import ml.docilealligator.infinityforreddit.font.ContentFontStyle; import ml.docilealligator.infinityforreddit.font.FontFamily; @@ -45,14 +51,9 @@ import ml.docilealligator.infinityforreddit.font.TitleFontFamily; import ml.docilealligator.infinityforreddit.font.TitleFontStyle; import ml.docilealligator.infinityforreddit.fragments.ViewImgurImageFragment; import ml.docilealligator.infinityforreddit.fragments.ViewImgurVideoFragment; -import ml.docilealligator.infinityforreddit.ImgurMedia; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.WallpaperSetter; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -72,11 +73,12 @@ public class ViewImgurMediaActivity extends AppCompatActivity implements SetAsWa @BindView(R.id.progress_bar_view_imgur_media_activity) ProgressBar progressBar; @BindView(R.id.view_pager_view_imgur_media_activity) - ViewPager viewPager; + ViewPagerBugFixed viewPager; @BindView(R.id.load_image_error_linear_layout_view_imgur_media_activity) LinearLayout errorLinearLayout; private SectionsPagerAdapter sectionsPagerAdapter; private ArrayList<ImgurMedia> images; + private boolean useBottomAppBar; @Inject @Named("imgur") Retrofit imgurRetrofit; @@ -116,12 +118,17 @@ public class ViewImgurMediaActivity extends AppCompatActivity implements SetAsWa ButterKnife.bind(this); - ActionBar actionBar = getSupportActionBar(); - Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); - actionBar.setHomeAsUpIndicator(upArrow); - actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + useBottomAppBar = sharedPreferences.getBoolean(SharedPreferencesUtils.USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER, false); - setTitle(" "); + if (!useBottomAppBar) { + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + setTitle(" "); + } else { + getSupportActionBar().hide(); + } String imgurId = getIntent().getStringExtra(EXTRA_IMGUR_ID); if (imgurId == null) { @@ -133,11 +140,15 @@ public class ViewImgurMediaActivity extends AppCompatActivity implements SetAsWa images = savedInstanceState.getParcelableArrayList(IMGUR_IMAGES_STATE); } - haulerView.setOnDragDismissedListener(dragDirection -> { - int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; - finish(); - overridePendingTransition(0, slide); - }); + if (sharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_VERTICALLY_TO_GO_BACK_FROM_MEDIA, true)) { + haulerView.setOnDragDismissedListener(dragDirection -> { + int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; + finish(); + overridePendingTransition(0, slide); + }); + } else { + haulerView.setDragEnabled(false); + } if (images == null) { fetchImgurMedia(imgurId); @@ -149,6 +160,10 @@ public class ViewImgurMediaActivity extends AppCompatActivity implements SetAsWa errorLinearLayout.setOnClickListener(view -> fetchImgurMedia(imgurId)); } + public boolean isUseBottomAppBar() { + return useBottomAppBar; + } + private void fetchImgurMedia(String imgurId) { errorLinearLayout.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); @@ -260,15 +275,18 @@ public class ViewImgurMediaActivity extends AppCompatActivity implements SetAsWa } private void setupViewPager() { - setToolbarTitle(0); + if (!useBottomAppBar) { + setToolbarTitle(0); + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + setToolbarTitle(position); + } + }); + } sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - setToolbarTitle(position); - } - }); viewPager.setAdapter(sectionsPagerAdapter); + viewPager.setOffscreenPageLimit(3); } private void setToolbarTitle(int position) { @@ -374,12 +392,16 @@ public class ViewImgurMediaActivity extends AppCompatActivity implements SetAsWa ViewImgurVideoFragment fragment = new ViewImgurVideoFragment(); Bundle bundle = new Bundle(); bundle.putParcelable(ViewImgurVideoFragment.EXTRA_IMGUR_VIDEO, imgurMedia); + bundle.putInt(ViewImgurVideoFragment.EXTRA_INDEX, position); + bundle.putInt(ViewImgurVideoFragment.EXTRA_MEDIA_COUNT, images.size()); fragment.setArguments(bundle); return fragment; } else { ViewImgurImageFragment fragment = new ViewImgurImageFragment(); Bundle bundle = new Bundle(); bundle.putParcelable(ViewImgurImageFragment.EXTRA_IMGUR_IMAGES, imgurMedia); + bundle.putInt(ViewImgurImageFragment.EXTRA_INDEX, position); + bundle.putInt(ViewImgurImageFragment.EXTRA_MEDIA_COUNT, images.size()); fragment.setArguments(bundle); return fragment; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java index cd4e7fdb..ae3538b1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java @@ -1,8 +1,11 @@ package ml.docilealligator.infinityforreddit.activities; +import static ml.docilealligator.infinityforreddit.activities.CommentActivity.RETURN_EXTRA_COMMENT_DATA_KEY; + import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; +import android.content.res.ColorStateList; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -11,6 +14,7 @@ import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.widget.ImageView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -27,8 +31,11 @@ import com.evernote.android.state.State; import com.github.piasy.biv.BigImageViewer; import com.github.piasy.biv.loader.glide.GlideImageLoader; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.card.MaterialCardView; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; import com.livefront.bridge.Bridge; import com.r0adkll.slidr.Slidr; import com.r0adkll.slidr.model.SlidrInterface; @@ -62,8 +69,6 @@ import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import retrofit2.Retrofit; -import static ml.docilealligator.infinityforreddit.activities.CommentActivity.RETURN_EXTRA_COMMENT_DATA_KEY; - public class ViewPostDetailActivity extends BaseActivity implements SortTypeSelectionCallback, ActivityToolbarInterface { public static final String EXTRA_POST_DATA = "EPD"; @@ -89,6 +94,18 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele ViewPager2 viewPager2; @BindView(R.id.fab_view_post_detail_activity) FloatingActionButton fab; + @BindView(R.id.search_panel_material_card_view_view_post_detail_activity) + MaterialCardView searchPanelMaterialCardView; + @BindView(R.id.search_text_input_layout_view_post_detail_activity) + TextInputLayout searchTextInputLayout; + @BindView(R.id.search_text_input_edit_text_view_post_detail_activity) + TextInputEditText searchTextInputEditText; + @BindView(R.id.previous_result_image_view_view_post_detail_activity) + ImageView previousResultImageView; + @BindView(R.id.next_result_image_view_view_post_detail_activity) + ImageView nextResultImageView; + @BindView(R.id.close_search_panel_image_view_view_post_detail_activity) + ImageView closeSearchPanelImageView; @Inject @Named("oauth") Retrofit mOauthRetrofit; @@ -160,13 +177,21 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); params.bottomMargin += navBarHeight; fab.setLayoutParams(params); + + searchPanelMaterialCardView.setContentPadding(searchPanelMaterialCardView.getPaddingStart(), + searchPanelMaterialCardView.getPaddingTop(), + searchPanelMaterialCardView.getPaddingEnd(), + searchPanelMaterialCardView.getPaddingBottom() + navBarHeight); } } } boolean swipeBetweenPosts = mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_BETWEEN_POSTS, false); - if (!swipeBetweenPosts && mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); + if (!swipeBetweenPosts) { + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + viewPager2.setUserInputEnabled(false); } postFragmentId = getIntent().getLongExtra(EXTRA_POST_FRAGMENT_ID, -1); if (swipeBetweenPosts && posts == null && postFragmentId > 0) { @@ -206,6 +231,17 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele } }); + fab.setOnLongClickListener(view -> { + if (sectionsPagerAdapter != null) { + ViewPostDetailFragment fragment = sectionsPagerAdapter.getCurrentFragment(); + if (fragment != null) { + fragment.scrollToPreviousParentComment(); + return true; + } + } + return false; + }); + checkNewAccountAndBindView(savedInstanceState); } @@ -242,6 +278,14 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); applyFABTheme(fab); + searchPanelMaterialCardView.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimary())); + int searchPanelTextAndIconColor = mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor(); + searchTextInputLayout.setBoxStrokeColor(searchPanelTextAndIconColor); + searchTextInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(searchPanelTextAndIconColor)); + searchTextInputEditText.setTextColor(searchPanelTextAndIconColor); + previousResultImageView.setColorFilter(searchPanelTextAndIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + nextResultImageView.setColorFilter(searchPanelTextAndIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + closeSearchPanelImageView.setColorFilter(searchPanelTextAndIconColor, android.graphics.PorterDuff.Mode.SRC_IN); } private void checkNewAccountAndBindView(Bundle savedInstanceState) { @@ -270,6 +314,31 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele if (savedInstanceState == null) { viewPager2.setCurrentItem(getIntent().getIntExtra(EXTRA_POST_LIST_POSITION, 0), false); } + + searchPanelMaterialCardView.setOnClickListener(null); + + nextResultImageView.setOnClickListener(view -> { + ViewPostDetailFragment fragment = sectionsPagerAdapter.getCurrentFragment(); + if (fragment != null) { + searchComment(fragment, true); + } + }); + + previousResultImageView.setOnClickListener(view -> { + ViewPostDetailFragment fragment = sectionsPagerAdapter.getCurrentFragment(); + if (fragment != null) { + searchComment(fragment, false); + } + }); + + closeSearchPanelImageView.setOnClickListener(view -> { + ViewPostDetailFragment fragment = sectionsPagerAdapter.getCurrentFragment(); + if (fragment != null) { + fragment.resetSearchCommentIndex(); + } + + searchPanelMaterialCardView.setVisibility(View.GONE); + }); } public boolean isNsfwSubreddit() { @@ -358,6 +427,23 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele } } + public boolean toggleSearchPanelVisibility() { + if (searchPanelMaterialCardView.getVisibility() == View.GONE) { + searchPanelMaterialCardView.setVisibility(View.VISIBLE); + return false; + } else { + searchPanelMaterialCardView.setVisibility(View.GONE); + searchTextInputEditText.setText(""); + return true; + } + } + + public void searchComment(ViewPostDetailFragment fragment, boolean searchNextComment) { + if (!searchTextInputEditText.getText().toString().isEmpty()) { + fragment.searchComment(searchTextInputEditText.getText().toString(), searchNextComment); + } + } + @Subscribe public void onAccountSwitchEvent(SwitchAccountEvent event) { if (!getClass().getName().equals(event.excludeActivityClassName)) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPrivateMessagesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPrivateMessagesActivity.java index b7f914b9..ad09e76e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPrivateMessagesActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPrivateMessagesActivity.java @@ -14,7 +14,6 @@ import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.transition.AutoTransition; import androidx.transition.TransitionManager; @@ -39,6 +38,7 @@ import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.adapters.PrivateMessagesDetailRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.asynctasks.LoadUserData; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.RepliedToPrivateMessageEvent; import ml.docilealligator.infinityforreddit.message.Message; import ml.docilealligator.infinityforreddit.message.ReadMessage; @@ -87,7 +87,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit CustomThemeWrapper mCustomThemeWrapper; @Inject Executor mExecutor; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; private PrivateMessagesDetailRecyclerViewAdapter mAdapter; private Message privateMessage; private String mAccessToken; @@ -154,7 +154,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit } mAdapter = new PrivateMessagesDetailRecyclerViewAdapter(this, mSharedPreferences, getResources().getConfiguration().locale, privateMessage, mAccountName, mCustomThemeWrapper); - mLinearLayoutManager = new LinearLayoutManager(this); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(this); mLinearLayoutManager.setStackFromEnd(true); mRecyclerView.setLayoutManager(mLinearLayoutManager); mRecyclerView.setAdapter(mAdapter); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewRedditGalleryActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewRedditGalleryActivity.java index 6bcccfa3..b5047cc6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewRedditGalleryActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewRedditGalleryActivity.java @@ -28,6 +28,7 @@ import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.customviews.ViewPagerBugFixed; import ml.docilealligator.infinityforreddit.font.ContentFontFamily; import ml.docilealligator.infinityforreddit.font.ContentFontStyle; import ml.docilealligator.infinityforreddit.font.FontFamily; @@ -51,10 +52,11 @@ public class ViewRedditGalleryActivity extends AppCompatActivity implements SetA @BindView(R.id.hauler_view_view_reddit_gallery_activity) HaulerView haulerView; @BindView(R.id.view_pager_view_reddit_gallery_activity) - ViewPager viewPager; + ViewPagerBugFixed viewPager; private SectionsPagerAdapter sectionsPagerAdapter; private ArrayList<Post.Gallery> gallery; private String subredditName; + private boolean useBottomAppBar; @Inject @Named("default") SharedPreferences sharedPreferences; @@ -91,12 +93,17 @@ public class ViewRedditGalleryActivity extends AppCompatActivity implements SetA ButterKnife.bind(this); - ActionBar actionBar = getSupportActionBar(); - Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); - actionBar.setHomeAsUpIndicator(upArrow); - actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + useBottomAppBar = sharedPreferences.getBoolean(SharedPreferencesUtils.USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER, false); - setTitle(" "); + if (!useBottomAppBar) { + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + setTitle(" "); + } else { + getSupportActionBar().hide(); + } gallery = getIntent().getParcelableArrayListExtra(EXTRA_REDDIT_GALLERY); if (gallery == null || gallery.isEmpty()) { @@ -105,25 +112,36 @@ public class ViewRedditGalleryActivity extends AppCompatActivity implements SetA } subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - haulerView.setOnDragDismissedListener(dragDirection -> { - int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; - finish(); - overridePendingTransition(0, slide); - }); + if (sharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_VERTICALLY_TO_GO_BACK_FROM_MEDIA, true)) { + haulerView.setOnDragDismissedListener(dragDirection -> { + int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; + finish(); + overridePendingTransition(0, slide); + }); + } else { + haulerView.setDragEnabled(false); + } setupViewPager(); } + public boolean isUseBottomAppBar() { + return useBottomAppBar; + } + private void setupViewPager() { - setToolbarTitle(0); + if (!useBottomAppBar) { + setToolbarTitle(0); + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + setToolbarTitle(position); + } + }); + } sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - setToolbarTitle(position); - } - }); viewPager.setAdapter(sectionsPagerAdapter); + viewPager.setOffscreenPageLimit(3); } private void setToolbarTitle(int position) { @@ -226,6 +244,8 @@ public class ViewRedditGalleryActivity extends AppCompatActivity implements SetA Bundle bundle = new Bundle(); bundle.putParcelable(ViewRedditGalleryVideoFragment.EXTRA_REDDIT_GALLERY_VIDEO, media); bundle.putString(ViewRedditGalleryVideoFragment.EXTRA_SUBREDDIT_NAME, subredditName); + bundle.putInt(ViewRedditGalleryVideoFragment.EXTRA_INDEX, position); + bundle.putInt(ViewRedditGalleryVideoFragment.EXTRA_MEDIA_COUNT, gallery.size()); fragment.setArguments(bundle); return fragment; } else { @@ -233,6 +253,8 @@ public class ViewRedditGalleryActivity extends AppCompatActivity implements SetA Bundle bundle = new Bundle(); bundle.putParcelable(ViewRedditGalleryImageOrGifFragment.EXTRA_REDDIT_GALLERY_MEDIA, media); bundle.putString(ViewRedditGalleryImageOrGifFragment.EXTRA_SUBREDDIT_NAME, subredditName); + bundle.putInt(ViewRedditGalleryImageOrGifFragment.EXTRA_INDEX, position); + bundle.putInt(ViewRedditGalleryImageOrGifFragment.EXTRA_MEDIA_COUNT, gallery.size()); fragment.setArguments(bundle); return fragment; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java index bd73d838..57620c51 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java @@ -4,9 +4,13 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.text.Editable; +import android.text.TextWatcher; +import android.text.util.Linkify; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; @@ -14,6 +18,7 @@ import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.ImageView; import android.widget.LinearLayout; @@ -28,6 +33,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.widget.ViewPager2; @@ -51,6 +57,7 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Locale; import java.util.concurrent.Executor; @@ -59,7 +66,14 @@ import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.movement.MovementMethodPlugin; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; import ml.docilealligator.infinityforreddit.FragmentCommunicator; @@ -70,16 +84,20 @@ import ml.docilealligator.infinityforreddit.RecyclerViewContentScrollingInterfac import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.adapters.SubredditAutocompleteRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.asynctasks.AddSubredditOrUserToMultiReddit; import ml.docilealligator.infinityforreddit.asynctasks.CheckIsSubscribedToSubreddit; import ml.docilealligator.infinityforreddit.asynctasks.InsertSubredditData; import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccount; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.FABMoreOptionsBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostTypeBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.RandomBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; import ml.docilealligator.infinityforreddit.events.GoBackToMainPageEvent; @@ -92,12 +110,17 @@ import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.PostDataSource; import ml.docilealligator.infinityforreddit.readpost.InsertReadPost; import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; +import ml.docilealligator.infinityforreddit.subreddit.ParseSubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditSubscription; import ml.docilealligator.infinityforreddit.subreddit.SubredditViewModel; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; import pl.droidsonroids.gif.GifImageView; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; import retrofit2.Retrofit; public class ViewSubredditDetailActivity extends BaseActivity implements SortTypeSelectionCallback, @@ -196,9 +219,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp public SubredditViewModel mSubredditViewModel; private FragmentManager fragmentManager; private SectionsPagerAdapter sectionsPagerAdapter; + private Call<String> subredditAutocompleteCall; private String mAccessToken; private String mAccountName; private String subredditName; + private String description; private boolean mFetchSubredditInfoSuccess = false; private int mNCurrentOnlineSubscribers = 0; private boolean isNsfwSubreddit = false; @@ -317,7 +342,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp }); } - showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); + showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, true); lockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); boolean hideSubredditDescription = mSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_SUBREDDIT_DESCRIPTION, false); @@ -360,6 +385,44 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp glide = Glide.with(this); Locale locale = getResources().getConfiguration().locale; + Markwon markwon = Markwon.builder(this) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(ViewSubredditDetailActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(mCustomThemeWrapper.getLinkColor()); + } + }) + .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS, this).setOnLinkLongClickListener((textView, url) -> { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); + urlMenuBottomSheetFragment.setArguments(bundle); + urlMenuBottomSheetFragment.show(getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); + return true; + }))) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)).build(); + + descriptionTextView.setOnLongClickListener(view -> { + if (description != null && !description.equals("") && descriptionTextView.getSelectionStart() == -1 && descriptionTextView.getSelectionEnd() == -1) { + Bundle bundle = new Bundle(); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, description); + CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); + copyTextBottomSheetFragment.setArguments(bundle); + copyTextBottomSheetFragment.show(getSupportFragmentManager(), copyTextBottomSheetFragment.getTag()); + } + return true; + }); + mSubredditViewModel = new ViewModelProvider(this, new SubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, subredditName)) .get(SubredditViewModel.class); @@ -411,11 +474,12 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp nSubscribersTextView.setText(nSubscribers); creationTimeTextView.setText(new SimpleDateFormat("MMM d, yyyy", locale).format(subredditData.getCreatedUTC())); - if (hideSubredditDescription || subredditData.getDescription().equals("")) { + description = subredditData.getDescription(); + if (hideSubredditDescription || description.equals("")) { descriptionTextView.setVisibility(View.GONE); } else { descriptionTextView.setVisibility(View.VISIBLE); - descriptionTextView.setText(subredditData.getDescription()); + markwon.setMarkdown(descriptionTextView, description); } if (subredditData.isNSFW()) { @@ -1101,6 +1165,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp } Intent intent = new Intent(this, MultiredditSelectionActivity.class); startActivityForResult(intent, ADD_TO_MULTIREDDIT_REQUEST_CODE); + } else if (itemId == R.id.action_add_to_post_filter_view_subreddit_detail_activity) { + Intent intent = new Intent(this, PostFilterPreferenceActivity.class); + intent.putExtra(PostFilterPreferenceActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + return true; } else if (itemId == R.id.action_share_view_subreddit_detail_activity) { Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/plain"); @@ -1215,6 +1284,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp intent = new Intent(this, PostVideoActivity.class); intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, subredditName); startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_GALLERY: + intent = new Intent(this, PostGalleryActivity.class); + intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); } } @@ -1333,11 +1407,79 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp private void goToSubreddit() { View rootView = getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, coordinatorLayout, false); TextInputEditText thingEditText = rootView.findViewById(R.id.text_input_edit_text_go_to_thing_edit_text); + RecyclerView recyclerView = rootView.findViewById(R.id.recycler_view_go_to_thing_edit_text); thingEditText.requestFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + SubredditAutocompleteRecyclerViewAdapter adapter = new SubredditAutocompleteRecyclerViewAdapter( + this, mCustomThemeWrapper, subredditData -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent intent = new Intent(ViewSubredditDetailActivity.this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditData.getName()); + startActivity(intent); + }); + recyclerView.setAdapter(adapter); if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); + subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); + startActivity(subredditIntent); + return true; + } + return false; + }); + + boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false); + thingEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + if (subredditAutocompleteCall != null) { + subredditAutocompleteCall.cancel(); + } + subredditAutocompleteCall = mOauthRetrofit.create(RedditAPI.class).subredditAutocomplete(APIUtils.getOAuthHeader(mAccessToken), + editable.toString(), nsfw); + subredditAutocompleteCall.enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + ParseSubredditData.parseSubredditListingData(response.body(), nsfw, new ParseSubredditData.ParseSubredditListingDataListener() { + @Override + public void onParseSubredditListingDataSuccess(ArrayList<SubredditData> subredditData, String after) { + adapter.setSubreddits(subredditData); + } + + @Override + public void onParseSubredditListingDataFail() { + + } + }); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + + } + }); + } + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.go_to_subreddit) .setView(rootView) @@ -1350,7 +1492,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); startActivity(subredditIntent); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) .setOnDismissListener(dialogInterface -> { if (imm != null) { imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); @@ -1367,6 +1513,18 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent userIntent = new Intent(this, ViewUserDetailActivity.class); + userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); + startActivity(userIntent); + return true; + } + return false; + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.go_to_user) .setView(rootView) @@ -1379,7 +1537,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); startActivity(userIntent); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) .setOnDismissListener(dialogInterface -> { if (imm != null) { imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java index 47b6fac1..d6fbb3d4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java @@ -10,6 +10,8 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.text.Editable; +import android.text.TextWatcher; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; @@ -17,6 +19,7 @@ import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.ImageView; import android.widget.LinearLayout; @@ -31,6 +34,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.widget.ViewPager2; @@ -54,6 +58,7 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Locale; import java.util.concurrent.Executor; @@ -74,6 +79,8 @@ import ml.docilealligator.infinityforreddit.RecyclerViewContentScrollingInterfac import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.adapters.SubredditAutocompleteRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.asynctasks.AddSubredditOrUserToMultiReddit; import ml.docilealligator.infinityforreddit.asynctasks.CheckIsFollowingUser; import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccount; @@ -94,15 +101,21 @@ import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.PostDataSource; import ml.docilealligator.infinityforreddit.readpost.InsertReadPost; +import ml.docilealligator.infinityforreddit.subreddit.ParseSubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.user.BlockUser; import ml.docilealligator.infinityforreddit.user.FetchUserData; import ml.docilealligator.infinityforreddit.user.UserDao; import ml.docilealligator.infinityforreddit.user.UserData; import ml.docilealligator.infinityforreddit.user.UserFollowing; import ml.docilealligator.infinityforreddit.user.UserViewModel; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; import pl.droidsonroids.gif.GifImageView; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; import retrofit2.Retrofit; public class ViewUserDetailActivity extends BaseActivity implements SortTypeSelectionCallback, @@ -203,7 +216,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele private UserThingSortTypeBottomSheetFragment userThingSortTypeBottomSheetFragment; private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - private boolean mNullAccessToken = false; + private Call<String> subredditAutocompleteCall; private String mAccessToken; private String mAccountName; private String username; @@ -353,7 +366,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele }); } - showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); + showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, true); lockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); glide = Glide.with(this); @@ -968,6 +981,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele } Intent intent = new Intent(this, MultiredditSelectionActivity.class); startActivityForResult(intent, ADD_TO_MULTIREDDIT_REQUEST_CODE); + } else if (itemId == R.id.action_add_to_post_filter_view_user_detail_activity) { + Intent intent = new Intent(this, PostFilterPreferenceActivity.class); + intent.putExtra(PostFilterPreferenceActivity.EXTRA_USER_NAME, username); + startActivity(intent); + return true; } else if (itemId == R.id.action_report_view_user_detail_activity) { Intent reportIntent = new Intent(this, LinkResolverActivity.class); reportIntent.setData(Uri.parse("https://www.reddithelp.com/en/categories/rules-reporting/account-and-community-restrictions/what-should-i-do-if-i-see-something-i")); @@ -1144,11 +1162,79 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele private void goToSubreddit() { View rootView = getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, coordinatorLayout, false); TextInputEditText thingEditText = rootView.findViewById(R.id.text_input_edit_text_go_to_thing_edit_text); + RecyclerView recyclerView = rootView.findViewById(R.id.recycler_view_go_to_thing_edit_text); thingEditText.requestFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + SubredditAutocompleteRecyclerViewAdapter adapter = new SubredditAutocompleteRecyclerViewAdapter( + this, mCustomThemeWrapper, subredditData -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent intent = new Intent(ViewUserDetailActivity.this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditData.getName()); + startActivity(intent); + }); + recyclerView.setAdapter(adapter); if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); + subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); + startActivity(subredditIntent); + return true; + } + return false; + }); + + boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false); + thingEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + if (subredditAutocompleteCall != null) { + subredditAutocompleteCall.cancel(); + } + subredditAutocompleteCall = mOauthRetrofit.create(RedditAPI.class).subredditAutocomplete(APIUtils.getOAuthHeader(mAccessToken), + editable.toString(), nsfw); + subredditAutocompleteCall.enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + ParseSubredditData.parseSubredditListingData(response.body(), nsfw, new ParseSubredditData.ParseSubredditListingDataListener() { + @Override + public void onParseSubredditListingDataSuccess(ArrayList<SubredditData> subredditData, String after) { + adapter.setSubreddits(subredditData); + } + + @Override + public void onParseSubredditListingDataFail() { + + } + }); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + + } + }); + } + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.go_to_subreddit) .setView(rootView) @@ -1161,7 +1247,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); startActivity(subredditIntent); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) .setOnDismissListener(dialogInterface -> { if (imm != null) { imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); @@ -1178,6 +1268,18 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele if (imm != null) { imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } + thingEditText.setOnEditorActionListener((textView, i, keyEvent) -> { + if (i == EditorInfo.IME_ACTION_DONE) { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent userIntent = new Intent(this, ViewUserDetailActivity.class); + userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); + startActivity(userIntent); + return true; + } + return false; + }); new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) .setTitle(R.string.go_to_user) .setView(rootView) @@ -1190,7 +1292,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); startActivity(userIntent); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) .setOnDismissListener(dialogInterface -> { if (imm != null) { imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); @@ -1293,6 +1399,10 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele case PostTypeBottomSheetFragment.TYPE_VIDEO: intent = new Intent(this, PostVideoActivity.class); startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_GALLERY: + intent = new Intent(this, PostGalleryActivity.class); + startActivity(intent); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java index 61a12366..7362e892 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java @@ -3,22 +3,29 @@ package ml.docilealligator.infinityforreddit.activities; import android.Manifest; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Handler; +import android.provider.Settings; import android.text.Html; import android.view.Menu; import android.view.MenuItem; +import android.view.OrientationEventListener; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -43,7 +50,10 @@ import com.google.android.exoplayer2.ui.TrackSelectionDialogBuilder; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; +import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory; +import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.util.Util; +import com.google.android.material.bottomappbar.BottomAppBar; import com.google.android.material.snackbar.Snackbar; import com.thefuntasty.hauler.DragDirection; import com.thefuntasty.hauler.HaulerView; @@ -51,6 +61,7 @@ import com.thefuntasty.hauler.HaulerView; import org.apache.commons.io.FilenameUtils; import java.util.List; +import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; @@ -62,8 +73,11 @@ import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.apis.VReddIt; import ml.docilealligator.infinityforreddit.font.ContentFontFamily; +import ml.docilealligator.infinityforreddit.font.ContentFontStyle; import ml.docilealligator.infinityforreddit.font.FontFamily; +import ml.docilealligator.infinityforreddit.font.FontStyle; import ml.docilealligator.infinityforreddit.font.TitleFontFamily; +import ml.docilealligator.infinityforreddit.font.TitleFontStyle; import ml.docilealligator.infinityforreddit.post.FetchPost; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.services.DownloadMediaService; @@ -112,6 +126,12 @@ public class ViewVideoActivity extends AppCompatActivity { ImageButton muteButton; @BindView(R.id.hd_exo_playback_control_view) ImageButton hdButton; + @BindView(R.id.bottom_navigation_exo_playback_control_view) + BottomAppBar bottomAppBar; + @BindView(R.id.title_text_view_exo_playback_control_view) + TextView titleTextView; + @BindView(R.id.download_image_view_exo_playback_control_view) + ImageView downloadImageView; private Uri mVideoUri; private SimpleExoPlayer player; @@ -131,6 +151,7 @@ public class ViewVideoActivity extends AppCompatActivity { private int videoType; private boolean isDataSavingMode; private boolean isHd; + private Integer originalOrientation; @Inject @Named("no_oauth") @@ -152,6 +173,12 @@ public class ViewVideoActivity extends AppCompatActivity { @Named("default") SharedPreferences mSharedPreferences; + @Inject + Executor mExecutor; + + @Inject + SimpleCache mSimpleCache; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -160,6 +187,15 @@ public class ViewVideoActivity extends AppCompatActivity { getTheme().applyStyle(R.style.Theme_Normal, true); + getTheme().applyStyle(FontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(TitleFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(ContentFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); + getTheme().applyStyle(FontFamily.valueOf(mSharedPreferences .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); @@ -174,10 +210,31 @@ public class ViewVideoActivity extends AppCompatActivity { ButterKnife.bind(this); setVolumeControlStream(AudioManager.STREAM_MUSIC); - ActionBar actionBar = getSupportActionBar(); - Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); - actionBar.setHomeAsUpIndicator(upArrow); - actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + Resources resources = getResources(); + + boolean useBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER, false); + if (useBottomAppBar) { + getSupportActionBar().hide(); + bottomAppBar.setVisibility(View.VISIBLE); + downloadImageView.setOnClickListener(view -> { + if (isDownloading) { + return; + } + + if (videoDownloadUrl == null) { + Toast.makeText(this, R.string.fetching_video_info_please_wait, Toast.LENGTH_SHORT).show(); + return; + } + + isDownloading = true; + requestPermissionAndDownload(); + }); + } else { + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = resources.getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(resources.getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + } String dataSavingModeString = mSharedPreferences.getString(SharedPreferencesUtils.DATA_SAVING_MODE, SharedPreferencesUtils.DATA_SAVING_MODE_OFF); int networkType = Utils.getConnectedNetwork(this); @@ -189,18 +246,18 @@ public class ViewVideoActivity extends AppCompatActivity { isHd = !isDataSavingMode; if (!mSharedPreferences.getBoolean(SharedPreferencesUtils.VIDEO_PLAYER_IGNORE_NAV_BAR, false)) { - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) { + if (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || resources.getBoolean(R.bool.isTablet)) { //Set player controller bottom margin in order to display it above the navbar - int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); - params.bottomMargin = getResources().getDimensionPixelSize(resourceId); + params.bottomMargin = resources.getDimensionPixelSize(resourceId); } else { //Set player controller right margin in order to display it above the navbar - int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); - params.rightMargin = getResources().getDimensionPixelSize(resourceId); + params.rightMargin = resources.getDimensionPixelSize(resourceId); } } @@ -215,13 +272,45 @@ public class ViewVideoActivity extends AppCompatActivity { isNSFW = intent.getBooleanExtra(EXTRA_IS_NSFW, false); if (savedInstanceState == null) { resumePosition = intent.getLongExtra(EXTRA_PROGRESS_SECONDS, -1); + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.VIDEO_PLAYER_AUTOMATIC_LANDSCAPE_ORIENTATION, false)) { + originalOrientation = resources.getConfiguration().orientation; + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); + + if (android.provider.Settings.System.getInt(getContentResolver(), + Settings.System.ACCELEROMETER_ROTATION, 0) == 1) { + OrientationEventListener orientationEventListener = new OrientationEventListener(this) { + @Override + public void onOrientationChanged(int orientation) { + int epsilon = 10; + int leftLandscape = 90; + int rightLandscape = 270; + if(epsilonCheck(orientation, leftLandscape, epsilon) || + epsilonCheck(orientation, rightLandscape, epsilon)) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); + disable(); + } + } + + private boolean epsilonCheck(int a, int b, int epsilon) { + return a > b - epsilon && a < b + epsilon; + } + }; + orientationEventListener.enable(); + } + } } if (postTitle != null) { - setTitle(Html.fromHtml(String.format("<small>%s</small>", postTitle))); + if (useBottomAppBar) { + titleTextView.setText(Html.fromHtml(String.format("<small>%s</small>", postTitle))); + } else { + setTitle(Html.fromHtml(String.format("<small>%s</small>", postTitle))); + } } else { - setTitle(""); + if (!useBottomAppBar) { + setTitle(""); + } } videoPlayerView.setControllerVisibilityListener(visibility -> { @@ -284,8 +373,9 @@ public class ViewVideoActivity extends AppCompatActivity { loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false); } } else { - dataSourceFactory = new DefaultDataSourceFactory(ViewVideoActivity.this, - Util.getUserAgent(ViewVideoActivity.this, "Infinity")); + dataSourceFactory = new CacheDataSourceFactory(mSimpleCache, + new DefaultDataSourceFactory(ViewVideoActivity.this, + Util.getUserAgent(ViewVideoActivity.this, "Infinity"))); player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); preparePlayer(savedInstanceState); } @@ -293,7 +383,8 @@ public class ViewVideoActivity extends AppCompatActivity { videoDownloadUrl = mVideoUri.toString(); videoFileName = FilenameUtils.getName(videoDownloadUrl); // Produces DataSource instances through which media data is loaded. - dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity")); + dataSourceFactory = new CacheDataSourceFactory(mSimpleCache, + new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity"))); // Prepare the player with the source. player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); preparePlayer(savedInstanceState); @@ -303,7 +394,8 @@ public class ViewVideoActivity extends AppCompatActivity { id = intent.getStringExtra(EXTRA_ID); videoFileName = subredditName + "-" + id + ".mp4"; // Produces DataSource instances through which media data is loaded. - dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity")); + dataSourceFactory = new CacheDataSourceFactory(mSimpleCache, + new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity"))); // Prepare the player with the source. player.prepare(new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); preparePlayer(savedInstanceState); @@ -385,15 +477,16 @@ public class ViewVideoActivity extends AppCompatActivity { private void loadGfycatOrRedgifsVideo(Retrofit retrofit, String gfycatId, Bundle savedInstanceState, boolean needErrorHandling) { progressBar.setVisibility(View.VISIBLE); - FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinks(retrofit, gfycatId, + FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinks(mExecutor, new Handler(), retrofit, gfycatId, new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { @Override public void success(String webm, String mp4) { progressBar.setVisibility(View.GONE); mVideoUri = Uri.parse(webm); videoDownloadUrl = mp4; - dataSourceFactory = new DefaultDataSourceFactory(ViewVideoActivity.this, - Util.getUserAgent(ViewVideoActivity.this, "Infinity")); + dataSourceFactory = new CacheDataSourceFactory(mSimpleCache, + new DefaultDataSourceFactory(ViewVideoActivity.this, + Util.getUserAgent(ViewVideoActivity.this, "Infinity"))); player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); preparePlayer(savedInstanceState); } @@ -430,54 +523,58 @@ public class ViewVideoActivity extends AppCompatActivity { List<String> segments = redirectUri.getPathSegments(); int commentsIndex = segments.lastIndexOf("comments"); String postId = segments.get(commentsIndex + 1); - FetchPost.fetchPost(retrofit, postId, null, new FetchPost.FetchPostListener() { - @Override - public void fetchPostSuccess(Post post) { - if (post.isGfycat()) { - videoType = VIDEO_TYPE_GFYCAT; - String gfycatId = post.getGfycatId(); - if (gfycatId != null && gfycatId.contains("-")) { - gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); + FetchPost.fetchPost(mExecutor, new Handler(), retrofit, postId, null, + new FetchPost.FetchPostListener() { + @Override + public void fetchPostSuccess(Post post) { + if (post.isGfycat()) { + videoType = VIDEO_TYPE_GFYCAT; + String gfycatId = post.getGfycatId(); + if (gfycatId != null && gfycatId.contains("-")) { + gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); + } + if (videoType == VIDEO_TYPE_GFYCAT) { + videoFileName = "Gfycat-" + gfycatId + ".mp4"; + } else { + videoFileName = "Redgifs-" + gfycatId + ".mp4"; + } + loadGfycatOrRedgifsVideo(gfycatRetrofit, gfycatId, savedInstanceState, true); + } else if (post.isRedgifs()) { + videoType = VIDEO_TYPE_REDGIFS; + String gfycatId = post.getGfycatId(); + if (gfycatId != null && gfycatId.contains("-")) { + gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); + } + if (videoType == VIDEO_TYPE_GFYCAT) { + videoFileName = "Gfycat-" + gfycatId + ".mp4"; + } else { + videoFileName = "Redgifs-" + gfycatId + ".mp4"; + } + loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false); + } else { + progressBar.setVisibility(View.INVISIBLE); + mVideoUri = Uri.parse(post.getVideoUrl()); + subredditName = post.getSubredditName(); + id = post.getId(); + videoDownloadUrl = post.getVideoDownloadUrl(); + + videoFileName = subredditName + "-" + id + ".mp4"; + // Produces DataSource instances through which media data is loaded. + dataSourceFactory = new CacheDataSourceFactory(mSimpleCache, + new DefaultHttpDataSourceFactory( + Util.getUserAgent(ViewVideoActivity.this, + "Infinity"))); + // Prepare the player with the source. + player.prepare(new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); + preparePlayer(savedInstanceState); + } } - if (videoType == VIDEO_TYPE_GFYCAT) { - videoFileName = "Gfycat-" + gfycatId + ".mp4"; - } else { - videoFileName = "Redgifs-" + gfycatId + ".mp4"; - } - loadGfycatOrRedgifsVideo(gfycatRetrofit, gfycatId, savedInstanceState, true); - } else if (post.isRedgifs()) { - videoType = VIDEO_TYPE_REDGIFS; - String gfycatId = post.getGfycatId(); - if (gfycatId != null && gfycatId.contains("-")) { - gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); - } - if (videoType == VIDEO_TYPE_GFYCAT) { - videoFileName = "Gfycat-" + gfycatId + ".mp4"; - } else { - videoFileName = "Redgifs-" + gfycatId + ".mp4"; - } - loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false); - } else { - progressBar.setVisibility(View.INVISIBLE); - mVideoUri = Uri.parse(post.getVideoUrl()); - subredditName = post.getSubredditName(); - id = post.getId(); - videoDownloadUrl = post.getVideoDownloadUrl(); - - videoFileName = subredditName + "-" + id + ".mp4"; - // Produces DataSource instances through which media data is loaded. - dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(ViewVideoActivity.this, "Infinity")); - // Prepare the player with the source. - player.prepare(new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); - preparePlayer(savedInstanceState); - } - } - @Override - public void fetchPostFailed() { - Toast.makeText(ViewVideoActivity.this, R.string.error_fetching_v_redd_it_video_cannot_get_post, Toast.LENGTH_LONG).show(); - } - }); + @Override + public void fetchPostFailed() { + Toast.makeText(ViewVideoActivity.this, R.string.error_fetching_v_redd_it_video_cannot_get_post, Toast.LENGTH_LONG).show(); + } + }); } else { Toast.makeText(ViewVideoActivity.this, R.string.error_fetching_v_redd_it_video_cannot_get_post_id, Toast.LENGTH_LONG).show(); } @@ -521,29 +618,33 @@ public class ViewVideoActivity extends AppCompatActivity { } isDownloading = true; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (ContextCompat.checkSelfPermission(this, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - ActivityCompat.requestPermissions(this, - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } + requestPermissionAndDownload(); return true; } return false; } + private void requestPermissionAndDownload() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + if (ContextCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + } + @Override protected void onStart() { super.onStart(); @@ -557,6 +658,9 @@ public class ViewVideoActivity extends AppCompatActivity { super.onStop(); wasPlaying = player.getPlayWhenReady(); player.setPlayWhenReady(false); + if (originalOrientation != null) { + setRequestedOrientation(originalOrientation); + } } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java new file mode 100644 index 00000000..f4cc17fa --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java @@ -0,0 +1,370 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.style.ClickableSpan; +import android.text.util.Linkify; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; +import com.google.android.material.appbar.AppBarLayout; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.commonmark.ext.gfm.tables.TableBlock; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.recycler.MarkwonAdapter; +import io.noties.markwon.recycler.table.TableEntry; +import io.noties.markwon.recycler.table.TableEntryPlugin; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; +import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class WikiActivity extends BaseActivity { + + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + private static final String WIKI_MARKDOWN_STATE = "WMS"; + + @BindView(R.id.coordinator_layout_comment_wiki_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_comment_wiki_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_comment_wiki_activity) + Toolbar toolbar; + @BindView(R.id.swipe_refresh_layout_wiki_activity) + SwipeRefreshLayout swipeRefreshLayout; + @BindView(R.id.content_markdown_view_comment_wiki_activity) + RecyclerView markdownRecyclerView; + @BindView(R.id.fetch_wiki_linear_layout_wiki_activity) + LinearLayout mFetchWikiInfoLinearLayout; + @BindView(R.id.fetch_wiki_image_view_wiki_activity) + ImageView mFetchWikiInfoImageView; + @BindView(R.id.fetch_wiki_text_view_wiki_activity) + TextView mFetchWikiInfoTextView; + + @Inject + @Named("no_oauth") + Retrofit retrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private SlidrInterface mSlidrInterface; + private String wikiMarkdown; + private Markwon markwon; + private MarkwonAdapter markwonAdapter; + private boolean isRefreshing = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_wiki); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + markdownRecyclerView.setPadding(markdownRecyclerView.getPaddingLeft(), 0, markdownRecyclerView.getPaddingRight(), getNavBarHeight()); + } + } + + swipeRefreshLayout.setEnabled(mSharedPreferences.getBoolean(SharedPreferencesUtils.PULL_TO_REFRESH, true)); + swipeRefreshLayout.setOnRefreshListener(this::loadWiki); + + int markdownColor = mCustomThemeWrapper.getPrimaryTextColor(); + int spoilerBackgroundColor = markdownColor | 0xFF000000; + int linkColor = mCustomThemeWrapper.getLinkColor(); + markwon = Markwon.builder(this) + .usePlugin(HtmlPlugin.create()) + .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + StringBuilder markdownStringBuilder = new StringBuilder(markdown); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + while (matcher.find()) { + markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); + } + return super.processMarkdown(markdownStringBuilder.toString()); + } + + @Override + public void afterSetText(@NonNull TextView textView) { + textView.setHighlightColor(Color.TRANSPARENT); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + int start = 0; + boolean find = false; + while (matcher.find(start)) { + if (markdownStringBuilder.length() < 4 + || matcher.start() < 0 + || matcher.end() > markdownStringBuilder.length()) { + break; + } + find = true; + markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); + markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); + ClickableSpan clickableSpan = new ClickableSpan() { + private boolean isShowing = false; + @Override + public void updateDrawState(@NonNull TextPaint ds) { + if (isShowing) { + super.updateDrawState(ds); + ds.setColor(markdownColor); + } else { + ds.bgColor = spoilerBackgroundColor; + ds.setColor(markdownColor); + } + ds.setUnderlineText(false); + } + + @Override + public void onClick(@NonNull View view) { + isShowing = !isShowing; + view.invalidate(); + } + }; + markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + start = matcher.end() - 4; + } + if (find) { + textView.setText(markdownStringBuilder); + } + } + + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + textView.setTextColor(markdownColor); + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(WikiActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(TableEntryPlugin.create(this)) + .build(); + + markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) + .include(TableBlock.class, TableEntry.create(builder -> builder + .tableLayout(R.layout.adapter_table_block, R.id.table_layout) + .textLayoutIsRoot(R.layout.view_table_entry_cell))) + .build(); + LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { + @Override + public void onScrolledLeft() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + @Override + public void onScrolledRight() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } + }); + markdownRecyclerView.setLayoutManager(linearLayoutManager); + markdownRecyclerView.setAdapter(markwonAdapter); + + if (savedInstanceState != null) { + wikiMarkdown = savedInstanceState.getString(WIKI_MARKDOWN_STATE); + } + + if (wikiMarkdown == null) { + loadWiki(); + } else { + markwonAdapter.setMarkdown(markwon, wikiMarkdown); + markwonAdapter.notifyDataSetChanged(); + } + } + + private void loadWiki() { + if (isRefreshing) { + return; + } + isRefreshing = true; + + swipeRefreshLayout.setRefreshing(true); + + Glide.with(this).clear(mFetchWikiInfoImageView); + mFetchWikiInfoLinearLayout.setVisibility(View.GONE); + + retrofit.create(RedditAPI.class).getWiki(getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME)).enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + try { + markwonAdapter.setMarkdown(markwon, new JSONObject(response.body()) + .getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.CONTENT_MD_KEY)); + markwonAdapter.notifyDataSetChanged(); + } catch (JSONException e) { + e.printStackTrace(); + showErrorView(R.string.error_loading_wiki); + } + } else { + if (response.code() == 404 || response.code() == 403) { + showErrorView(R.string.no_wiki); + } else { + showErrorView(R.string.error_loading_wiki); + } + } + isRefreshing = false; + swipeRefreshLayout.setRefreshing(false); + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + showErrorView(R.string.error_loading_wiki); + isRefreshing = false; + swipeRefreshLayout.setRefreshing(false); + } + }); + } + + private void showErrorView(int stringResId) { + swipeRefreshLayout.setRefreshing(false); + mFetchWikiInfoLinearLayout.setVisibility(View.VISIBLE); + mFetchWikiInfoTextView.setText(stringResId); + Glide.with(this).load(R.drawable.error_image).into(mFetchWikiInfoImageView); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(WIKI_MARKDOWN_STATE, wikiMarkdown); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + swipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); + swipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); + mFetchWikiInfoTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + if (!getClass().getName().equals(event.excludeActivityClassName)) { + finish(); + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java index f3a9c582..15dce401 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -16,6 +16,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; @@ -400,6 +401,8 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment public class CommentViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.vertical_block_indentation_item_comment) CommentIndentationView commentIndentationView; + @BindView(R.id.linear_layout_item_comment) + LinearLayout linearLayout; @BindView(R.id.author_text_view_item_post_comment) TextView authorTextView; @BindView(R.id.author_flair_text_view_item_post_comment) @@ -455,6 +458,8 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment constraintSet.applyTo(bottomConstraintLayout); } + linearLayout.getLayoutTransition().setAnimateParentHierarchy(false); + commentIndentationView.setVisibility(View.GONE); if (mShowCommentDivider) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java new file mode 100644 index 00000000..14f53a2d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java @@ -0,0 +1,1715 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.style.ClickableSpan; +import android.text.util.Linkify; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.constraintlayout.widget.ConstraintSet; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar; + +import java.util.ArrayList; +import java.util.Locale; +import java.util.concurrent.Executor; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.movement.MovementMethodPlugin; +import me.saket.bettermovementmethod.BetterLinkMovementMethod; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SaveThing; +import ml.docilealligator.infinityforreddit.VoteThing; +import ml.docilealligator.infinityforreddit.activities.CommentActivity; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPostDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CommentMoreBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; +import ml.docilealligator.infinityforreddit.comment.Comment; +import ml.docilealligator.infinityforreddit.comment.FetchComment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.CommentIndentationView; +import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Retrofit; + +public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private static final int VIEW_TYPE_FIRST_LOADING = 9; + private static final int VIEW_TYPE_FIRST_LOADING_FAILED = 10; + private static final int VIEW_TYPE_NO_COMMENT_PLACEHOLDER = 11; + private static final int VIEW_TYPE_COMMENT = 12; + private static final int VIEW_TYPE_COMMENT_FULLY_COLLAPSED = 13; + private static final int VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS = 14; + private static final int VIEW_TYPE_IS_LOADING_MORE_COMMENTS = 15; + private static final int VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED = 16; + private static final int VIEW_TYPE_VIEW_ALL_COMMENTS = 17; + + private AppCompatActivity mActivity; + private ViewPostDetailFragment mFragment; + private Executor mExecutor; + private Retrofit mRetrofit; + private Retrofit mOauthRetrofit; + private Markwon mCommentMarkwon; + private String mAccessToken; + private String mAccountName; + private Post mPost; + private ArrayList<Comment> mVisibleComments; + private Locale mLocale; + private String mSingleCommentId; + private boolean mIsSingleCommentThreadMode; + private boolean mVoteButtonsOnTheRight; + private boolean mShowElapsedTime; + private String mTimeFormatPattern; + private boolean mExpandChildren; + private boolean mCommentToolbarHidden; + private boolean mCommentToolbarHideOnClick; + private boolean mSwapTapAndLong; + private boolean mShowCommentDivider; + private boolean mShowAbsoluteNumberOfVotes; + private boolean mFullyCollapseComment; + private boolean mShowOnlyOneCommentLevelIndicator; + private CommentRecyclerViewAdapterCallback mCommentRecyclerViewAdapterCallback; + private boolean isInitiallyLoading; + private boolean isInitiallyLoadingFailed; + private boolean mHasMoreComments; + private boolean loadMoreCommentsFailed; + + private int depthThreshold = 5; + private int mColorPrimaryLightTheme; + private int mColorAccent; + private int mCircularProgressBarBackgroundColor; + private int mSecondaryTextColor; + private int mPrimaryTextColor; + private int mCommentTextColor; + private int mCommentBackgroundColor; + private int mDividerColor; + private int mUsernameColor; + private int mSubmitterColor; + private int mModeratorColor; + private int mCurrentUserColor; + private int mAuthorFlairTextColor; + private int mUpvotedColor; + private int mDownvotedColor; + private int mSingleCommentThreadBackgroundColor; + private int mVoteAndReplyUnavailableVoteButtonColor; + private int mButtonTextColor; + private int mPostIconAndInfoColor; + private int mCommentIconAndInfoColor; + private int mFullyCollapsedCommentBackgroundColor; + private int mAwardedCommentBackgroundColor; + private Integer[] verticalBlockColors; + + private Drawable mCommentIcon; + + private int mSearchCommentIndex = -1; + + public CommentsRecyclerViewAdapter(AppCompatActivity activity, ViewPostDetailFragment fragment, + CustomThemeWrapper customThemeWrapper, + Executor executor, Retrofit retrofit, Retrofit oauthRetrofit, + String accessToken, String accountName, + Post post, Locale locale, String singleCommentId, + boolean isSingleCommentThreadMode, + SharedPreferences sharedPreferences, + CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) { + mActivity = activity; + mFragment = fragment; + mExecutor = executor; + mRetrofit = retrofit; + mOauthRetrofit = oauthRetrofit; + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + mCommentTextColor = customThemeWrapper.getCommentColor(); + int commentSpoilerBackgroundColor = mCommentTextColor | 0xFF000000; + int linkColor = customThemeWrapper.getLinkColor(); + mCommentMarkwon = Markwon.builder(mActivity) + .usePlugin(HtmlPlugin.create()) + .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + StringBuilder markdownStringBuilder = new StringBuilder(markdown); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + while (matcher.find()) { + markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); + } + return super.processMarkdown(markdownStringBuilder.toString()); + } + + @Override + public void afterSetText(@NonNull TextView textView) { + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + int start = 0; + boolean find = false; + while (matcher.find(start)) { + if (markdownStringBuilder.length() < 4 + || matcher.start() < 0 + || matcher.end() > markdownStringBuilder.length()) { + break; + } + find = true; + markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); + markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); + ClickableSpan clickableSpan = new ClickableSpan() { + private boolean isShowing = false; + @Override + public void updateDrawState(@NonNull TextPaint ds) { + if (isShowing) { + super.updateDrawState(ds); + ds.setColor(mCommentTextColor); + } else { + ds.bgColor = commentSpoilerBackgroundColor; + ds.setColor(mCommentTextColor); + } + ds.setUnderlineText(false); + } + + @Override + public void onClick(@NonNull View view) { + isShowing = !isShowing; + view.invalidate(); + } + }; + markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + start = matcher.end() - 4; + } + if (find) { + textView.setText(markdownStringBuilder); + } + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS, activity).setOnLinkLongClickListener((textView, url) -> { + if (!activity.isDestroyed() && !activity.isFinishing()) { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); + urlMenuBottomSheetFragment.setArguments(bundle); + urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); + } + return true; + }))) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .build(); + mAccessToken = accessToken; + mAccountName = accountName; + mPost = post; + mVisibleComments = new ArrayList<>(); + mLocale = locale; + mSingleCommentId = singleCommentId; + mIsSingleCommentThreadMode = isSingleCommentThreadMode; + + mVoteButtonsOnTheRight = sharedPreferences.getBoolean(SharedPreferencesUtils.VOTE_BUTTONS_ON_THE_RIGHT_KEY, false); + mShowElapsedTime = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY, false); + mTimeFormatPattern = sharedPreferences.getString(SharedPreferencesUtils.TIME_FORMAT_KEY, SharedPreferencesUtils.TIME_FORMAT_DEFAULT_VALUE); + mExpandChildren = !sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_TOP_LEVEL_COMMENTS_FIRST, false); + mCommentToolbarHidden = sharedPreferences.getBoolean(SharedPreferencesUtils.COMMENT_TOOLBAR_HIDDEN, false); + mCommentToolbarHideOnClick = sharedPreferences.getBoolean(SharedPreferencesUtils.COMMENT_TOOLBAR_HIDE_ON_CLICK, true); + mSwapTapAndLong = sharedPreferences.getBoolean(SharedPreferencesUtils.SWAP_TAP_AND_LONG_COMMENTS, false); + mShowCommentDivider = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_COMMENT_DIVIDER, false); + mShowAbsoluteNumberOfVotes = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ABSOLUTE_NUMBER_OF_VOTES, true); + + mFullyCollapseComment = sharedPreferences.getBoolean(SharedPreferencesUtils.FULLY_COLLAPSE_COMMENT, false); + + mShowOnlyOneCommentLevelIndicator = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ONLY_ONE_COMMENT_LEVEL_INDICATOR, false); + + mCommentRecyclerViewAdapterCallback = commentRecyclerViewAdapterCallback; + isInitiallyLoading = true; + isInitiallyLoadingFailed = false; + mHasMoreComments = false; + loadMoreCommentsFailed = false; + + mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); + mColorAccent = customThemeWrapper.getColorAccent(); + mCircularProgressBarBackgroundColor = customThemeWrapper.getCircularProgressBarBackground(); + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mDividerColor = customThemeWrapper.getDividerColor(); + mCommentBackgroundColor = customThemeWrapper.getCommentBackgroundColor(); + mSubmitterColor = customThemeWrapper.getSubmitter(); + mModeratorColor = customThemeWrapper.getModerator(); + mCurrentUserColor = customThemeWrapper.getCurrentUser(); + mAuthorFlairTextColor = customThemeWrapper.getAuthorFlairTextColor(); + mUsernameColor = customThemeWrapper.getUsername(); + mUpvotedColor = customThemeWrapper.getUpvoted(); + mDownvotedColor = customThemeWrapper.getDownvoted(); + mSingleCommentThreadBackgroundColor = customThemeWrapper.getSingleCommentThreadBackgroundColor(); + mVoteAndReplyUnavailableVoteButtonColor = customThemeWrapper.getVoteAndReplyUnavailableButtonColor(); + mButtonTextColor = customThemeWrapper.getButtonTextColor(); + mPostIconAndInfoColor = customThemeWrapper.getPostIconAndInfoColor(); + mCommentIconAndInfoColor = customThemeWrapper.getCommentIconAndInfoColor(); + mFullyCollapsedCommentBackgroundColor = customThemeWrapper.getFullyCollapsedCommentBackgroundColor(); + mAwardedCommentBackgroundColor = customThemeWrapper.getAwardedCommentBackgroundColor(); + + verticalBlockColors = new Integer[] { + customThemeWrapper.getCommentVerticalBarColor1(), + customThemeWrapper.getCommentVerticalBarColor2(), + customThemeWrapper.getCommentVerticalBarColor3(), + customThemeWrapper.getCommentVerticalBarColor4(), + customThemeWrapper.getCommentVerticalBarColor5(), + customThemeWrapper.getCommentVerticalBarColor6(), + customThemeWrapper.getCommentVerticalBarColor7(), + }; + + mCommentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); + if (mCommentIcon != null) { + DrawableCompat.setTint(mCommentIcon, mPostIconAndInfoColor); + } + } + + @Override + public int getItemViewType(int position) { + if (mVisibleComments.size() == 0) { + if (isInitiallyLoading) { + return VIEW_TYPE_FIRST_LOADING; + } else if (isInitiallyLoadingFailed) { + return VIEW_TYPE_FIRST_LOADING_FAILED; + } else { + return VIEW_TYPE_NO_COMMENT_PLACEHOLDER; + } + } + + if (mIsSingleCommentThreadMode) { + if (position == 0) { + return VIEW_TYPE_VIEW_ALL_COMMENTS; + } + + if (position == mVisibleComments.size() + 1) { + if (mHasMoreComments) { + return VIEW_TYPE_IS_LOADING_MORE_COMMENTS; + } else { + return VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED; + } + } + + Comment comment = mVisibleComments.get(position - 1); + if (comment.getPlaceholderType() == Comment.NOT_PLACEHOLDER) { + if (mFullyCollapseComment && !comment.isExpanded() && comment.hasExpandedBefore()) { + return VIEW_TYPE_COMMENT_FULLY_COLLAPSED; + } + return VIEW_TYPE_COMMENT; + } else { + return VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS; + } + } else { + if (position == mVisibleComments.size()) { + if (mHasMoreComments) { + return VIEW_TYPE_IS_LOADING_MORE_COMMENTS; + } else { + return VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED; + } + } + + Comment comment = mVisibleComments.get(position); + if (comment.getPlaceholderType() == Comment.NOT_PLACEHOLDER) { + if (mFullyCollapseComment && !comment.isExpanded() && comment.hasExpandedBefore()) { + return VIEW_TYPE_COMMENT_FULLY_COLLAPSED; + } + return VIEW_TYPE_COMMENT; + } else { + return VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS; + } + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + switch (viewType) { + case VIEW_TYPE_FIRST_LOADING: + return new LoadCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments, parent, false)); + case VIEW_TYPE_FIRST_LOADING_FAILED: + return new LoadCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments_failed_placeholder, parent, false)); + case VIEW_TYPE_NO_COMMENT_PLACEHOLDER: + return new NoCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_no_comment_placeholder, parent, false)); + case VIEW_TYPE_COMMENT: + return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); + case VIEW_TYPE_COMMENT_FULLY_COLLAPSED: + return new CommentFullyCollapsedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_fully_collapsed, parent, false)); + case VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS: + return new LoadMoreChildCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_more_comments_placeholder, parent, false)); + case VIEW_TYPE_IS_LOADING_MORE_COMMENTS: + return new IsLoadingMoreCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_footer_loading, parent, false)); + case VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED: + return new LoadMoreCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_footer_error, parent, false)); + default: + return new ViewAllCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_all_comments, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof CommentViewHolder) { + Comment comment = getCurrentComment(position); + if (comment != null) { + if (mIsSingleCommentThreadMode && comment.getId().equals(mSingleCommentId)) { + holder.itemView.setBackgroundColor(mSingleCommentThreadBackgroundColor); + } else if (comment.getAwards() != null && !comment.getAwards().equals("")) { + holder.itemView.setBackgroundColor(mAwardedCommentBackgroundColor); + } + + String authorPrefixed = "u/" + comment.getAuthor(); + ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed); + + if (comment.getAuthorFlairHTML() != null && !comment.getAuthorFlairHTML().equals("")) { + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).authorFlairTextView, comment.getAuthorFlairHTML(), true); + } else if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) { + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); + ((CommentViewHolder) holder).authorFlairTextView.setText(comment.getAuthorFlair()); + } + + if (comment.isSubmitter()) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mSubmitterColor); + Drawable submitterDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_mic_14dp, mSubmitterColor); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( + submitterDrawable, null, null, null); + } else if (comment.isModerator()) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mModeratorColor); + Drawable moderatorDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_verified_user_14dp, mModeratorColor); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( + moderatorDrawable, null, null, null); + } else if (comment.getAuthor().equals(mAccountName)) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mCurrentUserColor); + Drawable currentUserDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_current_user_14dp, mCurrentUserColor); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( + currentUserDrawable, null, null, null); + } + + if (mShowElapsedTime) { + ((CommentViewHolder) holder).commentTimeTextView.setText( + Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); + } else { + ((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); + } + + if (mCommentToolbarHidden) { + ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = 0; + ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.VISIBLE); + } else { + ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; + ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.GONE); + } + + if (comment.getAwards() != null && !comment.getAwards().equals("")) { + ((CommentViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).awardsTextView, comment.getAwards(), true); + } + + mCommentMarkwon.setMarkdown(((CommentViewHolder) holder).commentMarkdownView, comment.getCommentMarkdown()); + ((CommentViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + ((CommentViewHolder) holder).topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + + ((CommentViewHolder) holder).commentIndentationView.setShowOnlyOneDivider(mShowOnlyOneCommentLevelIndicator); + ((CommentViewHolder) holder).commentIndentationView.setLevelAndColors(comment.getDepth(), verticalBlockColors); + if (comment.getDepth() > depthThreshold) { + ((CommentViewHolder) holder).saveButton.setVisibility(View.GONE); + ((CommentViewHolder) holder).replyButton.setVisibility(View.GONE); + } else { + ((CommentViewHolder) holder).saveButton.setVisibility(View.VISIBLE); + ((CommentViewHolder) holder).replyButton.setVisibility(View.VISIBLE); + } + + if (comment.hasReply()) { + if (comment.isExpanded()) { + ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); + } else { + ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); + } + ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); + } + + switch (comment.getVoteType()) { + case Comment.VOTE_TYPE_UPVOTE: + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + ((CommentViewHolder) holder).topScoreTextView.setTextColor(mUpvotedColor); + break; + case Comment.VOTE_TYPE_DOWNVOTE: + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + ((CommentViewHolder) holder).topScoreTextView.setTextColor(mDownvotedColor); + break; + } + + if (mPost.isArchived()) { + ((CommentViewHolder) holder).replyButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (mPost.isLocked()) { + ((CommentViewHolder) holder).replyButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (comment.isSaved()) { + ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + + if (position == mSearchCommentIndex) { + holder.itemView.setBackgroundColor(Color.parseColor("#03A9F4")); + } + } + } else if (holder instanceof CommentFullyCollapsedViewHolder) { + Comment comment = getCurrentComment(position); + if (comment != null) { + String authorWithPrefix = "u/" + comment.getAuthor(); + ((CommentFullyCollapsedViewHolder) holder).usernameTextView.setText(authorWithPrefix); + if (mShowElapsedTime) { + ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); + } else { + ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); + } + ((CommentFullyCollapsedViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType()))); + ((CommentFullyCollapsedViewHolder) holder).commentIndentationView.setShowOnlyOneDivider(mShowOnlyOneCommentLevelIndicator); + ((CommentFullyCollapsedViewHolder) holder).commentIndentationView.setLevelAndColors(comment.getDepth(), verticalBlockColors); + } + } else if (holder instanceof LoadMoreChildCommentsViewHolder) { + Comment placeholder; + placeholder = mIsSingleCommentThreadMode ? mVisibleComments.get(holder.getBindingAdapterPosition() - 1) + : mVisibleComments.get(holder.getBindingAdapterPosition()); + + ((LoadMoreChildCommentsViewHolder) holder).commentIndentationView.setShowOnlyOneDivider(mShowOnlyOneCommentLevelIndicator); + ((LoadMoreChildCommentsViewHolder) holder).commentIndentationView.setLevelAndColors(placeholder.getDepth(), verticalBlockColors); + + if (placeholder.getPlaceholderType() == Comment.PLACEHOLDER_LOAD_MORE_COMMENTS) { + if (placeholder.isLoadingMoreChildren()) { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); + } else if (placeholder.isLoadMoreChildrenFailed()) { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + } else { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); + } + } else { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_continue_thread); + } + + if (placeholder.getPlaceholderType() == Comment.PLACEHOLDER_LOAD_MORE_COMMENTS) { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setOnClickListener(view -> { + int commentPosition = mIsSingleCommentThreadMode ? holder.getBindingAdapterPosition() - 1 : holder.getBindingAdapterPosition(); + int parentPosition = getParentPosition(commentPosition); + if (parentPosition >= 0) { + Comment parentComment = mVisibleComments.get(parentPosition); + + mVisibleComments.get(commentPosition).setLoadingMoreChildren(true); + mVisibleComments.get(commentPosition).setLoadMoreChildrenFailed(false); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); + + Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; + FetchComment.fetchMoreComment(mExecutor, new Handler(), retrofit, mAccessToken, + parentComment.getMoreChildrenFullnames(), + parentComment.getMoreChildrenStartingIndex(), parentComment.getDepth() + 1, + mExpandChildren, new FetchComment.FetchMoreCommentListener() { + @Override + public void onFetchMoreCommentSuccess(ArrayList<Comment> expandedComments, + int childrenStartingIndex) { + if (mVisibleComments.size() > parentPosition + && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { + if (mVisibleComments.get(parentPosition).isExpanded()) { + if (mVisibleComments.get(parentPosition).getChildren().size() > childrenStartingIndex) { + mVisibleComments.get(parentPosition).setMoreChildrenStartingIndex(childrenStartingIndex); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadMoreChildrenFailed(false); + + int placeholderPosition = commentPosition; + if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; + break; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); + + mVisibleComments.addAll(placeholderPosition, expandedComments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); + } else { + notifyItemRangeInserted(placeholderPosition, expandedComments.size()); + } + } else { + mVisibleComments.get(parentPosition).getChildren() + .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); + mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); + + int placeholderPosition = commentPosition; + if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; + break; + } + } + } + + mVisibleComments.remove(placeholderPosition); + if (mIsSingleCommentThreadMode) { + notifyItemRemoved(placeholderPosition + 1); + } else { + notifyItemRemoved(placeholderPosition); + } + + mVisibleComments.addAll(placeholderPosition, expandedComments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); + } else { + notifyItemRangeInserted(placeholderPosition, expandedComments.size()); + } + } + } else { + if (mVisibleComments.get(parentPosition).hasReply() && mVisibleComments.get(parentPosition).getChildren().size() <= childrenStartingIndex) { + mVisibleComments.get(parentPosition).getChildren() + .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); + mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); + } + } + + mVisibleComments.get(parentPosition).addChildren(expandedComments); + } else { + for (int i = 0; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + if (mVisibleComments.get(i).isExpanded()) { + int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); + + if (!mVisibleComments.get(i).getFullName() + .equals(mVisibleComments.get(placeholderPosition).getFullName())) { + for (int j = i + 1; j < mVisibleComments.size(); j++) { + if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { + placeholderPosition = j; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); + + mVisibleComments.addAll(placeholderPosition, expandedComments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); + } else { + notifyItemRangeInserted(placeholderPosition, expandedComments.size()); + } + } + + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) + .setLoadMoreChildrenFailed(false); + mVisibleComments.get(i).addChildren(expandedComments); + + break; + } + } + } + } + + @Override + public void onFetchMoreCommentFailed() { + if (parentPosition < mVisibleComments.size() + && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { + if (mVisibleComments.get(parentPosition).isExpanded()) { + int commentPosition = mIsSingleCommentThreadMode ? holder.getBindingAdapterPosition() - 1 : holder.getBindingAdapterPosition(); + int placeholderPosition = commentPosition; + if (commentPosition >= mVisibleComments.size() || commentPosition < 0 || !mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; + break; + } + } + } + + if (placeholderPosition >= mVisibleComments.size() || placeholderPosition < 0) { + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); + } + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + } + + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadMoreChildrenFailed(true); + } else { + for (int i = 0; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + if (mVisibleComments.get(i).isExpanded()) { + int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); + if (!mVisibleComments.get(placeholderPosition).getFullName().equals(mVisibleComments.get(i).getFullName())) { + for (int j = i + 1; j < mVisibleComments.size(); j++) { + if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { + placeholderPosition = j; + break; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + } + + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadingMoreChildren(false); + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadMoreChildrenFailed(true); + + break; + } + } + } + } + }); + } + }); + } else { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setOnClickListener(view -> { + Comment comment = getCurrentComment(position); + if (comment != null) { + Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mPost); + intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getParentId()); + intent.putExtra(ViewPostDetailActivity.EXTRA_CONTEXT_NUMBER, "0"); + mActivity.startActivity(intent); + } + }); + } + } + } + + private int getParentPosition(int position) { + if (position >= 0 && position < mVisibleComments.size()) { + int childDepth = mVisibleComments.get(position).getDepth(); + for (int i = position; i >= 0; i--) { + if (mVisibleComments.get(i).getDepth() < childDepth) { + return i; + } + } + } + return -1; + } + + private void expandChildren(ArrayList<Comment> comments, ArrayList<Comment> newList, int position) { + if (comments != null && comments.size() > 0) { + newList.addAll(position, comments); + for (int i = 0; i < comments.size(); i++) { + position++; + if (comments.get(i).getChildren() != null && comments.get(i).getChildren().size() > 0) { + expandChildren(comments.get(i).getChildren(), newList, position); + position = position + comments.get(i).getChildren().size(); + } + comments.get(i).setExpanded(true); + } + } + } + + private void collapseChildren(int position) { + mVisibleComments.get(position).setExpanded(false); + int depth = mVisibleComments.get(position).getDepth(); + int allChildrenSize = 0; + for (int i = position + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getDepth() > depth) { + allChildrenSize++; + } else { + break; + } + } + + if (allChildrenSize > 0) { + mVisibleComments.subList(position + 1, position + 1 + allChildrenSize).clear(); + } + if (mIsSingleCommentThreadMode) { + notifyItemRangeRemoved(position + 2, allChildrenSize); + if (mFullyCollapseComment) { + notifyItemChanged(position + 1); + } + } else { + notifyItemRangeRemoved(position + 1, allChildrenSize); + if (mFullyCollapseComment) { + notifyItemChanged(position); + } + } + } + + public void addComments(@NonNull ArrayList<Comment> comments, boolean hasMoreComments) { + if (mVisibleComments.size() == 0) { + isInitiallyLoading = false; + isInitiallyLoadingFailed = false; + if (comments.size() == 0) { + notifyItemChanged(0); + } else { + notifyItemRemoved(0); + } + } + + int sizeBefore = mVisibleComments.size(); + mVisibleComments.addAll(comments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(sizeBefore, comments.size() + 1); + } else { + notifyItemRangeInserted(sizeBefore, comments.size()); + } + + if (mHasMoreComments != hasMoreComments) { + if (hasMoreComments) { + if (mIsSingleCommentThreadMode) { + notifyItemInserted(mVisibleComments.size() + 1); + } else { + notifyItemInserted(mVisibleComments.size()); + } + } else { + if (mIsSingleCommentThreadMode) { + notifyItemRemoved(mVisibleComments.size() + 1); + } else { + notifyItemRemoved(mVisibleComments.size()); + } + } + } + mHasMoreComments = hasMoreComments; + } + + public void addComment(Comment comment) { + if (mVisibleComments.size() == 0 || isInitiallyLoadingFailed) { + notifyItemRemoved(1); + } + + mVisibleComments.add(0, comment); + + if (isInitiallyLoading) { + notifyItemInserted(1); + } else { + notifyItemInserted(0); + } + } + + public void addChildComment(Comment comment, String parentFullname, int parentPosition) { + if (!parentFullname.equals(mVisibleComments.get(parentPosition).getFullName())) { + for (int i = 0; i < mVisibleComments.size(); i++) { + if (parentFullname.equals(mVisibleComments.get(i).getFullName())) { + parentPosition = i; + break; + } + } + } + + mVisibleComments.get(parentPosition).addChild(comment); + mVisibleComments.get(parentPosition).setHasReply(true); + if (!mVisibleComments.get(parentPosition).isExpanded()) { + ArrayList<Comment> newList = new ArrayList<>(); + expandChildren(mVisibleComments.get(parentPosition).getChildren(), newList, 0); + mVisibleComments.get(parentPosition).setExpanded(true); + mVisibleComments.addAll(parentPosition + 1, newList); + if (mIsSingleCommentThreadMode) { + notifyItemChanged(parentPosition + 1); + notifyItemRangeInserted(parentPosition + 2, newList.size()); + } else { + notifyItemChanged(parentPosition); + notifyItemRangeInserted(parentPosition + 1, newList.size()); + } + } else { + mVisibleComments.add(parentPosition + 1, comment); + if (mIsSingleCommentThreadMode) { + notifyItemInserted(parentPosition + 2); + } else { + notifyItemInserted(parentPosition + 1); + } + } + } + + public void setSingleComment(String singleCommentId, boolean isSingleCommentThreadMode) { + mSingleCommentId = singleCommentId; + mIsSingleCommentThreadMode = isSingleCommentThreadMode; + } + + public ArrayList<Comment> getVisibleComments() { + return mVisibleComments; + } + + public void initiallyLoading() { + resetCommentSearchIndex(); + notifyItemRangeRemoved(0, getItemCount()); + mVisibleComments.clear(); + isInitiallyLoading = true; + isInitiallyLoadingFailed = false; + notifyItemInserted(0); + } + + public void initiallyLoadCommentsFailed() { + isInitiallyLoading = false; + isInitiallyLoadingFailed = true; + notifyItemChanged(0); + } + + public void loadMoreCommentsFailed() { + loadMoreCommentsFailed = true; + if (mIsSingleCommentThreadMode) { + notifyItemChanged(mVisibleComments.size() + 1); + } else { + notifyItemChanged(mVisibleComments.size()); + } + } + + public void editComment(String commentAuthor, String commentContentMarkdown, int position) { + if (commentAuthor != null) + mVisibleComments.get(position).setAuthor(commentAuthor); + + mVisibleComments.get(position).setCommentMarkdown(commentContentMarkdown); + if (mIsSingleCommentThreadMode) { + notifyItemChanged(position + 1); + } else { + notifyItemChanged(position); + } + } + + public void deleteComment(int position) { + if (mVisibleComments != null && position >= 0 && position < mVisibleComments.size()) { + if (mVisibleComments.get(position).hasReply()) { + mVisibleComments.get(position).setAuthor("[deleted]"); + mVisibleComments.get(position).setCommentMarkdown("[deleted]"); + if (mIsSingleCommentThreadMode) { + notifyItemChanged(position + 1); + } else { + notifyItemChanged(position); + } + } else { + mVisibleComments.remove(position); + if (mIsSingleCommentThreadMode) { + notifyItemRemoved(position + 1); + } else { + notifyItemRemoved(position); + } + } + } + } + + public int getNextParentCommentPosition(int currentPosition) { + if (mVisibleComments != null && !mVisibleComments.isEmpty()) { + if (mIsSingleCommentThreadMode) { + for (int i = currentPosition + 1; i - 1 < mVisibleComments.size() && i - 1 >= 0; i++) { + if (mVisibleComments.get(i - 1).getDepth() == 0) { + return i; + } + } + } else { + for (int i = currentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getDepth() == 0) { + return i; + } + } + } + } + return -1; + } + + public int getPreviousParentCommentPosition(int currentPosition) { + if (mVisibleComments != null && !mVisibleComments.isEmpty()) { + if (mIsSingleCommentThreadMode) { + for (int i = currentPosition - 1; i - 1 >= 0; i--) { + if (mVisibleComments.get(i - 1).getDepth() == 0) { + return i; + } + } + } else { + for (int i = currentPosition - 1; i >= 0; i--) { + if (mVisibleComments.get(i).getDepth() == 0) { + return i; + } + } + } + } + return -1; + } + + public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction, int swipeLeftAction, int swipeRightAction) { + if (viewHolder instanceof CommentViewHolder) { + if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((CommentViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((CommentViewHolder) viewHolder).downvoteButton.performClick(); + } + } else { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((CommentViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((CommentViewHolder) viewHolder).downvoteButton.performClick(); + } + } + } + } + + public void giveAward(String awardsHTML, int awardCount, int position) { + position = mIsSingleCommentThreadMode ? position + 1 : position; + Comment comment = getCurrentComment(position); + if (comment != null) { + comment.addAwards(awardsHTML); + notifyItemChanged(position); + } + } + + public void setSaveComment(int position, boolean isSaved) { + Comment comment = getCurrentComment(position); + if (comment != null) { + comment.setSaved(isSaved); + } + } + + public int getSearchCommentIndex() { + return mSearchCommentIndex; + } + + public void highlightSearchResult(int searchCommentIndex) { + mSearchCommentIndex = searchCommentIndex; + } + + public void resetCommentSearchIndex() { + mSearchCommentIndex = -1; + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if (holder instanceof CommentViewHolder) { + holder.itemView.setBackgroundColor(mCommentBackgroundColor); + ((CommentViewHolder) holder).authorTextView.setTextColor(mUsernameColor); + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); + ((CommentViewHolder) holder).topScoreTextView.setTextColor(mSecondaryTextColor); + ((CommentViewHolder) holder).awardsTextView.setText(""); + ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); + ((CommentViewHolder) holder).expandButton.setVisibility(View.GONE); + ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); + ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + } + + @Override + public int getItemCount() { + if (isInitiallyLoading || isInitiallyLoadingFailed || mVisibleComments.size() == 0) { + return 1; + } + + if (mHasMoreComments || loadMoreCommentsFailed) { + if (mIsSingleCommentThreadMode) { + return mVisibleComments.size() + 2; + } else { + return mVisibleComments.size() + 1; + } + } + + if (mIsSingleCommentThreadMode) { + return mVisibleComments.size() + 1; + } else { + return mVisibleComments.size(); + } + } + + public interface CommentRecyclerViewAdapterCallback { + void retryFetchingComments(); + + void retryFetchingMoreComments(); + } + + public class CommentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.linear_layout_item_comment) + LinearLayout linearLayout; + @BindView(R.id.author_text_view_item_post_comment) + TextView authorTextView; + @BindView(R.id.author_flair_text_view_item_post_comment) + TextView authorFlairTextView; + @BindView(R.id.comment_time_text_view_item_post_comment) + TextView commentTimeTextView; + @BindView(R.id.top_score_text_view_item_post_comment) + TextView topScoreTextView; + @BindView(R.id.awards_text_view_item_comment) + TextView awardsTextView; + @BindView(R.id.comment_markdown_view_item_post_comment) + TextView commentMarkdownView; + @BindView(R.id.bottom_constraint_layout_item_post_comment) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.up_vote_button_item_post_comment) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_comment) + TextView scoreTextView; + @BindView(R.id.down_vote_button_item_post_comment) + ImageView downvoteButton; + @BindView(R.id.more_button_item_post_comment) + ImageView moreButton; + @BindView(R.id.save_button_item_post_comment) + ImageView saveButton; + @BindView(R.id.expand_button_item_post_comment) + ImageView expandButton; + @BindView(R.id.reply_button_item_post_comment) + ImageView replyButton; + @BindView(R.id.vertical_block_indentation_item_comment) + CommentIndentationView commentIndentationView; + @BindView(R.id.divider_item_comment) + View commentDivider; + + CommentViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + if (mVoteButtonsOnTheRight) { + ConstraintSet constraintSet = new ConstraintSet(); + constraintSet.clone(bottomConstraintLayout); + constraintSet.clear(upvoteButton.getId(), ConstraintSet.START); + constraintSet.clear(scoreTextView.getId(), ConstraintSet.START); + constraintSet.clear(downvoteButton.getId(), ConstraintSet.START); + constraintSet.clear(expandButton.getId(), ConstraintSet.END); + constraintSet.clear(saveButton.getId(), ConstraintSet.END); + constraintSet.clear(replyButton.getId(), ConstraintSet.END); + constraintSet.clear(moreButton.getId(), ConstraintSet.END); + constraintSet.connect(upvoteButton.getId(), ConstraintSet.END, scoreTextView.getId(), ConstraintSet.START); + constraintSet.connect(scoreTextView.getId(), ConstraintSet.END, downvoteButton.getId(), ConstraintSet.START); + constraintSet.connect(downvoteButton.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END); + constraintSet.connect(moreButton.getId(), ConstraintSet.START, expandButton.getId(), ConstraintSet.END); + constraintSet.connect(expandButton.getId(), ConstraintSet.START, saveButton.getId(), ConstraintSet.END); + constraintSet.connect(saveButton.getId(), ConstraintSet.START, replyButton.getId(), ConstraintSet.END); + constraintSet.connect(replyButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); + constraintSet.setHorizontalBias(moreButton.getId(), 0); + constraintSet.applyTo(bottomConstraintLayout); + } + + if (linearLayout.getLayoutTransition() != null) { + linearLayout.getLayoutTransition().setAnimateParentHierarchy(false); + } + + if (mShowCommentDivider) { + commentDivider.setBackgroundColor(mDividerColor); + commentDivider.setVisibility(View.VISIBLE); + } + + itemView.setBackgroundColor(mCommentBackgroundColor); + authorTextView.setTextColor(mUsernameColor); + commentTimeTextView.setTextColor(mSecondaryTextColor); + commentMarkdownView.setTextColor(mCommentTextColor); + authorFlairTextView.setTextColor(mAuthorFlairTextColor); + topScoreTextView.setTextColor(mSecondaryTextColor); + awardsTextView.setTextColor(mSecondaryTextColor); + commentDivider.setBackgroundColor(mDividerColor); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + moreButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + expandButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + saveButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + authorFlairTextView.setOnClickListener(view -> authorTextView.performClick()); + + moreButton.setOnClickListener(view -> { + getItemCount(); + Comment comment = getCurrentComment(this); + if (comment != null) { + Bundle bundle = new Bundle(); + if (!mPost.isArchived() && !mPost.isLocked() && comment.getAuthor().equals(mAccountName)) { + bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_EDIT_AND_DELETE_AVAILABLE, true); + } + bundle.putString(CommentMoreBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putParcelable(CommentMoreBottomSheetFragment.EXTRA_COMMENT, comment); + if (mIsSingleCommentThreadMode) { + bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getBindingAdapterPosition() - 1); + } else { + bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getBindingAdapterPosition()); + } + bundle.putString(CommentMoreBottomSheetFragment.EXTRA_COMMENT_MARKDOWN, comment.getCommentMarkdown()); + bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_IS_NSFW, mPost.isNSFW()); + if (comment.getDepth() > depthThreshold) { + bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_SHOW_REPLY_AND_SAVE_OPTION, true); + } + CommentMoreBottomSheetFragment commentMoreBottomSheetFragment = new CommentMoreBottomSheetFragment(); + commentMoreBottomSheetFragment.setArguments(bundle); + commentMoreBottomSheetFragment.show(mActivity.getSupportFragmentManager(), commentMoreBottomSheetFragment.getTag()); + } + }); + + replyButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_reply_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mPost.isLocked()) { + Toast.makeText(mActivity, R.string.locked_post_reply_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + Comment comment = getCurrentComment(this); + if (comment != null) { + Intent intent = new Intent(mActivity, CommentActivity.class); + intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, comment.getDepth() + 1); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, comment.getCommentMarkdown()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, comment.getCommentRawText()); + intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, comment.getFullName()); + intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true); + + int parentPosition = mIsSingleCommentThreadMode ? getBindingAdapterPosition() - 1 : getBindingAdapterPosition(); + intent.putExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, parentPosition); + mFragment.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE); + } + }); + + upvoteButton.setOnClickListener(view -> { + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + Comment comment = getCurrentComment(this); + if (comment != null) { + int previousVoteType = comment.getVoteType(); + String newVoteType; + + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { + //Not upvoted before + comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); + newVoteType = APIUtils.DIR_UPVOTE; + upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + topScoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + newVoteType = APIUtils.DIR_UNVOTE; + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + topScoreTextView.setTextColor(mSecondaryTextColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + + int position = getBindingAdapterPosition(); + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position) { + int currentPosition = getBindingAdapterPosition(); + if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { + comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); + if (currentPosition == position) { + upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + topScoreTextView.setTextColor(mUpvotedColor); + } + } else { + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + if (currentPosition == position) { + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + topScoreTextView.setTextColor(mSecondaryTextColor); + } + } + + if (currentPosition == position) { + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + } + } + + @Override + public void onVoteThingFail(int position) { + } + }, comment.getFullName(), newVoteType, getBindingAdapterPosition()); + } + }); + + downvoteButton.setOnClickListener(view -> { + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + Comment comment = getCurrentComment(this); + if (comment != null) { + int previousVoteType = comment.getVoteType(); + String newVoteType; + + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { + //Not downvoted before + comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); + newVoteType = APIUtils.DIR_DOWNVOTE; + downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + topScoreTextView.setTextColor(mDownvotedColor); + } else { + //Downvoted before + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + newVoteType = APIUtils.DIR_UNVOTE; + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + topScoreTextView.setTextColor(mSecondaryTextColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + + int position = getBindingAdapterPosition(); + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + int currentPosition = getBindingAdapterPosition(); + if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { + comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); + if (currentPosition == position) { + downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + topScoreTextView.setTextColor(mDownvotedColor); + } + } else { + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + if (currentPosition == position) { + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + topScoreTextView.setTextColor(mSecondaryTextColor); + } + } + + if (currentPosition == position) { + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + } + } + + @Override + public void onVoteThingFail(int position1) { + } + }, comment.getFullName(), newVoteType, getBindingAdapterPosition()); + } + }); + + saveButton.setOnClickListener(view -> { + Comment comment = getCurrentComment(this); + if (comment != null) { + int position = getBindingAdapterPosition(); + if (comment.isSaved()) { + comment.setSaved(false); + SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { + @Override + public void success() { + comment.setSaved(false); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + Toast.makeText(mActivity, R.string.comment_unsaved_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + comment.setSaved(true); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } + Toast.makeText(mActivity, R.string.comment_unsaved_failed, Toast.LENGTH_SHORT).show(); + } + }); + } else { + comment.setSaved(true); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { + @Override + public void success() { + comment.setSaved(true); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } + Toast.makeText(mActivity, R.string.comment_saved_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + comment.setSaved(false); + if (getBindingAdapterPosition() == position) { + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + Toast.makeText(mActivity, R.string.comment_saved_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + } + }); + + authorTextView.setOnClickListener(view -> { + Comment comment = getCurrentComment(this); + if (comment != null) { + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, comment.getAuthor()); + mActivity.startActivity(intent); + } + }); + + expandButton.setOnClickListener(view -> { + if (expandButton.getVisibility() == View.VISIBLE) { + int commentPosition = mIsSingleCommentThreadMode ? getBindingAdapterPosition() - 1 : getBindingAdapterPosition(); + Comment comment = getCurrentComment(this); + if (comment != null) { + if (mVisibleComments.get(commentPosition).isExpanded()) { + collapseChildren(commentPosition); + expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); + } else { + comment.setExpanded(true); + ArrayList<Comment> newList = new ArrayList<>(); + expandChildren(mVisibleComments.get(commentPosition).getChildren(), newList, 0); + mVisibleComments.get(commentPosition).setExpanded(true); + mVisibleComments.addAll(commentPosition + 1, newList); + + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(commentPosition + 2, newList.size()); + } else { + notifyItemRangeInserted(commentPosition + 1, newList.size()); + } + expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); + } + } + } else if (mFullyCollapseComment) { + int commentPosition = mIsSingleCommentThreadMode ? getBindingAdapterPosition() - 1 : getBindingAdapterPosition(); + if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { + collapseChildren(commentPosition); + } + } + }); + + if (mSwapTapAndLong) { + if (mCommentToolbarHideOnClick) { + View.OnLongClickListener hideToolbarOnLongClickListener = view -> hideToolbar(); + itemView.setOnLongClickListener(hideToolbarOnLongClickListener); + commentMarkdownView.setOnLongClickListener(hideToolbarOnLongClickListener); + commentTimeTextView.setOnLongClickListener(hideToolbarOnLongClickListener); + } + commentMarkdownView.setOnClickListener(view -> { + if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { + expandComments(); + } + }); + itemView.setOnClickListener(view -> expandComments()); + } else { + if (mCommentToolbarHideOnClick) { + commentMarkdownView.setOnClickListener(view -> { + if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { + hideToolbar(); + } + }); + View.OnClickListener hideToolbarOnClickListener = view -> hideToolbar(); + itemView.setOnClickListener(hideToolbarOnClickListener); + commentTimeTextView.setOnClickListener(hideToolbarOnClickListener); + } + commentMarkdownView.setOnLongClickListener(view -> { + if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { + expandComments(); + } + return true; + }); + itemView.setOnLongClickListener(view -> { + expandComments(); + return true; + }); + } + commentMarkdownView.setHighlightColor(Color.TRANSPARENT); + } + + private boolean expandComments() { + expandButton.performClick(); + return true; + } + + private boolean hideToolbar() { + if (bottomConstraintLayout.getLayoutParams().height == 0) { + bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; + topScoreTextView.setVisibility(View.GONE); + mFragment.delayTransition(); + } else { + mFragment.delayTransition(); + bottomConstraintLayout.getLayoutParams().height = 0; + topScoreTextView.setVisibility(View.VISIBLE); + } + return true; + } + } + + @Nullable + private Comment getCurrentComment(RecyclerView.ViewHolder holder) { + return getCurrentComment(holder.getBindingAdapterPosition()); + } + + @Nullable + private Comment getCurrentComment(int position) { + if (mIsSingleCommentThreadMode) { + if (position - 1 >= 0 && position - 1 < mVisibleComments.size()) { + return mVisibleComments.get(position - 1); + } + } else { + if (position >= 0 && position < mVisibleComments.size()) { + return mVisibleComments.get(position); + } + } + + return null; + } + + class CommentFullyCollapsedViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.vertical_block_indentation_item_comment_fully_collapsed) + CommentIndentationView commentIndentationView; + @BindView(R.id.user_name_text_view_item_comment_fully_collapsed) + TextView usernameTextView; + @BindView(R.id.score_text_view_item_comment_fully_collapsed) + TextView scoreTextView; + @BindView(R.id.time_text_view_item_comment_fully_collapsed) + TextView commentTimeTextView; + @BindView(R.id.divider_item_comment_fully_collapsed) + View commentDivider; + + public CommentFullyCollapsedViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + itemView.setBackgroundColor(mFullyCollapsedCommentBackgroundColor); + usernameTextView.setTextColor(mUsernameColor); + scoreTextView.setTextColor(mSecondaryTextColor); + commentTimeTextView.setTextColor(mSecondaryTextColor); + + if (mShowCommentDivider) { + commentDivider.setBackgroundColor(mDividerColor); + commentDivider.setVisibility(View.VISIBLE); + } + + itemView.setOnClickListener(view -> { + int commentPosition = mIsSingleCommentThreadMode ? getBindingAdapterPosition() - 1 : getBindingAdapterPosition(); + if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { + Comment comment = getCurrentComment(this); + if (comment != null) { + comment.setExpanded(true); + ArrayList<Comment> newList = new ArrayList<>(); + expandChildren(mVisibleComments.get(commentPosition).getChildren(), newList, 0); + mVisibleComments.get(commentPosition).setExpanded(true); + mVisibleComments.addAll(commentPosition + 1, newList); + + if (mIsSingleCommentThreadMode) { + notifyItemChanged(commentPosition + 1); + notifyItemRangeInserted(commentPosition + 2, newList.size()); + } else { + notifyItemChanged(commentPosition); + notifyItemRangeInserted(commentPosition + 1, newList.size()); + } + } + } + }); + + itemView.setOnLongClickListener(view -> { + itemView.performClick(); + return true; + }); + } + } + + class LoadMoreChildCommentsViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.vertical_block_indentation_item_load_more_comments_placeholder) + CommentIndentationView commentIndentationView; + @BindView(R.id.placeholder_text_view_item_load_more_comments) + TextView placeholderTextView; + @BindView(R.id.divider_item_load_more_comments_placeholder) + View commentDivider; + + LoadMoreChildCommentsViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + if (mShowCommentDivider) { + commentDivider.setVisibility(View.VISIBLE); + } + + itemView.setBackgroundColor(mCommentBackgroundColor); + placeholderTextView.setTextColor(mPrimaryTextColor); + commentDivider.setBackgroundColor(mDividerColor); + } + } + + class LoadCommentsViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.comment_progress_bar_item_load_comments) + CircleProgressBar circleProgressBar; + + LoadCommentsViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + circleProgressBar.setBackgroundTintList(ColorStateList.valueOf(mCircularProgressBarBackgroundColor)); + circleProgressBar.setColorSchemeColors(mColorAccent); + } + } + + class LoadCommentsFailedViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_load_comments_failed_placeholder) + TextView errorTextView; + + LoadCommentsFailedViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + itemView.setOnClickListener(view -> mCommentRecyclerViewAdapterCallback.retryFetchingComments()); + errorTextView.setTextColor(mSecondaryTextColor); + } + } + + class NoCommentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_no_comment_placeholder) + TextView errorTextView; + + NoCommentViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + errorTextView.setTextColor(mSecondaryTextColor); + } + } + + class IsLoadingMoreCommentsViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_item_comment_footer_loading) + ProgressBar progressbar; + + IsLoadingMoreCommentsViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + progressbar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + } + } + + class LoadMoreCommentsFailedViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_comment_footer_error) + TextView errorTextView; + @BindView(R.id.retry_button_item_comment_footer_error) + Button retryButton; + + LoadMoreCommentsFailedViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + errorTextView.setText(R.string.load_comments_failed); + retryButton.setOnClickListener(view -> mCommentRecyclerViewAdapterCallback.retryFetchingMoreComments()); + errorTextView.setTextColor(mSecondaryTextColor); + retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); + retryButton.setTextColor(mButtonTextColor); + } + } + + class ViewAllCommentsViewHolder extends RecyclerView.ViewHolder { + + ViewAllCommentsViewHolder(@NonNull View itemView) { + super(itemView); + + itemView.setOnClickListener(view -> { + if (mActivity != null && mActivity instanceof ViewPostDetailActivity) { + mIsSingleCommentThreadMode = false; + mSingleCommentId = null; + notifyItemRemoved(0); + mFragment.changeToNomalThreadMode(); + } + }); + + itemView.setBackgroundTintList(ColorStateList.valueOf(mCommentBackgroundColor)); + ((TextView) itemView).setTextColor(mColorAccent); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FlairBottomSheetRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FlairBottomSheetRecyclerViewAdapter.java index 4585c95e..4d738aa3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FlairBottomSheetRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FlairBottomSheetRecyclerViewAdapter.java @@ -39,7 +39,7 @@ public class FlairBottomSheetRecyclerViewAdapter extends RecyclerView.Adapter<Fl @NonNull @Override public FlairViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new FlairViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_flair, null, false)); + return new FlairViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_flair, parent, false)); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java index b7057106..54f0c090 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java @@ -29,6 +29,7 @@ public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter<R public static final int SPOILER = 7; public static final int QUOTE = 8; public static final int CODE_BLOCK = 9; + public static final int UPLOAD_IMAGE = 10; private static final int ITEM_COUNT = 10; @@ -37,6 +38,7 @@ public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter<R public interface ItemClickListener { void onClick(int item); + void onUploadImage(); } public MarkdownBottomBarRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, @@ -85,6 +87,9 @@ public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter<R case CODE_BLOCK: ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_code_24dp); break; + case UPLOAD_IMAGE: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_image_24dp); + break; } } } @@ -289,7 +294,14 @@ public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter<R public MarkdownBottomBarItemViewHolder(@NonNull View itemView) { super(itemView); imageView = (ImageView) itemView; - itemView.setOnClickListener(view -> itemClickListener.onClick(getAdapterPosition())); + itemView.setOnClickListener(view -> { + int position = getBindingAdapterPosition(); + if (position == UPLOAD_IMAGE) { + itemClickListener.onUploadImage(); + } else { + itemClickListener.onClick(position); + } + }); imageView.setColorFilter(customThemeWrapper.getPrimaryIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/NavigationDrawerRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/NavigationDrawerRecyclerViewAdapter.java index f7046a7c..bf9dea5b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/NavigationDrawerRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/NavigationDrawerRecyclerViewAdapter.java @@ -56,8 +56,9 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re private static final int VIEW_TYPE_FAVORITE_SUBSCRIBED_SUBREDDIT = 4; private static final int VIEW_TYPE_SUBSCRIBED_SUBREDDIT = 5; private static final int VIEW_TYPE_ACCOUNT = 6; - private static final int CURRENT_MENU_ITEMS = 17; + private static final int CURRENT_MENU_ITEMS = 20; private static final int ACCOUNT_SECTION_ITEMS = 4; + private static final int REDDIT_SECTION_ITEMS = 2; private static final int POST_SECTION_ITEMS = 5; private static final int PREFERENCES_SECTION_ITEMS = 3; @@ -76,6 +77,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re private boolean isLoggedIn; private boolean isInMainPage = true; private boolean collapseAccountSection; + private boolean collapseRedditSection; private boolean collapsePostSection; private boolean collapsePreferencesSection; private boolean collapseFavoriteSubredditsSection; @@ -105,12 +107,14 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re showAvatarOnTheRightInTheNavigationDrawer = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_AVATAR_ON_THE_RIGHT, false); isLoggedIn = accountName != null; collapseAccountSection = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.COLLAPSE_ACCOUNT_SECTION, false); + collapseRedditSection = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.COLLAPSE_REDDIT_SECTION, false); collapsePostSection = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.COLLAPSE_POST_SECTION, false); collapsePreferencesSection = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.COLLAPSE_PREFERENCES_SECTION, false); collapseFavoriteSubredditsSection = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.COLLAPSE_FAVORITE_SUBREDDITS_SECTION, false); collapseSubscribedSubredditsSection = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.COLLAPSE_SUBSCRIBED_SUBREDDITS_SECTION, false); hideFavoriteSubredditsSection = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_FAVORITE_SUBREDDITS_SECTION, false); hideSubscribedSubredditsSection = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_SUBSCRIBED_SUBREDDITS_SECTIONS, false); + showAvatarOnTheRightInTheNavigationDrawer = navigationDrawerSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_AVATAR_ON_THE_RIGHT, false); this.itemClickListener = itemClickListener; primaryTextColor = customThemeWrapper.getPrimaryTextColor(); @@ -126,21 +130,25 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re if (isInMainPage) { if (isLoggedIn) { if (position == CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0)) { return VIEW_TYPE_MENU_GROUP_TITLE; } else if (!hideFavoriteSubredditsSection && !favoriteSubscribedSubreddits.isEmpty() && position == CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0) + (collapseFavoriteSubredditsSection ? 0 : favoriteSubscribedSubreddits.size()) + 1) { return VIEW_TYPE_MENU_GROUP_TITLE; } else if (position > CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0)) { if (!favoriteSubscribedSubreddits.isEmpty() && !hideFavoriteSubredditsSection && !collapseFavoriteSubredditsSection && position <= CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0) + favoriteSubscribedSubreddits.size()) { @@ -151,11 +159,17 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re } else if (position == 0) { return VIEW_TYPE_NAV_HEADER; } else if (position == 1 - || position == 6 - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) - || position == 12 - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + || position == (ACCOUNT_SECTION_ITEMS + 2) - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + || position == (ACCOUNT_SECTION_ITEMS + REDDIT_SECTION_ITEMS + 3) + - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) + || position == (ACCOUNT_SECTION_ITEMS + REDDIT_SECTION_ITEMS + POST_SECTION_ITEMS + 4) + - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0)) { return VIEW_TYPE_MENU_GROUP_TITLE; - } else if (position == 16 - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + } else if (position == (CURRENT_MENU_ITEMS - 1) - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0)) { return VIEW_TYPE_DIVIDER; @@ -216,15 +230,13 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (holder instanceof NavHeaderViewHolder) { + RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) ((NavHeaderViewHolder) holder).profileImageView.getLayoutParams(); if (showAvatarOnTheRightInTheNavigationDrawer) { - RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) ((NavHeaderViewHolder) holder).profileImageView.getLayoutParams(); params.addRule(RelativeLayout.ALIGN_PARENT_END); - ((NavHeaderViewHolder) holder).profileImageView.setLayoutParams(params); } else { - RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) ((NavHeaderViewHolder) holder).profileImageView.getLayoutParams(); params.removeRule(RelativeLayout.ALIGN_PARENT_END); - ((NavHeaderViewHolder) holder).profileImageView.setLayoutParams(params); } + ((NavHeaderViewHolder) holder).profileImageView.setLayoutParams(params); if (isLoggedIn) { ((NavHeaderViewHolder) holder).karmaTextView.setText(appCompatActivity.getString(R.string.karma_info, karma)); ((NavHeaderViewHolder) holder).accountNameTextView.setText(accountName); @@ -257,7 +269,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_arrow_drop_up_24px)); } - ((NavHeaderViewHolder) holder).itemView.setOnClickListener(view -> { + holder.itemView.setOnClickListener(view -> { if (isInMainPage) { if (requireAuthToAccountSection) { BiometricManager biometricManager = BiometricManager.from(appCompatActivity); @@ -300,15 +312,27 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re ((MenuGroupTitleViewHolder) holder).collapseIndicatorImageView.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24px); } type = 0; - } else if (position == 6 - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0)) { + } else if (position == (ACCOUNT_SECTION_ITEMS + 2) - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0)) { + ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_reddit); + if (collapseRedditSection) { + ((MenuGroupTitleViewHolder) holder).collapseIndicatorImageView.setImageResource(R.drawable.ic_baseline_arrow_drop_up_24px); + } else { + ((MenuGroupTitleViewHolder) holder).collapseIndicatorImageView.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24px); + } + type = 1; + } else if (position == (ACCOUNT_SECTION_ITEMS + REDDIT_SECTION_ITEMS + 3) + - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0)) { ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_post); if (collapsePostSection) { ((MenuGroupTitleViewHolder) holder).collapseIndicatorImageView.setImageResource(R.drawable.ic_baseline_arrow_drop_up_24px); } else { ((MenuGroupTitleViewHolder) holder).collapseIndicatorImageView.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24px); } - type = 1; - } else if (position == 12 - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + type = 2; + } else if (position == (ACCOUNT_SECTION_ITEMS + REDDIT_SECTION_ITEMS + POST_SECTION_ITEMS + 4) + - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0)) { ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_preferences); if (collapsePreferencesSection) { @@ -316,10 +340,11 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re } else { ((MenuGroupTitleViewHolder) holder).collapseIndicatorImageView.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24px); } - type = 2; + type = 3; } else { if (!hideFavoriteSubredditsSection && !favoriteSubscribedSubreddits.isEmpty() && position == CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0)) { ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.favorites); @@ -328,7 +353,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re } else { ((MenuGroupTitleViewHolder) holder).collapseIndicatorImageView.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24px); } - type = 3; + type = 4; } else { ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.subscriptions); if (collapseSubscribedSubredditsSection) { @@ -336,11 +361,11 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re } else { ((MenuGroupTitleViewHolder) holder).collapseIndicatorImageView.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24px); } - type = 4; + type = 5; } } - ((MenuGroupTitleViewHolder) holder).itemView.setOnClickListener(view -> { + holder.itemView.setOnClickListener(view -> { switch (type) { case 0: if (collapseAccountSection) { @@ -352,6 +377,15 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re } break; case 1: + if (collapseRedditSection) { + collapseRedditSection = !collapseRedditSection; + notifyItemRangeInserted(holder.getBindingAdapterPosition() + 1, REDDIT_SECTION_ITEMS); + } else { + collapseRedditSection = !collapseRedditSection; + notifyItemRangeRemoved(holder.getBindingAdapterPosition() + 1, REDDIT_SECTION_ITEMS); + } + break; + case 2: if (collapsePostSection) { collapsePostSection = !collapsePostSection; notifyItemRangeInserted(holder.getBindingAdapterPosition() + 1, POST_SECTION_ITEMS); @@ -360,7 +394,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re notifyItemRangeRemoved(holder.getBindingAdapterPosition() + 1, POST_SECTION_ITEMS); } break; - case 2: + case 3: if (collapsePreferencesSection) { collapsePreferencesSection = !collapsePreferencesSection; notifyItemRangeInserted(holder.getBindingAdapterPosition() + 1, PREFERENCES_SECTION_ITEMS); @@ -369,7 +403,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re notifyItemRangeRemoved(holder.getBindingAdapterPosition() + 1, PREFERENCES_SECTION_ITEMS); } break; - case 3: + case 4: if (collapseFavoriteSubredditsSection) { collapseFavoriteSubredditsSection = !collapseFavoriteSubredditsSection; notifyItemRangeInserted(holder.getBindingAdapterPosition() + 1, favoriteSubscribedSubreddits.size()); @@ -378,7 +412,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re notifyItemRangeRemoved(holder.getBindingAdapterPosition() + 1, favoriteSubscribedSubreddits.size()); } break; - case 4: + case 5: if (collapseSubscribedSubredditsSection) { collapseSubscribedSubredditsSection = !collapseSubscribedSubredditsSection; notifyItemRangeInserted(holder.getBindingAdapterPosition() + 1, subscribedSubreddits.size()); @@ -398,14 +432,28 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re if (isInMainPage) { if (isLoggedIn) { int pseudoPosition = position; - if (collapseAccountSection && collapsePostSection) { - pseudoPosition += ACCOUNT_SECTION_ITEMS + POST_SECTION_ITEMS; - } else if (collapseAccountSection && collapsePreferencesSection) { - pseudoPosition += ACCOUNT_SECTION_ITEMS; + if (collapseAccountSection && collapseRedditSection && collapsePostSection) { + pseudoPosition += ACCOUNT_SECTION_ITEMS + REDDIT_SECTION_ITEMS + POST_SECTION_ITEMS; + } else if (collapseAccountSection && collapseRedditSection) { + pseudoPosition += ACCOUNT_SECTION_ITEMS + REDDIT_SECTION_ITEMS; + } else if (collapseAccountSection && collapsePostSection) { + if (position > REDDIT_SECTION_ITEMS + 2) { + pseudoPosition += ACCOUNT_SECTION_ITEMS + POST_SECTION_ITEMS; + } else { + pseudoPosition += ACCOUNT_SECTION_ITEMS; + } + } else if (collapseRedditSection && collapsePostSection) { + if (position > ACCOUNT_SECTION_ITEMS + 1) { + pseudoPosition += REDDIT_SECTION_ITEMS + POST_SECTION_ITEMS; + } } else if (collapseAccountSection) { pseudoPosition += ACCOUNT_SECTION_ITEMS; - } else if (collapsePostSection) { + } else if (collapseRedditSection) { if (position > ACCOUNT_SECTION_ITEMS + 1) { + pseudoPosition += REDDIT_SECTION_ITEMS; + } + } else if (collapsePostSection) { + if (position > ACCOUNT_SECTION_ITEMS + REDDIT_SECTION_ITEMS + 2) { pseudoPosition += POST_SECTION_ITEMS; } } @@ -430,32 +478,40 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re ((MenuItemViewHolder) holder).menuTextView.setText(R.string.inbox); } ((MenuItemViewHolder) holder).imageView.setImageDrawable(ContextCompat.getDrawable(appCompatActivity, R.drawable.ic_inbox_24dp)); - ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> { + holder.itemView.setOnClickListener(view -> { Intent intent = new Intent(appCompatActivity, InboxActivity.class); appCompatActivity.startActivity(intent); }); break; case 7: + stringId = R.string.rpan; + drawableId = R.drawable.ic_rpan_24dp; + break; + case 8: + stringId = R.string.trending; + drawableId = R.drawable.ic_trending_24dp; + break; + case 10: stringId = R.string.upvoted; drawableId = R.drawable.ic_arrow_upward_black_24dp; break; - case 8: + case 11: stringId = R.string.downvoted; drawableId = R.drawable.ic_arrow_downward_black_24dp; break; - case 9: + case 12: stringId = R.string.hidden; drawableId = R.drawable.ic_outline_lock_24dp; break; - case 10: + case 13: stringId = R.string.account_saved_thing_activity_label; drawableId = R.drawable.ic_outline_bookmarks_24dp; break; - case 11: + case 14: stringId = R.string.gilded; drawableId = R.drawable.ic_star_border_24dp; break; - case 13: + case 16: if ((resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { stringId = R.string.dark_theme; drawableId = R.drawable.ic_dark_theme_24dp; @@ -464,7 +520,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re drawableId = R.drawable.ic_light_theme_24dp; } break; - case 14: + case 17: setOnClickListener = false; if (isNSFWEnabled) { stringId = R.string.disable_nsfw; @@ -474,21 +530,21 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re drawableId = R.drawable.ic_nsfw_on_24dp; } - ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> { + holder.itemView.setOnClickListener(view -> { if (isNSFWEnabled) { isNSFWEnabled = false; ((MenuItemViewHolder) holder).menuTextView.setText(R.string.enable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_on_24dp)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(ContextCompat.getDrawable(appCompatActivity, R.drawable.ic_nsfw_on_24dp)); itemClickListener.onMenuClick(R.string.disable_nsfw); } else { isNSFWEnabled = true; ((MenuItemViewHolder) holder).menuTextView.setText(R.string.disable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_off_24dp)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(ContextCompat.getDrawable(appCompatActivity, R.drawable.ic_nsfw_off_24dp)); itemClickListener.onMenuClick(R.string.enable_nsfw); } }); break; - case 15: + case 18: stringId = R.string.settings; drawableId = R.drawable.ic_settings_24dp; } @@ -517,16 +573,16 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re drawableId = R.drawable.ic_nsfw_on_24dp; } - ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> { + holder.itemView.setOnClickListener(view -> { if (isNSFWEnabled) { isNSFWEnabled = false; ((MenuItemViewHolder) holder).menuTextView.setText(R.string.enable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_on_24dp)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(ContextCompat.getDrawable(appCompatActivity, R.drawable.ic_nsfw_on_24dp)); itemClickListener.onMenuClick(R.string.disable_nsfw); } else { isNSFWEnabled = true; ((MenuItemViewHolder) holder).menuTextView.setText(R.string.disable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_off_24dp)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(ContextCompat.getDrawable(appCompatActivity, R.drawable.ic_nsfw_off_24dp)); itemClickListener.onMenuClick(R.string.enable_nsfw); } }); @@ -557,15 +613,16 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re if (stringId != 0) { ((MenuItemViewHolder) holder).menuTextView.setText(stringId); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(drawableId)); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(ContextCompat.getDrawable(appCompatActivity, drawableId)); if (setOnClickListener) { int finalStringId = stringId; - ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> itemClickListener.onMenuClick(finalStringId)); + holder.itemView.setOnClickListener(view -> itemClickListener.onMenuClick(finalStringId)); } } } else if (holder instanceof FavoriteSubscribedThingViewHolder) { SubscribedSubredditData subreddit = favoriteSubscribedSubreddits.get(position - (CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0)) - 1); @@ -584,17 +641,19 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re .into(((FavoriteSubscribedThingViewHolder) holder).iconGifImageView); } - ((FavoriteSubscribedThingViewHolder) holder).itemView.setOnClickListener(view -> { + holder.itemView.setOnClickListener(view -> { itemClickListener.onSubscribedSubredditClick(subredditName); }); } else if (holder instanceof SubscribedThingViewHolder) { SubscribedSubredditData subreddit = favoriteSubscribedSubreddits.isEmpty() || hideFavoriteSubredditsSection ? subscribedSubreddits.get(position - (CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0)) - 1) : subscribedSubreddits.get(position - (CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0)) - (collapseFavoriteSubredditsSection ? 0 : favoriteSubscribedSubreddits.size()) @@ -614,7 +673,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re .into(((SubscribedThingViewHolder) holder).iconGifImageView); } - ((SubscribedThingViewHolder) holder).itemView.setOnClickListener(view -> { + holder.itemView.setOnClickListener(view -> { itemClickListener.onSubscribedSubredditClick(subredditName); }); } else if (holder instanceof AccountViewHolder) { @@ -623,7 +682,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(128, 0))) .into(((AccountViewHolder) holder).profileImageGifImageView); ((AccountViewHolder) holder).usernameTextView.setText(accounts.get(position - 1).getAccountName()); - ((AccountViewHolder) holder).itemView.setOnClickListener(view -> + holder.itemView.setOnClickListener(view -> itemClickListener.onAccountClick(accounts.get(position - 1).getAccountName())); } } @@ -668,18 +727,21 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re if (hideFavoriteSubredditsSection && hideSubscribedSubredditsSection) { return CURRENT_MENU_ITEMS - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0); } else if (hideFavoriteSubredditsSection) { return CURRENT_MENU_ITEMS + (subscribedSubreddits.isEmpty() ? 0 : subscribedSubreddits.size() + 1) - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0) - (collapseSubscribedSubredditsSection ? subscribedSubreddits.size() : 0); } else if (hideSubscribedSubredditsSection) { return CURRENT_MENU_ITEMS + (favoriteSubscribedSubreddits.isEmpty() ? 0 : favoriteSubscribedSubreddits.size() + 1) - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0) - (collapseFavoriteSubredditsSection ? favoriteSubscribedSubreddits.size() : 0); @@ -687,6 +749,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re return CURRENT_MENU_ITEMS + (favoriteSubscribedSubreddits.isEmpty() ? 0 : favoriteSubscribedSubreddits.size() + 1) + (subscribedSubreddits.isEmpty() ? 0 : subscribedSubreddits.size() + 1) - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0) - (collapseFavoriteSubredditsSection ? favoriteSubscribedSubreddits.size() : 0) @@ -694,6 +757,7 @@ public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter<Re } return CURRENT_MENU_ITEMS - 1 - (collapseAccountSection ? ACCOUNT_SECTION_ITEMS : 0) + - (collapseRedditSection ? REDDIT_SECTION_ITEMS : 0) - (collapsePostSection ? POST_SECTION_ITEMS : 0) - (collapsePreferencesSection ? PREFERENCES_SECTION_ITEMS : 0); } else { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java index a3e8dbb4..5529f1fd 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java @@ -1,5 +1,7 @@ package ml.docilealligator.infinityforreddit.adapters; +import static ml.docilealligator.infinityforreddit.activities.CommentActivity.WRITE_COMMENT_REQUEST_CODE; + import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; @@ -20,9 +22,7 @@ import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; @@ -35,7 +35,6 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import androidx.core.graphics.drawable.DrawableCompat; import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.RequestBuilder; @@ -52,7 +51,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.PlayerView; import com.libRG.CustomTextView; -import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar; import org.commonmark.ext.gfm.tables.TableBlock; @@ -103,15 +101,12 @@ import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.activities.ViewVideoActivity; import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIcon; import ml.docilealligator.infinityforreddit.asynctasks.LoadUserData; -import ml.docilealligator.infinityforreddit.bottomsheetfragments.CommentMoreBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.ShareLinkBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; -import ml.docilealligator.infinityforreddit.comment.Comment; -import ml.docilealligator.infinityforreddit.comment.FetchComment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView; -import ml.docilealligator.infinityforreddit.customviews.CommentIndentationView; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; import ml.docilealligator.infinityforreddit.post.Post; @@ -122,9 +117,7 @@ import ml.docilealligator.infinityforreddit.utils.Utils; import pl.droidsonroids.gif.GifImageView; import retrofit2.Retrofit; -import static ml.docilealligator.infinityforreddit.activities.CommentActivity.WRITE_COMMENT_REQUEST_CODE; - -public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements CacheManager { +public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements CacheManager { private static final int VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY = 1; private static final int VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW = 2; private static final int VIEW_TYPE_POST_DETAIL_IMAGE = 3; @@ -133,15 +126,6 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy private static final int VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK = 6; private static final int VIEW_TYPE_POST_DETAIL_GALLERY = 7; private static final int VIEW_TYPE_POST_DETAIL_TEXT_TYPE = 8; - private static final int VIEW_TYPE_FIRST_LOADING = 9; - private static final int VIEW_TYPE_FIRST_LOADING_FAILED = 10; - private static final int VIEW_TYPE_NO_COMMENT_PLACEHOLDER = 11; - private static final int VIEW_TYPE_COMMENT = 12; - private static final int VIEW_TYPE_COMMENT_FULLY_COLLAPSED = 13; - private static final int VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS = 14; - private static final int VIEW_TYPE_IS_LOADING_MORE_COMMENTS = 15; - private static final int VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED = 16; - private static final int VIEW_TYPE_VIEW_ALL_COMMENTS = 17; private AppCompatActivity mActivity; private ViewPostDetailFragment mFragment; @@ -153,63 +137,47 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy private RedditDataRoomDatabase mRedditDataRoomDatabase; private RequestManager mGlide; private Markwon mPostDetailMarkwon; - private Markwon mCommentMarkwon; private final MarkwonAdapter mMarkwonAdapter; private int mImageViewWidth; private String mAccessToken; private String mAccountName; private Post mPost; - private ArrayList<Comment> mVisibleComments; private String mSubredditNamePrefixed; private Locale mLocale; - private String mSingleCommentId; - private boolean mIsSingleCommentThreadMode; private boolean mNeedBlurNsfw; private boolean mDoNotBlurNsfwInNsfwSubreddits; private boolean mNeedBlurSpoiler; private boolean mVoteButtonsOnTheRight; private boolean mShowElapsedTime; private String mTimeFormatPattern; - private boolean mExpandChildren; - private boolean mCommentToolbarHidden; - private boolean mCommentToolbarHideOnClick; - private boolean mSwapTapAndLong; - private boolean mShowCommentDivider; private boolean mShowAbsoluteNumberOfVotes; private boolean mAutoplay = false; private boolean mAutoplayNsfwVideos; private boolean mMuteAutoplayingVideos; - private boolean mFullyCollapseComment; private double mStartAutoplayVisibleAreaOffset; private boolean mMuteNSFWVideo; private boolean mAutomaticallyTryRedgifs; private boolean mDataSavingMode; private boolean mDisableImagePreview; private boolean mOnlyDisablePreviewInVideoAndGifPosts; - private CommentRecyclerViewAdapterCallback mCommentRecyclerViewAdapterCallback; - private boolean isInitiallyLoading; - private boolean isInitiallyLoadingFailed; - private boolean mHasMoreComments; - private boolean loadMoreCommentsFailed; - - private int depthThreshold = 5; - private int mColorPrimaryLightTheme; + private boolean mHidePostType; + private boolean mHidePostFlair; + private boolean mHideTheNumberOfAwards; + private boolean mHideSubredditAndUserPrefix; + private boolean mHideTheNumberOfVotes; + private boolean mHideTheNumberOfComments; + private boolean mSeparatePostAndComments; + private PostDetailRecyclerViewAdapterCallback mPostDetailRecyclerViewAdapterCallback; + private int mColorAccent; - private int mCircularProgressBarBackgroundColor; private int mCardViewColor; private int mSecondaryTextColor; private int mPostTitleColor; private int mPrimaryTextColor; - private int mCommentTextColor; - private int mCommentBackgroundColor; private int mPostTypeBackgroundColor; private int mPostTypeTextColor; - private int mDividerColor; private int mSubredditColor; private int mUsernameColor; - private int mSubmitterColor; - private int mModeratorColor; - private int mCurrentUserColor; private int mAuthorFlairTextColor; private int mSpoilerBackgroundColor; private int mSpoilerTextColor; @@ -225,29 +193,25 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy private int mNoPreviewPostTypeIconTint; private int mUpvotedColor; private int mDownvotedColor; - private int mSingleCommentThreadBackgroundColor; private int mVoteAndReplyUnavailableVoteButtonColor; - private int mButtonTextColor; private int mPostIconAndInfoColor; - private int mCommentIconAndInfoColor; - private int mFullyCollapsedCommentBackgroundColor; - private int mAwardedCommentBackgroundColor; - private Integer[] verticalBlockColors; private Drawable mCommentIcon; private float mScale; private ExoCreator mExoCreator; - public CommentAndPostRecyclerViewAdapter(AppCompatActivity activity, ViewPostDetailFragment fragment, Executor executor, CustomThemeWrapper customThemeWrapper, - Retrofit retrofit, Retrofit oauthRetrofit, Retrofit gfycatRetrofit, - Retrofit redgifsRetrofit, - RedditDataRoomDatabase redditDataRoomDatabase, RequestManager glide, - int imageViewWidth, String accessToken, String accountName, - Post post, Locale locale, String singleCommentId, - boolean isSingleCommentThreadMode, - SharedPreferences sharedPreferences, - SharedPreferences nsfwAndSpoilerSharedPreferences, ExoCreator exoCreator, - CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) { + public PostDetailRecyclerViewAdapter(AppCompatActivity activity, ViewPostDetailFragment fragment, + Executor executor, CustomThemeWrapper customThemeWrapper, + Retrofit retrofit, Retrofit oauthRetrofit, Retrofit gfycatRetrofit, + Retrofit redgifsRetrofit, RedditDataRoomDatabase redditDataRoomDatabase, + RequestManager glide, int imageViewWidth, + boolean separatePostAndComments, String accessToken, + String accountName, Post post, Locale locale, + SharedPreferences sharedPreferences, + SharedPreferences nsfwAndSpoilerSharedPreferences, + SharedPreferences postDetailsSharedPreferences, + ExoCreator exoCreator, + PostDetailRecyclerViewAdapterCallback postDetailRecyclerViewAdapterCallback) { mActivity = activity; mFragment = fragment; mExecutor = executor; @@ -258,8 +222,6 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mRedditDataRoomDatabase = redditDataRoomDatabase; mGlide = glide; mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - mCommentTextColor = customThemeWrapper.getCommentColor(); - int commentSpoilerBackgroundColor = mCommentTextColor | 0xFF000000; int markdownColor = customThemeWrapper.getPostContentColor(); int postSpoilerBackgroundColor = markdownColor | 0xFF000000; int linkColor = customThemeWrapper.getLinkColor(); @@ -369,108 +331,18 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(TableEntryPlugin.create(mActivity)) .build(); - mCommentMarkwon = Markwon.builder(mActivity) - .usePlugin(HtmlPlugin.create()) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - while (matcher.find()) { - markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); - } - - @Override - public void afterSetText(@NonNull TextView textView) { - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - if (markdownStringBuilder.length() < 4 - || matcher.start() < 0 - || matcher.end() > markdownStringBuilder.length()) { - break; - } - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(mCommentTextColor); - } else { - ds.bgColor = commentSpoilerBackgroundColor; - ds.setColor(mCommentTextColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcher.end() - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS, activity).setOnLinkLongClickListener((textView, url) -> { - if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); - } - return true; - }))) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .build(); mMarkwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) .include(TableBlock.class, TableEntry.create(builder -> builder .tableLayout(R.layout.adapter_table_block, R.id.table_layout) .textLayoutIsRoot(R.layout.view_table_entry_cell))) .build(); mImageViewWidth = imageViewWidth; + mSeparatePostAndComments = separatePostAndComments; mAccessToken = accessToken; mAccountName = accountName; mPost = post; - mVisibleComments = new ArrayList<>(); mSubredditNamePrefixed = post.getSubredditNamePrefixed(); mLocale = locale; - mSingleCommentId = singleCommentId; - mIsSingleCommentThreadMode = isSingleCommentThreadMode; mNeedBlurNsfw = nsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.BLUR_NSFW_BASE, true); mDoNotBlurNsfwInNsfwSubreddits = nsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.DO_NOT_BLUR_NSFW_IN_NSFW_SUBREDDITS, false); @@ -478,11 +350,6 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mVoteButtonsOnTheRight = sharedPreferences.getBoolean(SharedPreferencesUtils.VOTE_BUTTONS_ON_THE_RIGHT_KEY, false); mShowElapsedTime = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY, false); mTimeFormatPattern = sharedPreferences.getString(SharedPreferencesUtils.TIME_FORMAT_KEY, SharedPreferencesUtils.TIME_FORMAT_DEFAULT_VALUE); - mExpandChildren = !sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_TOP_LEVEL_COMMENTS_FIRST, false); - mCommentToolbarHidden = sharedPreferences.getBoolean(SharedPreferencesUtils.COMMENT_TOOLBAR_HIDDEN, false); - mCommentToolbarHideOnClick = sharedPreferences.getBoolean(SharedPreferencesUtils.COMMENT_TOOLBAR_HIDE_ON_CLICK, true); - mSwapTapAndLong = sharedPreferences.getBoolean(SharedPreferencesUtils.SWAP_TAP_AND_LONG_COMMENTS, false); - mShowCommentDivider = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_COMMENT_DIVIDER, false); mShowAbsoluteNumberOfVotes = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ABSOLUTE_NUMBER_OF_VOTES, true); String autoplayString = sharedPreferences.getString(SharedPreferencesUtils.VIDEO_AUTOPLAY, SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_NEVER); @@ -494,7 +361,6 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy } mAutoplayNsfwVideos = sharedPreferences.getBoolean(SharedPreferencesUtils.AUTOPLAY_NSFW_VIDEOS, true); mMuteAutoplayingVideos = sharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_AUTOPLAYING_VIDEOS, true); - mFullyCollapseComment = sharedPreferences.getBoolean(SharedPreferencesUtils.FULLY_COLLAPSE_COMMENT, false); Resources resources = activity.getResources(); mStartAutoplayVisibleAreaOffset = resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? @@ -513,26 +379,22 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mDisableImagePreview = sharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false); mOnlyDisablePreviewInVideoAndGifPosts = sharedPreferences.getBoolean(SharedPreferencesUtils.ONLY_DISABLE_PREVIEW_IN_VIDEO_AND_GIF_POSTS, false); - mCommentRecyclerViewAdapterCallback = commentRecyclerViewAdapterCallback; - isInitiallyLoading = true; - isInitiallyLoadingFailed = false; - mHasMoreComments = false; - loadMoreCommentsFailed = false; + mHidePostType = postDetailsSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_POST_TYPE, false); + mHidePostFlair = postDetailsSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_POST_FLAIR, false); + mHideTheNumberOfAwards = postDetailsSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_AWARDS, false); + mHideSubredditAndUserPrefix = postDetailsSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_SUBREDDIT_AND_USER_PREFIX, false); + mHideTheNumberOfVotes = postDetailsSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_VOTES, false); + mHideTheNumberOfComments = postDetailsSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_COMMENTS, false); + + mPostDetailRecyclerViewAdapterCallback = postDetailRecyclerViewAdapterCallback; mScale = resources.getDisplayMetrics().density; - mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); mColorAccent = customThemeWrapper.getColorAccent(); - mCircularProgressBarBackgroundColor = customThemeWrapper.getCircularProgressBarBackground(); mCardViewColor = customThemeWrapper.getCardViewBackgroundColor(); mPostTitleColor = customThemeWrapper.getPostTitleColor(); mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); - mDividerColor = customThemeWrapper.getDividerColor(); - mCommentBackgroundColor = customThemeWrapper.getCommentBackgroundColor(); mPostTypeBackgroundColor = customThemeWrapper.getPostTypeBackgroundColor(); mPostTypeTextColor = customThemeWrapper.getPostTypeTextColor(); - mSubmitterColor = customThemeWrapper.getSubmitter(); - mModeratorColor = customThemeWrapper.getModerator(); - mCurrentUserColor = customThemeWrapper.getCurrentUser(); mAuthorFlairTextColor = customThemeWrapper.getAuthorFlairTextColor(); mSpoilerBackgroundColor = customThemeWrapper.getSpoilerBackgroundColor(); mSpoilerTextColor = customThemeWrapper.getSpoilerTextColor(); @@ -550,23 +412,8 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mUsernameColor = customThemeWrapper.getUsername(); mUpvotedColor = customThemeWrapper.getUpvoted(); mDownvotedColor = customThemeWrapper.getDownvoted(); - mSingleCommentThreadBackgroundColor = customThemeWrapper.getSingleCommentThreadBackgroundColor(); mVoteAndReplyUnavailableVoteButtonColor = customThemeWrapper.getVoteAndReplyUnavailableButtonColor(); - mButtonTextColor = customThemeWrapper.getButtonTextColor(); mPostIconAndInfoColor = customThemeWrapper.getPostIconAndInfoColor(); - mCommentIconAndInfoColor = customThemeWrapper.getCommentIconAndInfoColor(); - mFullyCollapsedCommentBackgroundColor = customThemeWrapper.getFullyCollapsedCommentBackgroundColor(); - mAwardedCommentBackgroundColor = customThemeWrapper.getAwardedCommentBackgroundColor(); - - verticalBlockColors = new Integer[] { - customThemeWrapper.getCommentVerticalBarColor1(), - customThemeWrapper.getCommentVerticalBarColor2(), - customThemeWrapper.getCommentVerticalBarColor3(), - customThemeWrapper.getCommentVerticalBarColor4(), - customThemeWrapper.getCommentVerticalBarColor5(), - customThemeWrapper.getCommentVerticalBarColor6(), - customThemeWrapper.getCommentVerticalBarColor7(), - }; mCommentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); if (mCommentIcon != null) { @@ -578,91 +425,35 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy @Override public int getItemViewType(int position) { - if (position == 0) { - switch (mPost.getPostType()) { - case Post.VIDEO_TYPE: - if (mAutoplay) { - if (!mAutoplayNsfwVideos && mPost.isNSFW()) { - return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; - } - return VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY; - } else { - return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; - } - case Post.GIF_TYPE: - if (mAutoplay) { - if (!mAutoplayNsfwVideos && mPost.isNSFW()) { - return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; - } - return VIEW_TYPE_POST_DETAIL_GIF_AUTOPLAY; - } else { + switch (mPost.getPostType()) { + case Post.VIDEO_TYPE: + if (mAutoplay && !mSeparatePostAndComments) { + if (!mAutoplayNsfwVideos && mPost.isNSFW()) { return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; } - case Post.IMAGE_TYPE: - return VIEW_TYPE_POST_DETAIL_IMAGE; - case Post.LINK_TYPE: - return VIEW_TYPE_POST_DETAIL_LINK; - case Post.NO_PREVIEW_LINK_TYPE: - return VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK; - case Post.GALLERY_TYPE: - return VIEW_TYPE_POST_DETAIL_GALLERY; - default: - return VIEW_TYPE_POST_DETAIL_TEXT_TYPE; - } - } - - if (mVisibleComments.size() == 0) { - if (position == 1) { - if (isInitiallyLoading) { - return VIEW_TYPE_FIRST_LOADING; - } else if (isInitiallyLoadingFailed) { - return VIEW_TYPE_FIRST_LOADING_FAILED; - } else { - return VIEW_TYPE_NO_COMMENT_PLACEHOLDER; - } - } - } - - if (mIsSingleCommentThreadMode) { - if (position == 1) { - return VIEW_TYPE_VIEW_ALL_COMMENTS; - } - - if (position == mVisibleComments.size() + 2) { - if (mHasMoreComments) { - return VIEW_TYPE_IS_LOADING_MORE_COMMENTS; + return VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY; } else { - return VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED; - } - } - - Comment comment = mVisibleComments.get(position - 2); - if (comment.getPlaceholderType() == Comment.NOT_PLACEHOLDER) { - if (mFullyCollapseComment && !comment.isExpanded() && comment.hasExpandedBefore()) { - return VIEW_TYPE_COMMENT_FULLY_COLLAPSED; + return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; } - return VIEW_TYPE_COMMENT; - } else { - return VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS; - } - } else { - if (position == mVisibleComments.size() + 1) { - if (mHasMoreComments) { - return VIEW_TYPE_IS_LOADING_MORE_COMMENTS; + case Post.GIF_TYPE: + if (mAutoplay) { + if (!mAutoplayNsfwVideos && mPost.isNSFW()) { + return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; + } + return VIEW_TYPE_POST_DETAIL_GIF_AUTOPLAY; } else { - return VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED; - } - } - - Comment comment = mVisibleComments.get(position - 1); - if (comment.getPlaceholderType() == Comment.NOT_PLACEHOLDER) { - if (mFullyCollapseComment && !comment.isExpanded() && comment.hasExpandedBefore()) { - return VIEW_TYPE_COMMENT_FULLY_COLLAPSED; - } - return VIEW_TYPE_COMMENT; - } else { - return VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS; - } + return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; + } + case Post.IMAGE_TYPE: + return VIEW_TYPE_POST_DETAIL_IMAGE; + case Post.LINK_TYPE: + return VIEW_TYPE_POST_DETAIL_LINK; + case Post.NO_PREVIEW_LINK_TYPE: + return VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK; + case Post.GALLERY_TYPE: + return VIEW_TYPE_POST_DETAIL_GALLERY; + default: + return VIEW_TYPE_POST_DETAIL_TEXT_TYPE; } } @@ -702,26 +493,8 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); case VIEW_TYPE_POST_DETAIL_GALLERY: return new PostDetailGalleryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_gallery, parent, false)); - case VIEW_TYPE_POST_DETAIL_TEXT_TYPE: - return new PostDetailTextViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_text, parent, false)); - case VIEW_TYPE_FIRST_LOADING: - return new LoadCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments, parent, false)); - case VIEW_TYPE_FIRST_LOADING_FAILED: - return new LoadCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments_failed_placeholder, parent, false)); - case VIEW_TYPE_NO_COMMENT_PLACEHOLDER: - return new NoCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_no_comment_placeholder, parent, false)); - case VIEW_TYPE_COMMENT: - return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); - case VIEW_TYPE_COMMENT_FULLY_COLLAPSED: - return new CommentFullyCollapsedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_fully_collapsed, parent, false)); - case VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS: - return new LoadMoreChildCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_more_comments_placeholder, parent, false)); - case VIEW_TYPE_IS_LOADING_MORE_COMMENTS: - return new IsLoadingMoreCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_footer_loading, parent, false)); - case VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED: - return new LoadMoreCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_footer_error, parent, false)); default: - return new ViewAllCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_all_comments, parent, false)); + return new PostDetailTextViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_text, parent, false)); } } @@ -767,20 +540,20 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, mPost.getSubredditNamePrefixed().substring(2), mRetrofit, iconImageUrl -> { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } - mPost.setSubredditIconUrl(iconImageUrl); - }); + mPost.setSubredditIconUrl(iconImageUrl); + }); } else if (!mPost.getSubredditIconUrl().equals("")) { mGlide.load(mPost.getSubredditIconUrl()) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) @@ -830,8 +603,13 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy ((PostDetailBaseViewHolder) holder).mCrosspostImageView.setVisibility(View.VISIBLE); } - ((PostDetailBaseViewHolder) holder).mSubredditTextView.setText(mPost.getSubredditNamePrefixed()); - ((PostDetailBaseViewHolder) holder).mUserTextView.setText(mPost.getAuthorNamePrefixed()); + if (!mHideSubredditAndUserPrefix) { + ((PostDetailBaseViewHolder) holder).mSubredditTextView.setText(mPost.getSubredditNamePrefixed()); + ((PostDetailBaseViewHolder) holder).mUserTextView.setText(mPost.getAuthorNamePrefixed()); + } else { + ((PostDetailBaseViewHolder) holder).mSubredditTextView.setText(mPost.getSubredditName()); + ((PostDetailBaseViewHolder) holder).mUserTextView.setText(mPost.getAuthor()); + } if (mShowElapsedTime) { ((PostDetailBaseViewHolder) holder).mPostTimeTextView.setText( @@ -852,12 +630,12 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy ((PostDetailBaseViewHolder) holder).mSpoilerTextView.setVisibility(View.VISIBLE); } - if (mPost.getFlair() != null && !mPost.getFlair().equals("")) { + if (!mHidePostFlair && mPost.getFlair() != null && !mPost.getFlair().equals("")) { ((PostDetailBaseViewHolder) holder).mFlairTextView.setVisibility(View.VISIBLE); Utils.setHTMLWithImageToTextView(((PostDetailBaseViewHolder) holder).mFlairTextView, mPost.getFlair(), false); } - if (mPost.getAwards() != null && !mPost.getAwards().equals("")) { + if (!mHideTheNumberOfAwards && mPost.getAwards() != null && !mPost.getAwards().equals("")) { ((PostDetailBaseViewHolder) holder).mAwardsTextView.setVisibility(View.VISIBLE); Utils.setHTMLWithImageToTextView(((PostDetailBaseViewHolder) holder).mAwardsTextView, mPost.getAwards(), true); } @@ -870,7 +648,11 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy ((PostDetailBaseViewHolder) holder).mNSFWTextView.setVisibility(View.GONE); } - ((PostDetailBaseViewHolder) holder).mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, mPost.getScore() + mPost.getVoteType())); + if (!mHideTheNumberOfVotes) { + ((PostDetailBaseViewHolder) holder).mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, mPost.getScore() + mPost.getVoteType())); + } else { + ((PostDetailBaseViewHolder) holder).mScoreTextView.setText(mActivity.getString(R.string.vote)); + } ((PostDetailBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(mPost.getNComments())); @@ -911,16 +693,19 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy } }); ((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks - .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mGfycatRetrofit, mRedgifsRetrofit, - mPost.getGfycatId(), mPost.isGfycat(), mAutomaticallyTryRedgifs); + .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mExecutor, new Handler(), + mGfycatRetrofit, mRedgifsRetrofit, mPost.getGfycatId(), + mPost.isGfycat(), mAutomaticallyTryRedgifs); } else { ((PostDetailVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(mPost.getVideoUrl())); } } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { - if (mPost.getPostType() == Post.GIF_TYPE) { - ((PostDetailVideoAndGifPreviewHolder) holder).mTypeTextView.setText(mActivity.getString(R.string.gif)); - } else { - ((PostDetailVideoAndGifPreviewHolder) holder).mTypeTextView.setText(mActivity.getString(R.string.video)); + if (!mHidePostType) { + if (mPost.getPostType() == Post.GIF_TYPE) { + ((PostDetailVideoAndGifPreviewHolder) holder).mTypeTextView.setText(mActivity.getString(R.string.gif)); + } else { + ((PostDetailVideoAndGifPreviewHolder) holder).mTypeTextView.setText(mActivity.getString(R.string.video)); + } } Post.Preview preview = getSuitablePreview(mPost.getPreviews()); if (preview != null) { @@ -928,10 +713,12 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy loadImage((PostDetailVideoAndGifPreviewHolder) holder, preview); } } else if (holder instanceof PostDetailImageAndGifAutoplayViewHolder) { - if (mPost.getPostType() == Post.IMAGE_TYPE) { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mTypeTextView.setText(R.string.image); - } else { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mTypeTextView.setText(R.string.gif); + if (!mHidePostType) { + if (mPost.getPostType() == Post.IMAGE_TYPE) { + ((PostDetailImageAndGifAutoplayViewHolder) holder).mTypeTextView.setText(R.string.image); + } else { + ((PostDetailImageAndGifAutoplayViewHolder) holder).mTypeTextView.setText(R.string.gif); + } } Post.Preview preview = getSuitablePreview(mPost.getPreviews()); @@ -958,7 +745,9 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy } else if (holder instanceof PostDetailNoPreviewViewHolder) { if (mPost.getPostType() == Post.LINK_TYPE || mPost.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.link); + if (!mHidePostType) { + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.link); + } String noPreviewLinkDomain = Uri.parse(mPost.getUrl()).getHost(); ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setVisibility(View.VISIBLE); ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setText(noPreviewLinkDomain); @@ -967,27 +756,35 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setVisibility(View.GONE); switch (mPost.getPostType()) { case Post.VIDEO_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.video); + if (!mHidePostType) { + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.video); + } ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_outline_video_24dp); break; case Post.IMAGE_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.image); + if (!mHidePostType) { + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.image); + } ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_image_24dp); break; case Post.GIF_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.gif); + if (!mHidePostType) { + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.gif); + } ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_image_24dp); break; case Post.GALLERY_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.gallery); - ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_gallery_24dp); + if (!mHidePostType) { + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.gallery); + } + ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); break; } } if (mPost.getSelfText() != null && !mPost.getSelfText().equals("")) { ((PostDetailNoPreviewViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); - LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { + LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { @Override public void onScrolledLeft() { ((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack(); @@ -1017,7 +814,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy } else if (holder instanceof PostDetailTextViewHolder) { if (mPost.getSelfText() != null && !mPost.getSelfText().equals("")) { ((PostDetailTextViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); - LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { + LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { @Override public void onScrolledLeft() { ((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack(); @@ -1034,353 +831,6 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mMarkwonAdapter.notifyDataSetChanged(); } } - } else if (holder instanceof CommentViewHolder) { - Comment comment = getCurrentComment(position); - if (comment != null) { - if (mIsSingleCommentThreadMode && comment.getId().equals(mSingleCommentId)) { - ((CommentViewHolder) holder).itemView.setBackgroundColor(mSingleCommentThreadBackgroundColor); - } else if (comment.getAwards() != null && !comment.getAwards().equals("")) { - ((CommentViewHolder) holder).itemView.setBackgroundColor(mAwardedCommentBackgroundColor); - } - - String authorPrefixed = "u/" + comment.getAuthor(); - ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed); - - if (comment.getAuthorFlairHTML() != null && !comment.getAuthorFlairHTML().equals("")) { - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).authorFlairTextView, comment.getAuthorFlairHTML(), true); - } else if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) { - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); - ((CommentViewHolder) holder).authorFlairTextView.setText(comment.getAuthorFlair()); - } - - if (comment.isSubmitter()) { - ((CommentViewHolder) holder).authorTextView.setTextColor(mSubmitterColor); - Drawable submitterDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_mic_14dp, mSubmitterColor); - ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( - submitterDrawable, null, null, null); - } else if (comment.isModerator()) { - ((CommentViewHolder) holder).authorTextView.setTextColor(mModeratorColor); - Drawable moderatorDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_verified_user_14dp, mModeratorColor); - ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( - moderatorDrawable, null, null, null); - } else if (comment.getAuthor().equals(mAccountName)) { - ((CommentViewHolder) holder).authorTextView.setTextColor(mCurrentUserColor); - Drawable currentUserDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_current_user_14dp, mCurrentUserColor); - ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( - currentUserDrawable, null, null, null); - } - - if (mShowElapsedTime) { - ((CommentViewHolder) holder).commentTimeTextView.setText( - Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); - } else { - ((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); - } - - if (mCommentToolbarHidden) { - ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = 0; - ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.VISIBLE); - } else { - ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; - ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.GONE); - } - - if (comment.getAwards() != null && !comment.getAwards().equals("")) { - ((CommentViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).awardsTextView, comment.getAwards(), true); - } - - mCommentMarkwon.setMarkdown(((CommentViewHolder) holder).commentMarkdownView, comment.getCommentMarkdown()); - ((CommentViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - ((CommentViewHolder) holder).topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - - ((CommentViewHolder) holder).commentIndentationView.setLevelAndColors(comment.getDepth(), verticalBlockColors); - if (comment.getDepth() > depthThreshold) { - ((CommentViewHolder) holder).saveButton.setVisibility(View.GONE); - ((CommentViewHolder) holder).replyButton.setVisibility(View.GONE); - } else { - ((CommentViewHolder) holder).saveButton.setVisibility(View.VISIBLE); - ((CommentViewHolder) holder).replyButton.setVisibility(View.VISIBLE); - } - - if (comment.hasReply()) { - if (comment.isExpanded()) { - ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); - } else { - ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); - } - ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); - } - - switch (comment.getVoteType()) { - case Comment.VOTE_TYPE_UPVOTE: - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); - ((CommentViewHolder) holder).topScoreTextView.setTextColor(mUpvotedColor); - break; - case Comment.VOTE_TYPE_DOWNVOTE: - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); - ((CommentViewHolder) holder).topScoreTextView.setTextColor(mDownvotedColor); - break; - } - - if (mPost.isArchived()) { - ((CommentViewHolder) holder).replyButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - } - - if (mPost.isLocked()) { - ((CommentViewHolder) holder).replyButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - } - - if (comment.isSaved()) { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - } else { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - } - } - } else if (holder instanceof CommentFullyCollapsedViewHolder) { - Comment comment = getCurrentComment(position); - if (comment != null) { - String authorWithPrefix = "u/" + comment.getAuthor(); - ((CommentFullyCollapsedViewHolder) holder).usernameTextView.setText(authorWithPrefix); - if (mShowElapsedTime) { - ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); - } else { - ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); - } - ((CommentFullyCollapsedViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType()))); - ((CommentFullyCollapsedViewHolder) holder).commentIndentationView.setLevelAndColors(comment.getDepth(), verticalBlockColors); - } - } else if (holder instanceof LoadMoreChildCommentsViewHolder) { - Comment placeholder; - placeholder = mIsSingleCommentThreadMode ? mVisibleComments.get(holder.getBindingAdapterPosition() - 2) - : mVisibleComments.get(holder.getBindingAdapterPosition() - 1); - - ((LoadMoreChildCommentsViewHolder) holder).commentIndentationView.setLevelAndColors(placeholder.getDepth(), verticalBlockColors); - - if (placeholder.getPlaceholderType() == Comment.PLACEHOLDER_LOAD_MORE_COMMENTS) { - if (placeholder.isLoadingMoreChildren()) { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); - } else if (placeholder.isLoadMoreChildrenFailed()) { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); - } else { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); - } - } else { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_continue_thread); - } - - if (placeholder.getPlaceholderType() == Comment.PLACEHOLDER_LOAD_MORE_COMMENTS) { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setOnClickListener(view -> { - int commentPosition = mIsSingleCommentThreadMode ? holder.getBindingAdapterPosition() - 2 : holder.getBindingAdapterPosition() - 1; - int parentPosition = getParentPosition(commentPosition); - if (parentPosition >= 0) { - Comment parentComment = mVisibleComments.get(parentPosition); - - mVisibleComments.get(commentPosition).setLoadingMoreChildren(true); - mVisibleComments.get(commentPosition).setLoadMoreChildrenFailed(false); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); - - Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; - FetchComment.fetchMoreComment(retrofit, mAccessToken, parentComment.getMoreChildrenFullnames(), - parentComment.getMoreChildrenStartingIndex(), parentComment.getDepth() + 1, - mExpandChildren, mLocale, - new FetchComment.FetchMoreCommentListener() { - @Override - public void onFetchMoreCommentSuccess(ArrayList<Comment> expandedComments, - int childrenStartingIndex) { - if (mVisibleComments.size() > parentPosition - && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { - if (mVisibleComments.get(parentPosition).isExpanded()) { - if (mVisibleComments.get(parentPosition).getChildren().size() > childrenStartingIndex) { - mVisibleComments.get(parentPosition).setMoreChildrenStartingIndex(childrenStartingIndex); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadingMoreChildren(false); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadMoreChildrenFailed(false); - - int placeholderPosition = commentPosition; - if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); - - mVisibleComments.addAll(placeholderPosition, expandedComments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); - } else { - notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); - } - } else { - mVisibleComments.get(parentPosition).getChildren() - .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); - mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); - - int placeholderPosition = commentPosition; - if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.remove(placeholderPosition); - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(placeholderPosition + 2); - } else { - notifyItemRemoved(placeholderPosition + 1); - } - - mVisibleComments.addAll(placeholderPosition, expandedComments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); - } else { - notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); - } - } - } else { - if (mVisibleComments.get(parentPosition).hasReply() && mVisibleComments.get(parentPosition).getChildren().size() <= childrenStartingIndex) { - mVisibleComments.get(parentPosition).getChildren() - .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); - mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); - } - } - - mVisibleComments.get(parentPosition).addChildren(expandedComments); - } else { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - if (mVisibleComments.get(i).isExpanded()) { - int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); - - if (!mVisibleComments.get(i).getFullName() - .equals(mVisibleComments.get(placeholderPosition).getFullName())) { - for (int j = i + 1; j < mVisibleComments.size(); j++) { - if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { - placeholderPosition = j; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); - - mVisibleComments.addAll(placeholderPosition, expandedComments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); - } else { - notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); - } - } - - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) - .setLoadingMoreChildren(false); - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) - .setLoadMoreChildrenFailed(false); - mVisibleComments.get(i).addChildren(expandedComments); - - break; - } - } - } - } - - @Override - public void onFetchMoreCommentFailed() { - if (parentPosition < mVisibleComments.size() - && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { - if (mVisibleComments.get(parentPosition).isExpanded()) { - int commentPosition = mIsSingleCommentThreadMode ? holder.getBindingAdapterPosition() - 2 : holder.getBindingAdapterPosition() - 1; - int placeholderPosition = commentPosition; - if (commentPosition >= mVisibleComments.size() || commentPosition < 0 || !mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); - } - - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadingMoreChildren(false); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadMoreChildrenFailed(true); - } else { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - if (mVisibleComments.get(i).isExpanded()) { - int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); - if (!mVisibleComments.get(placeholderPosition).getFullName().equals(mVisibleComments.get(i).getFullName())) { - for (int j = i + 1; j < mVisibleComments.size(); j++) { - if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { - placeholderPosition = j; - break; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); - } - - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadingMoreChildren(false); - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadMoreChildrenFailed(true); - - break; - } - } - } - } - }); - } - }); - } else { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setOnClickListener(view -> { - Comment comment = getCurrentComment(position); - if (comment != null) { - Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mPost); - intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getParentId()); - intent.putExtra(ViewPostDetailActivity.EXTRA_CONTEXT_NUMBER, "0"); - mActivity.startActivity(intent); - } - }); - } } } @@ -1428,7 +878,8 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy private void loadImage(PostDetailBaseViewHolder holder, @NonNull Post.Preview preview) { if (holder instanceof PostDetailImageAndGifAutoplayViewHolder) { - String url = mPost.getPostType() == Post.IMAGE_TYPE ? preview.getPreviewUrl() : mPost.getUrl(); + boolean blurImage = (mPost.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(mPost.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || (mPost.isSpoiler() && mNeedBlurSpoiler); + String url = mPost.getPostType() == Post.IMAGE_TYPE || blurImage ? preview.getPreviewUrl() : mPost.getUrl(); RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(url) .listener(new RequestListener<Drawable>() { @Override @@ -1450,7 +901,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy } }); - if ((mPost.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(mPost.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { + if (blurImage) { imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); } else { if (mImageViewWidth > preview.getPreviewWidth()) { @@ -1562,224 +1013,6 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy notifyItemChanged(0); } - private int getParentPosition(int position) { - if (position >= 0 && position < mVisibleComments.size()) { - int childDepth = mVisibleComments.get(position).getDepth(); - for (int i = position; i >= 0; i--) { - if (mVisibleComments.get(i).getDepth() < childDepth) { - return i; - } - } - } - return -1; - } - - private void expandChildren(ArrayList<Comment> comments, ArrayList<Comment> newList, int position) { - if (comments != null && comments.size() > 0) { - newList.addAll(position, comments); - for (int i = 0; i < comments.size(); i++) { - position++; - if (comments.get(i).getChildren() != null && comments.get(i).getChildren().size() > 0) { - expandChildren(comments.get(i).getChildren(), newList, position); - position = position + comments.get(i).getChildren().size(); - } - comments.get(i).setExpanded(true); - } - } - } - - private void collapseChildren(int position) { - mVisibleComments.get(position).setExpanded(false); - int depth = mVisibleComments.get(position).getDepth(); - int allChildrenSize = 0; - for (int i = position + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getDepth() > depth) { - allChildrenSize++; - } else { - break; - } - } - - if (allChildrenSize > 0) { - mVisibleComments.subList(position + 1, position + 1 + allChildrenSize).clear(); - } - if (mIsSingleCommentThreadMode) { - if (mFullyCollapseComment) { - notifyItemChanged(position + 2); - } - notifyItemRangeRemoved(position + 3, allChildrenSize); - } else { - if (mFullyCollapseComment) { - notifyItemChanged(position + 1); - } - notifyItemRangeRemoved(position + 2, allChildrenSize); - } - } - - public void addComments(@NonNull ArrayList<Comment> comments, boolean hasMoreComments) { - if (mVisibleComments.size() == 0) { - isInitiallyLoading = false; - isInitiallyLoadingFailed = false; - if (comments.size() == 0) { - notifyItemChanged(1); - } else { - notifyItemRemoved(1); - } - } - - int sizeBefore = mVisibleComments.size(); - mVisibleComments.addAll(comments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(sizeBefore + 2, comments.size()); - } else { - notifyItemRangeInserted(sizeBefore + 1, comments.size()); - } - - if (mHasMoreComments != hasMoreComments) { - if (hasMoreComments) { - if (mIsSingleCommentThreadMode) { - notifyItemInserted(mVisibleComments.size() + 2); - } else { - notifyItemInserted(mVisibleComments.size() + 1); - } - } else { - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(mVisibleComments.size() + 2); - } else { - notifyItemRemoved(mVisibleComments.size() + 1); - } - } - } - mHasMoreComments = hasMoreComments; - } - - public void addComment(Comment comment) { - if (mVisibleComments.size() == 0 || isInitiallyLoadingFailed) { - notifyItemRemoved(1); - } - - mVisibleComments.add(0, comment); - - if (isInitiallyLoading) { - notifyItemInserted(2); - } else { - notifyItemInserted(1); - } - } - - public void addChildComment(Comment comment, String parentFullname, int parentPosition) { - if (!parentFullname.equals(mVisibleComments.get(parentPosition).getFullName())) { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (parentFullname.equals(mVisibleComments.get(i).getFullName())) { - parentPosition = i; - break; - } - } - } - - mVisibleComments.get(parentPosition).addChild(comment); - mVisibleComments.get(parentPosition).setHasReply(true); - if (!mVisibleComments.get(parentPosition).isExpanded()) { - ArrayList<Comment> newList = new ArrayList<>(); - expandChildren(mVisibleComments.get(parentPosition).getChildren(), newList, 0); - mVisibleComments.get(parentPosition).setExpanded(true); - mVisibleComments.addAll(parentPosition + 1, newList); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(parentPosition + 2); - notifyItemRangeInserted(parentPosition + 3, newList.size()); - } else { - notifyItemChanged(parentPosition + 1); - notifyItemRangeInserted(parentPosition + 2, newList.size()); - } - } else { - mVisibleComments.add(parentPosition + 1, comment); - if (mIsSingleCommentThreadMode) { - notifyItemInserted(parentPosition + 3); - } else { - notifyItemInserted(parentPosition + 2); - } - } - } - - public void setSingleComment(String singleCommentId, boolean isSingleCommentThreadMode) { - mSingleCommentId = singleCommentId; - mIsSingleCommentThreadMode = isSingleCommentThreadMode; - } - - public ArrayList<Comment> getVisibleComments() { - return mVisibleComments; - } - - public void initiallyLoading() { - if (mVisibleComments.size() != 0) { - int previousSize = mVisibleComments.size(); - mVisibleComments.clear(); - if (mIsSingleCommentThreadMode) { - notifyItemRangeRemoved(1, previousSize + 1); - } else { - notifyItemRangeRemoved(1, previousSize); - } - } - - if (isInitiallyLoading || isInitiallyLoadingFailed || mVisibleComments.size() == 0) { - isInitiallyLoading = true; - isInitiallyLoadingFailed = false; - notifyItemChanged(1); - } else { - isInitiallyLoading = true; - isInitiallyLoadingFailed = false; - notifyItemInserted(1); - } - } - - public void initiallyLoadCommentsFailed() { - isInitiallyLoading = false; - isInitiallyLoadingFailed = true; - notifyItemChanged(1); - } - - public void loadMoreCommentsFailed() { - loadMoreCommentsFailed = true; - if (mIsSingleCommentThreadMode) { - notifyItemChanged(mVisibleComments.size() + 2); - } else { - notifyItemChanged(mVisibleComments.size() + 1); - } - } - - public void editComment(String commentAuthor, String commentContentMarkdown, int position) { - if (commentAuthor != null) - mVisibleComments.get(position).setAuthor(commentAuthor); - - mVisibleComments.get(position).setCommentMarkdown(commentContentMarkdown); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(position + 2); - } else { - notifyItemChanged(position + 1); - } - } - - public void deleteComment(int position) { - if (mVisibleComments != null && position >= 0 && position < mVisibleComments.size()) { - if (mVisibleComments.get(position).hasReply()) { - mVisibleComments.get(position).setAuthor("[deleted]"); - mVisibleComments.get(position).setCommentMarkdown("[deleted]"); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(position + 2); - } else { - notifyItemChanged(position + 1); - } - } else { - mVisibleComments.remove(position); - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(position + 2); - } else { - notifyItemRemoved(position + 1); - } - } - } - } - public void setBlurNsfwAndDoNotBlurNsfwInNsfwSubreddits(boolean needBlurNsfw, boolean doNotBlurNsfwInNsfwSubreddits) { mNeedBlurNsfw = needBlurNsfw; mDoNotBlurNsfwInNsfwSubreddits = doNotBlurNsfwInNsfwSubreddits; @@ -1789,44 +1022,6 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mNeedBlurSpoiler = needBlurSpoiler; } - public int getNextParentCommentPosition(int currentPosition) { - if (mVisibleComments != null && !mVisibleComments.isEmpty()) { - if (mIsSingleCommentThreadMode) { - for (int i = currentPosition + 1; i - 2 < mVisibleComments.size() && i - 2 >= 0; i++) { - if (mVisibleComments.get(i - 2).getDepth() == 0) { - return i; - } - } - } else { - for (int i = currentPosition + 1; i - 1 < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i - 1).getDepth() == 0) { - return i; - } - } - } - } - return -1; - } - - public int getPreviousParentCommentPosition(int currentPosition) { - if (mVisibleComments != null && !mVisibleComments.isEmpty()) { - if (mIsSingleCommentThreadMode) { - for (int i = currentPosition + 1; i - 2 >= 0; i--) { - if (mVisibleComments.get(i - 2).getDepth() == 0) { - return i; - } - } - } else { - for (int i = currentPosition - 1; i - 1 >= 0; i--) { - if (mVisibleComments.get(i - 1).getDepth() == 0) { - return i; - } - } - } - } - return -1; - } - public void setAutoplay(boolean autoplay) { mAutoplay = autoplay; } @@ -1850,63 +1045,20 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy ((PostDetailBaseViewHolder) viewHolder).mDownvoteButton.performClick(); } } - } else if (viewHolder instanceof CommentViewHolder) { - if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { - if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - ((CommentViewHolder) viewHolder).upvoteButton.performClick(); - } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - ((CommentViewHolder) viewHolder).downvoteButton.performClick(); - } - } else { - if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - ((CommentViewHolder) viewHolder).upvoteButton.performClick(); - } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - ((CommentViewHolder) viewHolder).downvoteButton.performClick(); - } - } - } - } - - public void giveAward(String awardsHTML, int awardCount, int position) { - if (position == 0) { - if (mPost != null) { - mPost.addAwards(awardsHTML); - mPost.addAwards(awardCount); - notifyItemChanged(0); - } - } else { - position = mIsSingleCommentThreadMode ? position + 2 : position + 1; - Comment comment = getCurrentComment(position); - if (comment != null) { - comment.addAwards(awardsHTML); - notifyItemChanged(position); - } } } - public void setSaveComment(int position, boolean isSaved) { - Comment comment = getCurrentComment(position); - if (comment != null) { - comment.setSaved(isSaved); + public void giveAward(String awardsHTML, int awardCount) { + if (mPost != null) { + mPost.addAwards(awardsHTML); + mPost.addAwards(awardCount); + notifyItemChanged(0); } } @Override public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if (holder instanceof CommentViewHolder) { - ((CommentViewHolder) holder).authorTextView.setTextColor(mUsernameColor); - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); - ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); - ((CommentViewHolder) holder).topScoreTextView.setTextColor(mSecondaryTextColor); - ((CommentViewHolder) holder).awardsTextView.setText(""); - ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); - ((CommentViewHolder) holder).expandButton.setVisibility(View.GONE); - ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); - ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).itemView.setBackgroundColor(mCommentBackgroundColor); - } else if (holder instanceof PostDetailBaseViewHolder) { + if (holder instanceof PostDetailBaseViewHolder) { ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mPostIconAndInfoColor); ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); @@ -1935,23 +1087,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy @Override public int getItemCount() { - if (isInitiallyLoading || isInitiallyLoadingFailed || mVisibleComments.size() == 0) { - return 2; - } - - if (mHasMoreComments || loadMoreCommentsFailed) { - if (mIsSingleCommentThreadMode) { - return mVisibleComments.size() + 3; - } else { - return mVisibleComments.size() + 2; - } - } - - if (mIsSingleCommentThreadMode) { - return mVisibleComments.size() + 2; - } else { - return mVisibleComments.size() + 1; - } + return 1; } @Nullable @@ -1966,12 +1102,8 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy return 0; } - public interface CommentRecyclerViewAdapterCallback { + public interface PostDetailRecyclerViewAdapterCallback { void updatePost(Post post); - - void retryFetchingComments(); - - void retryFetchingMoreComments(); } public class PostDetailBaseViewHolder extends RecyclerView.ViewHolder { @@ -2076,21 +1208,29 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mActivity.startActivity(crosspostIntent); }); - mTypeTextView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, FilteredPostsActivity.class); - intent.putExtra(FilteredPostsActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); - intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, mPost.getPostType()); - mActivity.startActivity(intent); - }); + if (!mHidePostType) { + mTypeTextView.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, mPost.getPostType()); + mActivity.startActivity(intent); + }); + } else { + mTypeTextView.setVisibility(View.GONE); + } - mFlairTextView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, FilteredPostsActivity.class); - intent.putExtra(FilteredPostsActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); - intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - intent.putExtra(FilteredPostsActivity.EXTRA_CONTAIN_FLAIR, mPost.getFlair()); - mActivity.startActivity(intent); - }); + if (!mHidePostFlair) { + mFlairTextView.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + intent.putExtra(FilteredPostsActivity.EXTRA_CONTAIN_FLAIR, mPost.getFlair()); + mActivity.startActivity(intent); + }); + } else { + mFlairTextView.setVisibility(View.GONE); + } mNSFWTextView.setOnClickListener(view -> { Intent intent = new Intent(mActivity, FilteredPostsActivity.class); @@ -2134,10 +1274,12 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mScoreTextView.setTextColor(mPostIconAndInfoColor); } - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + mPost.getVoteType())); + if (!mHideTheNumberOfVotes) { + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + mPost.getVoteType())); + } - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingWithoutPositionListener() { @Override @@ -2153,23 +1295,27 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy } mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + mPost.getVoteType())); + if (!mHideTheNumberOfVotes) { + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + mPost.getVoteType())); + } - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } @Override public void onVoteThingFail() { Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); mPost.setVoteType(previousVoteType); - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + previousVoteType)); + if (!mHideTheNumberOfVotes) { + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + previousVoteType)); + } mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter); mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter); mScoreTextView.setTextColor(previousScoreTextViewColor); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } }, mPost.getFullName(), newVoteType); }); @@ -2208,10 +1354,12 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mScoreTextView.setTextColor(mPostIconAndInfoColor); } - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + mPost.getVoteType())); + if (!mHideTheNumberOfVotes) { + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + mPost.getVoteType())); + } - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingWithoutPositionListener() { @Override @@ -2227,52 +1375,60 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy } mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + mPost.getVoteType())); + if (!mHideTheNumberOfVotes) { + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + mPost.getVoteType())); + } - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } @Override public void onVoteThingFail() { Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); mPost.setVoteType(previousVoteType); - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + previousVoteType)); + if (!mHideTheNumberOfVotes) { + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + previousVoteType)); + } mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter); mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter); mScoreTextView.setTextColor(previousScoreTextViewColor); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } }, mPost.getFullName(), newVoteType); }); - commentsCountTextView.setOnClickListener(view -> { - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_comment_unavailable, Toast.LENGTH_SHORT).show(); - return; - } + if (!mHideTheNumberOfComments) { + commentsCountTextView.setOnClickListener(view -> { + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_comment_unavailable, Toast.LENGTH_SHORT).show(); + return; + } - if (mPost.isLocked()) { - Toast.makeText(mActivity, R.string.locked_post_comment_unavailable, Toast.LENGTH_SHORT).show(); - return; - } + if (mPost.isLocked()) { + Toast.makeText(mActivity, R.string.locked_post_comment_unavailable, Toast.LENGTH_SHORT).show(); + return; + } - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } - Intent intent = new Intent(mActivity, CommentActivity.class); - intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, mPost.getFullName()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, mPost.getTitle()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY, mPost.getSelfText()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_KEY, mPost.getSelfTextPlain()); - intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, false); - intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, 0); - mActivity.startActivityForResult(intent, WRITE_COMMENT_REQUEST_CODE); - }); + Intent intent = new Intent(mActivity, CommentActivity.class); + intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, mPost.getFullName()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, mPost.getTitle()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY, mPost.getSelfText()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_KEY, mPost.getSelfTextPlain()); + intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, false); + intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, 0); + mActivity.startActivityForResult(intent, WRITE_COMMENT_REQUEST_CODE); + }); + } else { + commentsCountTextView.setVisibility(View.GONE); + } mSaveButton.setOnClickListener(view -> { if (mAccessToken == null) { @@ -2289,7 +1445,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mPost.setSaved(false); mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); Toast.makeText(mActivity, R.string.post_unsaved_success, Toast.LENGTH_SHORT).show(); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } @Override @@ -2297,7 +1453,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mPost.setSaved(true); mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } }); } else { @@ -2309,7 +1465,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mPost.setSaved(true); mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } @Override @@ -2317,7 +1473,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mPost.setSaved(false); mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); Toast.makeText(mActivity, R.string.post_saved_failed, Toast.LENGTH_SHORT).show(); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); + mPostDetailRecyclerViewAdapterCallback.updatePost(mPost); } }); } @@ -2495,11 +1651,11 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy muteButton.setOnClickListener(view -> { if (helper != null) { if (helper.getVolume() != 0) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_24dp)); helper.setVolume(0f); volume = 0f; } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_24dp)); helper.setVolume(1f); volume = 1f; } @@ -2523,6 +1679,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); } } else { + intent.setData(Uri.parse(mPost.getVideoUrl())); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, mPost.getSubredditName()); intent.putExtra(ViewVideoActivity.EXTRA_ID, mPost.getId()); @@ -2580,9 +1737,9 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy helper.setVolume(volume); muteButton.setVisibility(View.VISIBLE); if (volume != 0f) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_24dp)); } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_24dp)); } break; } @@ -2642,7 +1799,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy @Override public int getPlayerOrder() { - return getBindingAdapterPosition(); + return 0; } } @@ -3276,625 +2433,4 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy mShareButton); } } - - public class CommentViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.author_text_view_item_post_comment) - TextView authorTextView; - @BindView(R.id.author_flair_text_view_item_post_comment) - TextView authorFlairTextView; - @BindView(R.id.comment_time_text_view_item_post_comment) - TextView commentTimeTextView; - @BindView(R.id.top_score_text_view_item_post_comment) - TextView topScoreTextView; - @BindView(R.id.awards_text_view_item_comment) - TextView awardsTextView; - @BindView(R.id.comment_markdown_view_item_post_comment) - TextView commentMarkdownView; - @BindView(R.id.bottom_constraint_layout_item_post_comment) - ConstraintLayout bottomConstraintLayout; - @BindView(R.id.up_vote_button_item_post_comment) - ImageView upvoteButton; - @BindView(R.id.score_text_view_item_post_comment) - TextView scoreTextView; - @BindView(R.id.down_vote_button_item_post_comment) - ImageView downvoteButton; - @BindView(R.id.more_button_item_post_comment) - ImageView moreButton; - @BindView(R.id.save_button_item_post_comment) - ImageView saveButton; - @BindView(R.id.expand_button_item_post_comment) - ImageView expandButton; - @BindView(R.id.reply_button_item_post_comment) - ImageView replyButton; - @BindView(R.id.vertical_block_indentation_item_comment) - CommentIndentationView commentIndentationView; - @BindView(R.id.divider_item_comment) - View commentDivider; - - CommentViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - if (mVoteButtonsOnTheRight) { - ConstraintSet constraintSet = new ConstraintSet(); - constraintSet.clone(bottomConstraintLayout); - constraintSet.clear(upvoteButton.getId(), ConstraintSet.START); - constraintSet.clear(scoreTextView.getId(), ConstraintSet.START); - constraintSet.clear(downvoteButton.getId(), ConstraintSet.START); - constraintSet.clear(expandButton.getId(), ConstraintSet.END); - constraintSet.clear(saveButton.getId(), ConstraintSet.END); - constraintSet.clear(replyButton.getId(), ConstraintSet.END); - constraintSet.clear(moreButton.getId(), ConstraintSet.END); - constraintSet.connect(upvoteButton.getId(), ConstraintSet.END, scoreTextView.getId(), ConstraintSet.START); - constraintSet.connect(scoreTextView.getId(), ConstraintSet.END, downvoteButton.getId(), ConstraintSet.START); - constraintSet.connect(downvoteButton.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END); - constraintSet.connect(moreButton.getId(), ConstraintSet.START, expandButton.getId(), ConstraintSet.END); - constraintSet.connect(expandButton.getId(), ConstraintSet.START, saveButton.getId(), ConstraintSet.END); - constraintSet.connect(saveButton.getId(), ConstraintSet.START, replyButton.getId(), ConstraintSet.END); - constraintSet.connect(replyButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); - constraintSet.setHorizontalBias(moreButton.getId(), 0); - constraintSet.applyTo(bottomConstraintLayout); - } - - if (mShowCommentDivider) { - commentDivider.setBackgroundColor(mDividerColor); - commentDivider.setVisibility(View.VISIBLE); - } - - itemView.setBackgroundColor(mCommentBackgroundColor); - authorTextView.setTextColor(mUsernameColor); - commentTimeTextView.setTextColor(mSecondaryTextColor); - commentMarkdownView.setTextColor(mCommentTextColor); - authorFlairTextView.setTextColor(mAuthorFlairTextColor); - topScoreTextView.setTextColor(mSecondaryTextColor); - awardsTextView.setTextColor(mSecondaryTextColor); - commentDivider.setBackgroundColor(mDividerColor); - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - moreButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - expandButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - saveButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - authorFlairTextView.setOnClickListener(view -> authorTextView.performClick()); - - moreButton.setOnClickListener(view -> { - Comment comment = getCurrentComment(this); - if (comment != null) { - Bundle bundle = new Bundle(); - if (!mPost.isArchived() && !mPost.isLocked() && comment.getAuthor().equals(mAccountName)) { - bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_EDIT_AND_DELETE_AVAILABLE, true); - } - bundle.putString(CommentMoreBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putParcelable(CommentMoreBottomSheetFragment.EXTRA_COMMENT, comment); - if (mIsSingleCommentThreadMode) { - bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getBindingAdapterPosition() - 2); - } else { - bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getBindingAdapterPosition() - 1); - } - bundle.putString(CommentMoreBottomSheetFragment.EXTRA_COMMENT_MARKDOWN, comment.getCommentMarkdown()); - bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_IS_NSFW, mPost.isNSFW()); - if (comment.getDepth() > depthThreshold) { - bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_SHOW_REPLY_AND_SAVE_OPTION, true); - } - CommentMoreBottomSheetFragment commentMoreBottomSheetFragment = new CommentMoreBottomSheetFragment(); - commentMoreBottomSheetFragment.setArguments(bundle); - commentMoreBottomSheetFragment.show(mActivity.getSupportFragmentManager(), commentMoreBottomSheetFragment.getTag()); - } - }); - - replyButton.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_reply_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mPost.isLocked()) { - Toast.makeText(mActivity, R.string.locked_post_reply_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - Comment comment = getCurrentComment(this); - if (comment != null) { - Intent intent = new Intent(mActivity, CommentActivity.class); - intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, comment.getDepth() + 1); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, comment.getCommentMarkdown()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, comment.getCommentRawText()); - intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, comment.getFullName()); - intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true); - - int parentPosition = mIsSingleCommentThreadMode ? getBindingAdapterPosition() - 2 : getBindingAdapterPosition() - 1; - intent.putExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, parentPosition); - mFragment.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE); - } - }); - - upvoteButton.setOnClickListener(view -> { - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - Comment comment = getCurrentComment(this); - if (comment != null) { - int previousVoteType = comment.getVoteType(); - String newVoteType; - - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { - //Not upvoted before - comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); - newVoteType = APIUtils.DIR_UPVOTE; - upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - topScoreTextView.setTextColor(mUpvotedColor); - } else { - //Upvoted before - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - newVoteType = APIUtils.DIR_UNVOTE; - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - topScoreTextView.setTextColor(mSecondaryTextColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - - int position = getBindingAdapterPosition(); - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position) { - int currentPosition = getBindingAdapterPosition(); - if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { - comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); - if (currentPosition == position) { - upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - topScoreTextView.setTextColor(mUpvotedColor); - } - } else { - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - if (currentPosition == position) { - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - topScoreTextView.setTextColor(mSecondaryTextColor); - } - } - - if (currentPosition == position) { - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - } - } - - @Override - public void onVoteThingFail(int position) { - } - }, comment.getFullName(), newVoteType, getBindingAdapterPosition()); - } - }); - - downvoteButton.setOnClickListener(view -> { - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - Comment comment = getCurrentComment(this); - if (comment != null) { - int previousVoteType = comment.getVoteType(); - String newVoteType; - - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { - //Not downvoted before - comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); - newVoteType = APIUtils.DIR_DOWNVOTE; - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - topScoreTextView.setTextColor(mDownvotedColor); - } else { - //Downvoted before - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - newVoteType = APIUtils.DIR_UNVOTE; - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - topScoreTextView.setTextColor(mSecondaryTextColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - - int position = getBindingAdapterPosition(); - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - int currentPosition = getBindingAdapterPosition(); - if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { - comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); - if (currentPosition == position) { - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - topScoreTextView.setTextColor(mDownvotedColor); - } - } else { - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - if (currentPosition == position) { - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - topScoreTextView.setTextColor(mSecondaryTextColor); - } - } - - if (currentPosition == position) { - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - } - } - - @Override - public void onVoteThingFail(int position1) { - } - }, comment.getFullName(), newVoteType, getBindingAdapterPosition()); - } - }); - - saveButton.setOnClickListener(view -> { - Comment comment = getCurrentComment(this); - if (comment != null) { - int position = getBindingAdapterPosition(); - if (comment.isSaved()) { - comment.setSaved(false); - SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { - @Override - public void success() { - comment.setSaved(false); - if (getBindingAdapterPosition() == position) { - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - } - Toast.makeText(mActivity, R.string.comment_unsaved_success, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - comment.setSaved(true); - if (getBindingAdapterPosition() == position) { - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - } - Toast.makeText(mActivity, R.string.comment_unsaved_failed, Toast.LENGTH_SHORT).show(); - } - }); - } else { - comment.setSaved(true); - SaveThing.saveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { - @Override - public void success() { - comment.setSaved(true); - if (getBindingAdapterPosition() == position) { - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - } - Toast.makeText(mActivity, R.string.comment_saved_success, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - comment.setSaved(false); - if (getBindingAdapterPosition() == position) { - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - } - Toast.makeText(mActivity, R.string.comment_saved_failed, Toast.LENGTH_SHORT).show(); - } - }); - } - } - }); - - authorTextView.setOnClickListener(view -> { - Comment comment = getCurrentComment(this); - if (comment != null) { - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, comment.getAuthor()); - mActivity.startActivity(intent); - } - }); - - expandButton.setOnClickListener(view -> { - if (expandButton.getVisibility() == View.VISIBLE) { - int commentPosition = mIsSingleCommentThreadMode ? getBindingAdapterPosition() - 2 : getBindingAdapterPosition() - 1; - if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { - Comment comment = getCurrentComment(this); - if (comment != null) { - if (mVisibleComments.get(commentPosition).isExpanded()) { - collapseChildren(commentPosition); - expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); - } else { - comment.setExpanded(true); - ArrayList<Comment> newList = new ArrayList<>(); - expandChildren(mVisibleComments.get(commentPosition).getChildren(), newList, 0); - mVisibleComments.get(commentPosition).setExpanded(true); - mVisibleComments.addAll(commentPosition + 1, newList); - - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(commentPosition + 3, newList.size()); - } else { - notifyItemRangeInserted(commentPosition + 2, newList.size()); - } - expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); - } - } - } - } else if (mFullyCollapseComment) { - int commentPosition = mIsSingleCommentThreadMode ? getBindingAdapterPosition() - 2 : getBindingAdapterPosition() - 1; - if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { - collapseChildren(commentPosition); - } - } - }); - - if (mSwapTapAndLong) { - if (mCommentToolbarHideOnClick) { - View.OnLongClickListener hideToolbarOnLongClickListener = view -> hideToolbar(); - itemView.setOnLongClickListener(hideToolbarOnLongClickListener); - commentMarkdownView.setOnLongClickListener(hideToolbarOnLongClickListener); - commentTimeTextView.setOnLongClickListener(hideToolbarOnLongClickListener); - } - commentMarkdownView.setOnClickListener(view -> { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - expandComments(); - } - }); - itemView.setOnClickListener(view -> expandComments()); - } else { - if (mCommentToolbarHideOnClick) { - commentMarkdownView.setOnClickListener(view -> { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - hideToolbar(); - } - }); - View.OnClickListener hideToolbarOnClickListener = view -> hideToolbar(); - itemView.setOnClickListener(hideToolbarOnClickListener); - commentTimeTextView.setOnClickListener(hideToolbarOnClickListener); - } - commentMarkdownView.setOnLongClickListener(view -> { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - expandComments(); - } - return true; - }); - itemView.setOnLongClickListener(view -> { - expandComments(); - return true; - }); - } - commentMarkdownView.setHighlightColor(Color.TRANSPARENT); - } - - private boolean expandComments() { - expandButton.performClick(); - return true; - } - - private boolean hideToolbar() { - if (bottomConstraintLayout.getLayoutParams().height == 0) { - bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; - topScoreTextView.setVisibility(View.GONE); - mFragment.delayTransition(); - } else { - mFragment.delayTransition(); - bottomConstraintLayout.getLayoutParams().height = 0; - topScoreTextView.setVisibility(View.VISIBLE); - } - return true; - } - } - - @Nullable - private Comment getCurrentComment(RecyclerView.ViewHolder holder) { - return getCurrentComment(holder.getBindingAdapterPosition()); - } - - @Nullable - private Comment getCurrentComment(int position) { - if (mIsSingleCommentThreadMode) { - if (position - 2 >= 0 && position - 2 < mVisibleComments.size()) { - return mVisibleComments.get(position - 2); - } - } else { - if (position - 1 >= 0 && position - 1 < mVisibleComments.size()) { - return mVisibleComments.get(position - 1); - } - } - - return null; - } - - class CommentFullyCollapsedViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.vertical_block_indentation_item_comment_fully_collapsed) - CommentIndentationView commentIndentationView; - @BindView(R.id.user_name_text_view_item_comment_fully_collapsed) - TextView usernameTextView; - @BindView(R.id.score_text_view_item_comment_fully_collapsed) - TextView scoreTextView; - @BindView(R.id.time_text_view_item_comment_fully_collapsed) - TextView commentTimeTextView; - @BindView(R.id.divider_item_comment_fully_collapsed) - View commentDivider; - - public CommentFullyCollapsedViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - itemView.setBackgroundColor(mFullyCollapsedCommentBackgroundColor); - usernameTextView.setTextColor(mUsernameColor); - scoreTextView.setTextColor(mSecondaryTextColor); - commentTimeTextView.setTextColor(mSecondaryTextColor); - - if (mShowCommentDivider) { - commentDivider.setBackgroundColor(mDividerColor); - commentDivider.setVisibility(View.VISIBLE); - } - - itemView.setOnClickListener(view -> { - int commentPosition = mIsSingleCommentThreadMode ? getBindingAdapterPosition() - 2 : getBindingAdapterPosition() - 1; - if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { - Comment comment = getCurrentComment(this); - if (comment != null) { - comment.setExpanded(true); - ArrayList<Comment> newList = new ArrayList<>(); - expandChildren(mVisibleComments.get(commentPosition).getChildren(), newList, 0); - mVisibleComments.get(commentPosition).setExpanded(true); - mVisibleComments.addAll(commentPosition + 1, newList); - - if (mIsSingleCommentThreadMode) { - notifyItemChanged(commentPosition + 2); - notifyItemRangeInserted(commentPosition + 3, newList.size()); - } else { - notifyItemChanged(commentPosition + 1); - notifyItemRangeInserted(commentPosition + 2, newList.size()); - } - } - } - }); - - itemView.setOnLongClickListener(view -> { - itemView.performClick(); - return true; - }); - } - } - - class LoadMoreChildCommentsViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.vertical_block_indentation_item_load_more_comments_placeholder) - CommentIndentationView commentIndentationView; - @BindView(R.id.placeholder_text_view_item_load_more_comments) - TextView placeholderTextView; - @BindView(R.id.divider_item_load_more_comments_placeholder) - View commentDivider; - - LoadMoreChildCommentsViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - if (mShowCommentDivider) { - commentDivider.setVisibility(View.VISIBLE); - } - - itemView.setBackgroundColor(mCommentBackgroundColor); - placeholderTextView.setTextColor(mPrimaryTextColor); - commentDivider.setBackgroundColor(mDividerColor); - } - } - - class LoadCommentsViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.comment_progress_bar_item_load_comments) - CircleProgressBar circleProgressBar; - - LoadCommentsViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - circleProgressBar.setBackgroundTintList(ColorStateList.valueOf(mCircularProgressBarBackgroundColor)); - circleProgressBar.setColorSchemeColors(mColorAccent); - } - } - - class LoadCommentsFailedViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_load_comments_failed_placeholder) - TextView errorTextView; - - LoadCommentsFailedViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - itemView.setOnClickListener(view -> mCommentRecyclerViewAdapterCallback.retryFetchingComments()); - errorTextView.setTextColor(mSecondaryTextColor); - } - } - - class NoCommentViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_no_comment_placeholder) - TextView errorTextView; - - NoCommentViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - errorTextView.setTextColor(mSecondaryTextColor); - } - } - - class IsLoadingMoreCommentsViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.progress_bar_item_comment_footer_loading) - ProgressBar progressbar; - - IsLoadingMoreCommentsViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - progressbar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - } - } - - class LoadMoreCommentsFailedViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_comment_footer_error) - TextView errorTextView; - @BindView(R.id.retry_button_item_comment_footer_error) - Button retryButton; - - LoadMoreCommentsFailedViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - errorTextView.setText(R.string.load_comments_failed); - retryButton.setOnClickListener(view -> mCommentRecyclerViewAdapterCallback.retryFetchingMoreComments()); - errorTextView.setTextColor(mSecondaryTextColor); - retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); - retryButton.setTextColor(mButtonTextColor); - } - } - - class ViewAllCommentsViewHolder extends RecyclerView.ViewHolder { - - ViewAllCommentsViewHolder(@NonNull View itemView) { - super(itemView); - - itemView.setOnClickListener(view -> { - if (mActivity != null && mActivity instanceof ViewPostDetailActivity) { - mIsSingleCommentThreadMode = false; - mSingleCommentId = null; - mFragment.changeToNomalThreadMode(); - } - }); - - itemView.setBackgroundTintList(ColorStateList.valueOf(mCommentBackgroundColor)); - ((TextView) itemView).setTextColor(mColorAccent); - } - } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostRecyclerViewAdapter.java index 95be0ca5..12d6c0d1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostRecyclerViewAdapter.java @@ -29,6 +29,7 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.Barrier; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; +import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; import androidx.paging.PagedListAdapter; import androidx.recyclerview.widget.DiffUtil; @@ -106,19 +107,15 @@ import retrofit2.Retrofit; public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHolder> implements CacheManager { private static final int VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE = 1; - private static final int VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE = 2; - private static final int VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE = 3; - private static final int VIEW_TYPE_POST_CARD_LINK_TYPE = 4; - private static final int VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE = 5; - private static final int VIEW_TYPE_POST_CARD_TEXT_TYPE = 6; - private static final int VIEW_TYPE_POST_CARD_GALLERY_TYPE = 7; - private static final int VIEW_TYPE_POST_COMPACT = 8; - private static final int VIEW_TYPE_POST_GALLERY = 9; - private static final int VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE = 10; - private static final int VIEW_TYPE_POST_CARD_2_WITH_PREVIEW = 11; - private static final int VIEW_TYPE_POST_CARD_2_TEXT_TYPE = 12; - private static final int VIEW_TYPE_ERROR = 13; - private static final int VIEW_TYPE_LOADING = 14; + private static final int VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE = 2; + private static final int VIEW_TYPE_POST_CARD_TEXT_TYPE = 3; + private static final int VIEW_TYPE_POST_COMPACT = 4; + private static final int VIEW_TYPE_POST_GALLERY = 5; + private static final int VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE = 6; + private static final int VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE = 7; + private static final int VIEW_TYPE_POST_CARD_2_TEXT_TYPE = 8; + private static final int VIEW_TYPE_ERROR = 9; + private static final int VIEW_TYPE_LOADING = 10; private static final DiffUtil.ItemCallback<Post> DIFF_CALLBACK = new DiffUtil.ItemCallback<Post>() { @Override @@ -148,6 +145,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView private boolean canStartActivity = true; private int mPostType; private int mPostLayout; + private int mDefaultLinkPostLayout; private int mColorPrimaryLightTheme; private int mColorAccent; private int mCardViewBackgroundColor; @@ -210,6 +208,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView private boolean mMarkPostsAsReadOnScroll; private boolean mHideReadPostsAutomatically; private boolean mHidePostType; + private boolean mHidePostFlair; private boolean mHideTheNumberOfAwards; private boolean mHideSubredditAndUserPrefix; private boolean mHideTheNumberOfVotes; @@ -287,12 +286,14 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView mHideReadPostsAutomatically = postHistorySharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.HIDE_READ_POSTS_AUTOMATICALLY_BASE, false); mHidePostType = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_POST_TYPE, false); + mHidePostFlair = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_POST_FLAIR, false); mHideTheNumberOfAwards = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_AWARDS, false); mHideSubredditAndUserPrefix = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_SUBREDDIT_AND_USER_PREFIX, false); mHideTheNumberOfVotes = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_VOTES, false); mHideTheNumberOfComments = sharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_COMMENTS, false); mPostLayout = postLayout; + mDefaultLinkPostLayout = Integer.parseInt(sharedPreferences.getString(SharedPreferencesUtils.DEFAULT_LINK_POST_LAYOUT_KEY, "-1")); mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); mColorAccent = customThemeWrapper.getColorAccent(); @@ -364,33 +365,45 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView case Post.VIDEO_TYPE: if (mAutoplay) { if (!mAutoplayNsfwVideos && post.isNSFW()) { - return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; } return VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE; } - return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; case Post.GIF_TYPE: - if (mAutoplay) { - if (!mAutoplayNsfwVideos && post.isNSFW()) { - return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; - } - return VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE; - } - return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; case Post.IMAGE_TYPE: - return VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE; + case Post.GALLERY_TYPE: + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; case Post.LINK_TYPE: - return VIEW_TYPE_POST_CARD_LINK_TYPE; case Post.NO_PREVIEW_LINK_TYPE: - return VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE; - case Post.GALLERY_TYPE: - return VIEW_TYPE_POST_CARD_GALLERY_TYPE; + switch (mDefaultLinkPostLayout) { + case SharedPreferencesUtils.POST_LAYOUT_CARD_2: + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; + case SharedPreferencesUtils.POST_LAYOUT_GALLERY: + return VIEW_TYPE_POST_GALLERY; + case SharedPreferencesUtils.POST_LAYOUT_COMPACT: + return VIEW_TYPE_POST_COMPACT; + } + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; default: return VIEW_TYPE_POST_CARD_TEXT_TYPE; } } return VIEW_TYPE_POST_CARD_TEXT_TYPE; } else if (mPostLayout == SharedPreferencesUtils.POST_LAYOUT_COMPACT) { + Post post = getItem(position); + if (post != null) { + if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + switch (mDefaultLinkPostLayout) { + case SharedPreferencesUtils.POST_LAYOUT_CARD: + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; + case SharedPreferencesUtils.POST_LAYOUT_GALLERY: + return VIEW_TYPE_POST_GALLERY; + case SharedPreferencesUtils.POST_LAYOUT_CARD_2: + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; + } + } + } return VIEW_TYPE_POST_COMPACT; } else if (mPostLayout == SharedPreferencesUtils.POST_LAYOUT_GALLERY) { return VIEW_TYPE_POST_GALLERY; @@ -401,17 +414,26 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView case Post.VIDEO_TYPE: if (mAutoplay) { if (!mAutoplayNsfwVideos && post.isNSFW()) { - return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW; + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; } return VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE; } - return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW; + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; case Post.GIF_TYPE: case Post.IMAGE_TYPE: + case Post.GALLERY_TYPE: + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; case Post.LINK_TYPE: case Post.NO_PREVIEW_LINK_TYPE: - case Post.GALLERY_TYPE: - return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW; + switch (mDefaultLinkPostLayout) { + case SharedPreferencesUtils.POST_LAYOUT_CARD: + return VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE; + case SharedPreferencesUtils.POST_LAYOUT_GALLERY: + return VIEW_TYPE_POST_GALLERY; + case SharedPreferencesUtils.POST_LAYOUT_COMPACT: + return VIEW_TYPE_POST_COMPACT; + } + return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; default: return VIEW_TYPE_POST_CARD_2_TEXT_TYPE; } @@ -429,11 +451,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView return new PostWithPreviewTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_with_preview, parent, false)); } return new PostVideoAutoplayViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_video_type_autoplay, parent, false)); - } else if (viewType == VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE - || viewType == VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE - || viewType == VIEW_TYPE_POST_CARD_LINK_TYPE - || viewType == VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE - || viewType == VIEW_TYPE_POST_CARD_GALLERY_TYPE) { + } else if (viewType == VIEW_TYPE_POST_CARD_WITH_PREVIEW_TYPE) { return new PostWithPreviewTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_with_preview, parent, false)); } else if (viewType == VIEW_TYPE_POST_CARD_TEXT_TYPE) { return new PostTextTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_text, parent, false)); @@ -447,7 +465,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView return new PostGalleryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_gallery, parent, false)); } else if (viewType == VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE) { return new PostCard2VideoAutoplayViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_card_2_video_autoplay, parent, false)); - } else if (viewType == VIEW_TYPE_POST_CARD_2_WITH_PREVIEW) { + } else if (viewType == VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE) { return new PostCard2WithPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_card_2_with_preview, parent, false)); } else if (viewType == VIEW_TYPE_POST_CARD_2_TEXT_TYPE) { return new PostCard2TextTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_card_2_text, parent, false)); @@ -474,7 +492,12 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView holder.itemView.setLayoutParams(params); return; } - holder.itemView.setBackgroundTintList(ColorStateList.valueOf(mReadPostCardViewBackgroundColor)); + if (((PostBaseViewHolder) holder).itemViewIsNotCardView) { + holder.itemView.setBackgroundColor(mReadPostCardViewBackgroundColor); + } else { + holder.itemView.setBackgroundTintList(ColorStateList.valueOf(mReadPostCardViewBackgroundColor)); + } + ((PostBaseViewHolder) holder).titleTextView.setTextColor(mReadPostTitleColor); } String subredditNamePrefixed = post.getSubredditNamePrefixed(); @@ -622,8 +645,12 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } if (flair != null && !flair.equals("")) { - ((PostBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((PostBaseViewHolder) holder).flairTextView, flair, false); + if (mHidePostFlair) { + ((PostBaseViewHolder) holder).flairTextView.setVisibility(View.GONE); + } else { + ((PostBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostBaseViewHolder) holder).flairTextView, flair, false); + } } if (nAwards > 0 && !mHideTheNumberOfAwards) { @@ -698,7 +725,11 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } else { ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); } - ((PostVideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + if (mFragment.getMasterMutingOption() == null) { + ((PostVideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + } else { + ((PostVideoAutoplayViewHolder) holder).setVolume(mFragment.getMasterMutingOption() ? 0f : 1f); + } if (post.isGfycat() || post.isRedgifs() && !post.isLoadGfyOrRedgifsVideoSuccess()) { ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks = new FetchGfycatOrRedgifsVideoLinks(new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { @@ -720,18 +751,21 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } }); ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks - .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mGfycatRetrofit, mRedgifsRetrofit, - post.getGfycatId(), post.isGfycat(), mAutomaticallyTryRedgifs); + .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mExecutor, new Handler(), + mGfycatRetrofit, mRedgifsRetrofit, post.getGfycatId(), + post.isGfycat(), mAutomaticallyTryRedgifs); } else { ((PostVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); } } else if (holder instanceof PostWithPreviewTypeViewHolder) { if (post.getPostType() == Post.VIDEO_TYPE) { ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.video)); } else if (post.getPostType() == Post.GIF_TYPE) { if (!mAutoplay) { ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); } ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gif)); } else if (post.getPostType() == Post.IMAGE_TYPE) { @@ -747,6 +781,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } } else if (post.getPostType() == Post.GALLERY_TYPE) { ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gallery)); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_gallery_reverse_color_24dp)); } if (post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { @@ -764,7 +800,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } else if (post.getPostType() == Post.LINK_TYPE) { ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); } else if (post.getPostType() == Post.GALLERY_TYPE) { - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_24dp); + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); } } else if (mDataSavingMode && mOnlyDisablePreviewInVideoAndGifPosts && (post.getPostType() == Post.VIDEO_TYPE || post.getPostType() == Post.GIF_TYPE)) { ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); @@ -796,7 +832,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } else if (post.getPostType() == Post.LINK_TYPE) { ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); } else if (post.getPostType() == Post.GALLERY_TYPE) { - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_24dp); + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); } } } @@ -821,7 +857,11 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } else { ((PostCard2VideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); } - ((PostCard2VideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + if (mFragment.getMasterMutingOption() == null) { + ((PostCard2VideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + } else { + ((PostCard2VideoAutoplayViewHolder) holder).setVolume(mFragment.getMasterMutingOption() ? 0f : 1f); + } if (post.isGfycat() || post.isRedgifs() && !post.isLoadGfyOrRedgifsVideoSuccess()) { ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks = new FetchGfycatOrRedgifsVideoLinks(new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { @@ -843,18 +883,21 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } }); ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks - .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mGfycatRetrofit, mRedgifsRetrofit, - post.getGfycatId(), post.isGfycat(), mAutomaticallyTryRedgifs); + .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mExecutor, new Handler(), + mGfycatRetrofit, mRedgifsRetrofit, post.getGfycatId(), post.isGfycat(), + mAutomaticallyTryRedgifs); } else { ((PostCard2VideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); } } else if (holder instanceof PostCard2WithPreviewViewHolder) { if (post.getPostType() == Post.VIDEO_TYPE) { ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); ((PostCard2WithPreviewViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.video)); } else if (post.getPostType() == Post.GIF_TYPE) { if (!mAutoplay) { ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); } ((PostCard2WithPreviewViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gif)); } else if (post.getPostType() == Post.IMAGE_TYPE) { @@ -870,6 +913,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } } else if (post.getPostType() == Post.GALLERY_TYPE) { ((PostCard2WithPreviewViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gallery)); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + ((PostCard2WithPreviewViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_gallery_reverse_color_24dp)); } if (post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { @@ -888,7 +933,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } else if (post.getPostType() == Post.LINK_TYPE) { ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); } else if (post.getPostType() == Post.GALLERY_TYPE) { - ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); } } else if (mDataSavingMode && mOnlyDisablePreviewInVideoAndGifPosts && (post.getPostType() == Post.VIDEO_TYPE || post.getPostType() == Post.GIF_TYPE)) { ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); @@ -922,7 +967,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } else if (post.getPostType() == Post.LINK_TYPE) { ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); } else if (post.getPostType() == Post.GALLERY_TYPE) { - ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); } } } @@ -1123,8 +1168,12 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } if (flair != null && !flair.equals("")) { - ((PostCompactBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((PostCompactBaseViewHolder) holder).flairTextView, flair, false); + if (mHidePostFlair) { + ((PostCompactBaseViewHolder) holder).flairTextView.setVisibility(View.GONE); + } else { + ((PostCompactBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostCompactBaseViewHolder) holder).flairTextView, flair, false); + } } if (nAwards > 0 && !mHideTheNumberOfAwards) { @@ -1153,7 +1202,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostCompactBaseViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); if (post.getPostType() == Post.GALLERY_TYPE && post.getPreviews() != null && post.getPreviews().isEmpty()) { ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); - ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_gallery_24dp); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); } ArrayList<Post.Preview> previews = post.getPreviews(); if (previews != null && !previews.isEmpty()) { @@ -1242,7 +1291,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.gallery); if (mDataSavingMode && mDisableImagePreview) { ((PostCompactBaseViewHolder) holder).noPreviewPostImageFrameLayout.setVisibility(View.VISIBLE); - ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_gallery_24dp); + ((PostCompactBaseViewHolder) holder).noPreviewPostImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); } break; case Post.TEXT_TYPE: @@ -1307,12 +1356,11 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_outline_video_24dp); ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { - ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); } else if (post.getPostType() == Post.LINK_TYPE) { ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); } else if (post.getPostType() == Post.GALLERY_TYPE) { - ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); } ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); } @@ -1322,7 +1370,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); - ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(mActivity.getDrawable(R.drawable.ic_play_circle_36dp)); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); Post.Preview preview = getSuitablePreview(post.getPreviews()); if (preview != null) { @@ -1347,7 +1395,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); - ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(mActivity.getDrawable(R.drawable.ic_play_circle_36dp)); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); Post.Preview preview = getSuitablePreview(post.getPreviews()); if (preview != null) { @@ -1372,7 +1420,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); - ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(mActivity.getDrawable(R.drawable.ic_link_post_type_indicator)); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_link_post_type_indicator)); Post.Preview preview = getSuitablePreview(post.getPreviews()); if (preview != null) { @@ -1407,7 +1455,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); - ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(mActivity.getDrawable(R.drawable.ic_gallery_24dp)); + ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_gallery_reverse_color_24dp)); Post.Preview preview = getSuitablePreview(post.getPreviews()); if (preview != null) { @@ -1424,7 +1472,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView loadImage(holder, post, preview); } else { ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); - ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_24dp); + ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_gallery_reverse_color_24dp); } break; } @@ -1477,7 +1525,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView private void loadImage(final RecyclerView.ViewHolder holder, final Post post, @NonNull Post.Preview preview) { if (holder instanceof PostWithPreviewTypeViewHolder) { String url; - if (post.getPostType() == Post.GIF_TYPE && mAutoplay) { + boolean blurImage = (post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(post.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler; + if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { url = post.getUrl(); } else { url = preview.getPreviewUrl(); @@ -1503,7 +1552,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } }); - if ((post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(post.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler) { + if (blurImage) { imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) .into(((PostWithPreviewTypeViewHolder) holder).imageView); } else { @@ -1546,7 +1595,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } } else if (holder instanceof PostGalleryViewHolder) { String url; - if (post.getPostType() == Post.GIF_TYPE && mAutoplay) { + boolean blurImage = (post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(post.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler; + if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { url = post.getUrl(); } else { url = preview.getPreviewUrl(); @@ -1572,7 +1622,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } }); - if ((post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(post.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler) { + if (blurImage) { imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) .into(((PostGalleryViewHolder) holder).imageView); } else { @@ -1584,7 +1634,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } } else if (holder instanceof PostCard2WithPreviewViewHolder) { String url; - if (post.getPostType() == Post.GIF_TYPE && mAutoplay) { + boolean blurImage = (post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(post.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler; + if (post.getPostType() == Post.GIF_TYPE && mAutoplay && !blurImage) { url = post.getUrl(); } else { url = preview.getPreviewUrl(); @@ -1610,7 +1661,7 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } }); - if ((post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(post.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler) { + if (blurImage) { imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) .into(((PostCard2WithPreviewViewHolder) holder).imageView); } else { @@ -1801,6 +1852,10 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView mHidePostType = hidePostType; } + public void setHidePostFlair(boolean hidePostFlair) { + mHidePostFlair = hidePostFlair; + } + public void setHideTheNumberOfAwards(boolean hideTheNumberOfAwards) { mHideTheNumberOfAwards = hideTheNumberOfAwards; } @@ -1817,6 +1872,10 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView mHideTheNumberOfComments = hideTheNumberOfComments; } + public void setDefaultLinkPostLayout(int defaultLinkPostLayout) { + mDefaultLinkPostLayout = defaultLinkPostLayout; + } + @Override public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { super.onViewRecycled(holder); @@ -1828,22 +1887,26 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostBaseViewHolder) holder).markPostRead(post, false); } } - ((PostBaseViewHolder) holder).itemView.setVisibility(View.VISIBLE); + holder.itemView.setVisibility(View.VISIBLE); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); params.height = ViewGroup.LayoutParams.WRAP_CONTENT; if (holder instanceof PostCard2VideoAutoplayViewHolder || holder instanceof PostCard2WithPreviewViewHolder) { int paddingPixel = (int) Utils.convertDpToPixel(16, mActivity); - ((PostBaseViewHolder) holder).itemView.setPadding(0, paddingPixel, 0, 0); + holder.itemView.setPadding(0, paddingPixel, 0, 0); } else if (holder instanceof PostCard2TextTypeViewHolder) { int paddingPixel = (int) Utils.convertDpToPixel(12, mActivity); - ((PostBaseViewHolder) holder).itemView.setPadding(0, paddingPixel, 0, 0); + holder.itemView.setPadding(0, paddingPixel, 0, 0); } else { int marginPixel = (int) Utils.convertDpToPixel(8, mActivity); params.topMargin = marginPixel; params.bottomMargin = marginPixel; } holder.itemView.setLayoutParams(params); - ((PostBaseViewHolder) holder).itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + if (((PostBaseViewHolder) holder).itemViewIsNotCardView) { + holder.itemView.setBackgroundColor(mCardViewBackgroundColor); + } else { + holder.itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + } ((PostBaseViewHolder) holder).titleTextView.setTextColor(mPostTitleColor); if (holder instanceof PostVideoAutoplayViewHolder) { ((PostVideoAutoplayViewHolder) holder).mediaUri = null; @@ -1867,6 +1930,16 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ((PostTextTypeViewHolder) holder).contentTextView.setText(""); ((PostTextTypeViewHolder) holder).contentTextView.setTextColor(mPostContentColor); ((PostTextTypeViewHolder) holder).contentTextView.setVisibility(View.GONE); + } else if (holder instanceof PostCard2VideoAutoplayViewHolder) { + ((PostCard2VideoAutoplayViewHolder) holder).mediaUri = null; + if (((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks != null) { + ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks.cancel(); + } + ((PostCard2VideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.GONE); + ((PostCard2VideoAutoplayViewHolder) holder).muteButton.setVisibility(View.GONE); + ((PostCard2VideoAutoplayViewHolder) holder).resetVolume(); + mGlide.clear(((PostCard2VideoAutoplayViewHolder) holder).previewImageView); + ((PostCard2VideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.GONE); } else if (holder instanceof PostCard2WithPreviewViewHolder) { mGlide.clear(((PostCard2WithPreviewViewHolder) holder).imageView); ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); @@ -1964,14 +2037,14 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView if (super.getItemCount() <= 0 || order >= super.getItemCount()) { return null; } - return getItem(order); + return order; } @Nullable @Override public Integer getOrderForKey(@NonNull Object key) { - if (getCurrentList() != null && key instanceof Post) { - return getCurrentList().indexOf(key); + if (key instanceof Integer) { + return (Integer) key; } return null; @@ -2103,6 +2176,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView ImageView saveButton; ImageView shareButton; + boolean itemViewIsNotCardView = false; + PostBaseViewHolder(@NonNull View itemView) { super(itemView); } @@ -2171,7 +2246,11 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView constraintSet.applyTo(bottomConstraintLayout); } - itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + if (itemViewIsNotCardView) { + itemView.setBackgroundColor(mCardViewBackgroundColor); + } else { + itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + } subredditTextView.setTextColor(mSubredditColor); userTextView.setTextColor(mUsernameColor); postTimeTextView.setTextColor(mSecondaryTextColor); @@ -2587,11 +2666,44 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView }); } + void setBaseView(AspectRatioGifImageView iconGifImageView, + TextView subredditTextView, + TextView userTextView, + ImageView stickiedPostImageView, + TextView postTimeTextView, + TextView titleTextView, + CustomTextView typeTextView, + ImageView archivedImageView, + ImageView lockedImageView, + ImageView crosspostImageView, + CustomTextView nsfwTextView, + CustomTextView spoilerTextView, + CustomTextView flairTextView, + CustomTextView awardsTextView, + ConstraintLayout bottomConstraintLayout, + ImageView upvoteButton, + TextView scoreTextView, + ImageView downvoteButton, + TextView commentsCountTextView, + ImageView saveButton, + ImageView shareButton, boolean itemViewIsNotCardView) { + this.itemViewIsNotCardView = itemViewIsNotCardView; + + setBaseView(iconGifImageView, subredditTextView, userTextView, stickiedPostImageView, postTimeTextView, + titleTextView, typeTextView, archivedImageView, lockedImageView, crosspostImageView, + nsfwTextView, spoilerTextView, flairTextView, awardsTextView, bottomConstraintLayout, + upvoteButton, scoreTextView, downvoteButton, commentsCountTextView, saveButton, shareButton); + } + void markPostRead(Post post, boolean changePostItemColor) { if (mAccessToken != null && !post.isRead() && mMarkPostsAsRead) { post.markAsRead(true); if (changePostItemColor) { - itemView.setBackgroundTintList(ColorStateList.valueOf(mReadPostCardViewBackgroundColor)); + if (itemViewIsNotCardView) { + itemView.setBackgroundColor(mReadPostCardViewBackgroundColor); + } else { + itemView.setBackgroundTintList(ColorStateList.valueOf(mReadPostCardViewBackgroundColor)); + } titleTextView.setTextColor(mReadPostTitleColor); if (this instanceof PostTextTypeViewHolder) { ((PostTextTypeViewHolder) this).contentTextView.setTextColor(mReadPostContentColor); @@ -2697,13 +2809,15 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView muteButton.setOnClickListener(view -> { if (helper != null) { if (helper.getVolume() != 0) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); helper.setVolume(0f); volume = 0f; + mFragment.videoAutoplayChangeMutingOption(true); } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); helper.setVolume(1f); volume = 1f; + mFragment.videoAutoplayChangeMutingOption(false); } } }); @@ -2747,7 +2861,6 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView }); previewImageView.setOnLongClickListener(view -> fullscreenButton.performClick()); - videoPlayer.setOnLongClickListener(view -> fullscreenButton.performClick()); } void bindVideoUri(Uri videoUri) { @@ -2788,12 +2901,15 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView for (int i = 0; i < trackGroups.length; i++) { String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; if (mimeType != null && mimeType.contains("audio")) { + if (mFragment.getMasterMutingOption() != null) { + volume = mFragment.getMasterMutingOption() ? 0f : 1f; + } helper.setVolume(volume); muteButton.setVisibility(View.VISIBLE); if (volume != 0f) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); } break; } @@ -3149,6 +3265,10 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView constraintSet.applyTo(bottomConstraintLayout); } + if (((ViewGroup) itemView).getLayoutTransition() != null) { + ((ViewGroup) itemView).getLayoutTransition().setAnimateParentHierarchy(false); + } + itemView.setBackgroundColor(mCardViewBackgroundColor); postTimeTextView.setTextColor(mSecondaryTextColor); titleTextView.setTextColor(mPostTitleColor); @@ -3902,7 +4022,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView downvoteButton, commentsCountTextView, saveButton, - shareButton); + shareButton, + true); divider.setBackgroundColor(mDividerColor); @@ -3911,13 +4032,15 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView muteButton.setOnClickListener(view -> { if (helper != null) { if (helper.getVolume() != 0) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); helper.setVolume(0f); volume = 0f; + mFragment.videoAutoplayChangeMutingOption(true); } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); helper.setVolume(1f); volume = 1f; + mFragment.videoAutoplayChangeMutingOption(false); } } }); @@ -3961,7 +4084,6 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView }); previewImageView.setOnLongClickListener(view -> fullscreenButton.performClick()); - videoPlayer.setOnLongClickListener(view -> fullscreenButton.performClick()); } void bindVideoUri(Uri videoUri) { @@ -4002,12 +4124,15 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView for (int i = 0; i < trackGroups.length; i++) { String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; if (mimeType != null && mimeType.contains("audio")) { + if (mFragment.getMasterMutingOption() != null) { + volume = mFragment.getMasterMutingOption() ? 0f : 1f; + } helper.setVolume(volume); muteButton.setVisibility(View.VISIBLE); if (volume != 0f) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_unmute_white_rounded_24dp)); } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + muteButton.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_mute_white_rounded_24dp)); } break; } @@ -4157,7 +4282,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView downvoteButton, commentsCountTextView, saveButton, - shareButton); + shareButton, + true); linkTextView.setTextColor(mSecondaryTextColor); noPreviewImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); @@ -4256,7 +4382,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView downvoteButton, commentsCountTextView, saveButton, - shareButton); + shareButton, + true); contentTextView.setTextColor(mPostContentColor); divider.setBackgroundColor(mDividerColor); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RPANCommentStreamRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RPANCommentStreamRecyclerViewAdapter.java new file mode 100644 index 00000000..ba7dcd34 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RPANCommentStreamRecyclerViewAdapter.java @@ -0,0 +1,83 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import java.util.ArrayList; + +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RPANComment; + +public class RPANCommentStreamRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private RequestManager glide; + private ArrayList<RPANComment> rpanComments; + + public RPANCommentStreamRecyclerViewAdapter(Context context) { + glide = Glide.with(context); + rpanComments = new ArrayList<>(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new RPANCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate( + R.layout.item_rpan_comment, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof RPANCommentViewHolder) { + ((RPANCommentViewHolder) holder).authorTextView.setText(rpanComments.get(position).author); + ((RPANCommentViewHolder) holder).contentTextView.setText(rpanComments.get(position).content); + glide.load(rpanComments.get(position).authorIconImage) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((RPANCommentViewHolder) holder).iconImageView); + } + } + + @Override + public int getItemCount() { + return rpanComments == null ? 0 : rpanComments.size(); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof RPANCommentViewHolder) { + glide.clear(((RPANCommentViewHolder) holder).iconImageView); + } + } + + public void addRPANComment(RPANComment rpanComment) { + rpanComments.add(rpanComment); + notifyItemInserted(rpanComments.size() - 1); + } + + class RPANCommentViewHolder extends RecyclerView.ViewHolder { + ImageView iconImageView; + TextView authorTextView; + TextView timeTextView; + TextView contentTextView; + + public RPANCommentViewHolder(@NonNull View itemView) { + super(itemView); + iconImageView = itemView.findViewById(R.id.icon_image_view_item_rpan_comment); + authorTextView = itemView.findViewById(R.id.author_text_view_item_rpan_comment); + contentTextView = itemView.findViewById(R.id.content_text_view_item_rpan_comment); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RedditGallerySubmissionRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RedditGallerySubmissionRecyclerViewAdapter.java new file mode 100644 index 00000000..bec2d265 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RedditGallerySubmissionRecyclerViewAdapter.java @@ -0,0 +1,231 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.widget.ImageView; +import android.widget.ProgressBar; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.Target; +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditGalleryPayload; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView; + +public class RedditGallerySubmissionRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + + private static final int VIEW_TYPE_IMAGE = 1; + private static final int VIEW_TYPE_ADD_IMAGE = 2; + + private ArrayList<RedditGalleryImageInfo> redditGalleryImageInfoList; + private CustomThemeWrapper customThemeWrapper; + private ItemClickListener itemClickListener; + private RequestManager glide; + + public RedditGallerySubmissionRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper, + ItemClickListener itemClickListener) { + glide = Glide.with(context); + this.customThemeWrapper = customThemeWrapper; + this.itemClickListener = itemClickListener; + } + + @Override + public int getItemViewType(int position) { + if (redditGalleryImageInfoList == null || position >= redditGalleryImageInfoList.size()) { + return VIEW_TYPE_ADD_IMAGE; + } + + return VIEW_TYPE_IMAGE; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_ADD_IMAGE) { + return new AddImageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_reddit_gallery_submission_add_image, parent, false)); + } + return new ImageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_reddit_gallery_submission_image, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof ImageViewHolder) { + glide.load(redditGalleryImageInfoList.get(position).imageUrlString) + .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(48))) + .listener(new RequestListener<Drawable>() { + + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + ((ImageViewHolder) holder).progressBar.setVisibility(View.GONE); + ((ImageViewHolder) holder).closeImageView.setVisibility(View.VISIBLE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + return false; + } + }) + .into(((ImageViewHolder) holder).imageView); + + if (redditGalleryImageInfoList.get(position).payload != null) { + ((ImageViewHolder) holder).progressBar.setVisibility(View.GONE); + ((ImageViewHolder) holder).closeImageView.setVisibility(View.VISIBLE); + } + } + } + + @Override + public int getItemCount() { + return redditGalleryImageInfoList == null ? 1 : (redditGalleryImageInfoList.size() >= 20 ? 20 : redditGalleryImageInfoList.size() + 1); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof ImageViewHolder) { + glide.clear(((ImageViewHolder) holder).imageView); + ((ImageViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((ImageViewHolder) holder).closeImageView.setVisibility(View.GONE); + } + } + + public ArrayList<RedditGalleryImageInfo> getRedditGalleryImageInfoList() { + return redditGalleryImageInfoList; + } + + public void setRedditGalleryImageInfoList(ArrayList<RedditGalleryImageInfo> redditGalleryImageInfoList) { + this.redditGalleryImageInfoList = redditGalleryImageInfoList; + notifyDataSetChanged(); + } + + public void addImage(String imageUrl) { + if (redditGalleryImageInfoList == null) { + redditGalleryImageInfoList = new ArrayList<>(); + } + redditGalleryImageInfoList.add(new RedditGalleryImageInfo(imageUrl)); + notifyItemInserted(redditGalleryImageInfoList.size() - 1); + } + + public void setImageAsUploaded(String mediaId) { + redditGalleryImageInfoList.get(redditGalleryImageInfoList.size() - 1).payload = new RedditGalleryPayload.Item("", "", mediaId); + notifyItemChanged(redditGalleryImageInfoList.size() - 1); + } + + public void removeFailedToUploadImage() { + redditGalleryImageInfoList.remove(redditGalleryImageInfoList.size() - 1); + notifyItemRemoved(redditGalleryImageInfoList.size()); + } + + class ImageViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.aspect_ratio_gif_image_view_item_reddit_gallery_submission_image) + AspectRatioGifImageView imageView; + @BindView(R.id.progress_bar_item_reddit_gallery_submission_image) + ProgressBar progressBar; + @BindView(R.id.close_image_view_item_reddit_gallery_submission_image) + ImageView closeImageView; + + public ImageViewHolder(@NonNull View itemView) { + super(itemView); + + ButterKnife.bind(this, itemView); + + imageView.setRatio(1); + + closeImageView.setOnClickListener(view -> { + redditGalleryImageInfoList.remove(getBindingAdapterPosition()); + notifyItemRemoved(getBindingAdapterPosition()); + }); + } + } + + class AddImageViewHolder extends RecyclerView.ViewHolder { + + public AddImageViewHolder(@NonNull View itemView) { + super(itemView); + + FloatingActionButton fab = itemView.findViewById(R.id.fab_item_gallery_submission_add_image); + fab.setBackgroundTintList(ColorStateList.valueOf(customThemeWrapper.getColorPrimaryLightTheme())); + fab.setImageTintList(ColorStateList.valueOf(customThemeWrapper.getFABIconColor())); + + itemView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + itemView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + int width = itemView.getMeasuredWidth(); + ViewGroup.LayoutParams params = itemView.getLayoutParams(); + params.height = width; + itemView.setLayoutParams(params); + } + }); + + fab.setOnClickListener(view -> itemClickListener.onAddImageClicked()); + itemView.setOnClickListener(view -> fab.performClick()); + } + } + + public static class RedditGalleryImageInfo implements Parcelable { + public String imageUrlString; + public RedditGalleryPayload.Item payload; + + public RedditGalleryImageInfo(String imageUrlString) { + this.imageUrlString = imageUrlString; + } + + protected RedditGalleryImageInfo(Parcel in) { + imageUrlString = in.readString(); + payload = in.readParcelable(RedditGalleryPayload.Item.class.getClassLoader()); + } + + public static final Creator<RedditGalleryImageInfo> CREATOR = new Creator<RedditGalleryImageInfo>() { + @Override + public RedditGalleryImageInfo createFromParcel(Parcel in) { + return new RedditGalleryImageInfo(in); + } + + @Override + public RedditGalleryImageInfo[] newArray(int size) { + return new RedditGalleryImageInfo[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(imageUrlString); + parcel.writeParcelable(payload, i); + } + } + + public interface ItemClickListener { + void onAddImageClicked(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditAutocompleteRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditAutocompleteRecyclerViewAdapter.java new file mode 100644 index 00000000..c657f422 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditAutocompleteRecyclerViewAdapter.java @@ -0,0 +1,103 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.checkbox.MaterialCheckBox; + +import java.util.List; + +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import pl.droidsonroids.gif.GifImageView; + +public class SubredditAutocompleteRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private List<SubredditData> subreddits; + private RequestManager glide; + private CustomThemeWrapper customThemeWrapper; + private ItemOnClickListener itemOnClickListener; + + public SubredditAutocompleteRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper, + ItemOnClickListener itemOnClickListener) { + glide = Glide.with(context); + this.customThemeWrapper = customThemeWrapper; + this.itemOnClickListener = itemOnClickListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new SubredditViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_subreddit_listing, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof SubredditViewHolder) { + glide.load(subreddits.get(position).getIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((SubredditViewHolder) holder).iconImageView); + ((SubredditViewHolder) holder).subredditNameTextView.setText(subreddits.get(position).getName()); + } + } + + @Override + public int getItemCount() { + return subreddits == null ? 0 : subreddits.size(); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof SubredditViewHolder) { + glide.clear(((SubredditViewHolder) holder).iconImageView); + } + } + + public void setSubreddits(List<SubredditData> subreddits) { + this.subreddits = subreddits; + notifyDataSetChanged(); + } + + class SubredditViewHolder extends RecyclerView.ViewHolder { + + GifImageView iconImageView; + TextView subredditNameTextView; + ImageView subscribeImageView; + MaterialCheckBox checkBox; + + public SubredditViewHolder(@NonNull View itemView) { + super(itemView); + iconImageView = itemView.findViewById(R.id.subreddit_icon_gif_image_view_item_subreddit_listing); + subredditNameTextView = itemView.findViewById(R.id.subreddit_name_text_view_item_subreddit_listing); + subscribeImageView = itemView.findViewById(R.id.subscribe_image_view_item_subreddit_listing); + checkBox = itemView.findViewById(R.id.checkbox_item_subreddit_listing); + + subscribeImageView.setVisibility(View.GONE); + checkBox.setVisibility(View.GONE); + + subredditNameTextView.setTextColor(customThemeWrapper.getPrimaryTextColor()); + + itemView.setOnClickListener(view -> { + itemOnClickListener.onClick(subreddits.get(getBindingAdapterPosition())); + }); + } + } + + public interface ItemOnClickListener { + void onClick(SubredditData subredditData); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditListingRecyclerViewAdapter.java index f7891958..18268b54 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditListingRecyclerViewAdapter.java @@ -262,7 +262,7 @@ public class SubredditListingRecyclerViewAdapter extends PagedListAdapter<Subred TextView subredditNameTextView; @BindView(R.id.subscribe_image_view_item_subreddit_listing) ImageView subscribeButton; - @BindView(R.id.checkbox__item_subreddit_listing) + @BindView(R.id.checkbox_item_subreddit_listing) MaterialCheckBox checkBox; DataViewHolder(View itemView) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/TrendingSearchRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/TrendingSearchRecyclerViewAdapter.java new file mode 100644 index 00000000..8ab40aff --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/TrendingSearchRecyclerViewAdapter.java @@ -0,0 +1,228 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestBuilder; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.TrendingSearch; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView; +import ml.docilealligator.infinityforreddit.post.Post; + +public class TrendingSearchRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private ArrayList<TrendingSearch> trendingSearches; + private CustomThemeWrapper customThemeWrapper; + private RequestManager glide; + private int imageViewWidth; + private boolean dataSavingMode; + private boolean disableImagePreview; + private float mScale; + private ItemClickListener itemClickListener; + + public TrendingSearchRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper, + int imageViewWidth, boolean dataSavingMode, boolean disableImagePreview, + ItemClickListener itemClickListener) { + this.customThemeWrapper = customThemeWrapper; + this.glide = Glide.with(context); + this.imageViewWidth = imageViewWidth; + this.dataSavingMode = dataSavingMode; + this.disableImagePreview = disableImagePreview; + mScale = context.getResources().getDisplayMetrics().density; + this.itemClickListener = itemClickListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new TrendingSearchViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_trending_search, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof TrendingSearchViewHolder) { + TrendingSearch trendingSearch = trendingSearches.get(position); + if (dataSavingMode && disableImagePreview) { + ((TrendingSearchViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + } else { + Post.Preview preview = getSuitablePreview(trendingSearch.previews); + if (preview != null) { + ((TrendingSearchViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.VISIBLE); + if (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0) { + int height = (int) (400 * mScale); + ((TrendingSearchViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((TrendingSearchViewHolder) holder).imageView.getLayoutParams().height = height; + preview.setPreviewWidth(imageViewWidth); + preview.setPreviewHeight(height); + } else { + ((TrendingSearchViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + loadImage((TrendingSearchViewHolder) holder, preview); + } else { + ((TrendingSearchViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + } + } + + ((TrendingSearchViewHolder) holder).titleTextView.setText(trendingSearch.displayString); + } + } + + @Override + public int getItemCount() { + return trendingSearches == null ? 0 : trendingSearches.size(); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof TrendingSearchViewHolder) { + glide.clear(((TrendingSearchViewHolder) holder).imageView); + ((TrendingSearchViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.GONE); + ((TrendingSearchViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); + ((TrendingSearchViewHolder) holder).noPreviewLinkImageView.setVisibility(View.GONE); + ((TrendingSearchViewHolder) holder).progressBar.setVisibility(View.GONE); + } + } + + @Nullable + private Post.Preview getSuitablePreview(ArrayList<Post.Preview> previews) { + Post.Preview preview; + if (!previews.isEmpty()) { + int previewIndex; + if (dataSavingMode && previews.size() > 2) { + previewIndex = previews.size() / 2; + } else { + previewIndex = 0; + } + preview = previews.get(previewIndex); + if (preview.getPreviewWidth() * preview.getPreviewHeight() > 10_000_000) { + for (int i = previews.size() - 1; i >= 1; i--) { + preview = previews.get(i); + if (imageViewWidth >= preview.getPreviewWidth()) { + if (preview.getPreviewWidth() * preview.getPreviewHeight() <= 10_000_000) { + return preview; + } + } else { + int height = imageViewWidth / preview.getPreviewWidth() * preview.getPreviewHeight(); + if (imageViewWidth * height <= 10_000_000) { + return preview; + } + } + } + } + + if (preview.getPreviewWidth() * preview.getPreviewHeight() > 10_000_000) { + int divisor = 2; + do { + preview.setPreviewWidth(preview.getPreviewWidth() / divisor); + preview.setPreviewHeight(preview.getPreviewHeight() / divisor); + divisor *= 2; + } while (preview.getPreviewWidth() * preview.getPreviewHeight() > 10_000_000); + } + return preview; + } + + return null; + } + + private void loadImage(final TrendingSearchViewHolder holder, @NonNull Post.Preview preview) { + String url = preview.getPreviewUrl(); + RequestBuilder<Drawable> imageRequestBuilder = glide.load(url).listener(new RequestListener<Drawable>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + holder.progressBar.setVisibility(View.GONE); + holder.errorRelativeLayout.setVisibility(View.VISIBLE); + holder.errorRelativeLayout.setOnClickListener(view -> { + holder.progressBar.setVisibility(View.VISIBLE); + holder.errorRelativeLayout.setVisibility(View.GONE); + loadImage(holder, preview); + }); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + holder.errorRelativeLayout.setVisibility(View.GONE); + holder.progressBar.setVisibility(View.GONE); + return false; + } + }); + + if (imageViewWidth > preview.getPreviewWidth()) { + imageRequestBuilder.override(preview.getPreviewWidth(), preview.getPreviewHeight()).into(holder.imageView); + } else { + imageRequestBuilder.into(holder.imageView); + } + } + + public void setTrendingSearches(ArrayList<TrendingSearch> trendingSearches) { + if (trendingSearches != null) { + this.trendingSearches = trendingSearches; + notifyItemRangeInserted(0, trendingSearches.size()); + } else { + int size = this.trendingSearches == null ? 0 : this.trendingSearches.size(); + this.trendingSearches = null; + notifyItemRangeRemoved(0, size); + } + } + + class TrendingSearchViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.image_wrapper_relative_layout_item_trending_search) + RelativeLayout imageWrapperRelativeLayout; + @BindView(R.id.progress_bar_item_trending_search) + ProgressBar progressBar; + @BindView(R.id.image_view_item_trending_search) + AspectRatioGifImageView imageView; + @BindView(R.id.load_image_error_relative_layout_item_trending_search) + RelativeLayout errorRelativeLayout; + @BindView(R.id.load_image_error_text_view_item_trending_search) + TextView errorTextView; + @BindView(R.id.image_view_no_preview_gallery_item_trending_search) + ImageView noPreviewLinkImageView; + @BindView(R.id.title_text_view_item_trending_search) + TextView titleTextView; + + public TrendingSearchViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + noPreviewLinkImageView.setBackgroundColor(customThemeWrapper.getNoPreviewPostTypeBackgroundColor()); + noPreviewLinkImageView.setColorFilter(customThemeWrapper.getNoPreviewPostTypeIconTint(), android.graphics.PorterDuff.Mode.SRC_IN); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(customThemeWrapper.getColorAccent())); + errorTextView.setTextColor(customThemeWrapper.getPrimaryTextColor()); + + itemView.setOnClickListener(view -> { + itemClickListener.onClick(trendingSearches.get(getBindingAdapterPosition())); + }); + } + } + + public interface ItemClickListener { + void onClick(TrendingSearch trendingSearch); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UploadedImagesRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UploadedImagesRecyclerViewAdapter.java new file mode 100644 index 00000000..eebd6482 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UploadedImagesRecyclerViewAdapter.java @@ -0,0 +1,61 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.UploadedImage; + +public class UploadedImagesRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private ArrayList<UploadedImage> uploadedImages; + private ItemClickListener itemClickListener; + + public UploadedImagesRecyclerViewAdapter(ArrayList<UploadedImage> uploadedImages, ItemClickListener itemClickListener) { + this.uploadedImages = uploadedImages; + this.itemClickListener = itemClickListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new UploadedImageViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_uploaded_image, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + ((UploadedImageViewHolder) holder).imageNameTextView.setText(uploadedImages.get(position).imageName); + ((UploadedImageViewHolder) holder).imageUrlTextView.setText(uploadedImages.get(position).imageUrl); + } + + @Override + public int getItemCount() { + return uploadedImages == null ? 0 : uploadedImages.size(); + } + + private class UploadedImageViewHolder extends RecyclerView.ViewHolder { + TextView imageNameTextView; + TextView imageUrlTextView; + + public UploadedImageViewHolder(@NonNull View itemView) { + super(itemView); + imageNameTextView = itemView.findViewById(R.id.image_name_item_uploaded_image); + imageUrlTextView = itemView.findViewById(R.id.image_url_item_uploaded_image); + + itemView.setOnClickListener(view -> { + itemClickListener.onClick(uploadedImages.get(getBindingAdapterPosition())); + }); + } + } + + public interface ItemClickListener { + void onClick(UploadedImage uploadedImage); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java index 5e43ca3d..44a65ebb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java @@ -5,6 +5,7 @@ import java.util.Map; import okhttp3.MultipartBody; import okhttp3.RequestBody; import retrofit2.Call; +import retrofit2.http.Body; import retrofit2.http.DELETE; import retrofit2.http.FieldMap; import retrofit2.http.FormUrlEncoded; @@ -137,21 +138,23 @@ public interface RedditAPI { @GET("search.json?include_over_18=1&raw_json=1&type=link") Call<String> searchPostsOauth(@Query("q") String query, @Query("after") String after, - @Query("sort") String sort, + @Query("sort") String sort, @Query("source") String source, @HeaderMap Map<String, String> headers); @GET("search.json?include_over_18=1&raw_json=1&type=link") Call<String> searchPostsOauth(@Query("q") String query, @Query("after") String after, @Query("sort") String sort, @Query("t") String sortTime, + @Query("source") String source, @HeaderMap Map<String, String> headers); @GET("search.json?include_over_18=1&raw_json=1&type=link") Call<String> searchPosts(@Query("q") String query, @Query("after") String after, - @Query("sort") String sort); + @Query("sort") String sort, @Query("source") String source); @GET("search.json?include_over_18=1&raw_json=1&type=link") Call<String> searchPosts(@Query("q") String query, @Query("after") String after, - @Query("sort") String sort, @Query("t") String sortTime); + @Query("sort") String sort, @Query("t") String sortTime, + @Query("source") String source); @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") Call<String> searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName, @@ -345,11 +348,24 @@ public interface RedditAPI { @FormUrlEncoded - @PUT("/api/multi{multipath}r/{subredditName}") + @PUT("/api/multi{multipath}/r/{subredditName}") Call<String> addSubredditToMultiReddit(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params, @Path(value = "multipath", encoded = true) String multipath, @Path("subredditName") String subredditName); @FormUrlEncoded - @POST("/api/quarantine_optin?raw_json=1") + @POST("/api/quarantine_option?raw_json=1") Call<String> optInQuarantinedSubreddit(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params); + + @GET("/api/subreddit_autocomplete_v2?typeahead_active=true&include_profiles=false&raw_json=1") + Call<String> subredditAutocomplete(@HeaderMap Map<String ,String> headers, @Query("query") String query, + @Query("include_over_18") boolean nsfw); + + @POST("/api/submit_gallery_post.json?resubmit=true&raw_json=1") + Call<String> submitGalleryPost(@HeaderMap Map<String, String> headers, @Body String body); + + @GET("/api/trending_searches_v1.json?withAds=0&raw_json=1&gilding_detail=1") + Call<String> getTrendingSearches(@HeaderMap Map<String, String> headers); + + @GET("/r/{subredditName}/wiki/index.json?raw_json=1") + Call<String> getWiki(@Path("subredditName") String subredditName); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/Strapi.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/Strapi.java new file mode 100644 index 00000000..e68b8850 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/Strapi.java @@ -0,0 +1,13 @@ +package ml.docilealligator.infinityforreddit.apis; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Path; + +public interface Strapi { + @GET("/broadcasts") + Call<String> getAllBroadcasts(); + + @GET("/videos/{rpan_id_or_fullname}") + Call<String> getRPANBroadcast(@Path("rpan_id_or_fullname") String rpanIdOrFullname); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsSubscribedToSubreddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsSubscribedToSubreddit.java index f6768d11..572baf17 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsSubscribedToSubreddit.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsSubscribedToSubreddit.java @@ -5,6 +5,7 @@ import android.os.Handler; import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; public class CheckIsSubscribedToSubreddit { @@ -13,8 +14,10 @@ public class CheckIsSubscribedToSubreddit { String subredditName, String accountName, CheckIsSubscribedToSubredditListener checkIsSubscribedToSubredditListener) { executor.execute(() -> { - if (!redditDataRoomDatabase.accountDao().isAnonymousAccountInserted()) { - redditDataRoomDatabase.accountDao().insertAnonymousAccount(); + if (accountName == null) { + if (!redditDataRoomDatabase.accountDao().isAnonymousAccountInserted()) { + redditDataRoomDatabase.accountDao().insert(Account.getAnonymousAccount()); + } } SubscribedSubredditData subscribedSubredditData = redditDataRoomDatabase.subscribedSubredditDao().getSubscribedSubreddit(subredditName, accountName == null ? "-" : accountName); handler.post(() -> { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java index d29a1510..7b6452ec 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java @@ -39,6 +39,7 @@ public class CopyTextBottomSheetFragment extends RoundedBottomSheetDialogFragmen TextView copyAllMarkdownTextView; private Activity activity; + private String markdownText; public CopyTextBottomSheetFragment() { // Required empty public constructor @@ -52,20 +53,26 @@ public class CopyTextBottomSheetFragment extends RoundedBottomSheetDialogFragmen View rootView = inflater.inflate(R.layout.fragment_copy_text_bottom_sheet, container, false); ButterKnife.bind(this, rootView); - String rawText = getArguments().getString(EXTRA_RAW_TEXT); - String markdownText = getArguments().getString(EXTRA_MARKDOWN).replaceAll("<sup>", "^").replaceAll("</sup>", ""); + String rawText = getArguments().getString(EXTRA_RAW_TEXT, null); + markdownText = getArguments().getString(EXTRA_MARKDOWN, null); - copyRawTextTextView.setOnClickListener(view -> { - showCopyDialog(rawText); - dismiss(); - }); + if (rawText != null) { + copyRawTextTextView.setOnClickListener(view -> { + showCopyDialog(rawText); + dismiss(); + }); - copyAllRawTextTextView.setOnClickListener(view -> { - copyText(rawText); - dismiss(); - }); + copyAllRawTextTextView.setOnClickListener(view -> { + copyText(rawText); + dismiss(); + }); + } else { + copyRawTextTextView.setVisibility(View.GONE); + copyAllRawTextTextView.setVisibility(View.GONE); + } if (markdownText != null) { + markdownText = markdownText.replaceAll("<sup>", "^").replaceAll("</sup>", ""); copyMarkdownTextView.setOnClickListener(view -> { showCopyDialog(markdownText); dismiss(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FlairBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FlairBottomSheetFragment.java index d8b39b7e..b7b651a6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FlairBottomSheetFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FlairBottomSheetFragment.java @@ -12,7 +12,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; @@ -87,7 +86,6 @@ public class FlairBottomSheetFragment extends BottomSheetDialogFragment { dismiss(); }); - recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(mAdapter); mAccessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java index 64b604ab..046c512b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java @@ -30,6 +30,7 @@ public class PostTypeBottomSheetFragment extends RoundedBottomSheetDialogFragmen public static final int TYPE_LINK = 1; public static final int TYPE_IMAGE = 2; public static final int TYPE_VIDEO = 3; + public static final int TYPE_GALLERY = 4; @BindView(R.id.text_type_linear_layout_post_type_bottom_sheet_fragment) TextView textTypeTextView; @BindView(R.id.link_type_linear_layout_post_type_bottom_sheet_fragment) @@ -38,6 +39,8 @@ public class PostTypeBottomSheetFragment extends RoundedBottomSheetDialogFragmen TextView imageTypeTextView; @BindView(R.id.video_type_linear_layout_post_type_bottom_sheet_fragment) TextView videoTypeTextView; + @BindView(R.id.gallery_type_linear_layout_post_type_bottom_sheet_fragment) + TextView galleryTypeTextView; private Activity activity; public PostTypeBottomSheetFragment() { @@ -75,6 +78,11 @@ public class PostTypeBottomSheetFragment extends RoundedBottomSheetDialogFragmen dismiss(); }); + galleryTypeTextView.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_GALLERY); + dismiss(); + }); + return rootView; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SelectOrCaptureImageBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SelectOrCaptureImageBottomSheetFragment.java new file mode 100644 index 00000000..4be9b51f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SelectOrCaptureImageBottomSheetFragment.java @@ -0,0 +1,52 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.activities.PostGalleryActivity; + +public class SelectOrCaptureImageBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + private PostGalleryActivity mActivity; + + public SelectOrCaptureImageBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_select_or_capture_image_bottom_sheet, container, false); + + TextView selectImageTextView = rootView.findViewById(R.id.select_image_text_view_select_or_capture_image_bottom_sheet_fragment); + TextView captureImageTextView = rootView.findViewById(R.id.capture_image_text_view_select_or_capture_image_bottom_sheet_fragment); + + selectImageTextView.setOnClickListener(view -> { + mActivity.selectImage(); + dismiss(); + }); + + captureImageTextView.setOnClickListener(view -> { + mActivity.captureImage(); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (PostGalleryActivity) context; + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UploadedImagesBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UploadedImagesBottomSheetFragment.java new file mode 100644 index 00000000..cc100c79 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UploadedImagesBottomSheetFragment.java @@ -0,0 +1,67 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; +import com.google.android.material.button.MaterialButton; + +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.UploadImageEnabledActivity; +import ml.docilealligator.infinityforreddit.adapters.UploadedImagesRecyclerViewAdapter; + +public class UploadedImagesBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_UPLOADED_IMAGES = "EUI"; + + private MaterialButton uploadButton; + private MaterialButton captureButton; + private RecyclerView uploadedImagesRecyclerView; + private UploadedImagesRecyclerViewAdapter adapter; + private UploadImageEnabledActivity activity; + + public UploadedImagesBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_uploaded_images_bottom_sheet, container, false); + uploadButton = rootView.findViewById(R.id.upload_button_uploaded_images_bottom_sheet_fragment); + captureButton = rootView.findViewById(R.id.capture_button_uploaded_images_bottom_sheet_fragment); + + uploadButton.setOnClickListener(view -> { + activity.uploadImage(); + dismiss(); + }); + + captureButton.setOnClickListener(view -> { + activity.captureImage(); + dismiss(); + }); + + uploadedImagesRecyclerView = rootView.findViewById(R.id.recycler_view_uploaded_images_bottom_sheet); + adapter = new UploadedImagesRecyclerViewAdapter( + getArguments().getParcelableArrayList(EXTRA_UPLOADED_IMAGES), uploadedImage -> { + activity.insertImageUrl(uploadedImage); + dismiss(); + }); + uploadedImagesRecyclerView.setAdapter(adapter); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (UploadImageEnabledActivity) context; + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java b/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java new file mode 100644 index 00000000..5a596308 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java @@ -0,0 +1,18 @@ +package ml.docilealligator.infinityforreddit.broadcastreceivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import androidx.core.content.ContextCompat; + +import ml.docilealligator.infinityforreddit.services.MaterialYouService; + +public class WallpaperChangeReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + Intent materialYouIntent = new Intent(context, MaterialYouService.class); + ContextCompat.startForegroundService(context, materialYouIntent); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java index fcbd58c1..7cb0b695 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java @@ -97,6 +97,7 @@ public class Comment implements Parcelable { if (placeholderType == PLACEHOLDER_LOAD_MORE_COMMENTS) { this.fullName = parentFullName; } else { + this.fullName = parentFullName; this.parentId = parentFullName.substring(3); } this.depth = depth; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java index 14849870..6162865b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java @@ -1,10 +1,13 @@ package ml.docilealligator.infinityforreddit.comment; +import android.os.Handler; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.ArrayList; import java.util.Locale; +import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.utils.APIUtils; @@ -14,7 +17,8 @@ import retrofit2.Response; import retrofit2.Retrofit; public class FetchComment { - public static void fetchComments(Retrofit retrofit, @Nullable String accessToken, String article, + public static void fetchComments(Executor executor, Handler handler, Retrofit retrofit, + @Nullable String accessToken, String article, String commentId, String sortType, String contextNumber, boolean expandChildren, Locale locale, FetchCommentListener fetchCommentListener) { RedditAPI api = retrofit.create(RedditAPI.class); @@ -38,8 +42,8 @@ public class FetchComment { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { if (response.isSuccessful()) { - ParseComment.parseComment(response.body(), new ArrayList<>(), - locale, expandChildren, new ParseComment.ParseCommentListener() { + ParseComment.parseComment(executor, handler, response.body(), new ArrayList<>(), + expandChildren, new ParseComment.ParseCommentListener() { @Override public void onParseCommentSuccess(ArrayList<Comment> expandedComments, String parentId, ArrayList<String> moreChildrenFullnames) { @@ -64,9 +68,10 @@ public class FetchComment { }); } - public static void fetchMoreComment(Retrofit retrofit, @Nullable String accessToken, + public static void fetchMoreComment(Executor executor, Handler handler, Retrofit retrofit, + @Nullable String accessToken, ArrayList<String> allChildren, int startingIndex, - int depth, boolean expandChildren, Locale locale, + int depth, boolean expandChildren, FetchMoreCommentListener fetchMoreCommentListener) { if (allChildren == null) { return; @@ -98,7 +103,7 @@ public class FetchComment { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { if (response.isSuccessful()) { - ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, + ParseComment.parseMoreComment(executor, handler, response.body(), new ArrayList<>(), depth, expandChildren, new ParseComment.ParseCommentListener() { @Override public void onParseCommentSuccess(ArrayList<Comment> expandedComments, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java index ace36940..62283989 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java @@ -1,6 +1,6 @@ package ml.docilealligator.infinityforreddit.comment; -import android.os.AsyncTask; +import android.os.Handler; import android.text.Html; import androidx.annotation.Nullable; @@ -10,7 +10,7 @@ import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; -import java.util.Locale; +import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -20,39 +20,83 @@ import static ml.docilealligator.infinityforreddit.comment.Comment.VOTE_TYPE_NO_ import static ml.docilealligator.infinityforreddit.comment.Comment.VOTE_TYPE_UPVOTE; public class ParseComment { - public static void parseComment(String response, ArrayList<Comment> commentData, Locale locale, - boolean expandChildren, ParseCommentListener parseCommentListener) { - try { - JSONArray childrenArray = new JSONArray(response); - String parentId = childrenArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY) - .getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY); - childrenArray = childrenArray.getJSONObject(1).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + public static void parseComment(Executor executor, Handler handler, String response, + ArrayList<Comment> commentData, boolean expandChildren, + ParseCommentListener parseCommentListener) { + executor.execute(() -> { + try { + JSONArray childrenArray = new JSONArray(response); + String parentId = childrenArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY) + .getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY); + childrenArray = childrenArray.getJSONObject(1).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - new ParseCommentAsyncTask(childrenArray, commentData, locale, parentId, 0, expandChildren, parseCommentListener).execute(); - } catch (JSONException e) { - e.printStackTrace(); - parseCommentListener.onParseCommentFailed(); - } + ArrayList<Comment> expandedNewComments = new ArrayList<>(); + ArrayList<String> moreChildrenFullnames = new ArrayList<>(); + ArrayList<Comment> newComments = new ArrayList<>(); + + parseCommentRecursion(childrenArray, newComments, moreChildrenFullnames, 0); + expandChildren(newComments, expandedNewComments, expandChildren); + + if (expandChildren) { + commentData.addAll(expandedNewComments); + } else { + commentData.addAll(newComments); + } + + handler.post(() -> parseCommentListener.onParseCommentSuccess(commentData, parentId, moreChildrenFullnames)); + } catch (JSONException e) { + e.printStackTrace(); + handler.post(parseCommentListener::onParseCommentFailed); + } + }); } - static void parseMoreComment(String response, ArrayList<Comment> commentData, Locale locale, - int depth, boolean expandChildren, ParseCommentListener parseCommentListener) { - try { - JSONArray childrenArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - new ParseCommentAsyncTask(childrenArray, commentData, locale, null, depth, expandChildren, parseCommentListener).execute(); - } catch (JSONException e) { - e.printStackTrace(); - parseCommentListener.onParseCommentFailed(); - } + static void parseMoreComment(Executor executor, Handler handler, String response, + ArrayList<Comment> commentData, int depth, boolean expandChildren, + ParseCommentListener parseCommentListener) { + executor.execute(() -> { + try { + JSONArray childrenArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + + ArrayList<Comment> newComments = new ArrayList<>(); + ArrayList<Comment> expandedNewComments = new ArrayList<>(); + ArrayList<String> moreChildrenFullnames = new ArrayList<>(); + + parseCommentRecursion(childrenArray, newComments, moreChildrenFullnames, depth); + expandChildren(newComments, expandedNewComments, expandChildren); + + if (expandChildren) { + commentData.addAll(expandedNewComments); + } else { + commentData.addAll(newComments); + } + + handler.post(() -> parseCommentListener.onParseCommentSuccess(commentData, null, moreChildrenFullnames)); + } catch (JSONException e) { + e.printStackTrace(); + handler.post(parseCommentListener::onParseCommentFailed); + } + }); } - static void parseSentComment(String response, int depth, Locale locale, + static void parseSentComment(Executor executor, Handler handler, String response, int depth, ParseSentCommentListener parseSentCommentListener) { - new ParseSentCommentAsyncTask(response, depth, locale, parseSentCommentListener).execute(); + executor.execute(() -> { + try { + JSONObject sentCommentData = new JSONObject(response); + Comment comment = parseSingleComment(sentCommentData, depth); + + handler.post(() -> parseSentCommentListener.onParseSentCommentSuccess(comment)); + } catch (JSONException e) { + e.printStackTrace(); + String errorMessage = parseSentCommentErrorMessage(response); + handler.post(() -> parseSentCommentListener.onParseSentCommentFailed(errorMessage)); + } + }); } private static void parseCommentRecursion(JSONArray comments, ArrayList<Comment> newCommentData, - ArrayList<String> moreChildrenFullnames, int depth, Locale locale) throws JSONException { + ArrayList<String> moreChildrenFullnames, int depth) throws JSONException { int actualCommentLength; if (comments.length() == 0) { @@ -88,8 +132,7 @@ public class ParseComment { .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); ArrayList<Comment> children = new ArrayList<>(); ArrayList<String> nextMoreChildrenFullnames = new ArrayList<>(); - parseCommentRecursion(childrenArray, children, nextMoreChildrenFullnames, singleComment.getDepth(), - locale); + parseCommentRecursion(childrenArray, children, nextMoreChildrenFullnames, singleComment.getDepth()); singleComment.addChildren(children); singleComment.setMoreChildrenFullnames(nextMoreChildrenFullnames); } @@ -230,101 +273,4 @@ public class ParseComment { void onParseSentCommentFailed(@Nullable String errorMessage); } - - private static class ParseCommentAsyncTask extends AsyncTask<Void, Void, Void> { - private JSONArray commentsJSONArray; - private ArrayList<Comment> comments; - private ArrayList<Comment> newComments; - private ArrayList<Comment> expandedNewComments; - private ArrayList<String> moreChildrenFullnames; - private Locale locale; - private String parentId; - private int depth; - private boolean expandChildren; - private ParseCommentListener parseCommentListener; - private boolean parseFailed; - - ParseCommentAsyncTask(JSONArray commentsJSONArray, ArrayList<Comment> comments, Locale locale, - @Nullable String parentId, int depth, boolean expandChildren, - ParseCommentListener parseCommentListener) { - this.commentsJSONArray = commentsJSONArray; - this.comments = comments; - newComments = new ArrayList<>(); - expandedNewComments = new ArrayList<>(); - moreChildrenFullnames = new ArrayList<>(); - this.locale = locale; - this.parentId = parentId; - this.depth = depth; - this.expandChildren = expandChildren; - parseFailed = false; - this.parseCommentListener = parseCommentListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - parseCommentRecursion(commentsJSONArray, newComments, moreChildrenFullnames, depth, locale); - expandChildren(newComments, expandedNewComments, expandChildren); - } catch (JSONException e) { - parseFailed = true; - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - if (expandChildren) { - comments.addAll(expandedNewComments); - } else { - comments.addAll(newComments); - } - parseCommentListener.onParseCommentSuccess(comments, parentId, moreChildrenFullnames); - } else { - parseCommentListener.onParseCommentFailed(); - } - } - } - - private static class ParseSentCommentAsyncTask extends AsyncTask<Void, Void, Void> { - private String response; - private int depth; - private Locale locale; - private ParseSentCommentListener parseSentCommentListener; - private boolean parseFailed; - private String errorMessage; - private Comment comment; - - ParseSentCommentAsyncTask(String response, int depth, Locale locale, ParseSentCommentListener parseSentCommentListener) { - this.response = response; - this.depth = depth; - this.locale = locale; - this.parseSentCommentListener = parseSentCommentListener; - parseFailed = false; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject sentCommentData = new JSONObject(response); - comment = parseSingleComment(sentCommentData, depth); - } catch (JSONException e) { - e.printStackTrace(); - errorMessage = parseSentCommentErrorMessage(response); - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - parseSentCommentListener.onParseSentCommentFailed(errorMessage); - } else { - parseSentCommentListener.onParseSentCommentSuccess(comment); - } - } - } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java index 114cc30e..cf9efa54 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java @@ -1,11 +1,13 @@ package ml.docilealligator.infinityforreddit.comment; +import android.os.Handler; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.HashMap; -import java.util.Locale; import java.util.Map; +import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.utils.APIUtils; @@ -15,9 +17,9 @@ import retrofit2.Response; import retrofit2.Retrofit; public class SendComment { - - public static void sendComment(String commentMarkdown, String thingFullname, int parentDepth, - Locale locale, Retrofit oauthRetrofit, String accessToken, + public static void sendComment(Executor executor, Handler handler, String commentMarkdown, + String thingFullname, int parentDepth, + Retrofit oauthRetrofit, String accessToken, SendCommentListener sendCommentListener) { Map<String, String> headers = APIUtils.getOAuthHeader(accessToken); Map<String, String> params = new HashMap<>(); @@ -30,7 +32,7 @@ public class SendComment { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { if (response.isSuccessful()) { - ParseComment.parseSentComment(response.body(), parentDepth, locale, new ParseComment.ParseSentCommentListener() { + ParseComment.parseSentComment(executor, handler, response.body(), parentDepth, new ParseComment.ParseSentCommentListener() { @Override public void onParseSentCommentSuccess(Comment comment) { sendCommentListener.sendCommentSuccess(comment); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeWrapper.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeWrapper.java index f5e9c6bd..a5753d53 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeWrapper.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeWrapper.java @@ -54,22 +54,22 @@ public class CustomThemeWrapper { public int getColorPrimary() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY, - getDefaultColor("#1565C0", "#242424", "#000000")); + getDefaultColor("#0336FF", "#242424", "#000000")); } public int getColorPrimaryDark() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_DARK, - getDefaultColor("#0D47A1", "#121212", "#000000")); + getDefaultColor("#002BF0", "#121212", "#000000")); } public int getColorAccent() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + getDefaultColor("#FF1868", "#FF1868", "#FF1868")); } public int getColorPrimaryLightTheme() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, - getDefaultColor("#1565C0", "#1565C0", "#1565C0")); + getDefaultColor("#0336FF", "#0336FF", "#0336FF")); } public int getPrimaryTextColor() { @@ -179,17 +179,17 @@ public class CustomThemeWrapper { public int getTabLayoutWithExpandedCollapsingToolbarTextColor() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR, - getDefaultColor("#1565C0", "#FFFFFF", "#FFFFFF")); + getDefaultColor("#0336FF", "#FFFFFF", "#FFFFFF")); } public int getTabLayoutWithExpandedCollapsingToolbarTabIndicator() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR, - getDefaultColor("#1565C0", "#FFFFFF", "#FFFFFF")); + getDefaultColor("#0336FF", "#FFFFFF", "#FFFFFF")); } public int getTabLayoutWithCollapsedCollapsingToolbarTabBackground() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, - getDefaultColor("#1565C0", "#242424", "#000000")); + getDefaultColor("#0336FF", "#242424", "#000000")); } public int getTabLayoutWithCollapsedCollapsingToolbarTextColor() { @@ -204,7 +204,7 @@ public class CustomThemeWrapper { public int getUpvoted() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.UPVOTED, - getDefaultColor("#E91E63", "#E91E63", "#E91E63")); + getDefaultColor("#FF1868", "#FF1868", "#FF1868")); } public int getDownvoted() { @@ -214,7 +214,7 @@ public class CustomThemeWrapper { public int getPostTypeBackgroundColor() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_TYPE_BACKGROUND_COLOR, - getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); + getDefaultColor("#002BF0", "#0336FF", "#0336FF")); } public int getPostTypeTextColor() { @@ -234,7 +234,7 @@ public class CustomThemeWrapper { public int getNsfwBackgroundColor() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NSFW_BACKGROUND_COLOR, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + getDefaultColor("#FF1868", "#FF1868", "#FF1868")); } public int getNsfwTextColor() { @@ -274,7 +274,7 @@ public class CustomThemeWrapper { public int getCrosspostIconTint() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CROSSPOST_ICON_TINT, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + getDefaultColor("#FF1868", "#FF1868", "#FF1868")); } public int getUpvoteRatioIconTint() { @@ -284,7 +284,7 @@ public class CustomThemeWrapper { public int getStickiedPostIconTint() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.STICKIED_POST_ICON_TINT, - getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); + getDefaultColor("#002BF0", "#0336FF", "#0336FF")); } public int getNoPreviewPostTypeIconTint() { @@ -294,22 +294,22 @@ public class CustomThemeWrapper { public int getSubscribed() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SUBSCRIBED, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + getDefaultColor("#FF1868", "#FF1868", "#FF1868")); } public int getUnsubscribed() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.UNSUBSCRIBED, - getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); + getDefaultColor("#002BF0", "#0336FF", "#0336FF")); } public int getUsername() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.USERNAME, - getDefaultColor("#0D47A1", "#1E88E5", "#1E88E5")); + getDefaultColor("#002BF0", "#1E88E5", "#1E88E5")); } public int getSubreddit() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SUBREDDIT, - getDefaultColor("#E91E63", "#E91E63", "#E91E63")); + getDefaultColor("#FF1868", "#FF1868", "#FF1868")); } public int getAuthorFlairTextColor() { @@ -359,7 +359,7 @@ public class CustomThemeWrapper { public Integer getCommentVerticalBarColor1() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_1, - getDefaultColor("#1565C0", "#1565C0", "#1565C0")); + getDefaultColor("#0336FF", "#0336FF", "#0336FF")); } public Integer getCommentVerticalBarColor2() { @@ -404,7 +404,7 @@ public class CustomThemeWrapper { public int getLinkColor() { return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.LINK_COLOR, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + getDefaultColor("#FF1868", "#FF1868", "#FF1868")); } public int getReceivedMessageTextColor() { @@ -509,10 +509,10 @@ public class CustomThemeWrapper { customTheme.isLightTheme = true; customTheme.isDarkTheme = false; customTheme.isAmoledTheme = false; - customTheme.colorPrimary = Color.parseColor("#1565C0"); - customTheme.colorPrimaryDark = Color.parseColor("#0D47A1"); - customTheme.colorAccent = Color.parseColor("#FF4081"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); + customTheme.colorPrimary = Color.parseColor("#0336FF"); + customTheme.colorPrimaryDark = Color.parseColor("#002BF0"); + customTheme.colorAccent = Color.parseColor("#FF1868"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#0336FF"); customTheme.primaryTextColor = Color.parseColor("#000000"); customTheme.secondaryTextColor = Color.parseColor("#8A000000"); customTheme.postTitleColor = Color.parseColor("#000000"); @@ -534,18 +534,18 @@ public class CustomThemeWrapper { customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); customTheme.circularProgressBarBackground = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#1565C0"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#1565C0"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#1565C0"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#0336FF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#0336FF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#0336FF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); + customTheme.postTypeBackgroundColor = Color.parseColor("#002BF0"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -553,14 +553,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.stickiedPostIconTint = Color.parseColor("#002BF0"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#0D47A1"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#002BF0"); + customTheme.username = Color.parseColor("#002BF0"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -570,7 +570,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#E0E0E0"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); @@ -579,7 +579,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -602,8 +602,8 @@ public class CustomThemeWrapper { customTheme.isAmoledTheme = false; customTheme.colorPrimary = Color.parseColor("#242424"); customTheme.colorPrimaryDark = Color.parseColor("#121212"); - customTheme.colorAccent = Color.parseColor("#FF4081"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); + customTheme.colorAccent = Color.parseColor("#FF1868"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#0336FF"); customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); customTheme.postTitleColor = Color.parseColor("#FFFFFF"); @@ -630,13 +630,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0336FF"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -644,14 +644,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.stickiedPostIconTint = Color.parseColor("#0336FF"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#0336FF"); customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -661,7 +661,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#69666C"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); @@ -670,7 +670,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -693,8 +693,8 @@ public class CustomThemeWrapper { customTheme.isAmoledTheme = true; customTheme.colorPrimary = Color.parseColor("#000000"); customTheme.colorPrimaryDark = Color.parseColor("#000000"); - customTheme.colorAccent = Color.parseColor("#FF4081"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); + customTheme.colorAccent = Color.parseColor("#FF1868"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#0336FF"); customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); customTheme.postTitleColor = Color.parseColor("#FFFFFF"); @@ -721,13 +721,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0336FF"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -735,14 +735,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.stickiedPostIconTint = Color.parseColor("#0336FF"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#0336FF"); customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -752,7 +752,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#69666C"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); @@ -761,7 +761,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -812,13 +812,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#3C4043"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#3C4043"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); + customTheme.postTypeBackgroundColor = Color.parseColor("#002BF0"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -826,14 +826,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.stickiedPostIconTint = Color.parseColor("#002BF0"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#0D47A1"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#002BF0"); + customTheme.username = Color.parseColor("#002BF0"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -843,7 +843,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#E0E0E0"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); @@ -852,7 +852,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#000000"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -903,13 +903,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0336FF"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -917,14 +917,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.stickiedPostIconTint = Color.parseColor("#0336FF"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#0336FF"); customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -934,7 +934,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#69666C"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); @@ -943,7 +943,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -994,13 +994,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0336FF"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -1008,14 +1008,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.stickiedPostIconTint = Color.parseColor("#0336FF"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#0336FF"); customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -1025,7 +1025,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#69666C"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); @@ -1034,7 +1034,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -1085,13 +1085,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#EE0270"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); + customTheme.postTypeBackgroundColor = Color.parseColor("#002BF0"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -1099,14 +1099,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.stickiedPostIconTint = Color.parseColor("#002BF0"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#0D47A1"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#002BF0"); + customTheme.username = Color.parseColor("#002BF0"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -1116,7 +1116,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#E0E0E0"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); @@ -1125,7 +1125,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -1176,13 +1176,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0336FF"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -1190,14 +1190,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.stickiedPostIconTint = Color.parseColor("#0336FF"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#0336FF"); customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -1207,7 +1207,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#69666C"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); @@ -1216,7 +1216,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -1267,13 +1267,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0336FF"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -1281,14 +1281,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.stickiedPostIconTint = Color.parseColor("#0336FF"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#0336FF"); customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -1298,7 +1298,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#69666C"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); @@ -1307,7 +1307,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -1360,11 +1360,11 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); customTheme.upvoted = Color.parseColor("#FF008C"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0336FF"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -1372,12 +1372,12 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); customTheme.stickiedPostIconTint = Color.parseColor("#02ABEE"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#002BF0"); customTheme.username = Color.parseColor("#1E88E5"); customTheme.subreddit = Color.parseColor("#FF4B9C"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); @@ -1398,7 +1398,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#F1FA8C"); customTheme.fabIconColor = Color.parseColor("#FFFFFF"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); @@ -1449,13 +1449,13 @@ public class CustomThemeWrapper { customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#D48AE0"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#3C4043"); customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#3C4043"); - customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.upvoted = Color.parseColor("#FF1868"); customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); + customTheme.postTypeBackgroundColor = Color.parseColor("#002BF0"); customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF1868"); customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); customTheme.flairTextColor = Color.parseColor("#FFFFFF"); @@ -1463,14 +1463,14 @@ public class CustomThemeWrapper { customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); customTheme.archivedTint = Color.parseColor("#B4009F"); customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.crosspostIconTint = Color.parseColor("#FF1868"); customTheme.upvoteRatioIconTint = Color.parseColor("#0256EE"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.stickiedPostIconTint = Color.parseColor("#002BF0"); customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#0D47A1"); - customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.subscribed = Color.parseColor("#FF1868"); + customTheme.unsubscribed = Color.parseColor("#002BF0"); + customTheme.username = Color.parseColor("#002BF0"); + customTheme.subreddit = Color.parseColor("#FF1868"); customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); customTheme.submitter = Color.parseColor("#EE8A02"); customTheme.moderator = Color.parseColor("#00BA81"); @@ -1480,7 +1480,7 @@ public class CustomThemeWrapper { customTheme.dividerColor = Color.parseColor("#E0E0E0"); customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#0336FF"); customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); @@ -1489,7 +1489,7 @@ public class CustomThemeWrapper { customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); customTheme.fabIconColor = Color.parseColor("#000000"); customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.linkColor = Color.parseColor("#FF1868"); customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ClickableMotionLayout.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ClickableMotionLayout.java new file mode 100644 index 00000000..8c0f47ff --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ClickableMotionLayout.java @@ -0,0 +1,39 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.ViewConfiguration; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.constraintlayout.motion.widget.MotionLayout; + +public class ClickableMotionLayout extends MotionLayout { + private long mStartTime = 0; + + public ClickableMotionLayout(@NonNull Context context) { + super(context); + } + + public ClickableMotionLayout(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public ClickableMotionLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + if ( event.getAction() == MotionEvent.ACTION_DOWN ) { + mStartTime = event.getEventTime(); + } else if ( event.getAction() == MotionEvent.ACTION_UP ) { + if ( event.getEventTime() - mStartTime <= ViewConfiguration.getTapTimeout() ) { + return false; + } + } + + return super.onInterceptTouchEvent(event); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/CommentIndentationView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/CommentIndentationView.java index fc9dba03..27e1e142 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/CommentIndentationView.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/CommentIndentationView.java @@ -21,7 +21,8 @@ public class CommentIndentationView extends LinearLayout { private Integer[] colors; private ArrayList<Integer> startXs; private final int spacing; - private final int pathWidth; + private int pathWidth; + private boolean showOnlyOneDivider = false; public CommentIndentationView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); @@ -49,9 +50,16 @@ public class CommentIndentationView extends LinearLayout { protected void onDraw(Canvas canvas) { super.onDraw(canvas); - for (int i = 0; i < startXs.size(); i++) { - paint.setColor(colors[i % 7]); - canvas.drawLine(startXs.get(i), 0, startXs.get(i), getHeight(), paint); + if (showOnlyOneDivider) { + if (startXs.size() > 0) { + paint.setColor(colors[(startXs.size() - 1) % 7]); + canvas.drawLine(level * pathWidth, 0, level * pathWidth, getHeight(), paint); + } + } else { + for (int i = 0; i < startXs.size(); i++) { + paint.setColor(colors[i % 7]); + canvas.drawLine(startXs.get(i), 0, startXs.get(i), getHeight(), paint); + } } } @@ -81,7 +89,7 @@ public class CommentIndentationView extends LinearLayout { this.colors = colors; this.level = level; if (level > 0) { - int indentationSpacing = level * spacing + pathWidth; + int indentationSpacing = showOnlyOneDivider ? pathWidth * level : level * spacing + pathWidth; setPaddingRelative(indentationSpacing, 0, pathWidth, 0); } else { setPaddingRelative(0, 0, 0, 0); @@ -89,6 +97,13 @@ public class CommentIndentationView extends LinearLayout { invalidate(); } + public void setShowOnlyOneDivider(boolean showOnlyOneDivider) { + this.showOnlyOneDivider = showOnlyOneDivider; + if (showOnlyOneDivider) { + pathWidth = (int) Utils.convertDpToPixel(4, getContext()); + } + } + private static class SavedState extends BaseSavedState { ArrayList<Integer> startXs; Integer[] colors; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LinearLayoutManagerBugFixed.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LinearLayoutManagerBugFixed.java new file mode 100644 index 00000000..e2264225 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LinearLayoutManagerBugFixed.java @@ -0,0 +1,25 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.recyclerview.widget.LinearLayoutManager; + +public class LinearLayoutManagerBugFixed extends LinearLayoutManager { + public LinearLayoutManagerBugFixed(Context context) { + super(context); + } + + public LinearLayoutManagerBugFixed(Context context, int orientation, boolean reverseLayout) { + super(context, orientation, reverseLayout); + } + + public LinearLayoutManagerBugFixed(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + public boolean supportsPredictiveItemAnimations() { + return false; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java index a654b437..35923fa6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java @@ -5,9 +5,7 @@ import android.view.View; import android.view.ViewTreeObserver; import android.widget.HorizontalScrollView; -import androidx.recyclerview.widget.LinearLayoutManager; - -public class MarkwonLinearLayoutManager extends LinearLayoutManager { +public class MarkwonLinearLayoutManager extends LinearLayoutManagerBugFixed { public interface HorizontalScrollViewScrolledListener { void onScrolledLeft(); void onScrolledRight(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ViewPagerBugFixed.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ViewPagerBugFixed.java new file mode 100644 index 00000000..78e7b88e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ViewPagerBugFixed.java @@ -0,0 +1,37 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.viewpager.widget.ViewPager; + +public class ViewPagerBugFixed extends ViewPager { + public ViewPagerBugFixed(@NonNull Context context) { + super(context); + } + + public ViewPagerBugFixed(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + try { + return super.onTouchEvent(ev); + } catch (IllegalArgumentException ignore) {} + + return false; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + try { + return super.onInterceptTouchEvent(ev); + } catch (IllegalArgumentException ignore) {} + + return false; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDefaultLinkPostLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDefaultLinkPostLayoutEvent.java new file mode 100644 index 00000000..d7897beb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDefaultLinkPostLayoutEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeDefaultLinkPostLayoutEvent { + public int defaultLinkPostLayout; + + public ChangeDefaultLinkPostLayoutEvent(int defaultLinkPostLayout) { + this.defaultLinkPostLayout = defaultLinkPostLayout; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeHidePostFlairEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeHidePostFlairEvent.java new file mode 100644 index 00000000..f3a9a7a4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeHidePostFlairEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeHidePostFlairEvent { + public boolean hidePostFlair; + + public ChangeHidePostFlairEvent(boolean hidePostFlair) { + this.hidePostFlair = hidePostFlair; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeRememberMutingOptionInPostFeedEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeRememberMutingOptionInPostFeedEvent.java new file mode 100644 index 00000000..d49d5939 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeRememberMutingOptionInPostFeedEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeRememberMutingOptionInPostFeedEvent { + public boolean rememberMutingOptionInPostFeedEvent; + + public ChangeRememberMutingOptionInPostFeedEvent(boolean rememberMutingOptionInPostFeedEvent) { + this.rememberMutingOptionInPostFeedEvent = rememberMutingOptionInPostFeedEvent; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitGalleryPostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitGalleryPostEvent.java new file mode 100644 index 00000000..fcab85cd --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitGalleryPostEvent.java @@ -0,0 +1,13 @@ +package ml.docilealligator.infinityforreddit.events; + +public class SubmitGalleryPostEvent { + public boolean postSuccess; + public String postUrl; + public String errorMessage; + + public SubmitGalleryPostEvent(boolean postSuccess, String postUrl, String errorMessage) { + this.postSuccess = postSuccess; + this.postUrl = postUrl; + this.errorMessage = errorMessage; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ToggleSecureModeEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ToggleSecureModeEvent.java new file mode 100644 index 00000000..a7c27eb3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ToggleSecureModeEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ToggleSecureModeEvent { + public boolean isSecureMode; + + public ToggleSecureModeEvent(boolean isSecureMode) { + this.isSecureMode = isSecureMode; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/CommentsListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/CommentsListingFragment.java index c730b4ba..04cabb7a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/CommentsListingFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/CommentsListingFragment.java @@ -25,7 +25,6 @@ import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -50,6 +49,7 @@ import ml.docilealligator.infinityforreddit.activities.BaseActivity; import ml.docilealligator.infinityforreddit.adapters.CommentsListingRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.comment.CommentViewModel; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; @@ -105,7 +105,7 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni private String mAccessToken; private RequestManager mGlide; private AppCompatActivity mActivity; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; private CommentsListingRecyclerViewAdapter mAdapter; private SortType sortType; private ColorDrawable backgroundSwipeRight; @@ -255,7 +255,7 @@ public class CommentsListingFragment extends Fragment implements FragmentCommuni private void bindView(Resources resources) { if (mActivity != null && !mActivity.isFinishing() && !mActivity.isDestroyed()) { - mLinearLayoutManager = new LinearLayoutManager(mActivity); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity); mCommentRecyclerView.setLayoutManager(mLinearLayoutManager); mAdapter = new CommentsListingRecyclerViewAdapter(mActivity, mOauthRetrofit, customThemeWrapper, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/FollowedUsersListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/FollowedUsersListingFragment.java index 38726cd8..1fda28d4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/FollowedUsersListingFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/FollowedUsersListingFragment.java @@ -17,7 +17,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -40,6 +39,7 @@ import ml.docilealligator.infinityforreddit.activities.BaseActivity; import ml.docilealligator.infinityforreddit.activities.SubscribedThingListingActivity; import ml.docilealligator.infinityforreddit.adapters.FollowedUsersRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserViewModel; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import retrofit2.Retrofit; @@ -78,7 +78,7 @@ public class FollowedUsersListingFragment extends Fragment implements FragmentCo SubscribedUserViewModel mSubscribedUserViewModel; private Activity mActivity; private RequestManager mGlide; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; public FollowedUsersListingFragment() { // Required empty public constructor @@ -109,7 +109,7 @@ public class FollowedUsersListingFragment extends Fragment implements FragmentCo mGlide = Glide.with(this); - mLinearLayoutManager = new LinearLayoutManager(mActivity); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity); mRecyclerView.setLayoutManager(mLinearLayoutManager); FollowedUsersRecyclerViewAdapter adapter = new FollowedUsersRecyclerViewAdapter(mActivity, mExecutor, mOauthRetrofit, mRedditDataRoomDatabase, mCustomThemeWrapper, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/InboxFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/InboxFragment.java index b9879c3e..567f3a1b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/InboxFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/InboxFragment.java @@ -14,7 +14,6 @@ import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -38,6 +37,7 @@ import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.activities.BaseActivity; import ml.docilealligator.infinityforreddit.adapters.MessageRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.RepliedToPrivateMessageEvent; import ml.docilealligator.infinityforreddit.message.FetchMessage; import ml.docilealligator.infinityforreddit.message.MessageViewModel; @@ -72,7 +72,7 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { private String mWhere; private MessageRecyclerViewAdapter mAdapter; private RequestManager mGlide; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; private BaseActivity mActivity; public InboxFragment() { @@ -106,7 +106,7 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { mWhere = arguments.getString(EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); mAdapter = new MessageRecyclerViewAdapter(mActivity, mOauthRetrofit, mCustomThemeWrapper, mAccessToken, mWhere, () -> mMessageViewModel.retryLoadingMore()); - mLinearLayoutManager = new LinearLayoutManager(mActivity); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity); mRecyclerView.setLayoutManager(mLinearLayoutManager); mRecyclerView.setAdapter(mAdapter); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mActivity, mLinearLayoutManager.getOrientation()); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MultiRedditListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MultiRedditListingFragment.java index fc0723eb..0f80d47a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MultiRedditListingFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MultiRedditListingFragment.java @@ -17,7 +17,6 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -43,6 +42,7 @@ import ml.docilealligator.infinityforreddit.activities.ViewMultiRedditDetailActi import ml.docilealligator.infinityforreddit.adapters.MultiRedditListingRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.bottomsheetfragments.MultiRedditOptionsBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; import ml.docilealligator.infinityforreddit.multireddit.MultiRedditViewModel; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -80,7 +80,7 @@ public class MultiRedditListingFragment extends Fragment implements FragmentComm public MultiRedditViewModel mMultiRedditViewModel; private AppCompatActivity mActivity; private RequestManager mGlide; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; public MultiRedditListingFragment() { // Required empty public constructor @@ -114,7 +114,7 @@ public class MultiRedditListingFragment extends Fragment implements FragmentComm mGlide = Glide.with(this); - mLinearLayoutManager = new LinearLayoutManager(mActivity); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity); mRecyclerView.setLayoutManager(mLinearLayoutManager); MultiRedditListingRecyclerViewAdapter adapter = new MultiRedditListingRecyclerViewAdapter(mActivity, mExecutor, mOauthRetrofit, mRedditDataRoomDatabase, mCustomThemeWrapper, accessToken, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java index 7110e057..c98f27e6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java @@ -1,6 +1,9 @@ package ml.docilealligator.infinityforreddit.fragments; +import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; +import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; + import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -29,14 +32,13 @@ import android.widget.Toast; import androidx.annotation.DimenRes; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.paging.PagedList; import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.StaggeredGridLayoutManager; @@ -79,12 +81,15 @@ import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivi import ml.docilealligator.infinityforreddit.adapters.PostRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.CustomToroContainer; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.ChangeAutoplayNsfwVideosEvent; import ml.docilealligator.infinityforreddit.events.ChangeCompactLayoutToolbarHiddenByDefaultEvent; import ml.docilealligator.infinityforreddit.events.ChangeDataSavingModeEvent; +import ml.docilealligator.infinityforreddit.events.ChangeDefaultLinkPostLayoutEvent; import ml.docilealligator.infinityforreddit.events.ChangeDefaultPostLayoutEvent; import ml.docilealligator.infinityforreddit.events.ChangeDisableImagePreviewEvent; import ml.docilealligator.infinityforreddit.events.ChangeEnableSwipeActionSwitchEvent; +import ml.docilealligator.infinityforreddit.events.ChangeHidePostFlairEvent; import ml.docilealligator.infinityforreddit.events.ChangeHidePostTypeEvent; import ml.docilealligator.infinityforreddit.events.ChangeHideSubredditAndUserPrefixEvent; import ml.docilealligator.infinityforreddit.events.ChangeHideTheNumberOfAwardsEvent; @@ -97,6 +102,7 @@ import ml.docilealligator.infinityforreddit.events.ChangeNSFWBlurEvent; import ml.docilealligator.infinityforreddit.events.ChangeNetworkStatusEvent; import ml.docilealligator.infinityforreddit.events.ChangeOnlyDisablePreviewInVideoAndGifPostsEvent; import ml.docilealligator.infinityforreddit.events.ChangePostLayoutEvent; +import ml.docilealligator.infinityforreddit.events.ChangeRememberMutingOptionInPostFeedEvent; import ml.docilealligator.infinityforreddit.events.ChangeSavePostFeedScrolledPositionEvent; import ml.docilealligator.infinityforreddit.events.ChangeShowAbsoluteNumberOfVotesEvent; import ml.docilealligator.infinityforreddit.events.ChangeShowElapsedTimeEvent; @@ -123,9 +129,6 @@ import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; -import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; -import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; - /** * A simple {@link Fragment} subclass. @@ -136,6 +139,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { public static final String EXTRA_USER_NAME = "EUN"; public static final String EXTRA_USER_WHERE = "EUW"; public static final String EXTRA_QUERY = "EQ"; + public static final String EXTRA_TRENDING_SOURCE = "ETS"; public static final String EXTRA_POST_TYPE = "EPT"; public static final String EXTRA_FILTER = "EF"; public static final String EXTRA_ACCESS_TOKEN = "EAT"; @@ -201,7 +205,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { Executor mExecutor; private RequestManager mGlide; private AppCompatActivity activity; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; private StaggeredGridLayoutManager mStaggeredGridLayoutManager; private long postFragmentId; private int postType; @@ -210,6 +214,8 @@ public class PostFragment extends Fragment implements FragmentCommunicator { private boolean hasPost = false; private boolean isShown = false; private boolean savePostFeedScrolledPosition; + private boolean rememberMutingOptionInPostFeed; + private Boolean masterMutingOption; private PostRecyclerViewAdapter mAdapter; private RecyclerView.SmoothScroller smoothScroller; private Window window; @@ -221,6 +227,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { private String subredditName; private String username; private String query; + private String trendingSource; private String where; private String multiRedditPath; private String concatenatedSubredditNames; @@ -373,12 +380,10 @@ public class PostFragment extends Fragment implements FragmentCommunicator { mSwipeRefreshLayout.setEnabled(mSharedPreferences.getBoolean(SharedPreferencesUtils.PULL_TO_REFRESH, true)); mSwipeRefreshLayout.setOnRefreshListener(this::refresh); + int recyclerViewPosition = 0; int hideReadPostsIndex = 0; if (savedInstanceState != null) { - int recyclerViewPosition = savedInstanceState.getInt(RECYCLER_VIEW_POSITION_STATE); - if (recyclerViewPosition > 0) { - mPostRecyclerView.scrollToPosition(recyclerViewPosition); - } + recyclerViewPosition = savedInstanceState.getInt(RECYCLER_VIEW_POSITION_STATE); isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); readPosts = savedInstanceState.getParcelableArrayList(READ_POST_LIST_STATE); @@ -417,6 +422,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); int defaultPostLayout = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.DEFAULT_POST_LAYOUT_KEY, "0")); savePostFeedScrolledPosition = mSharedPreferences.getBoolean(SharedPreferencesUtils.SAVE_FRONT_PAGE_SCROLLED_POSITION, false); + rememberMutingOptionInPostFeed = mSharedPreferences.getBoolean(SharedPreferencesUtils.REMEMBER_MUTING_OPTION_IN_POST_FEED, false); Locale locale = getResources().getConfiguration().locale; int usage; @@ -425,6 +431,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { if (postType == PostDataSource.TYPE_SEARCH) { subredditName = getArguments().getString(EXTRA_NAME); query = getArguments().getString(EXTRA_QUERY); + trendingSource = getArguments().getString(EXTRA_TRENDING_SOURCE); if (savedInstanceState == null) { postFragmentId += query.hashCode(); } @@ -452,6 +459,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { Intent intent = new Intent(activity, FilteredPostsActivity.class); intent.putExtra(FilteredPostsActivity.EXTRA_NAME, subredditName); intent.putExtra(FilteredPostsActivity.EXTRA_QUERY, query); + intent.putExtra(FilteredPostsActivity.EXTRA_TRENDING_SOURCE, trendingSource); intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, filter); startActivity(intent); @@ -462,6 +470,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { Intent intent = new Intent(activity, FilteredPostsActivity.class); intent.putExtra(FilteredPostsActivity.EXTRA_NAME, subredditName); intent.putExtra(FilteredPostsActivity.EXTRA_QUERY, query); + intent.putExtra(FilteredPostsActivity.EXTRA_TRENDING_SOURCE, trendingSource); intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); intent.putExtra(FilteredPostsActivity.EXTRA_CONTAIN_FLAIR, flair); startActivity(intent); @@ -472,6 +481,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { Intent intent = new Intent(activity, FilteredPostsActivity.class); intent.putExtra(FilteredPostsActivity.EXTRA_NAME, subredditName); intent.putExtra(FilteredPostsActivity.EXTRA_QUERY, query); + intent.putExtra(FilteredPostsActivity.EXTRA_TRENDING_SOURCE, trendingSource); intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, Post.NSFW_TYPE); startActivity(intent); @@ -651,12 +661,6 @@ public class PostFragment extends Fragment implements FragmentCommunicator { usage = PostFilterUsage.USER_TYPE; nameOfUsage = username; - if (where != null && where.equals(PostDataSource.USER_WHERE_SUBMITTED)) { - CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mFetchPostInfoLinearLayout.getLayoutParams(); - params.height = ViewGroup.LayoutParams.WRAP_CONTENT; - mFetchPostInfoLinearLayout.setLayoutParams(params); - } - String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_USER_POST_BASE + username, mSharedPreferences.getString(SharedPreferencesUtils.USER_DEFAULT_SORT_TYPE, SortType.Type.NEW.name())); if (sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { @@ -843,7 +847,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { int nColumns = getNColumns(resources); if (nColumns == 1) { - mLinearLayoutManager = new LinearLayoutManager(activity); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(activity); mPostRecyclerView.setLayoutManager(mLinearLayoutManager); } else { mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(nColumns, StaggeredGridLayoutManager.VERTICAL); @@ -854,6 +858,10 @@ public class PostFragment extends Fragment implements FragmentCommunicator { windowWidth /= 2; } + if (recyclerViewPosition > 0) { + mPostRecyclerView.scrollToPosition(recyclerViewPosition); + } + mAdapter.setHideReadPostsIndex(hideReadPostsIndex); if (activity instanceof ActivityToolbarInterface) { @@ -1097,27 +1105,32 @@ public class PostFragment extends Fragment implements FragmentCommunicator { private void initializeAndBindPostViewModel(String accessToken) { if (postType == PostDataSource.TYPE_SEARCH) { - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, accountName, mSharedPreferences, - mPostFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, - postFilter, readPosts)).get(PostViewModel.class); + mPostFeedScrolledPositionSharedPreferences, subredditName, query, trendingSource, + postType, sortType, postFilter, readPosts)).get(PostViewModel.class); } else if (postType == PostDataSource.TYPE_SUBREDDIT) { - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, postFilter, readPosts)).get(PostViewModel.class); } else if (postType == PostDataSource.TYPE_MULTI_REDDIT) { - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, multiRedditPath, postType, sortType, postFilter, readPosts)).get(PostViewModel.class); } else if (postType == PostDataSource.TYPE_USER) { - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, username, postType, sortType, postFilter, where, readPosts)).get(PostViewModel.class); } else { - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mOauthRetrofit, accessToken, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), mOauthRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, postType, sortType, postFilter, readPosts)).get(PostViewModel.class); } @@ -1128,28 +1141,33 @@ public class PostFragment extends Fragment implements FragmentCommunicator { private void initializeAndBindPostViewModelForAnonymous(String concatenatedSubredditNames) { //For anonymous user if (postType == PostDataSource.TYPE_SEARCH) { - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mRetrofit, null, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), mRetrofit, null, accountName, mSharedPreferences, - mPostFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, - postFilter, readPosts)).get(PostViewModel.class); + mPostFeedScrolledPositionSharedPreferences, subredditName, query, trendingSource, + postType, sortType, postFilter, readPosts)).get(PostViewModel.class); } else if (postType == PostDataSource.TYPE_SUBREDDIT) { - mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(mRetrofit, null, + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(mExecutor, + new Handler(), mRetrofit, null, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, postFilter, readPosts)).get(PostViewModel.class); } else if (postType == PostDataSource.TYPE_MULTI_REDDIT) { - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mRetrofit, null, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), mRetrofit, null, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, multiRedditPath, postType, sortType, postFilter, readPosts)).get(PostViewModel.class); } else if (postType == PostDataSource.TYPE_USER) { - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mRetrofit, null, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), mRetrofit, null, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, username, postType, sortType, postFilter, where, readPosts)).get(PostViewModel.class); } else { //Anonymous Front Page - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mRetrofit, + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, + new Handler(), mRetrofit, mSharedPreferences, concatenatedSubredditNames, postType, sortType, postFilter)).get(PostViewModel.class); } @@ -1442,9 +1460,16 @@ public class PostFragment extends Fragment implements FragmentCommunicator { break; } + int previousPosition = -1; + if (mLinearLayoutManager != null) { + previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + } else if (mStaggeredGridLayoutManager != null) { + int[] into = new int[mStaggeredGridLayoutManager.getSpanCount()]; + previousPosition = mStaggeredGridLayoutManager.findFirstVisibleItemPositions(into)[0]; + } int nColumns = getNColumns(getResources()); if (nColumns == 1) { - mLinearLayoutManager = new LinearLayoutManager(activity); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(activity); if (mPostRecyclerView.getItemDecorationCount() > 0) { mPostRecyclerView.removeItemDecorationAt(0); } @@ -1462,6 +1487,10 @@ public class PostFragment extends Fragment implements FragmentCommunicator { mLinearLayoutManager = null; } + if (previousPosition > 0) { + mPostRecyclerView.scrollToPosition(previousPosition); + } + if (mAdapter != null) { mAdapter.setPostLayout(postLayout); refreshAdapter(); @@ -1503,6 +1532,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { Intent intent = new Intent(activity, FilteredPostsActivity.class); intent.putExtra(FilteredPostsActivity.EXTRA_NAME, subredditName); intent.putExtra(FilteredPostsActivity.EXTRA_QUERY, query); + intent.putExtra(FilteredPostsActivity.EXTRA_TRENDING_SOURCE, trendingSource); intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); startActivity(intent); } else if (postType == PostDataSource.TYPE_SUBREDDIT) { @@ -1537,6 +1567,17 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } } + @Nullable + public Boolean getMasterMutingOption() { + return masterMutingOption; + } + + public void videoAutoplayChangeMutingOption(boolean isMute) { + if (rememberMutingOptionInPostFeed) { + masterMutingOption = isMute; + } + } + @Subscribe public void onPostUpdateEvent(PostUpdateEventToPostList event) { PagedList<Post> posts = mAdapter.getCurrentList(); @@ -1644,6 +1685,14 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } @Subscribe + public void onChangeDefaultLinkPostLayoutEvent(ChangeDefaultLinkPostLayoutEvent event) { + if (mAdapter != null) { + mAdapter.setDefaultLinkPostLayout(event.defaultLinkPostLayout); + refreshAdapter(); + } + } + + @Subscribe public void onChangeShowAbsoluteNumberOfVotesEvent(ChangeShowAbsoluteNumberOfVotesEvent changeShowAbsoluteNumberOfVotesEvent) { if (mAdapter != null) { mAdapter.setShowAbsoluteNumberOfVotes(changeShowAbsoluteNumberOfVotesEvent.showAbsoluteNumberOfVotes); @@ -1826,6 +1875,14 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } @Subscribe + public void onChangeHidePostFlairEvent(ChangeHidePostFlairEvent event) { + if (mAdapter != null) { + mAdapter.setHidePostFlair(event.hidePostFlair); + refreshAdapter(); + } + } + + @Subscribe public void onChangeHideTheNumberOfAwardsEvent(ChangeHideTheNumberOfAwardsEvent event) { if (mAdapter != null) { mAdapter.setHideTheNumberOfAwards(event.hideTheNumberOfAwards); @@ -1857,6 +1914,14 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } } + @Subscribe + public void onChangeRememberMutingOptionInPostFeedEvent(ChangeRememberMutingOptionInPostFeedEvent event) { + rememberMutingOptionInPostFeed = event.rememberMutingOptionInPostFeedEvent; + if (!event.rememberMutingOptionInPostFeedEvent) { + masterMutingOption = null; + } + } + private void refreshAdapter() { int previousPosition = -1; if (mLinearLayoutManager != null) { @@ -1871,7 +1936,6 @@ public class PostFragment extends Fragment implements FragmentCommunicator { mPostRecyclerView.setLayoutManager(null); mPostRecyclerView.setAdapter(mAdapter); mPostRecyclerView.setLayoutManager(layoutManager); - if (previousPosition > 0) { mPostRecyclerView.scrollToPosition(previousPosition); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java index 7297cb54..d7a77b07 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java @@ -17,7 +17,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -48,8 +47,10 @@ import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; import ml.docilealligator.infinityforreddit.asynctasks.InsertSubredditData; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditViewModel; @@ -65,7 +66,7 @@ public class SidebarFragment extends Fragment { private Activity activity; private String subredditName; public SubredditViewModel mSubredditViewModel; - private LinearLayoutManager linearLayoutManager; + private LinearLayoutManagerBugFixed linearLayoutManager; private int markdownColor; @Inject @Named("no_oauth") @@ -76,6 +77,7 @@ public class SidebarFragment extends Fragment { CustomThemeWrapper mCustomThemeWrapper; @Inject Executor mExecutor; + private String sidebarDescription; public SidebarFragment() { // Required empty public constructor @@ -99,7 +101,7 @@ public class SidebarFragment extends Fragment { swipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); swipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); - markdownColor = mCustomThemeWrapper.getSecondaryTextColor(); + markdownColor = mCustomThemeWrapper.getPrimaryTextColor(); Markwon markwon = Markwon.builder(activity) .usePlugin(HtmlPlugin.create()) @@ -107,6 +109,16 @@ public class SidebarFragment extends Fragment { @Override public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { textView.setTextColor(markdownColor); + textView.setOnLongClickListener(view -> { + if (sidebarDescription != null && !sidebarDescription.equals("") && textView.getSelectionStart() == -1 && textView.getSelectionEnd() == -1) { + Bundle bundle = new Bundle(); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, sidebarDescription); + CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); + copyTextBottomSheetFragment.setArguments(bundle); + copyTextBottomSheetFragment.show(getChildFragmentManager(), copyTextBottomSheetFragment.getTag()); + } + return true; + }); } @Override @@ -142,7 +154,7 @@ public class SidebarFragment extends Fragment { .textLayoutIsRoot(R.layout.view_table_entry_cell))) .build(); - linearLayoutManager = new LinearLayoutManager(activity); + linearLayoutManager = new LinearLayoutManagerBugFixed(activity); recyclerView.setLayoutManager(linearLayoutManager); recyclerView.setAdapter(markwonAdapter); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @@ -162,8 +174,9 @@ public class SidebarFragment extends Fragment { .get(SubredditViewModel.class); mSubredditViewModel.getSubredditLiveData().observe(getViewLifecycleOwner(), subredditData -> { if (subredditData != null) { - if (subredditData.getSidebarDescription() != null && !subredditData.getSidebarDescription().equals("")) { - markwonAdapter.setMarkdown(markwon, subredditData.getSidebarDescription()); + sidebarDescription = subredditData.getSidebarDescription(); + if (sidebarDescription != null && !sidebarDescription.equals("")) { + markwonAdapter.setMarkdown(markwon, sidebarDescription); markwonAdapter.notifyDataSetChanged(); } } else { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubredditListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubredditListingFragment.java index e35520bd..46513616 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubredditListingFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubredditListingFragment.java @@ -19,7 +19,6 @@ import androidx.annotation.NonNull; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -46,6 +45,7 @@ import ml.docilealligator.infinityforreddit.activities.SearchSubredditsResultAct import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; import ml.docilealligator.infinityforreddit.adapters.SubredditListingRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditListingViewModel; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -97,7 +97,7 @@ public class SubredditListingFragment extends Fragment implements FragmentCommun CustomThemeWrapper mCustomThemeWrapper; @Inject Executor mExecutor; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; private SubredditListingRecyclerViewAdapter mAdapter; private Activity mActivity; private SortType sortType; @@ -131,7 +131,7 @@ public class SubredditListingFragment extends Fragment implements FragmentCommun } } - mLinearLayoutManager = new LinearLayoutManager(getActivity()); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(getActivity()); mSubredditListingRecyclerView.setLayoutManager(mLinearLayoutManager); String query = getArguments().getString(EXTRA_QUERY); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubscribedSubredditsListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubscribedSubredditsListingFragment.java index 7bb69a76..61333955 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubscribedSubredditsListingFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubscribedSubredditsListingFragment.java @@ -17,7 +17,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -41,6 +40,7 @@ import ml.docilealligator.infinityforreddit.FragmentCommunicator; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditViewModel; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import retrofit2.Retrofit; @@ -82,7 +82,7 @@ public class SubscribedSubredditsListingFragment extends Fragment implements Fra public SubscribedSubredditViewModel mSubscribedSubredditViewModel; private Activity mActivity; private RequestManager mGlide; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; public SubscribedSubredditsListingFragment() { // Required empty public constructor @@ -115,7 +115,7 @@ public class SubscribedSubredditsListingFragment extends Fragment implements Fra mGlide = Glide.with(this); - mLinearLayoutManager = new LinearLayoutManager(mActivity); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity); mRecyclerView.setLayoutManager(mLinearLayoutManager); SubscribedSubredditsRecyclerViewAdapter adapter; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/UserListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/UserListingFragment.java index 5e894706..912176d5 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/UserListingFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/UserListingFragment.java @@ -19,7 +19,6 @@ import androidx.annotation.NonNull; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -46,6 +45,7 @@ import ml.docilealligator.infinityforreddit.activities.SearchUsersResultActivity import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.adapters.UserListingRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.user.UserData; import ml.docilealligator.infinityforreddit.user.UserListingViewModel; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -97,7 +97,7 @@ public class UserListingFragment extends Fragment implements FragmentCommunicato CustomThemeWrapper mCustomThemeWrapper; @Inject Executor mExecutor; - private LinearLayoutManager mLinearLayoutManager; + private LinearLayoutManagerBugFixed mLinearLayoutManager; private String mQuery; private UserListingRecyclerViewAdapter mAdapter; private Activity mActivity; @@ -132,7 +132,7 @@ public class UserListingFragment extends Fragment implements FragmentCommunicato } } - mLinearLayoutManager = new LinearLayoutManager(getActivity()); + mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity); mUserListingRecyclerView.setLayoutManager(mLinearLayoutManager); mQuery = getArguments().getString(EXTRA_QUERY); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurImageFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurImageFragment.java index 0dcf1f01..2b6e9ea9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurImageFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurImageFragment.java @@ -16,8 +16,10 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -36,6 +38,7 @@ import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; import com.davemorrissey.labs.subscaleview.ImageSource; import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; +import com.google.android.material.bottomappbar.BottomAppBar; import java.io.File; import java.util.concurrent.Executor; @@ -57,6 +60,8 @@ import ml.docilealligator.infinityforreddit.services.DownloadMediaService; public class ViewImgurImageFragment extends Fragment { public static final String EXTRA_IMGUR_IMAGES = "EII"; + public static final String EXTRA_INDEX = "EI"; + public static final String EXTRA_MEDIA_COUNT = "EMC"; private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; @BindView(R.id.progress_bar_view_imgur_image_fragment) @@ -65,6 +70,16 @@ public class ViewImgurImageFragment extends Fragment { SubsamplingScaleImageView imageView; @BindView(R.id.load_image_error_linear_layout_view_imgur_image_fragment) LinearLayout errorLinearLayout; + @BindView(R.id.bottom_navigation_view_imgur_image_fragment) + BottomAppBar bottomAppBar; + @BindView(R.id.title_text_view_view_imgur_image_fragment) + TextView titleTextView; + @BindView(R.id.download_image_view_view_imgur_image_fragment) + ImageView downloadImageView; + @BindView(R.id.share_image_view_view_imgur_image_fragment) + ImageView shareImageView; + @BindView(R.id.wallpaper_image_view_view_imgur_image_fragment) + ImageView wallpaperImageView; @Inject Executor mExecutor; @@ -81,7 +96,7 @@ public class ViewImgurImageFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_view_imgur_images, container, false); + View rootView = inflater.inflate(R.layout.fragment_view_imgur_image, container, false); ((Infinity) activity.getApplication()).getAppComponent().inject(this); @@ -100,6 +115,9 @@ public class ViewImgurImageFragment extends Fragment { | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); isActionBarHidden = false; + if (activity.isUseBottomAppBar()) { + bottomAppBar.setVisibility(View.VISIBLE); + } } else { activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE @@ -109,6 +127,9 @@ public class ViewImgurImageFragment extends Fragment { | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE); isActionBarHidden = true; + if (activity.isUseBottomAppBar()) { + bottomAppBar.setVisibility(View.GONE); + } } }); imageView.setMinimumDpi(80); @@ -121,6 +142,25 @@ public class ViewImgurImageFragment extends Fragment { loadImage(); }); + if (activity.isUseBottomAppBar()) { + bottomAppBar.setVisibility(View.VISIBLE); + titleTextView.setText(getString(R.string.view_imgur_media_activity_image_label, + getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); + downloadImageView.setOnClickListener(view -> { + if (isDownloading) { + return; + } + isDownloading = true; + requestPermissionAndDownload(); + }); + shareImageView.setOnClickListener(view -> { + shareImage(); + }); + wallpaperImageView.setOnClickListener(view -> { + setWallpaper(); + }); + } + return rootView; } @@ -164,83 +204,39 @@ public class ViewImgurImageFragment extends Fragment { if (isDownloading) { return false; } - isDownloading = true; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (ContextCompat.checkSelfPermission(activity, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } - + requestPermissionAndDownload(); return true; } else if (itemId == R.id.action_share_view_imgur_image_fragment) { - glide.asBitmap().load(imgurMedia.getLink()).into(new CustomTarget<Bitmap>() { - - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { - if (activity.getExternalCacheDir() != null) { - Toast.makeText(activity, R.string.save_image_first, Toast.LENGTH_SHORT).show(); - SaveBitmapImageToFile.SaveBitmapImageToFile(mExecutor, new Handler(), resource, activity.getExternalCacheDir().getPath(), - imgurMedia.getFileName(), - new SaveBitmapImageToFile.SaveBitmapImageToFileListener() { - @Override - public void saveSuccess(File imageFile) { - Uri uri = FileProvider.getUriForFile(activity, - BuildConfig.APPLICATION_ID + ".provider", imageFile); - Intent shareIntent = new Intent(); - shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_STREAM, uri); - shareIntent.setType("image/*"); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); - } - - @Override - public void saveFailed() { - Toast.makeText(activity, - R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); - } - }); - } else { - Toast.makeText(activity, - R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); + shareImage(); return true; } else if (itemId == R.id.action_set_wallpaper_view_imgur_image_fragment) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(SetAsWallpaperBottomSheetFragment.EXTRA_VIEW_PAGER_POSITION, activity.getCurrentPagePosition()); - setAsWallpaperBottomSheetFragment.setArguments(bundle); - setAsWallpaperBottomSheetFragment.show(activity.getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); - } else { - ((SetAsWallpaperCallback) activity).setToBoth(activity.getCurrentPagePosition()); - } + setWallpaper(); return true; } return false; } + private void requestPermissionAndDownload() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + } + private void download() { isDownloading = false; @@ -252,6 +248,59 @@ public class ViewImgurImageFragment extends Fragment { Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); } + private void shareImage() { + glide.asBitmap().load(imgurMedia.getLink()).into(new CustomTarget<Bitmap>() { + + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { + if (activity.getExternalCacheDir() != null) { + Toast.makeText(activity, R.string.save_image_first, Toast.LENGTH_SHORT).show(); + SaveBitmapImageToFile.SaveBitmapImageToFile(mExecutor, new Handler(), resource, activity.getExternalCacheDir().getPath(), + imgurMedia.getFileName(), + new SaveBitmapImageToFile.SaveBitmapImageToFileListener() { + @Override + public void saveSuccess(File imageFile) { + Uri uri = FileProvider.getUriForFile(activity, + BuildConfig.APPLICATION_ID + ".provider", imageFile); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, uri); + shareIntent.setType("image/*"); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } + + @Override + public void saveFailed() { + Toast.makeText(activity, + R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); + } + }); + } else { + Toast.makeText(activity, + R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + } + + private void setWallpaper() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(SetAsWallpaperBottomSheetFragment.EXTRA_VIEW_PAGER_POSITION, activity.getCurrentPagePosition()); + setAsWallpaperBottomSheetFragment.setArguments(bundle); + setAsWallpaperBottomSheetFragment.show(activity.getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); + } else { + ((SetAsWallpaperCallback) activity).setToBoth(activity.getCurrentPagePosition()); + } + } + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { @@ -269,4 +318,10 @@ public class ViewImgurImageFragment extends Fragment { super.onAttach(context); activity = (ViewImgurMediaActivity) context; } + + @Override + public void onDestroyView() { + super.onDestroyView(); + glide.clear(imageView); + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurVideoFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurVideoFragment.java index 01961e17..65b283e1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurVideoFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurVideoFragment.java @@ -1,7 +1,6 @@ package ml.docilealligator.infinityforreddit.fragments; import android.Manifest; -import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -18,7 +17,9 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; +import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -39,6 +40,7 @@ import com.google.android.exoplayer2.ui.PlayerView; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.util.Util; +import com.google.android.material.bottomappbar.BottomAppBar; import javax.inject.Inject; import javax.inject.Named; @@ -48,6 +50,7 @@ import butterknife.ButterKnife; import ml.docilealligator.infinityforreddit.ImgurMedia; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.activities.ViewImgurMediaActivity; import ml.docilealligator.infinityforreddit.services.DownloadMediaService; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -56,12 +59,20 @@ public class ViewImgurVideoFragment extends Fragment { public static final String EXTRA_IMGUR_VIDEO = "EIV"; private static final String IS_MUTE_STATE = "IMS"; private static final String POSITION_STATE = "PS"; + public static final String EXTRA_INDEX = "EI"; + public static final String EXTRA_MEDIA_COUNT = "EMC"; private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; @BindView(R.id.player_view_view_imgur_video_fragment) PlayerView videoPlayerView; @BindView(R.id.mute_exo_playback_control_view) ImageButton muteButton; - private Activity activity; + @BindView(R.id.bottom_navigation_exo_playback_control_view) + BottomAppBar bottomAppBar; + @BindView(R.id.title_text_view_exo_playback_control_view) + TextView titleTextView; + @BindView(R.id.download_image_view_exo_playback_control_view) + ImageView downloadImageView; + private ViewImgurMediaActivity activity; private ImgurMedia imgurMedia; private SimpleExoPlayer player; private DataSource.Factory dataSourceFactory; @@ -136,6 +147,19 @@ public class ViewImgurVideoFragment extends Fragment { player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(imgurMedia.getLink()))); preparePlayer(savedInstanceState); + if (activity.isUseBottomAppBar()) { + bottomAppBar.setVisibility(View.VISIBLE); + titleTextView.setText(getString(R.string.view_imgur_media_activity_video_label, + getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); + downloadImageView.setOnClickListener(view -> { + if (isDownloading) { + return; + } + isDownloading = true; + requestPermissionAndDownload(); + }); + } + return rootView; } @@ -149,25 +173,29 @@ public class ViewImgurVideoFragment extends Fragment { public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.action_download_view_imgur_video_fragment) { isDownloading = true; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (ContextCompat.checkSelfPermission(activity, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } + requestPermissionAndDownload(); + return true; + } + return false; + } + + private void requestPermissionAndDownload() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); } else { + // Permission has already been granted download(); } - return true; + } else { + download(); } - return false; } @Override @@ -282,6 +310,6 @@ public class ViewImgurVideoFragment extends Fragment { @Override public void onAttach(@NonNull Context context) { super.onAttach(context); - activity = (Activity) context; + activity = (ViewImgurMediaActivity) context; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java index c8400b31..2b79125d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java @@ -1,14 +1,21 @@ package ml.docilealligator.infinityforreddit.fragments; +import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; +import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; +import static ml.docilealligator.infinityforreddit.activities.CommentActivity.RETURN_EXTRA_COMMENT_DATA_KEY; +import static ml.docilealligator.infinityforreddit.activities.CommentActivity.WRITE_COMMENT_REQUEST_CODE; + import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.res.Configuration; import android.graphics.Canvas; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.Handler; import android.util.DisplayMetrics; import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; @@ -29,8 +36,8 @@ import androidx.core.content.ContextCompat; import androidx.core.content.res.ResourcesCompat; import androidx.core.graphics.drawable.DrawableCompat; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.ConcatAdapter; import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -75,7 +82,8 @@ import ml.docilealligator.infinityforreddit.activities.PostFilterPreferenceActiv import ml.docilealligator.infinityforreddit.activities.ReportActivity; import ml.docilealligator.infinityforreddit.activities.SubmitCrosspostActivity; import ml.docilealligator.infinityforreddit.activities.ViewPostDetailActivity; -import ml.docilealligator.infinityforreddit.adapters.CommentAndPostRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.adapters.CommentsRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.adapters.PostDetailRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostCommentSortTypeBottomSheetFragment; @@ -85,6 +93,7 @@ import ml.docilealligator.infinityforreddit.comment.FetchRemovedComment; import ml.docilealligator.infinityforreddit.comment.ParseComment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.CustomToroContainer; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.ChangeNSFWBlurEvent; import ml.docilealligator.infinityforreddit.events.ChangeNetworkStatusEvent; import ml.docilealligator.infinityforreddit.events.ChangeSpoilerBlurEvent; @@ -107,11 +116,6 @@ import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; -import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; -import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; -import static ml.docilealligator.infinityforreddit.activities.CommentActivity.RETURN_EXTRA_COMMENT_DATA_KEY; -import static ml.docilealligator.infinityforreddit.activities.CommentActivity.WRITE_COMMENT_REQUEST_CODE; - public class ViewPostDetailFragment extends Fragment implements FragmentCommunicator { public static final String EXTRA_POST_DATA = "EPD"; @@ -124,8 +128,9 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @BindView(R.id.swipe_refresh_layout_view_post_detail_fragment) SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_view_post_detail_fragment) + @BindView(R.id.post_detail_recycler_view_view_post_detail_fragment) CustomToroContainer mRecyclerView; + RecyclerView mCommentsRecyclerView; @BindView(R.id.fetch_post_info_linear_layout_view_post_detail_fragment) LinearLayout mFetchPostInfoLinearLayout; @BindView(R.id.fetch_post_info_image_view_view_post_detail_fragment) @@ -162,6 +167,9 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Named("current_account") SharedPreferences mCurrentAccountSharedPreferences; @Inject + @Named("post_details") + SharedPreferences mPostDetailsSharedPreferences; + @Inject CustomThemeWrapper mCustomThemeWrapper; @Inject ExoCreator mExoCreator; @@ -210,9 +218,11 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic private boolean mLockFab; private boolean mSwipeUpToHideFab; private boolean mExpandChildren; + private boolean mSeparatePostAndComments = false; private int mWindowWidth; - private LinearLayoutManager mLinearLayoutManager; - private CommentAndPostRecyclerViewAdapter mAdapter; + private ConcatAdapter mConcatAdapter; + private PostDetailRecyclerViewAdapter mPostAdapter; + private CommentsRecyclerViewAdapter mCommentsAdapter; private RecyclerView.SmoothScroller mSmoothScroller; private Drawable mSavedIcon; private Drawable mUnsavedIcon; @@ -253,8 +263,25 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic mSavedIcon = getMenuItemIcon(R.drawable.ic_bookmark_toolbar_24dp); mUnsavedIcon = getMenuItemIcon(R.drawable.ic_bookmark_border_toolbar_24dp); + if (getResources().getBoolean(R.bool.isTablet) || getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + mCommentsRecyclerView = rootView.findViewById(R.id.comments_recycler_view_view_post_detail_fragment); + } + if (!((mPostDetailsSharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_POST_AND_COMMENTS_IN_LANDSCAPE_MODE, true) + && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) + || (mPostDetailsSharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_POST_AND_COMMENTS_IN_PORTRAIT_MODE, false)))) { + if (mCommentsRecyclerView != null) { + mCommentsRecyclerView.setVisibility(View.GONE); + mCommentsRecyclerView = null; + } + } else { + mSeparatePostAndComments = true; + } + if (activity != null && activity.isImmersiveInterface()) { mRecyclerView.setPadding(0, 0, 0, activity.getNavBarHeight() + mRecyclerView.getPaddingBottom()); + if (mCommentsRecyclerView != null) { + mCommentsRecyclerView.setPadding(0, 0, 0, activity.getNavBarHeight() + mCommentsRecyclerView.getPaddingBottom()); + } showToast = true; } @@ -273,11 +300,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic mGlide = Glide.with(this); mLocale = getResources().getConfiguration().locale; - mLinearLayoutManager = new LinearLayoutManager(activity); - mRecyclerView.setLayoutManager(mLinearLayoutManager); - if (children != null && children.size() > 0) { - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); @@ -302,11 +326,11 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { - int visibleItemCount = mLinearLayoutManager.getChildCount(); - int totalItemCount = mLinearLayoutManager.getItemCount(); - int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + int visibleItemCount = (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().getChildCount(); + int totalItemCount = (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().getItemCount(); + int firstVisibleItemPosition = ((LinearLayoutManagerBugFixed) (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager()).findFirstVisibleItemPosition(); - if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { + if (mCommentsAdapter != null && mCommentsAdapter.getItemCount() >= 1 && (visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { fetchMoreComments(); } } @@ -320,7 +344,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } }); } else { - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); @@ -365,7 +389,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { - if (!(viewHolder instanceof CommentAndPostRecyclerViewAdapter.CommentViewHolder)) { + if (!(viewHolder instanceof CommentsRecyclerViewAdapter.CommentViewHolder)) { return makeMovementFlags(0, 0); } int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; @@ -386,9 +410,9 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { if (touchHelper != null) { touchHelper.attachToRecyclerView(null); - touchHelper.attachToRecyclerView(mRecyclerView); - if (mAdapter != null) { - mAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); + touchHelper.attachToRecyclerView((mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView)); + if (mCommentsAdapter != null) { + mCommentsAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); } } } @@ -450,7 +474,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic }); if (enableSwipeAction) { - touchHelper.attachToRecyclerView(mRecyclerView); + touchHelper.attachToRecyclerView((mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView)); } mSwipeRefreshLayout.setOnRefreshListener(() -> refresh(true, true)); @@ -517,17 +541,17 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } else { setupMenu(); - mAdapter = new CommentAndPostRecyclerViewAdapter(activity, + mPostAdapter = new PostDetailRecyclerViewAdapter(activity, this, mExecutor, mCustomThemeWrapper, mRetrofit, mOauthRetrofit, mGfycatRetrofit, mRedgifsRetrofit, mRedditDataRoomDatabase, mGlide, - mWindowWidth, mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, - isSingleCommentThreadMode, mSharedPreferences, mNsfwAndSpoilerSharedPreferences, mExoCreator, - new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { - @Override - public void updatePost(Post post) { - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - + mWindowWidth, mSeparatePostAndComments, mAccessToken, mAccountName, mPost, mLocale, + mSharedPreferences, mNsfwAndSpoilerSharedPreferences, mPostDetailsSharedPreferences, + mExoCreator, post -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition))); + mCommentsAdapter = new CommentsRecyclerViewAdapter(activity, + this, mCustomThemeWrapper, mExecutor, mRetrofit, mOauthRetrofit, + mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, + isSingleCommentThreadMode, mSharedPreferences, + new CommentsRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { @Override public void retryFetchingComments() { fetchCommentsRespectRecommendedSort(false); @@ -541,7 +565,13 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic fetchMoreComments(); } }); - mRecyclerView.setAdapter(mAdapter); + if (mCommentsRecyclerView != null) { + mRecyclerView.setAdapter(mPostAdapter); + mCommentsRecyclerView.setAdapter(mCommentsAdapter); + } else { + mConcatAdapter = new ConcatAdapter(mPostAdapter, mCommentsAdapter); + mRecyclerView.setAdapter(mConcatAdapter); + } if (comments == null) { fetchCommentsRespectRecommendedSort(false); @@ -552,7 +582,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } else if (isFetchingComments) { fetchCommentsRespectRecommendedSort(false); } else { - mAdapter.addComments(comments, hasMoreChildren); + mCommentsAdapter.addComments(comments, hasMoreChildren); if (isLoadingMoreChildren) { isLoadingMoreChildren = false; fetchMoreComments(); @@ -561,7 +591,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } } - mRecyclerView.setCacheManager(mAdapter); + mRecyclerView.setCacheManager(mPostAdapter); mRecyclerView.setPlayerInitializer(order -> { VolumeInfo volumeInfo = new VolumeInfo(true, 0f); return new PlaybackInfo(INDEX_UNSET, TIME_UNSET, volumeInfo); @@ -661,28 +691,28 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } public void addComment(Comment comment) { - if (mAdapter != null) { - mAdapter.addComment(comment); + if (mCommentsAdapter != null) { + mCommentsAdapter.addComment(comment); } } public void addChildComment(Comment comment, String parentFullname, int parentPosition) { - if (mAdapter != null) { - mAdapter.addChildComment(comment, parentFullname, parentPosition); + if (mCommentsAdapter != null) { + mCommentsAdapter.addChildComment(comment, parentFullname, parentPosition); } } public void editComment(String commentAuthor, String commentContentMarkdown, int position) { - if (mAdapter != null) { - mAdapter.editComment(commentAuthor, + if (mCommentsAdapter != null) { + mCommentsAdapter.editComment(commentAuthor, commentContentMarkdown, position); } } public void awardGiven(String awardsHTML, int awardCount, int position) { - if (mAdapter != null) { - mAdapter.giveAward(awardsHTML, awardCount, position); + if (mCommentsAdapter != null) { + mCommentsAdapter.giveAward(awardsHTML, awardCount, position); } } @@ -728,14 +758,70 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } public void goToTop() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + ((LinearLayoutManagerBugFixed) mRecyclerView.getLayoutManager()).scrollToPositionWithOffset(0, 0); + if (mCommentsRecyclerView != null) { + ((LinearLayoutManagerBugFixed) mCommentsRecyclerView.getLayoutManager()).scrollToPositionWithOffset(0, 0); } } public void saveComment(int position, boolean isSaved) { - if (mAdapter != null) { - mAdapter.setSaveComment(position, isSaved); + if (mCommentsAdapter != null) { + mCommentsAdapter.setSaveComment(position, isSaved); + } + } + + public void searchComment(String query, boolean searchNextComment) { + if (mCommentsAdapter != null) { + ArrayList<Comment> visibleComments = mCommentsAdapter.getVisibleComments(); + int currentSearchIndex = mCommentsAdapter.getSearchCommentIndex(); + if (currentSearchIndex >= 0) { + mCommentsAdapter.notifyItemChanged(currentSearchIndex); + } + if (visibleComments != null) { + if (searchNextComment) { + for (int i = currentSearchIndex + 1; i < visibleComments.size(); i++) { + if (visibleComments.get(i).getCommentRawText() != null && + visibleComments.get(i).getCommentRawText().toLowerCase().contains(query.toLowerCase())) { + if (mCommentsAdapter != null) { + mCommentsAdapter.highlightSearchResult(i); + mCommentsAdapter.notifyItemChanged(i); + if (mCommentsRecyclerView == null) { + mRecyclerView.scrollToPosition(i + 1); + } else { + mCommentsRecyclerView.scrollToPosition(i); + } + } + return; + } + } + + return; + } else { + for (int i = currentSearchIndex - 1; i >= 0; i--) { + if (visibleComments.get(i).getCommentRawText() !=null && + visibleComments.get(i).getCommentRawText().toLowerCase().contains(query.toLowerCase())) { + if (mCommentsAdapter != null) { + mCommentsAdapter.highlightSearchResult(i); + mCommentsAdapter.notifyItemChanged(i); + if (mCommentsRecyclerView == null) { + mRecyclerView.scrollToPosition(i + 1); + } else { + mCommentsRecyclerView.scrollToPosition(i); + } + } + return; + } + } + + return; + } + } + } + } + + public void resetSearchCommentIndex() { + if (mCommentsAdapter != null) { + mCommentsAdapter.resetCommentSearchIndex(); } } @@ -752,7 +838,11 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { int itemId = item.getItemId(); - if (itemId == R.id.action_refresh_view_post_detail_fragment) { + if (itemId == R.id.action_search_view_post_detail_fragment) { + if (activity.toggleSearchPanelVisibility() && mCommentsAdapter != null) { + mCommentsAdapter.resetCommentSearchIndex(); + } + } else if (itemId == R.id.action_refresh_view_post_detail_fragment) { refresh(true, true); return true; } else if (itemId == R.id.action_comment_view_post_detail_fragment) { @@ -1000,7 +1090,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onResume() { super.onResume(); - if (mAdapter != null && mRecyclerView != null) { + if (mRecyclerView != null) { mRecyclerView.onWindowVisibilityChanged(View.VISIBLE); } } @@ -1008,7 +1098,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onPause() { super.onPause(); - if (mAdapter != null && mRecyclerView != null) { + if (mRecyclerView != null) { mRecyclerView.onWindowVisibilityChanged(View.GONE); } } @@ -1016,7 +1106,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - comments = mAdapter == null ? null : mAdapter.getVisibleComments(); + comments = mCommentsAdapter == null ? null : mCommentsAdapter.getVisibleComments(); Bridge.saveInstanceState(this, outState); } @@ -1079,25 +1169,27 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic mSwipeRefreshLayout.setRefreshing(false); if (response.isSuccessful()) { - ParsePost.parsePost(response.body(), new ParsePost.ParsePostListener() { + ParsePost.parsePost(mExecutor, new Handler(), response.body(), new ParsePost.ParsePostListener() { @Override public void onParsePostSuccess(Post post) { mPost = post; setupMenu(); - mAdapter = new CommentAndPostRecyclerViewAdapter(activity, - ViewPostDetailFragment.this, mExecutor, mCustomThemeWrapper, mRetrofit, mOauthRetrofit, mGfycatRetrofit, - mRedgifsRetrofit, mRedditDataRoomDatabase, mGlide, - mWindowWidth, mAccessToken, mAccountName, mPost, mLocale, + mPostAdapter = new PostDetailRecyclerViewAdapter(activity, + ViewPostDetailFragment.this, mExecutor, mCustomThemeWrapper, + mRetrofit, mOauthRetrofit, mGfycatRetrofit, mRedgifsRetrofit, + mRedditDataRoomDatabase, mGlide, mWindowWidth, mSeparatePostAndComments, + mAccessToken, mAccountName, mPost, mLocale, mSharedPreferences, + mNsfwAndSpoilerSharedPreferences, mPostDetailsSharedPreferences, + mExoCreator, + post1 -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition))); + + mCommentsAdapter = new CommentsRecyclerViewAdapter(activity, + ViewPostDetailFragment.this, mCustomThemeWrapper, mExecutor, + mRetrofit, mOauthRetrofit, mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences, - mNsfwAndSpoilerSharedPreferences, mExoCreator, - new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { - @Override - public void updatePost(Post post) { - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - + new CommentsRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { @Override public void retryFetchingComments() { fetchCommentsRespectRecommendedSort(false); @@ -1111,23 +1203,29 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic fetchMoreComments(); } }); - mRecyclerView.setAdapter(mAdapter); + if (mCommentsRecyclerView != null) { + mRecyclerView.setAdapter(mPostAdapter); + mCommentsRecyclerView.setAdapter(mCommentsAdapter); + } else { + mConcatAdapter = new ConcatAdapter(mPostAdapter, mCommentsAdapter); + mRecyclerView.setAdapter(mConcatAdapter); + } if (mRespectSubredditRecommendedSortType) { fetchCommentsRespectRecommendedSort(false); } else { - ParseComment.parseComment(response.body(), new ArrayList<>(), mLocale, + ParseComment.parseComment(mExecutor, new Handler(), response.body(), new ArrayList<>(), mExpandChildren, new ParseComment.ParseCommentListener() { @Override public void onParseCommentSuccess(ArrayList<Comment> expandedComments, String parentId, ArrayList<String> moreChildrenFullnames) { ViewPostDetailFragment.this.children = moreChildrenFullnames; hasMoreChildren = children.size() != 0; - mAdapter.addComments(expandedComments, hasMoreChildren); + mCommentsAdapter.addComments(expandedComments, hasMoreChildren); if (children.size() > 0) { - mRecyclerView.clearOnScrollListeners(); - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).clearOnScrollListeners(); + (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); @@ -1152,9 +1250,9 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { - int visibleItemCount = mLinearLayoutManager.getChildCount(); - int totalItemCount = mLinearLayoutManager.getItemCount(); - int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + int visibleItemCount = (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().getChildCount(); + int totalItemCount = (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().getItemCount(); + int firstVisibleItemPosition = ((LinearLayoutManagerBugFixed) (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager()).findFirstVisibleItemPosition(); if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { fetchMoreComments(); @@ -1174,7 +1272,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onParseCommentFailed() { - mAdapter.initiallyLoadCommentsFailed(); + mCommentsAdapter.initiallyLoadCommentsFailed(); } }); } @@ -1236,15 +1334,15 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic private void fetchComments(boolean changeRefreshState, boolean checkSortState, String sortType) { isFetchingComments = true; - mAdapter.setSingleComment(mSingleCommentId, isSingleCommentThreadMode); - mAdapter.initiallyLoading(); + mCommentsAdapter.setSingleComment(mSingleCommentId, isSingleCommentThreadMode); + mCommentsAdapter.initiallyLoading(); String commentId = null; if (isSingleCommentThreadMode) { commentId = mSingleCommentId; } Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; - FetchComment.fetchComments(retrofit, mAccessToken, mPost.getId(), commentId, sortType, + FetchComment.fetchComments(mExecutor, new Handler(), retrofit, mAccessToken, mPost.getId(), commentId, sortType, mContextNumber, mExpandChildren, mLocale, new FetchComment.FetchCommentListener() { @Override public void onFetchCommentSuccess(ArrayList<Comment> expandedComments, @@ -1261,11 +1359,11 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic comments = expandedComments; hasMoreChildren = children.size() != 0; - mAdapter.addComments(expandedComments, hasMoreChildren); + mCommentsAdapter.addComments(expandedComments, hasMoreChildren); if (children.size() > 0) { - mRecyclerView.clearOnScrollListeners(); - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).clearOnScrollListeners(); + (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); @@ -1290,9 +1388,9 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { - int visibleItemCount = mLinearLayoutManager.getChildCount(); - int totalItemCount = mLinearLayoutManager.getItemCount(); - int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + int visibleItemCount = (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().getChildCount(); + int totalItemCount = (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().getItemCount(); + int firstVisibleItemPosition = ((LinearLayoutManagerBugFixed) (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager()).findFirstVisibleItemPosition(); if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { fetchMoreComments(); @@ -1326,7 +1424,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic return; } - mAdapter.initiallyLoadCommentsFailed(); + mCommentsAdapter.initiallyLoadCommentsFailed(); if (changeRefreshState) { isRefreshing = false; } @@ -1346,12 +1444,12 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic isLoadingMoreChildren = true; Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; - FetchComment.fetchMoreComment(retrofit, mAccessToken, children, mChildrenStartingIndex, - 0, mExpandChildren, mLocale, new FetchComment.FetchMoreCommentListener() { + FetchComment.fetchMoreComment(mExecutor, new Handler(), retrofit, mAccessToken, children, mChildrenStartingIndex, + 0, mExpandChildren, new FetchComment.FetchMoreCommentListener() { @Override public void onFetchMoreCommentSuccess(ArrayList<Comment> expandedComments, int childrenStartingIndex) { hasMoreChildren = childrenStartingIndex < children.size(); - mAdapter.addComments(expandedComments, hasMoreChildren); + mCommentsAdapter.addComments(expandedComments, hasMoreChildren); mChildrenStartingIndex = childrenStartingIndex; isLoadingMoreChildren = false; loadMoreChildrenSuccess = true; @@ -1361,13 +1459,13 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic public void onFetchMoreCommentFailed() { isLoadingMoreChildren = false; loadMoreChildrenSuccess = false; - mAdapter.loadMoreCommentsFailed(); + mCommentsAdapter.loadMoreCommentsFailed(); } }); } public void refresh(boolean fetchPost, boolean fetchComments) { - if (mAdapter != null && !isRefreshing) { + if (mPostAdapter != null && !isRefreshing) { isRefreshing = true; mChildrenStartingIndex = 0; @@ -1385,12 +1483,12 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } else { retrofit = mOauthRetrofit; } - FetchPost.fetchPost(retrofit, mPost.getId(), mAccessToken, + FetchPost.fetchPost(mExecutor, new Handler(), retrofit, mPost.getId(), mAccessToken, new FetchPost.FetchPostListener() { @Override public void fetchPostSuccess(Post post) { mPost = post; - mAdapter.updatePost(mPost); + mPostAdapter.updatePost(mPost); EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); isRefreshing = false; setupMenu(); @@ -1584,7 +1682,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void deleteSuccess() { Toast.makeText(activity, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); - mAdapter.deleteComment(position); + mCommentsAdapter.deleteComment(position); } @Override @@ -1604,7 +1702,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic new FetchRemovedComment.FetchRemovedCommentListener() { @Override public void fetchSuccess(Comment comment) { - mAdapter.editComment(comment.getAuthor(), comment.getCommentMarkdown(), position); + mCommentsAdapter.editComment(comment.getAuthor(), comment.getCommentMarkdown(), position); } @Override @@ -1622,41 +1720,33 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } public void scrollToNextParentComment() { - if (mLinearLayoutManager != null) { - int currentPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - if (mAdapter != null) { - int nextParentPosition = mAdapter.getNextParentCommentPosition(currentPosition); - if (nextParentPosition < 0) { - return; - } - mSmoothScroller.setTargetPosition(nextParentPosition); - if (mLinearLayoutManager != null) { - mIsSmoothScrolling = true; - mLinearLayoutManager.startSmoothScroll(mSmoothScroller); - } + int currentPosition = ((LinearLayoutManagerBugFixed) (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager()).findFirstVisibleItemPosition(); + if (mCommentsAdapter != null) { + int nextParentPosition = mCommentsAdapter.getNextParentCommentPosition(mCommentsRecyclerView == null ? currentPosition - 1 : currentPosition); + if (nextParentPosition < 0) { + return; } + mSmoothScroller.setTargetPosition(mCommentsRecyclerView == null ? nextParentPosition + 1 : nextParentPosition); + mIsSmoothScrolling = true; + (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().startSmoothScroll(mSmoothScroller); } } public void scrollToPreviousParentComment() { - if (mLinearLayoutManager != null) { - int currentPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - if (mAdapter != null) { - int nextParentPosition = mAdapter.getPreviousParentCommentPosition(currentPosition); - if (nextParentPosition < 0) { - return; - } - mSmoothScroller.setTargetPosition(nextParentPosition); - if (mLinearLayoutManager != null) { - mIsSmoothScrolling = true; - mLinearLayoutManager.startSmoothScroll(mSmoothScroller); - } + int currentPosition = ((LinearLayoutManagerBugFixed) (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager()).findFirstVisibleItemPosition(); + if (mCommentsAdapter != null) { + int previousParentPosition = mCommentsAdapter.getPreviousParentCommentPosition(mCommentsRecyclerView == null ? currentPosition - 1 : currentPosition); + if (previousParentPosition < 0) { + return; } + mSmoothScroller.setTargetPosition(mCommentsRecyclerView == null ? previousParentPosition + 1 : previousParentPosition); + mIsSmoothScrolling = true; + (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().startSmoothScroll(mSmoothScroller); } } public void delayTransition() { - TransitionManager.beginDelayedTransition(mRecyclerView, new AutoTransition()); + TransitionManager.beginDelayedTransition((mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView), new AutoTransition()); } public void showRemovedPost() { @@ -1668,7 +1758,9 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void fetchSuccess(Post post) { mPost = post; - mAdapter.updatePost(post); + if (mPostAdapter != null) { + mPostAdapter.updatePost(post); + } } @Override @@ -1697,56 +1789,75 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic mMenu.findItem(R.id.action_save_view_post_detail_fragment).setIcon(mUnsavedIcon); } } - mAdapter.updatePost(mPost); + if (mPostAdapter != null) { + mPostAdapter.updatePost(mPost); + } } } @Subscribe public void onChangeNSFWBlurEvent(ChangeNSFWBlurEvent event) { - mAdapter.setBlurNsfwAndDoNotBlurNsfwInNsfwSubreddits(event.needBlurNSFW, event.doNotBlurNsfwInNsfwSubreddits); - refreshAdapter(); + if (mPostAdapter != null) { + mPostAdapter.setBlurNsfwAndDoNotBlurNsfwInNsfwSubreddits(event.needBlurNSFW, event.doNotBlurNsfwInNsfwSubreddits); + } + if (mCommentsRecyclerView != null) { + refreshAdapter(mRecyclerView, mConcatAdapter); + } else { + refreshAdapter(mRecyclerView, mPostAdapter); + } } @Subscribe public void onChangeSpoilerBlurEvent(ChangeSpoilerBlurEvent event) { - mAdapter.setBlurSpoiler(event.needBlurSpoiler); - refreshAdapter(); + if (mPostAdapter != null) { + mPostAdapter.setBlurSpoiler(event.needBlurSpoiler); + } + if (mCommentsRecyclerView != null) { + refreshAdapter(mRecyclerView, mConcatAdapter); + } else { + refreshAdapter(mRecyclerView, mPostAdapter); + } } - private void refreshAdapter() { + private void refreshAdapter(RecyclerView recyclerView, RecyclerView.Adapter<RecyclerView.ViewHolder> adapter) { int previousPosition = -1; - if (mLinearLayoutManager != null) { - previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + if (recyclerView.getLayoutManager() != null) { + previousPosition = ((LinearLayoutManagerBugFixed) recyclerView.getLayoutManager()).findFirstVisibleItemPosition(); } - RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager(); - mRecyclerView.setAdapter(null); - mRecyclerView.setLayoutManager(null); - mRecyclerView.setAdapter(mAdapter); - mRecyclerView.setLayoutManager(layoutManager); + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + recyclerView.setAdapter(null); + recyclerView.setLayoutManager(null); + recyclerView.setAdapter(adapter); + recyclerView.setLayoutManager(layoutManager); if (previousPosition > 0) { - mRecyclerView.scrollToPosition(previousPosition); + recyclerView.scrollToPosition(previousPosition); } } @Subscribe public void onChangeNetworkStatusEvent(ChangeNetworkStatusEvent changeNetworkStatusEvent) { - if (mAdapter != null) { + if (mPostAdapter != null) { String autoplay = mSharedPreferences.getString(SharedPreferencesUtils.VIDEO_AUTOPLAY, SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_NEVER); String dataSavingMode = mSharedPreferences.getString(SharedPreferencesUtils.DATA_SAVING_MODE, SharedPreferencesUtils.DATA_SAVING_MODE_OFF); boolean stateChanged = false; if (autoplay.equals(SharedPreferencesUtils.VIDEO_AUTOPLAY_VALUE_ON_WIFI)) { - mAdapter.setAutoplay(changeNetworkStatusEvent.connectedNetwork == Utils.NETWORK_TYPE_WIFI); + mPostAdapter.setAutoplay(changeNetworkStatusEvent.connectedNetwork == Utils.NETWORK_TYPE_WIFI); stateChanged = true; } if (dataSavingMode.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA)) { - mAdapter.setDataSavingMode(changeNetworkStatusEvent.connectedNetwork == Utils.NETWORK_TYPE_CELLULAR); + mPostAdapter.setDataSavingMode(changeNetworkStatusEvent.connectedNetwork == Utils.NETWORK_TYPE_CELLULAR); stateChanged = true; } if (stateChanged) { - refreshAdapter(); + if (mCommentsRecyclerView == null) { + refreshAdapter(mRecyclerView, mConcatAdapter); + } else { + refreshAdapter(mRecyclerView, mPostAdapter); + refreshAdapter(mCommentsRecyclerView, mCommentsAdapter); + } } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRPANBroadcastFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRPANBroadcastFragment.java new file mode 100644 index 00000000..8c0c2f57 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRPANBroadcastFragment.java @@ -0,0 +1,404 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.exoplayer2.ExoPlaybackException; +import com.google.android.exoplayer2.ExoPlayerFactory; +import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.source.BehindLiveWindowException; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.source.hls.HlsMediaSource; +import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.trackselection.TrackSelection; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.ui.PlayerView; +import com.google.android.exoplayer2.ui.TrackSelectionDialogBuilder; +import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; +import com.google.android.exoplayer2.util.Util; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RPANBroadcast; +import ml.docilealligator.infinityforreddit.RPANComment; +import ml.docilealligator.infinityforreddit.adapters.RPANCommentStreamRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import retrofit2.Retrofit; + +public class ViewRPANBroadcastFragment extends Fragment { + + public static final String EXTRA_RPAN_BROADCAST = "ERB"; + private static final String IS_MUTE_STATE = "IMS"; + + @BindView(R.id.constraint_layout_exo_rpan_broadcast_playback_control_view) + ConstraintLayout constraintLayout; + @BindView(R.id.player_view_view_rpan_broadcast_fragment) + PlayerView playerView; + @BindView(R.id.subreddit_icon_image_view_exo_rpan_broadcast_playback_control_view) + ImageView subredditIconImageView; + @BindView(R.id.subreddit_name_text_view_exo_rpan_broadcast_playback_control_view) + TextView subredditNameTextView; + @BindView(R.id.username_text_view_exo_rpan_broadcast_playback_control_view) + TextView usernameTextView; + @BindView(R.id.title_text_view_exo_rpan_broadcast_playback_control_view) + TextView titleTextView; + @BindView(R.id.recycler_view_exo_rpan_broadcast_playback_control_view) + RecyclerView recyclerView; + @BindView(R.id.mute_exo_rpan_broadcast_playback_control_view) + ImageButton muteButton; + @BindView(R.id.hd_exo_rpan_broadcast_playback_control_view) + ImageButton hdButton; + @Inject + @Named("strapi") + Retrofit mStrapiRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences mCurrentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + @Inject + @Named("rpan") + OkHttpClient okHttpClient; + private AppCompatActivity mActivity; + private RPANBroadcast rpanBroadcast; + private SimpleExoPlayer player; + private DefaultTrackSelector trackSelector; + private DataSource.Factory dataSourceFactory; + private Handler handler; + private RPANCommentStreamRecyclerViewAdapter adapter; + private WebSocket webSocket; + + private boolean wasPlaying; + private boolean isMute = false; + private long resumePosition = -1; + private boolean isDataSavingMode; + + public ViewRPANBroadcastFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_view_rpan_broadcast, container, false); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + rpanBroadcast = getArguments().getParcelable(EXTRA_RPAN_BROADCAST); + + if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) { + //Set player controller bottom margin in order to display it above the navbar + int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + //LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) constraintLayout.getLayoutParams(); + params.bottomMargin = getResources().getDimensionPixelSize(resourceId); + } else { + //Set player controller right margin in order to display it above the navbar + int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + //LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) constraintLayout.getLayoutParams(); + params.rightMargin = getResources().getDimensionPixelSize(resourceId); + } + + playerView.setControllerVisibilityListener(visibility -> { + switch (visibility) { + case View.GONE: + mActivity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE); + playerView.setControllerShowTimeoutMs(0); + break; + case View.VISIBLE: + mActivity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } + }); + + TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(); + trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); + player = ExoPlayerFactory.newSimpleInstance(mActivity, trackSelector); + playerView.setPlayer(player); + + wasPlaying = true; + + boolean muteVideo = mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_VIDEO, false) || + (mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_NSFW_VIDEO, false) && rpanBroadcast.rpanPost.isNsfw); + + if (savedInstanceState != null) { + isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); + if (isMute) { + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } else { + player.setVolume(1f); + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } + } else if (muteVideo) { + isMute = true; + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } else { + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } + + player.addListener(new Player.EventListener() { + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + if (!trackGroups.isEmpty()) { + if (isDataSavingMode) { + trackSelector.setParameters( + trackSelector.buildUponParameters() + .setMaxVideoSize(720, 720)); + } + + hdButton.setVisibility(View.VISIBLE); + hdButton.setOnClickListener(view -> { + TrackSelectionDialogBuilder build = new TrackSelectionDialogBuilder(mActivity, + getString(R.string.select_video_quality), trackSelector, 0); + build.setShowDisableOption(true); + build.setAllowAdaptiveSelections(false); + build.build().show(); + }); + + for (int i = 0; i < trackGroups.length; i++) { + String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; + if (mimeType != null && mimeType.contains("audio")) { + muteButton.setVisibility(View.VISIBLE); + muteButton.setOnClickListener(view -> { + if (isMute) { + isMute = false; + player.setVolume(1f); + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } else { + isMute = true; + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } + }); + break; + } + } + } else { + muteButton.setVisibility(View.GONE); + } + } + }); + + Glide.with(mActivity).load(rpanBroadcast.rpanPost.subredditIconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(Glide.with(mActivity).load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(subredditIconImageView); + subredditNameTextView.setText(rpanBroadcast.rpanPost.subredditName); + usernameTextView.setText(rpanBroadcast.rpanPost.username); + titleTextView.setText(rpanBroadcast.rpanPost.title); + + recyclerView.setOnTouchListener(new View.OnTouchListener() { + float x1; + float x2; + float y1; + float y2; + + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + switch (motionEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + x1 = motionEvent.getX(); + y1 = motionEvent.getY(); + return true; + case MotionEvent.ACTION_UP: + x2 = motionEvent.getX(); + y2 = motionEvent.getY(); + + if (x1 == x2 && y1 == y2) { + playerView.hideController(); + } + + return true; + } + + return false; + } + }); + adapter = new RPANCommentStreamRecyclerViewAdapter(mActivity); + recyclerView.setAdapter(adapter); + + handler = new Handler(); + + return rootView; + } + + private boolean isBehindLiveWindow(ExoPlaybackException e) { + if (e.type != ExoPlaybackException.TYPE_SOURCE) { + return false; + } + Throwable cause = e.getSourceException(); + while (cause != null) { + if (cause instanceof BehindLiveWindowException) { + return true; + } + cause = cause.getCause(); + } + return false; + } + + private void parseComment(String commentJson) { + mExecutor.execute(() -> { + try { + JSONObject commentObject = new JSONObject(commentJson); + if (commentObject.getString(JSONUtils.TYPE_KEY).equals("new_comment")) { + JSONObject payload = commentObject.getJSONObject(JSONUtils.PAYLOAD_KEY); + RPANComment rpanComment = new RPANComment( + payload.getString(JSONUtils.AUTHOR_KEY), + payload.getString(JSONUtils.AUTHOR_ICON_IMAGE), + payload.getString(JSONUtils.BODY_KEY), + payload.getLong(JSONUtils.CREATED_UTC_KEY)); + + handler.post(() -> { + LinearLayoutManagerBugFixed manager = ((LinearLayoutManagerBugFixed) recyclerView.getLayoutManager()); + boolean shouldScrollToBottom = false; + if (manager != null) { + int lastPosition = manager.findLastCompletelyVisibleItemPosition(); + int currentItemCount = adapter.getItemCount(); + if (currentItemCount > 0 && lastPosition == currentItemCount - 1) { + shouldScrollToBottom = true; + } + } + adapter.addRPANComment(rpanComment); + if (shouldScrollToBottom) { + recyclerView.smoothScrollToPosition(adapter.getItemCount() - 1); + } + }); + } + } catch (JSONException e) { + e.printStackTrace(); + } + }); + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_MUTE_STATE, isMute); + } + + @Override + public void onResume() { + super.onResume(); + if (dataSourceFactory == null) { + dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(mActivity, "Infinity")); + // Prepare the player with the source. + player.prepare(new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(rpanBroadcast.rpanStream.hlsUrl))); + player.setRepeatMode(Player.REPEAT_MODE_ALL); + if (resumePosition > 0) { + player.seekTo(resumePosition); + } + } + + if (wasPlaying) { + player.setPlayWhenReady(true); + } + + if (webSocket == null) { + Request request = new Request.Builder().url(rpanBroadcast.rpanPost.liveCommentsWebsocketUrl).build(); + CommentStreamWebSocketListener listener = new CommentStreamWebSocketListener(this::parseComment); + webSocket = okHttpClient.newWebSocket(request, listener); + } + } + + @Override + public void onPause() { + super.onPause(); + wasPlaying = player.getPlayWhenReady(); + player.setPlayWhenReady(false); + } + + @Override + public void onDestroy() { + super.onDestroy(); + player.seekToDefaultPosition(); + player.stop(true); + player.release(); + + if (webSocket != null) { + webSocket.cancel(); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (AppCompatActivity) context; + } + + private static class CommentStreamWebSocketListener extends WebSocketListener { + MessageReceivedListener messageReceivedListener; + + CommentStreamWebSocketListener(MessageReceivedListener messageReceivedListener) { + this.messageReceivedListener = messageReceivedListener; + } + + @Override + public void onMessage(@NonNull WebSocket webSocket, @NonNull String text) { + messageReceivedListener.onMessage(text); + } + + interface MessageReceivedListener { + void onMessage(String text); + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java index 75e3b2c6..cee6d404 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java @@ -16,8 +16,10 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -41,6 +43,7 @@ import com.github.piasy.biv.loader.ImageLoader; import com.github.piasy.biv.loader.glide.GlideImageLoader; import com.github.piasy.biv.view.BigImageView; import com.github.piasy.biv.view.GlideImageViewFactory; +import com.google.android.material.bottomappbar.BottomAppBar; import java.io.File; import java.util.concurrent.Executor; @@ -64,6 +67,8 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { public static final String EXTRA_REDDIT_GALLERY_MEDIA = "ERGM"; public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + public static final String EXTRA_INDEX = "EI"; + public static final String EXTRA_MEDIA_COUNT = "EMC"; private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; @BindView(R.id.progress_bar_view_reddit_gallery_image_or_gif_fragment) @@ -72,6 +77,16 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { BigImageView imageView; @BindView(R.id.load_image_error_linear_layout_view_reddit_gallery_image_or_gif_fragment) LinearLayout errorLinearLayout; + @BindView(R.id.bottom_navigation_view_reddit_gallery_image_or_gif_fragment) + BottomAppBar bottomAppBar; + @BindView(R.id.title_text_view_view_reddit_gallery_image_or_gif_fragment) + TextView titleTextView; + @BindView(R.id.download_image_view_view_reddit_gallery_image_or_gif_fragment) + ImageView downloadImageView; + @BindView(R.id.share_image_view_view_reddit_gallery_image_or_gif_fragment) + ImageView shareImageView; + @BindView(R.id.wallpaper_image_view_view_reddit_gallery_image_or_gif_fragment) + ImageView wallpaperImageView; @Inject Executor mExecutor; @@ -192,6 +207,9 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); isActionBarHidden = false; + if (activity.isUseBottomAppBar()) { + bottomAppBar.setVisibility(View.VISIBLE); + } } else { activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE @@ -201,6 +219,9 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE); isActionBarHidden = true; + if (activity.isUseBottomAppBar()) { + bottomAppBar.setVisibility(View.GONE); + } } }); @@ -210,6 +231,34 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { loadImage(); }); + if (activity.isUseBottomAppBar()) { + bottomAppBar.setVisibility(View.VISIBLE); + if (media.mediaType == Post.Gallery.TYPE_GIF) { + titleTextView.setText(getString(R.string.view_reddit_gallery_activity_gif_label, + getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); + } else { + titleTextView.setText(getString(R.string.view_reddit_gallery_activity_image_label, + getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); + } + downloadImageView.setOnClickListener(view -> { + if (isDownloading) { + return; + } + isDownloading = true; + requestPermissionAndDownload(); + }); + shareImageView.setOnClickListener(view -> { + if (media.mediaType == Post.Gallery.TYPE_GIF) { + shareGif(); + } else { + shareImage(); + } + }); + wallpaperImageView.setOnClickListener(view -> { + setWallpaper(); + }); + } + return rootView; } @@ -225,53 +274,46 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.action_download_view_reddit_gallery_image_or_gif_fragment: - if (isDownloading) { - return false; - } + int itemId = item.getItemId(); + if (itemId == R.id.action_download_view_reddit_gallery_image_or_gif_fragment) { + if (isDownloading) { + return false; + } + isDownloading = true; + requestPermissionAndDownload(); + return true; + } else if (itemId == R.id.action_share_view_reddit_gallery_image_or_gif_fragment) { + if (media.mediaType == Post.Gallery.TYPE_GIF) { + shareGif(); + } else { + shareImage(); + } + return true; + } else if (itemId == R.id.action_set_wallpaper_view_reddit_gallery_image_or_gif_fragment) { + setWallpaper(); + return true; + } - isDownloading = true; + return false; + } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (ContextCompat.checkSelfPermission(activity, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } + private void requestPermissionAndDownload() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { - return true; - case R.id.action_share_view_reddit_gallery_image_or_gif_fragment: - if (media.mediaType == Post.Gallery.TYPE_GIF) { - shareGif(); - } else { - shareImage(); - } - return true; - case R.id.action_set_wallpaper_view_reddit_gallery_image_or_gif_fragment: - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(SetAsWallpaperBottomSheetFragment.EXTRA_VIEW_PAGER_POSITION, activity.getCurrentPagePosition()); - setAsWallpaperBottomSheetFragment.setArguments(bundle); - setAsWallpaperBottomSheetFragment.show(activity.getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); - } else { - ((SetAsWallpaperCallback) activity).setToBoth(activity.getCurrentPagePosition()); - } - return true; + // Permission is not granted + // No explanation needed; request the permission + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); } - - return false; } private void download() { @@ -366,6 +408,20 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { }).submit(); } + private void setWallpaper() { + if (media.mediaType != Post.Gallery.TYPE_GIF) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(SetAsWallpaperBottomSheetFragment.EXTRA_VIEW_PAGER_POSITION, activity.getCurrentPagePosition()); + setAsWallpaperBottomSheetFragment.setArguments(bundle); + setAsWallpaperBottomSheetFragment.show(activity.getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); + } else { + ((SetAsWallpaperCallback) activity).setToBoth(activity.getCurrentPagePosition()); + } + } + } + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { @@ -385,8 +441,21 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { } @Override - public void onDestroy() { - super.onDestroy(); + public void onResume() { + super.onResume(); + SubsamplingScaleImageView ssiv = imageView.getSSIV(); + if (ssiv == null || !ssiv.hasImage()) { + imageView.showImage(Uri.parse(media.url)); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); BigImageViewer.imageLoader().cancelAll(); + SubsamplingScaleImageView subsamplingScaleImageView = imageView.getSSIV(); + if (subsamplingScaleImageView != null) { + subsamplingScaleImageView.recycle(); + } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryVideoFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryVideoFragment.java index a1258ce2..de1e5566 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryVideoFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryVideoFragment.java @@ -1,7 +1,6 @@ package ml.docilealligator.infinityforreddit.fragments; import android.Manifest; -import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -18,7 +17,9 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; +import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -39,6 +40,7 @@ import com.google.android.exoplayer2.ui.PlayerView; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.util.Util; +import com.google.android.material.bottomappbar.BottomAppBar; import javax.inject.Inject; import javax.inject.Named; @@ -46,8 +48,9 @@ import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.activities.ViewRedditGalleryActivity; +import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.services.DownloadMediaService; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -57,12 +60,20 @@ public class ViewRedditGalleryVideoFragment extends Fragment { public static final String EXTRA_SUBREDDIT_NAME = "ESN"; private static final String IS_MUTE_STATE = "IMS"; private static final String POSITION_STATE = "PS"; + public static final String EXTRA_INDEX = "EI"; + public static final String EXTRA_MEDIA_COUNT = "EMC"; private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; @BindView(R.id.player_view_view_reddit_gallery_video_fragment) PlayerView videoPlayerView; @BindView(R.id.mute_exo_playback_control_view) ImageButton muteButton; - private Activity activity; + @BindView(R.id.bottom_navigation_exo_playback_control_view) + BottomAppBar bottomAppBar; + @BindView(R.id.title_text_view_exo_playback_control_view) + TextView titleTextView; + @BindView(R.id.download_image_view_exo_playback_control_view) + ImageView downloadImageView; + private ViewRedditGalleryActivity activity; private Post.Gallery galleryVideo; private String subredditName; private SimpleExoPlayer player; @@ -139,6 +150,19 @@ public class ViewRedditGalleryVideoFragment extends Fragment { player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(galleryVideo.url))); preparePlayer(savedInstanceState); + if (activity.isUseBottomAppBar()) { + bottomAppBar.setVisibility(View.VISIBLE); + titleTextView.setText(getString(R.string.view_reddit_gallery_activity_video_label, + getArguments().getInt(EXTRA_INDEX) + 1, getArguments().getInt(EXTRA_MEDIA_COUNT))); + downloadImageView.setOnClickListener(view -> { + if (isDownloading) { + return; + } + isDownloading = true; + requestPermissionAndDownload(); + }); + } + return rootView; } @@ -152,25 +176,29 @@ public class ViewRedditGalleryVideoFragment extends Fragment { public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.action_download_view_reddit_gallery_video_fragment) { isDownloading = true; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (ContextCompat.checkSelfPermission(activity, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } + requestPermissionAndDownload(); + return true; + } + return false; + } + + private void requestPermissionAndDownload() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); } else { + // Permission has already been granted download(); } - return true; + } else { + download(); } - return false; } @Override @@ -286,6 +314,6 @@ public class ViewRedditGalleryVideoFragment extends Fragment { @Override public void onAttach(@NonNull Context context) { super.onAttach(context); - activity = (Activity) context; + activity = (ViewRedditGalleryActivity) context; } }
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchPost.java index 6566b623..9d5f0445 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchPost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchPost.java @@ -1,7 +1,11 @@ package ml.docilealligator.infinityforreddit.post; +import android.os.Handler; + import androidx.annotation.NonNull; +import java.util.concurrent.Executor; + import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; @@ -10,7 +14,8 @@ import retrofit2.Response; import retrofit2.Retrofit; public class FetchPost { - public static void fetchPost(Retrofit retrofit, String id, String accessToken, FetchPostListener fetchPostListener) { + public static void fetchPost(Executor executor, Handler handler, Retrofit retrofit, String id, String accessToken, + FetchPostListener fetchPostListener) { Call<String> postCall; if (accessToken == null) { postCall = retrofit.create(RedditAPI.class).getPost(id); @@ -21,7 +26,7 @@ public class FetchPost { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePost(response.body(), new ParsePost.ParsePostListener() { + ParsePost.parsePost(executor, handler, response.body(), new ParsePost.ParsePostListener() { @Override public void onParsePostSuccess(Post post) { fetchPostListener.fetchPostSuccess(post); @@ -44,7 +49,8 @@ public class FetchPost { }); } - public static void fetchRandomPost(Retrofit retrofit, boolean isNSFW, FetchRandomPostListener fetchRandomPostListener) { + public static void fetchRandomPost(Executor executor, Handler handler, Retrofit retrofit, boolean isNSFW, + FetchRandomPostListener fetchRandomPostListener) { Call<String> call; if (isNSFW) { call = retrofit.create(RedditAPI.class).getRandomNSFWPost(); @@ -56,18 +62,18 @@ public class FetchPost { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { if (response.isSuccessful()) { - new ParsePost.ParseRandomPostAsyncTask(response.body(), isNSFW, new ParsePost.ParseRandomPostListener() { + ParsePost.parseRandomPost(executor, handler, response.body(), isNSFW, + new ParsePost.ParseRandomPostListener() { + @Override + public void onParseRandomPostSuccess(String postId, String subredditName) { + fetchRandomPostListener.fetchRandomPostSuccess(postId, subredditName); + } - @Override - public void onParseRandomPostSuccess(String postId, String subredditName) { - fetchRandomPostListener.fetchRandomPostSuccess(postId, subredditName); - } - - @Override - public void onParseRandomPostFailed() { - fetchRandomPostListener.fetchRandomPostFailed(); - } - }).execute(); + @Override + public void onParseRandomPostFailed() { + fetchRandomPostListener.fetchRandomPostFailed(); + } + }); } else { fetchRandomPostListener.fetchRandomPostFailed(); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java index 9df78a45..881fb4d8 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java @@ -1,7 +1,7 @@ package ml.docilealligator.infinityforreddit.post; import android.net.Uri; -import android.os.AsyncTask; +import android.os.Handler; import android.text.Html; import org.json.JSONArray; @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; +import java.util.concurrent.Executor; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -25,18 +26,100 @@ import ml.docilealligator.infinityforreddit.utils.Utils; */ public class ParsePost { - public static void parsePosts(String response, int nPosts, PostFilter postFilter, List<ReadPost> readPostList, + public static void parsePosts(Executor executor, Handler handler, String response, int nPosts, + PostFilter postFilter, List<ReadPost> readPostList, ParsePostsListingListener parsePostsListingListener) { - new ParsePostDataAsyncTask(response, nPosts, postFilter, readPostList, parsePostsListingListener).execute(); + executor.execute(() -> { + LinkedHashSet<Post> newPosts = new LinkedHashSet<>(); + try { + JSONObject jsonResponse = new JSONObject(response); + JSONArray allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + String lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); + + //Posts listing + int size; + if (nPosts < 0 || nPosts > allData.length()) { + size = allData.length(); + } else { + size = nPosts; + } + + HashSet<ReadPost> readPostHashSet = null; + if (readPostList != null) { + readPostHashSet = new HashSet<>(readPostList); + } + for (int i = 0; i < size; i++) { + try { + if (allData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) { + JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + Post post = parseBasicData(data); + if (readPostHashSet != null && readPostHashSet.contains(ReadPost.convertPost(post))) { + post.markAsRead(false); + } + if (PostFilter.isPostAllowed(post, postFilter)) { + newPosts.add(post); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + handler.post(() -> parsePostsListingListener.onParsePostsListingSuccess(newPosts, lastItem)); + } catch (JSONException e) { + e.printStackTrace(); + handler.post(parsePostsListingListener::onParsePostsListingFail); + } + }); } - public static void parsePost(String response, ParsePostListener parsePostListener) { + public static void parsePost(Executor executor, Handler handler, String response, ParsePostListener parsePostListener) { PostFilter postFilter = new PostFilter(); postFilter.allowNSFW = true; - new ParsePostDataAsyncTask(response, postFilter, parsePostListener).execute(); + + executor.execute(() -> { + try { + JSONArray allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + if (allData.length() == 0) { + handler.post(parsePostListener::onParsePostFail); + return; + } + JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); + Post post = parseBasicData(data); + handler.post(() -> parsePostListener.onParsePostSuccess(post)); + } catch (JSONException e) { + e.printStackTrace(); + handler.post(parsePostListener::onParsePostFail); + } + }); + } + + public static void parseRandomPost(Executor executor, Handler handler, String response, boolean isNSFW, + ParseRandomPostListener parseRandomPostListener) { + executor.execute(() -> { + try { + JSONArray postsArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + if (postsArray.length() == 0) { + handler.post(parseRandomPostListener::onParseRandomPostFailed); + } else { + JSONObject post = postsArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); + String subredditName = post.getString(JSONUtils.SUBREDDIT_KEY); + String postId; + if (isNSFW) { + postId = post.getString(JSONUtils.ID_KEY); + } else { + postId = post.getString(JSONUtils.LINK_ID_KEY).substring("t3_".length()); + } + handler.post(() -> parseRandomPostListener.onParseRandomPostSuccess(postId, subredditName)); + } + } catch (JSONException e) { + e.printStackTrace(); + handler.post(parseRandomPostListener::onParseRandomPostFailed); + } + }); } - private static Post parseBasicData(JSONObject data) throws JSONException { + public static Post parseBasicData(JSONObject data) throws JSONException { String id = data.getString(JSONUtils.ID_KEY); String fullName = data.getString(JSONUtils.NAME_KEY); String subredditName = data.getString(JSONUtils.SUBREDDIT_KEY); @@ -217,16 +300,32 @@ public class ParsePost { } post.setPreviews(previews); } else { - //No preview link post - int postType = Post.NO_PREVIEW_LINK_TYPE; - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, - postType, voteType, nComments, upvoteRatio, flair, awards, nAwards, hidden, - spoiler, nsfw, stickied, archived, locked, saved, isCrosspost); - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); + if (isVideo) { + //No preview video post + JSONObject redditVideoObject = data.getJSONObject(JSONUtils.MEDIA_KEY).getJSONObject(JSONUtils.REDDIT_VIDEO_KEY); + int postType = Post.VIDEO_TYPE; + String videoUrl = Html.fromHtml(redditVideoObject.getString(JSONUtils.HLS_URL_KEY)).toString(); + String videoDownloadUrl = redditVideoObject.getString(JSONUtils.FALLBACK_URL_KEY); + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, authorFlair, + authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType, + nComments, upvoteRatio, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, + archived, locked, saved, isCrosspost); + + post.setVideoUrl(videoUrl); + post.setVideoDownloadUrl(videoDownloadUrl); } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + //No preview link post + int postType = Post.NO_PREVIEW_LINK_TYPE; + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, + postType, voteType, nComments, upvoteRatio, flair, awards, nAwards, hidden, + spoiler, nsfw, stickied, archived, locked, saved, isCrosspost); + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + } } } } @@ -494,13 +593,11 @@ public class ParsePost { public interface ParsePostsListingListener { void onParsePostsListingSuccess(LinkedHashSet<Post> newPostData, String lastItem); - void onParsePostsListingFail(); } public interface ParsePostListener { void onParsePostSuccess(Post post); - void onParsePostFail(); } @@ -508,166 +605,4 @@ public class ParsePost { void onParseRandomPostSuccess(String postId, String subredditName); void onParseRandomPostFailed(); } - - private static class ParsePostDataAsyncTask extends AsyncTask<Void, Void, Void> { - private JSONArray allData; - private int nPosts; - private PostFilter postFilter; - private List<ReadPost> readPostList; - private ParsePostsListingListener parsePostsListingListener; - private ParsePostListener parsePostListener; - private LinkedHashSet<Post> newPosts; - private Post post; - private String lastItem; - private boolean parseFailed; - - ParsePostDataAsyncTask(String response, int nPosts, PostFilter postFilter, List<ReadPost> readPostList, - ParsePostsListingListener parsePostsListingListener) { - this.parsePostsListingListener = parsePostsListingListener; - try { - JSONObject jsonResponse = new JSONObject(response); - allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); - this.nPosts = nPosts; - this.postFilter = postFilter; - this.readPostList = readPostList; - newPosts = new LinkedHashSet<>(); - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - ParsePostDataAsyncTask(String response, PostFilter postFilter, - ParsePostListener parsePostListener) { - this.parsePostListener = parsePostListener; - try { - allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - this.postFilter = postFilter; - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - @Override - protected Void doInBackground(Void... voids) { - if (parseFailed) { - return null; - } - - if (newPosts == null) { - //Only one post - if (allData.length() == 0) { - parseFailed = true; - return null; - } - - try { - JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); - post = parseBasicData(data); - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } else { - //Posts listing - int size; - if (nPosts < 0 || nPosts > allData.length()) { - size = allData.length(); - } else { - size = nPosts; - } - - HashSet<ReadPost> readPostHashSet = null; - if (readPostList != null) { - readPostHashSet = new HashSet<>(readPostList); - } - for (int i = 0; i < size; i++) { - try { - if (allData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) { - JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - Post post = parseBasicData(data); - if (readPostHashSet != null && readPostHashSet.contains(ReadPost.convertPost(post))) { - post.markAsRead(false); - } - if (PostFilter.isPostAllowed(post, postFilter)) { - newPosts.add(post); - } - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - if (newPosts != null) { - parsePostsListingListener.onParsePostsListingSuccess(newPosts, lastItem); - } else { - parsePostListener.onParsePostSuccess(post); - } - } else { - if (parsePostsListingListener != null) { - parsePostsListingListener.onParsePostsListingFail(); - } else { - parsePostListener.onParsePostFail(); - } - } - } - } - - public static class ParseRandomPostAsyncTask extends AsyncTask<Void, Void, Void> { - - private String response; - private boolean isNSFW; - private ParseRandomPostListener parseRandomPostListener; - private String subredditName; - private String postId; - private boolean parseFailed = false; - - ParseRandomPostAsyncTask(String response, boolean isNSFW, ParseRandomPostListener parseRandomPostListener) { - this.response = response; - this.isNSFW = isNSFW; - this.parseRandomPostListener = parseRandomPostListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONArray postsArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - if (postsArray.length() == 0) { - parseFailed = true; - } else { - JSONObject post = postsArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); - subredditName = post.getString(JSONUtils.SUBREDDIT_KEY); - if (isNSFW) { - postId = post.getString(JSONUtils.ID_KEY); - } else { - postId = post.getString(JSONUtils.LINK_ID_KEY).substring("t3_".length()); - } - } - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - parseRandomPostListener.onParseRandomPostFailed(); - } else { - parseRandomPostListener.onParseRandomPostSuccess(postId, subredditName); - } - } - } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSource.java index 8c567809..57a6b5e3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSource.java @@ -1,6 +1,7 @@ package ml.docilealligator.infinityforreddit.post; import android.content.SharedPreferences; +import android.os.Handler; import androidx.annotation.NonNull; import androidx.lifecycle.MutableLiveData; @@ -9,6 +10,7 @@ import androidx.paging.PageKeyedDataSource; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; +import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.SortType; @@ -37,6 +39,8 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { public static final String USER_WHERE_SAVED = "saved"; public static final String USER_WHERE_GILDED = "gilded"; + private Executor executor; + private Handler handler; private Retrofit retrofit; private String accessToken; private String accountName; @@ -44,6 +48,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { private SharedPreferences postFeedScrolledPositionSharedPreferences; private String subredditOrUserName; private String query; + private String trendingSource; private int postType; private SortType sortType; private PostFilter postFilter; @@ -59,10 +64,12 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { private LoadParams<String> params; private LoadCallback<String, Post> callback; - PostDataSource(Retrofit retrofit, String accessToken, String accountName, + PostDataSource(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -78,10 +85,12 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { postLinkedHashSet = new LinkedHashSet<>(); } - PostDataSource(Retrofit retrofit, String accessToken, String accountName, + PostDataSource(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String path, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -118,10 +127,12 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { postLinkedHashSet = new LinkedHashSet<>(); } - PostDataSource(Retrofit retrofit, String accessToken, String accountName, + PostDataSource(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, int postType, SortType sortType, PostFilter postFilter, String where, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -139,10 +150,12 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { postLinkedHashSet = new LinkedHashSet<>(); } - PostDataSource(Retrofit retrofit, String accessToken, String accountName, + PostDataSource(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - String subredditOrUserName, String query, int postType, SortType sortType, PostFilter postFilter, - List<ReadPost> readPostList) { + String subredditOrUserName, String query, String trendingSource, int postType, + SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -150,6 +163,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; this.subredditOrUserName = subredditOrUserName; this.query = query; + this.trendingSource = trendingSource; paginationNetworkStateLiveData = new MutableLiveData<>(); initialLoadStateLiveData = new MutableLiveData<>(); hasPostLiveData = new MutableLiveData<>(); @@ -254,7 +268,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -317,7 +331,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -377,7 +391,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -451,7 +465,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -512,7 +526,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -583,7 +597,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -627,16 +641,17 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { if (subredditOrUserName == null) { if (accessToken == null) { if (sortType.getTime() != null) { - getPost = api.searchPosts(query, lastItem, sortType.getType().value, sortType.getTime().value); + getPost = api.searchPosts(query, lastItem, sortType.getType().value, sortType.getTime().value, + trendingSource); } else { - getPost = api.searchPosts(query, lastItem, sortType.getType().value); + getPost = api.searchPosts(query, lastItem, sortType.getType().value, trendingSource); } } else { if(sortType.getTime() != null) { getPost = api.searchPostsOauth(query, lastItem, sortType.getType().value, - sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + sortType.getTime().value, trendingSource, APIUtils.getOAuthHeader(accessToken)); } else { - getPost = api.searchPostsOauth(query, lastItem, sortType.getType().value, + getPost = api.searchPostsOauth(query, lastItem, sortType.getType().value, trendingSource, APIUtils.getOAuthHeader(accessToken)); } } @@ -666,7 +681,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -720,16 +735,18 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { if (subredditOrUserName == null) { if (accessToken == null) { if (sortType.getTime() != null) { - getPost = api.searchPosts(query, after, sortType.getType().value, sortType.getTime().value); + getPost = api.searchPosts(query, after, sortType.getType().value, sortType.getTime().value, + trendingSource); } else { - getPost = api.searchPosts(query, after, sortType.getType().value); + getPost = api.searchPosts(query, after, sortType.getType().value, trendingSource); } } else { if (sortType.getTime() != null) { getPost = api.searchPostsOauth(query, after, sortType.getType().value, - sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + sortType.getTime().value, trendingSource, APIUtils.getOAuthHeader(accessToken)); } else { - getPost = api.searchPostsOauth(query, after, sortType.getType().value, APIUtils.getOAuthHeader(accessToken)); + getPost = api.searchPostsOauth(query, after, sortType.getType().value, trendingSource, + APIUtils.getOAuthHeader(accessToken)); } } } else { @@ -757,7 +774,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -817,7 +834,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -888,7 +905,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, readPostList, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, readPostList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -938,7 +955,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, null, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, null, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { @@ -1002,7 +1019,7 @@ public class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, postFilter, null, + ParsePost.parsePosts(executor, handler, response.body(), -1, postFilter, null, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet<Post> newPosts, String lastItem) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSourceFactory.java index da99a508..dd8312b7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSourceFactory.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSourceFactory.java @@ -1,6 +1,7 @@ package ml.docilealligator.infinityforreddit.post; import android.content.SharedPreferences; +import android.os.Handler; import android.util.Log; import androidx.annotation.NonNull; @@ -8,13 +9,16 @@ import androidx.lifecycle.MutableLiveData; import androidx.paging.DataSource; import java.util.List; +import java.util.concurrent.Executor; -import ml.docilealligator.infinityforreddit.postfilter.PostFilter; import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.postfilter.PostFilter; import ml.docilealligator.infinityforreddit.readpost.ReadPost; import retrofit2.Retrofit; class PostDataSourceFactory extends DataSource.Factory { + private Executor executor; + private Handler handler; private Retrofit retrofit; private String accessToken; private String accountName; @@ -22,6 +26,7 @@ class PostDataSourceFactory extends DataSource.Factory { private SharedPreferences postFeedScrolledPositionSharedPreferences; private String name; private String query; + private String trendingSource; private int postType; private SortType sortType; private PostFilter postFilter; @@ -31,10 +36,12 @@ class PostDataSourceFactory extends DataSource.Factory { private PostDataSource postDataSource; private MutableLiveData<PostDataSource> postDataSourceLiveData; - PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, + PostDataSourceFactory(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -47,10 +54,12 @@ class PostDataSourceFactory extends DataSource.Factory { this.readPostList = readPostList; } - PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, + PostDataSourceFactory(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String name, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -64,10 +73,12 @@ class PostDataSourceFactory extends DataSource.Factory { this.readPostList = readPostList; } - PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, + PostDataSourceFactory(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String name, int postType, SortType sortType, PostFilter postFilter, String where, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -82,10 +93,12 @@ class PostDataSourceFactory extends DataSource.Factory { this.readPostList = readPostList; } - PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, + PostDataSourceFactory(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - String name, String query, int postType, SortType sortType, PostFilter postFilter, - List<ReadPost> readPostList) { + String name, String query, String trendingSource, int postType, SortType sortType, + PostFilter postFilter, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -93,6 +106,7 @@ class PostDataSourceFactory extends DataSource.Factory { this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; this.name = name; this.query = query; + this.trendingSource = trendingSource; postDataSourceLiveData = new MutableLiveData<>(); this.postType = postType; this.sortType = sortType; @@ -104,24 +118,24 @@ class PostDataSourceFactory extends DataSource.Factory { @Override public DataSource<String, Post> create() { if (postType == PostDataSource.TYPE_FRONT_PAGE) { - postDataSource = new PostDataSource(retrofit, accessToken, accountName, + postDataSource = new PostDataSource(executor, handler, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postType, sortType, postFilter, readPostList); } else if (postType == PostDataSource.TYPE_SEARCH) { - postDataSource = new PostDataSource(retrofit, accessToken, accountName, - sharedPreferences, postFeedScrolledPositionSharedPreferences, name, query, + postDataSource = new PostDataSource(executor, handler, retrofit, accessToken, accountName, + sharedPreferences, postFeedScrolledPositionSharedPreferences, name, query, trendingSource, postType, sortType, postFilter, readPostList); } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { Log.i("asdasfd", "s5 " + (postFilter == null)); - postDataSource = new PostDataSource(retrofit, accessToken, accountName, + postDataSource = new PostDataSource(executor, handler, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, postType, sortType, postFilter, readPostList); } else if (postType == PostDataSource.TYPE_ANONYMOUS_FRONT_PAGE) { - postDataSource = new PostDataSource(retrofit, null, null, + postDataSource = new PostDataSource(executor, handler, retrofit, null, null, sharedPreferences, null, name, postType, sortType, postFilter, null); } else { - postDataSource = new PostDataSource(retrofit, accessToken, accountName, + postDataSource = new PostDataSource(executor, handler, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, postType, sortType, postFilter, userWhere, readPostList); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java index 45001fbf..ea56f54e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java @@ -1,6 +1,7 @@ package ml.docilealligator.infinityforreddit.post; import android.content.SharedPreferences; +import android.os.Handler; import androidx.annotation.NonNull; import androidx.core.util.Pair; @@ -14,6 +15,7 @@ import androidx.paging.LivePagedListBuilder; import androidx.paging.PagedList; import java.util.List; +import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.postfilter.PostFilter; @@ -31,10 +33,10 @@ public class PostViewModel extends ViewModel { private MutableLiveData<PostFilter> postFilterLiveData; private SortTypeAndPostFilterLiveData sortTypeAndPostFilterLiveData; - public PostViewModel(Retrofit retrofit, String accessToken, String accountName, + public PostViewModel(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences cache, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, + postDataSourceFactory = new PostDataSourceFactory(executor, handler, retrofit, accessToken, accountName, sharedPreferences, cache, postType, sortType, postFilter, readPostList); initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), @@ -64,11 +66,11 @@ public class PostViewModel extends ViewModel { }); } - public PostViewModel(Retrofit retrofit, String accessToken, String accountName, + public PostViewModel(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, + postDataSourceFactory = new PostDataSourceFactory(executor, handler, retrofit, accessToken, accountName, sharedPreferences, cache, subredditName, postType, sortType, postFilter, readPostList); @@ -99,11 +101,11 @@ public class PostViewModel extends ViewModel { }); } - public PostViewModel(Retrofit retrofit, String accessToken, String accountName, + public PostViewModel(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences cache, String username, int postType, SortType sortType, PostFilter postFilter, String where, List<ReadPost> readPostList) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, + postDataSourceFactory = new PostDataSourceFactory(executor, handler, retrofit, accessToken, accountName, sharedPreferences, cache, username, postType, sortType, postFilter, where, readPostList); initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), @@ -133,11 +135,12 @@ public class PostViewModel extends ViewModel { }); } - public PostViewModel(Retrofit retrofit, String accessToken, String accountName, + public PostViewModel(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, - String query, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, - sharedPreferences, cache, subredditName, query, postType, sortType, postFilter, + String query, String trendingSource, int postType, SortType sortType, + PostFilter postFilter, List<ReadPost> readPostList) { + postDataSourceFactory = new PostDataSourceFactory(executor, handler, retrofit, accessToken, accountName, + sharedPreferences, cache, subredditName, query, trendingSource, postType, sortType, postFilter, readPostList); initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), @@ -200,6 +203,8 @@ public class PostViewModel extends ViewModel { } public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Executor executor; + private Handler handler; private Retrofit retrofit; private String accessToken; private String accountName; @@ -207,15 +212,18 @@ public class PostViewModel extends ViewModel { private SharedPreferences postFeedScrolledPositionSharedPreferences; private String name; private String query; + private String trendingSource; private int postType; private SortType sortType; private PostFilter postFilter; private String userWhere; private List<ReadPost> readPostList; - public Factory(Retrofit retrofit, String accessToken, String accountName, + public Factory(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -227,10 +235,11 @@ public class PostViewModel extends ViewModel { this.readPostList = readPostList; } - public Factory(Retrofit retrofit, String accessToken, String accountName, - SharedPreferences sharedPreferences, - SharedPreferences postFeedScrolledPositionSharedPreferences, String name, - int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { + public Factory(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + String name, int postType, SortType sortType, PostFilter postFilter, + List<ReadPost> readPostList) {this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -244,9 +253,12 @@ public class PostViewModel extends ViewModel { } //User posts - public Factory(Retrofit retrofit, String accessToken, String accountName, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String username, - int postType, SortType sortType, PostFilter postFilter, String where, List<ReadPost> readPostList) { + public Factory(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + String username, int postType, SortType sortType, PostFilter postFilter, String where, + List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -260,9 +272,12 @@ public class PostViewModel extends ViewModel { this.readPostList = readPostList; } - public Factory(Retrofit retrofit, String accessToken, String accountName, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String name, - String query, int postType, SortType sortType, PostFilter postFilter, List<ReadPost> readPostList) { + public Factory(Executor executor, Handler handler, Retrofit retrofit, String accessToken, String accountName, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + String name, String query, String trendingSource, int postType, SortType sortType, + PostFilter postFilter, List<ReadPost> readPostList) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -270,6 +285,7 @@ public class PostViewModel extends ViewModel { this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; this.name = name; this.query = query; + this.trendingSource = trendingSource; this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; @@ -277,8 +293,10 @@ public class PostViewModel extends ViewModel { } //Anonymous Front Page - public Factory(Retrofit retrofit, SharedPreferences sharedPreferences, String concatenatedSubredditNames, - int postType, SortType sortType, PostFilter postFilter) { + public Factory(Executor executor, Handler handler, Retrofit retrofit, SharedPreferences sharedPreferences, + String concatenatedSubredditNames, int postType, SortType sortType, PostFilter postFilter) { + this.executor = executor; + this.handler = handler; this.retrofit = retrofit; this.sharedPreferences = sharedPreferences; this.name = concatenatedSubredditNames; @@ -291,22 +309,22 @@ public class PostViewModel extends ViewModel { @Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { if (postType == PostDataSource.TYPE_FRONT_PAGE) { - return (T) new PostViewModel(retrofit, accessToken, accountName, sharedPreferences, + return (T) new PostViewModel(executor, handler, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postType, sortType, postFilter, readPostList); } else if (postType == PostDataSource.TYPE_SEARCH) { - return (T) new PostViewModel(retrofit, accessToken, accountName, sharedPreferences, - postFeedScrolledPositionSharedPreferences, name, query, postType, sortType, + return (T) new PostViewModel(executor, handler, retrofit, accessToken, accountName, sharedPreferences, + postFeedScrolledPositionSharedPreferences, name, query, trendingSource, postType, sortType, postFilter, readPostList); } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { - return (T) new PostViewModel(retrofit, accessToken, accountName, sharedPreferences, + return (T) new PostViewModel(executor, handler, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, postType, sortType, postFilter, readPostList); } else if (postType == PostDataSource.TYPE_ANONYMOUS_FRONT_PAGE) { - return (T) new PostViewModel(retrofit, null, null, sharedPreferences, + return (T) new PostViewModel(executor, handler, retrofit, null, null, sharedPreferences, null, name, postType, sortType, postFilter, null); } else { - return (T) new PostViewModel(retrofit, accessToken, accountName, sharedPreferences, + return (T) new PostViewModel(executor, handler, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, postType, sortType, postFilter, userWhere, readPostList); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java index c31da124..bf6fdbda 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java @@ -1,28 +1,26 @@ package ml.docilealligator.infinityforreddit.post; import android.graphics.Bitmap; +import android.os.Handler; import androidx.annotation.Nullable; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.StringReader; import java.util.HashMap; -import java.util.Locale; import java.util.Map; +import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.Flair; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.UploadImageUtils; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.RequestBody; @@ -31,23 +29,25 @@ import retrofit2.Response; import retrofit2.Retrofit; public class SubmitPost { - public static void submitTextOrLinkPost(Retrofit oauthRetrofit, String accessToken, - Locale locale, String subredditName, String title, String content, - Flair flair, boolean isSpoiler, boolean isNSFW, String kind, + public static void submitTextOrLinkPost(Executor executor, Handler handler, Retrofit oauthRetrofit, String accessToken, + String subredditName, String title, String content, + Flair flair, boolean isSpoiler, boolean isNSFW, + boolean receivePostReplyNotifications, String kind, SubmitPostListener submitPostListener) { - submitPost(oauthRetrofit, accessToken, subredditName, title, content, - flair, isSpoiler, isNSFW, kind, null, submitPostListener); + submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, content, + flair, isSpoiler, isNSFW, receivePostReplyNotifications, kind, null, submitPostListener); } - public static void submitImagePost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + public static void submitImagePost(Executor executor, Handler handler, Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, String accessToken, String subredditName, String title, Bitmap image, - Flair flair, boolean isSpoiler, boolean isNSFW, SubmitPostListener submitPostListener) { + Flair flair, boolean isSpoiler, boolean isNSFW, + boolean receivePostReplyNotifications, SubmitPostListener submitPostListener) { try { - String imageUrlOrError = uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, image); + String imageUrlOrError = UploadImageUtils.uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, image); if (imageUrlOrError != null && !imageUrlOrError.startsWith("Error: ")) { - submitPost(oauthRetrofit, accessToken, + submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, imageUrlOrError, flair, isSpoiler, isNSFW, - APIUtils.KIND_IMAGE, null, submitPostListener); + receivePostReplyNotifications, APIUtils.KIND_IMAGE, null, submitPostListener); } else { submitPostListener.submitFailed(imageUrlOrError); } @@ -57,11 +57,11 @@ public class SubmitPost { } } - public static void submitVideoPost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + public static void submitVideoPost(Executor executor, Handler handler, Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, Retrofit uploadVideoRetrofit, String accessToken, String subredditName, String title, File buffer, String mimeType, Bitmap posterBitmap, Flair flair, boolean isSpoiler, boolean isNSFW, - SubmitPostListener submitPostListener) { + boolean receivePostReplyNotifications, SubmitPostListener submitPostListener) { RedditAPI api = oauthRetrofit.create(RedditAPI.class); String fileType = mimeType.substring(mimeType.indexOf("/") + 1); @@ -74,7 +74,7 @@ public class SubmitPost { try { Response<String> uploadImageResponse = uploadImageCall.execute(); if (uploadImageResponse.isSuccessful()) { - Map<String, RequestBody> nameValuePairsMap = parseJSONResponseFromAWS(uploadImageResponse.body()); + Map<String, RequestBody> nameValuePairsMap = UploadImageUtils.parseJSONResponseFromAWS(uploadImageResponse.body()); RequestBody fileBody = RequestBody.create(buffer, MediaType.parse("application/octet-stream")); MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_video." + fileType, fileBody); @@ -88,21 +88,23 @@ public class SubmitPost { Call<String> uploadMediaToAWS = uploadVideoToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); Response<String> uploadMediaToAWSResponse = uploadMediaToAWS.execute(); if (uploadMediaToAWSResponse.isSuccessful()) { - String url = parseXMLResponseFromAWS(uploadMediaToAWSResponse.body()); + String url = UploadImageUtils.parseXMLResponseFromAWS(uploadMediaToAWSResponse.body()); if (url == null) { submitPostListener.submitFailed(null); return; } - String imageUrlOrError = uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, posterBitmap); + String imageUrlOrError = UploadImageUtils.uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, posterBitmap); if (imageUrlOrError != null && !imageUrlOrError.startsWith("Error: ")) { if (fileType.equals("gif")) { - submitPost(oauthRetrofit, accessToken, + submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, url, flair, isSpoiler, isNSFW, - APIUtils.KIND_VIDEOGIF, imageUrlOrError, submitPostListener); + receivePostReplyNotifications, APIUtils.KIND_VIDEOGIF, imageUrlOrError, + submitPostListener); } else { - submitPost(oauthRetrofit, accessToken, + submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, url, flair, isSpoiler, isNSFW, - APIUtils.KIND_VIDEO, imageUrlOrError, submitPostListener); + receivePostReplyNotifications, APIUtils.KIND_VIDEO, imageUrlOrError, + submitPostListener); } } else { submitPostListener.submitFailed(imageUrlOrError); @@ -119,17 +121,19 @@ public class SubmitPost { } } - public static void submitCrosspost(Retrofit oauthRetrofit, String accessToken, - String subredditName, String title, String crosspostFullname, - Flair flair, boolean isSpoiler, boolean isNSFW, String kind, - SubmitPostListener submitPostListener) { - submitPost(oauthRetrofit, accessToken, subredditName, title, crosspostFullname, - flair, isSpoiler, isNSFW, kind, null, submitPostListener); + public static void submitCrosspost(Executor executor, Handler handler, Retrofit oauthRetrofit, String accessToken, + String subredditName, String title, String crosspostFullname, + Flair flair, boolean isSpoiler, boolean isNSFW, + boolean receivePostReplyNotifications, String kind, + SubmitPostListener submitPostListener) { + submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, crosspostFullname, + flair, isSpoiler, isNSFW, receivePostReplyNotifications, kind, null, submitPostListener); } - private static void submitPost(Retrofit oauthRetrofit, String accessToken, + private static void submitPost(Executor executor, Handler handler, Retrofit oauthRetrofit, String accessToken, String subredditName, String title, String content, - Flair flair, boolean isSpoiler, boolean isNSFW, String kind, + Flair flair, boolean isSpoiler, boolean isNSFW, + boolean receivePostReplyNotifications, String kind, @Nullable String posterUrl, SubmitPostListener submitPostListener) { RedditAPI api = oauthRetrofit.create(RedditAPI.class); @@ -166,13 +170,15 @@ public class SubmitPost { } params.put(APIUtils.SPOILER_KEY, Boolean.toString(isSpoiler)); params.put(APIUtils.NSFW_KEY, Boolean.toString(isNSFW)); + params.put(APIUtils.SEND_REPLIES_KEY, Boolean.toString(receivePostReplyNotifications)); Call<String> submitPostCall = api.submit(APIUtils.getOAuthHeader(accessToken), params); try { Response<String> response = submitPostCall.execute(); if (response.isSuccessful()) { - getSubmittedPost(response.body(), kind, oauthRetrofit, accessToken, submitPostListener); + getSubmittedPost(executor, handler, response.body(), kind, oauthRetrofit, accessToken, + submitPostListener); } else { submitPostListener.submitFailed(response.message()); } @@ -182,42 +188,9 @@ public class SubmitPost { } } - @Nullable - private static String uploadImage(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, - String accessToken, Bitmap image) throws IOException, JSONException, XmlPullParserException { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Map<String, String> uploadImageParams = new HashMap<>(); - uploadImageParams.put(APIUtils.FILEPATH_KEY, "post_image.jpg"); - uploadImageParams.put(APIUtils.MIMETYPE_KEY, "image/jpeg"); - - Call<String> uploadImageCall = api.uploadImage(APIUtils.getOAuthHeader(accessToken), uploadImageParams); - Response<String> uploadImageResponse = uploadImageCall.execute(); - if (uploadImageResponse.isSuccessful()) { - Map<String, RequestBody> nameValuePairsMap = parseJSONResponseFromAWS(uploadImageResponse.body()); - - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - image.compress(Bitmap.CompressFormat.JPEG, 100, stream); - byte[] byteArray = stream.toByteArray(); - - RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), byteArray); - MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_image.jpg", fileBody); - - RedditAPI uploadMediaToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); - Call<String> uploadMediaToAWS = uploadMediaToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); - Response<String> uploadMediaToAWSResponse = uploadMediaToAWS.execute(); - if (uploadMediaToAWSResponse.isSuccessful()) { - return parseXMLResponseFromAWS(uploadMediaToAWSResponse.body()); - } else { - return "Error: " + uploadMediaToAWSResponse.code(); - } - } else { - return "Error: " + uploadImageResponse.message(); - } - } - - private static void getSubmittedPost(String response, String kind, Retrofit oauthRetrofit, - String accessToken, SubmitPostListener submitPostListener) throws JSONException, IOException { + private static void getSubmittedPost(Executor executor, Handler handler, String response, String kind, + Retrofit oauthRetrofit, String accessToken, + SubmitPostListener submitPostListener) throws JSONException, IOException { JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) @@ -245,7 +218,7 @@ public class SubmitPost { Call<String> getPostCall = api.getPostOauth(postId, APIUtils.getOAuthHeader(accessToken)); Response<String> getPostCallResponse = getPostCall.execute(); if (getPostCallResponse.isSuccessful()) { - ParsePost.parsePost(getPostCallResponse.body(), new ParsePost.ParsePostListener() { + ParsePost.parsePost(executor, handler, getPostCallResponse.body(), new ParsePost.ParsePostListener() { @Override public void onParsePostSuccess(Post post) { submitPostListener.submitSuccessful(post); @@ -269,40 +242,4 @@ public class SubmitPost { void submitFailed(@Nullable String errorMessage); } - - private static Map<String, RequestBody> parseJSONResponseFromAWS(String response) throws JSONException { - JSONObject responseObject = new JSONObject(response); - JSONArray nameValuePairs = responseObject.getJSONObject(JSONUtils.ARGS_KEY).getJSONArray(JSONUtils.FIELDS_KEY); - - Map<String, RequestBody> nameValuePairsMap = new HashMap<>(); - for (int i = 0; i < nameValuePairs.length(); i++) { - nameValuePairsMap.put(nameValuePairs.getJSONObject(i).getString(JSONUtils.NAME_KEY), - APIUtils.getRequestBody(nameValuePairs.getJSONObject(i).getString(JSONUtils.VALUE_KEY))); - } - - return nameValuePairsMap; - } - - @Nullable - private static String parseXMLResponseFromAWS(String response) throws XmlPullParserException, IOException { - XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser(); - xmlPullParser.setInput(new StringReader(response)); - - boolean isLocationTag = false; - int eventType = xmlPullParser.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - if (xmlPullParser.getName().equals("Location")) { - isLocationTag = true; - } - } else if (eventType == XmlPullParser.TEXT) { - if (isLocationTag) { - return xmlPullParser.getText(); - } - } - eventType = xmlPullParser.next(); - } - - return null; - } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java index a326d81f..e5534ef9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java @@ -263,7 +263,7 @@ public class DownloadMediaService extends Service { contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, destinationFileUriString); contentValues.put(mediaType == EXTRA_MEDIA_TYPE_VIDEO ? MediaStore.Video.Media.IS_PENDING : MediaStore.Images.Media.IS_PENDING, 1); - final Uri contentUri = mediaType == EXTRA_MEDIA_TYPE_VIDEO ? MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL) : MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL); + final Uri contentUri = mediaType == EXTRA_MEDIA_TYPE_VIDEO ? MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY) : MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); Uri uri = contentResolver.insert(contentUri, contentValues); if (uri == null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java index f1b9633e..a398871e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java @@ -25,7 +25,6 @@ import android.os.Looper; import android.os.Message; import android.os.Process; import android.provider.MediaStore; -import android.util.Log; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; @@ -417,7 +416,7 @@ public class DownloadRedditVideoService extends Service { Uri uri = null; try { - final Uri contentUri = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL); + final Uri contentUri = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); uri = contentResolver.insert(contentUri, contentValues); if (uri == null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/MaterialYouService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/MaterialYouService.java new file mode 100644 index 00000000..66bd4e0b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/MaterialYouService.java @@ -0,0 +1,98 @@ +package ml.docilealligator.infinityforreddit.services; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.Service; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Handler; +import android.os.IBinder; + +import androidx.annotation.Nullable; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.utils.MaterialYouUtils; +import ml.docilealligator.infinityforreddit.utils.NotificationUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class MaterialYouService extends Service { + + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("light_theme") + SharedPreferences lightThemeSharedPreferences; + @Inject + @Named("dark_theme") + SharedPreferences darkThemeSharedPreferences; + @Inject + @Named("amoled_theme") + SharedPreferences amoledThemeSharedPreferences; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + @Inject + Executor executor; + + public MaterialYouService() { + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + ((Infinity) getApplication()).getAppComponent().inject(this); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel serviceChannel = new NotificationChannel( + NotificationUtils.CHANNEL_ID_MATERIAL_YOU, + NotificationUtils.CHANNEL_MATERIAL_YOU, + NotificationManager.IMPORTANCE_LOW + ); + + NotificationManagerCompat manager = NotificationManagerCompat.from(this); + manager.createNotificationChannel(serviceChannel); + } + Notification notification = new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_MATERIAL_YOU) + .setContentTitle(getString(R.string.material_you_notification_title)) + .setContentText(getString(R.string.please_wait)) + .setSmallIcon(R.drawable.ic_notification) + .setColor(customThemeWrapper.getColorPrimaryLightTheme()) + .build(); + startForeground(NotificationUtils.MATERIAL_YOU_NOTIFICATION_ID, notification); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_MATERIAL_YOU, false)) { + MaterialYouUtils.changeTheme(this, executor, new Handler(), redditDataRoomDatabase, + customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences, + amoledThemeSharedPreferences, () -> { + stopService(); + }); + } else { + stopService(); + } + + return START_NOT_STICKY; + } + + private void stopService() { + stopForeground(true); + stopSelf(); + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java index 2f313125..e22bc541 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java @@ -25,6 +25,9 @@ import androidx.core.app.NotificationManagerCompat; import com.bumptech.glide.Glide; import org.greenrobot.eventbus.EventBus; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; import java.io.File; import java.io.FileOutputStream; @@ -33,6 +36,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Random; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; @@ -40,15 +44,19 @@ import javax.inject.Named; import ml.docilealligator.infinityforreddit.Flair; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.SubmitCrosspostEvent; +import ml.docilealligator.infinityforreddit.events.SubmitGalleryPostEvent; import ml.docilealligator.infinityforreddit.events.SubmitImagePostEvent; import ml.docilealligator.infinityforreddit.events.SubmitTextOrLinkPostEvent; import ml.docilealligator.infinityforreddit.events.SubmitVideoOrGifPostEvent; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.SubmitPost; import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.NotificationUtils; +import retrofit2.Response; import retrofit2.Retrofit; public class SubmitPostService extends Service { @@ -56,15 +64,19 @@ public class SubmitPostService extends Service { public static final String EXTRA_SUBREDDIT_NAME = "ESN"; public static final String EXTRA_TITLE = "ET"; public static final String EXTRA_CONTENT = "EC"; + public static final String EXTRA_REDDIT_GALLERY_PAYLOAD = "ERGP"; public static final String EXTRA_KIND = "EK"; public static final String EXTRA_FLAIR = "EF"; public static final String EXTRA_IS_SPOILER = "EIS"; public static final String EXTRA_IS_NSFW = "EIN"; + public static final String EXTRA_RECEIVE_POST_REPLY_NOTIFICATIONS = "ERPRN"; public static final String EXTRA_POST_TYPE = "EPT"; public static final int EXTRA_POST_TEXT_OR_LINK = 0; public static final int EXTRA_POST_TYPE_IMAGE = 1; public static final int EXTRA_POST_TYPE_VIDEO = 2; - public static final int EXTRA_POST_TYPE_CROSSPOST = 3; + public static final int EXTRA_POST_TYPE_GALLERY = 3; + public static final int EXTRA_POST_TYPE_CROSSPOST = 4; + private static final String EXTRA_MEDIA_URI = "EU"; @Inject @Named("oauth") @@ -77,6 +89,9 @@ public class SubmitPostService extends Service { Retrofit mUploadVideoRetrofit; @Inject CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + private Handler handler; private ServiceHandler serviceHandler; public SubmitPostService() { @@ -103,21 +118,28 @@ public class SubmitPostService extends Service { Flair flair = bundle.getParcelable(EXTRA_FLAIR); boolean isSpoiler = bundle.getBoolean(EXTRA_IS_SPOILER, false); boolean isNSFW = bundle.getBoolean(EXTRA_IS_NSFW, false); + boolean receivePostReplyNotifications = bundle.getBoolean(EXTRA_RECEIVE_POST_REPLY_NOTIFICATIONS, true); int postType = bundle.getInt(EXTRA_POST_TYPE, EXTRA_POST_TEXT_OR_LINK); if (postType == EXTRA_POST_TEXT_OR_LINK) { String content = bundle.getString(EXTRA_CONTENT); String kind = bundle.getString(EXTRA_KIND); - submitTextOrLinkPost(accessToken, subredditName, title, content, flair, isSpoiler, isNSFW, kind); + submitTextOrLinkPost(accessToken, subredditName, title, content, flair, isSpoiler, isNSFW, + receivePostReplyNotifications, kind); } else if (postType == EXTRA_POST_TYPE_CROSSPOST) { String content = bundle.getString(EXTRA_CONTENT); - submitCrosspost(accessToken, subredditName, title, content, flair, isSpoiler, isNSFW); + submitCrosspost(mExecutor, handler, accessToken, subredditName, title, content, + flair, isSpoiler, isNSFW, receivePostReplyNotifications); } else if (postType == EXTRA_POST_TYPE_IMAGE) { Uri mediaUri = Uri.parse(bundle.getString(EXTRA_MEDIA_URI)); - submitImagePost(accessToken, mediaUri, subredditName, title, flair, isSpoiler, isNSFW); - } else { + submitImagePost(accessToken, mediaUri, subredditName, title, flair, isSpoiler, isNSFW, + receivePostReplyNotifications); + } else if (postType == EXTRA_POST_TYPE_VIDEO) { Uri mediaUri = Uri.parse(bundle.getString(EXTRA_MEDIA_URI)); - submitVideoPost(accessToken, mediaUri, subredditName, title, flair, isSpoiler, isNSFW); + submitVideoPost(accessToken, mediaUri, subredditName, title, flair, isSpoiler, isNSFW, + receivePostReplyNotifications); + } else { + submitGalleryPost(accessToken, bundle.getString(EXTRA_REDDIT_GALLERY_PAYLOAD)); } } } @@ -129,6 +151,7 @@ public class SubmitPostService extends Service { // separate thread because the service normally runs in the process's // main thread, which we don't want to block. We also make it // background priority so CPU-intensive work doesn't disrupt our UI. + handler = new Handler(); HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); @@ -163,9 +186,11 @@ public class SubmitPostService extends Service { } else if (postType == EXTRA_POST_TYPE_IMAGE) { bundle.putString(EXTRA_MEDIA_URI, intent.getData().toString()); startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID + randomNotificationIdOffset, createNotification(R.string.posting_image)); - } else { + } else if (postType == EXTRA_POST_TYPE_VIDEO) { bundle.putString(EXTRA_MEDIA_URI, intent.getData().toString()); startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID + randomNotificationIdOffset, createNotification(R.string.posting_video)); + } else { + startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID + randomNotificationIdOffset, createNotification(R.string.posting_gallery)); } Message msg = serviceHandler.obtainMessage(); @@ -184,73 +209,83 @@ public class SubmitPostService extends Service { .build(); } - private void submitTextOrLinkPost(String accessToken, String subredditName, String title, String content, Flair flair, boolean isSpoiler, boolean isNSFW, String kind) { - SubmitPost.submitTextOrLinkPost(mOauthRetrofit, accessToken, getResources().getConfiguration().locale, - subredditName, title, content, flair, isSpoiler, isNSFW, kind, new SubmitPost.SubmitPostListener() { + private void submitTextOrLinkPost(String accessToken, String subredditName, String title, String content, + Flair flair, boolean isSpoiler, boolean isNSFW, boolean receivePostReplyNotifications, + String kind) { + SubmitPost.submitTextOrLinkPost(mExecutor, handler, mOauthRetrofit, accessToken, + subredditName, title, content, flair, isSpoiler, + isNSFW, receivePostReplyNotifications, kind, new SubmitPost.SubmitPostListener() { @Override public void submitSuccessful(Post post) { - EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(true, post, null)); + handler.post(() -> EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(true, post, null))); stopService(); } @Override public void submitFailed(@Nullable String errorMessage) { - EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(false, null, errorMessage)); + handler.post(() -> EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(false, null, errorMessage))); stopService(); } }); } - private void submitCrosspost(String accessToken, String subredditName, String title, String content, Flair flair, boolean isSpoiler, boolean isNSFW) { - SubmitPost.submitCrosspost(mOauthRetrofit, accessToken, subredditName, title, content, flair, isSpoiler, - isNSFW, APIUtils.KIND_CROSSPOST, new SubmitPost.SubmitPostListener() { + private void submitCrosspost(Executor executor, Handler handler, String accessToken, String subredditName, + String title, String content, Flair flair, boolean isSpoiler, boolean isNSFW, + boolean receivePostReplyNotifications) { + SubmitPost.submitCrosspost(executor, handler, mOauthRetrofit, accessToken, subredditName, title, + content, flair, isSpoiler, isNSFW, receivePostReplyNotifications, APIUtils.KIND_CROSSPOST, + new SubmitPost.SubmitPostListener() { @Override public void submitSuccessful(Post post) { - EventBus.getDefault().post(new SubmitCrosspostEvent(true, post, null)); + handler.post(() -> EventBus.getDefault().post(new SubmitCrosspostEvent(true, post, null))); stopService(); } @Override public void submitFailed(@Nullable String errorMessage) { - EventBus.getDefault().post(new SubmitCrosspostEvent(false, null, errorMessage)); + handler.post(() -> EventBus.getDefault().post(new SubmitCrosspostEvent(false, null, errorMessage))); stopService(); } }); } - private void submitImagePost(String accessToken, Uri mediaUri, String subredditName, String title, Flair flair, boolean isSpoiler, boolean isNSFW) { + private void submitImagePost(String accessToken, Uri mediaUri, String subredditName, String title, + Flair flair, boolean isSpoiler, boolean isNSFW, boolean receivePostReplyNotifications) { try { Bitmap resource = Glide.with(this).asBitmap().load(mediaUri).submit().get(); - SubmitPost.submitImagePost(mOauthRetrofit, mUploadMediaRetrofit, accessToken, subredditName, title, resource, - flair, isSpoiler, isNSFW, new SubmitPost.SubmitPostListener() { + SubmitPost.submitImagePost(mExecutor, handler, mOauthRetrofit, mUploadMediaRetrofit, + accessToken, subredditName, title, resource, flair, isSpoiler, isNSFW, receivePostReplyNotifications, + new SubmitPost.SubmitPostListener() { @Override public void submitSuccessful(Post post) { - EventBus.getDefault().post(new SubmitImagePostEvent(true, null)); - Toast.makeText(SubmitPostService.this, R.string.image_is_processing, Toast.LENGTH_SHORT).show(); + handler.post(() -> { + EventBus.getDefault().post(new SubmitImagePostEvent(true, null)); + Toast.makeText(SubmitPostService.this, R.string.image_is_processing, Toast.LENGTH_SHORT).show(); + }); stopService(); } @Override public void submitFailed(@Nullable String errorMessage) { - EventBus.getDefault().post(new SubmitImagePostEvent(false, errorMessage)); + handler.post(() -> EventBus.getDefault().post(new SubmitImagePostEvent(false, errorMessage))); stopService(); } }); } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); - EventBus.getDefault().post(new SubmitImagePostEvent(false, getString(R.string.error_processing_image))); + handler.post(() -> EventBus.getDefault().post(new SubmitImagePostEvent(false, getString(R.string.error_processing_image)))); stopService(); } } private void submitVideoPost(String accessToken, Uri mediaUri, String subredditName, String title, - Flair flair, boolean isSpoiler, boolean isNSFW) { + Flair flair, boolean isSpoiler, boolean isNSFW, boolean receivePostReplyNotifications) { try { InputStream in = getContentResolver().openInputStream(mediaUri); String type = getContentResolver().getType(mediaUri); @@ -266,37 +301,77 @@ public class SubmitPostService extends Service { Bitmap resource = Glide.with(this).asBitmap().load(mediaUri).submit().get(); if (type != null) { - SubmitPost.submitVideoPost(mOauthRetrofit, mUploadMediaRetrofit, mUploadVideoRetrofit, - accessToken, subredditName, title, new File(cacheFilePath), type, resource, flair, - isSpoiler, isNSFW, new SubmitPost.SubmitPostListener() { + SubmitPost.submitVideoPost(mExecutor, handler, mOauthRetrofit, mUploadMediaRetrofit, + mUploadVideoRetrofit, accessToken, subredditName, title, new File(cacheFilePath), + type, resource, flair, isSpoiler, isNSFW, receivePostReplyNotifications, + new SubmitPost.SubmitPostListener() { @Override public void submitSuccessful(Post post) { - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(true, false, null)); - if (type.contains("gif")) { - Toast.makeText(SubmitPostService.this, R.string.gif_is_processing, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(SubmitPostService.this, R.string.video_is_processing, Toast.LENGTH_SHORT).show(); - } + handler.post(() -> { + EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(true, false, null)); + if (type.contains("gif")) { + Toast.makeText(SubmitPostService.this, R.string.gif_is_processing, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(SubmitPostService.this, R.string.video_is_processing, Toast.LENGTH_SHORT).show(); + } + }); + stopService(); } @Override public void submitFailed(@Nullable String errorMessage) { - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, false, errorMessage)); + handler.post(() -> EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, false, errorMessage))); stopService(); } }); } else { - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); + handler.post(() -> EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null))); stopService(); } } catch (IOException | InterruptedException | ExecutionException e) { e.printStackTrace(); - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); + handler.post(() -> EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null))); + + stopService(); + } + } + private void submitGalleryPost(String accessToken, String payload) { + try { + Response<String> response = mOauthRetrofit.create(RedditAPI.class).submitGalleryPost(APIUtils.getOAuthHeader(accessToken), payload).execute(); + if (response.isSuccessful()) { + JSONObject responseObject = new JSONObject(response.body()).getJSONObject(JSONUtils.JSON_KEY); + if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { + JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) + .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); + if (error.length() != 0) { + String errorMessage; + if (error.length() >= 2) { + errorMessage = error.getString(1); + } else { + errorMessage = error.getString(0); + } + handler.post(() -> EventBus.getDefault().post(new SubmitGalleryPostEvent(false, null, errorMessage))); + } else { + handler.post(() -> EventBus.getDefault().post(new SubmitGalleryPostEvent(false, null, null))); + } + } else { + String postUrl = responseObject.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.URL_KEY); + handler.post(() -> { + EventBus.getDefault().post(new SubmitGalleryPostEvent(true, postUrl, null)); + }); + } + } else { + handler.post(() -> EventBus.getDefault().post(new SubmitGalleryPostEvent(false, null, response.message()))); + } + } catch (IOException | JSONException e) { + e.printStackTrace(); + handler.post(() -> EventBus.getDefault().post(new SubmitGalleryPostEvent(false, null, e.getMessage()))); + } finally { stopService(); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AcknowledgementFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AcknowledgementFragment.java index 59adcf9d..2f2aa91e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AcknowledgementFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AcknowledgementFragment.java @@ -11,7 +11,6 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; @@ -20,6 +19,7 @@ import butterknife.BindView; import butterknife.ButterKnife; import ml.docilealligator.infinityforreddit.adapters.AcknowledgementRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; /** * A simple {@link Fragment} subclass. @@ -127,7 +127,7 @@ public class AcknowledgementFragment extends Fragment { Uri.parse("https://github.com/saket/Better-Link-Movement-Method"))); AcknowledgementRecyclerViewAdapter adapter = new AcknowledgementRecyclerViewAdapter(activity, acknowledgements); - recyclerView.setLayoutManager(new LinearLayoutManager(activity)); + recyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(activity)); recyclerView.setAdapter(adapter); return rootView; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CrashReportsFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CrashReportsFragment.java index 350addf8..6cb67a5f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CrashReportsFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CrashReportsFragment.java @@ -17,7 +17,6 @@ import androidx.annotation.NonNull; import androidx.appcompat.view.menu.MenuItemImpl; import androidx.core.graphics.drawable.DrawableCompat; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.crazylegend.crashyreporter.CrashyReporter; @@ -49,7 +48,6 @@ public class CrashReportsFragment extends Fragment { setHasOptionsMenu(true); - recyclerView.setLayoutManager(new LinearLayoutManager(activity)); recyclerView.setAdapter(new CrashReportsRecyclerViewAdapter(CrashyReporter.INSTANCE.getLogsAsStrings())); return recyclerView; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeMainPageTabsFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeMainPageTabsFragment.java index 7a2cca00..51813f8f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeMainPageTabsFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeMainPageTabsFragment.java @@ -101,6 +101,14 @@ public class CustomizeMainPageTabsFragment extends Fragment { TextView moreTabsGroupSummaryTextView; @BindView(R.id.more_tabs_info_text_view_customize_main_page_tabs_fragment) TextView moreTabsInfoTextView; + @BindView(R.id.show_favorite_multireddits_linear_layout_customize_main_page_tabs_fragment) + LinearLayout showFavoriteMultiredditsLinearLayout; + @BindView(R.id.show_favorite_multireddits_switch_material_customize_main_page_tabs_fragment) + SwitchMaterial showFavoriteMultiredditsSwitchMaterial; + @BindView(R.id.show_multireddits_linear_layout_customize_main_page_tabs_fragment) + LinearLayout showMultiredditsLinearLayout; + @BindView(R.id.show_multireddits_switch_material_customize_main_page_tabs_fragment) + SwitchMaterial showMultiredditsSwitchMaterial; @BindView(R.id.show_subscribed_subreddits_linear_layout_customize_main_page_tabs_fragment) LinearLayout showSubscribedSubredditsLinearLayout; @BindView(R.id.show_subscribed_subreddits_switch_material_customize_main_page_tabs_fragment) @@ -159,6 +167,8 @@ public class CustomizeMainPageTabsFragment extends Fragment { divider4.setVisibility(View.GONE); moreTabsGroupSummaryTextView.setVisibility(View.GONE); moreTabsInfoTextView.setVisibility(View.GONE); + showFavoriteMultiredditsLinearLayout.setVisibility(View.GONE); + showMultiredditsLinearLayout.setVisibility(View.GONE); showSubscribedSubredditsLinearLayout.setVisibility(View.GONE); showFavoriteSubscribedSubredditsLinearLayout.setVisibility(View.GONE); @@ -483,14 +493,26 @@ public class CustomizeMainPageTabsFragment extends Fragment { .show(); }); - showSubscribedSubredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, false)); - showSubscribedSubredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, b).apply()); + showMultiredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean(accountName + SharedPreferencesUtils.MAIN_PAGE_SHOW_MULTIREDDITS, false)); + showMultiredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean(accountName + SharedPreferencesUtils.MAIN_PAGE_SHOW_MULTIREDDITS, b).apply()); + showMultiredditsLinearLayout.setOnClickListener(view -> { + showMultiredditsSwitchMaterial.performClick(); + }); + + showFavoriteMultiredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean(accountName + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_MULTIREDDITS, false)); + showFavoriteMultiredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean(accountName + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_MULTIREDDITS, b).apply()); + showFavoriteMultiredditsLinearLayout.setOnClickListener(view -> { + showFavoriteMultiredditsSwitchMaterial.performClick(); + }); + + showSubscribedSubredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean(accountName + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, false)); + showSubscribedSubredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean(accountName + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, b).apply()); showSubscribedSubredditsLinearLayout.setOnClickListener(view -> { showSubscribedSubredditsSwitchMaterial.performClick(); }); - showFavoriteSubscribedSubredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, false)); - showFavoriteSubscribedSubredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, b).apply()); + showFavoriteSubscribedSubredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean(accountName + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, false)); + showFavoriteSubscribedSubredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean(accountName + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, b).apply()); showFavoriteSubscribedSubredditsLinearLayout.setOnClickListener(view -> { showFavoriteSubscribedSubredditsSwitchMaterial.performClick(); }); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/GesturesAndButtonsPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/GesturesAndButtonsPreferenceFragment.java index 882455ef..831755c2 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/GesturesAndButtonsPreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/GesturesAndButtonsPreferenceFragment.java @@ -56,7 +56,7 @@ public class GesturesAndButtonsPreferenceFragment extends PreferenceFragmentComp return true; }); - if (sharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false)) { + if (sharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, true)) { lockBottomAppBarSwitch.setVisible(true); lockBottomAppBarSwitch.setOnPreferenceChangeListener((preference, newValue) -> { EventBus.getDefault().post(new ChangeLockBottomAppBarEvent((Boolean) newValue)); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostDetailsPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostDetailsPreferenceFragment.java new file mode 100644 index 00000000..2e0db830 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostDetailsPreferenceFragment.java @@ -0,0 +1,18 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.os.Bundle; + +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; + +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class PostDetailsPreferenceFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + PreferenceManager preferenceManager = getPreferenceManager(); + preferenceManager.setSharedPreferencesName(SharedPreferencesUtils.POST_DETAILS_SHARED_PREFERENCES_FILE); + setPreferencesFromResource(R.xml.post_details_preferences, rootKey); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostPreferenceFragment.java index c45a2c1a..5b508a96 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostPreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostPreferenceFragment.java @@ -11,7 +11,9 @@ import org.greenrobot.eventbus.EventBus; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.events.ChangeCompactLayoutToolbarHiddenByDefaultEvent; +import ml.docilealligator.infinityforreddit.events.ChangeDefaultLinkPostLayoutEvent; import ml.docilealligator.infinityforreddit.events.ChangeDefaultPostLayoutEvent; +import ml.docilealligator.infinityforreddit.events.ChangeHidePostFlairEvent; import ml.docilealligator.infinityforreddit.events.ChangeHidePostTypeEvent; import ml.docilealligator.infinityforreddit.events.ChangeHideSubredditAndUserPrefixEvent; import ml.docilealligator.infinityforreddit.events.ChangeHideTheNumberOfAwardsEvent; @@ -30,12 +32,14 @@ public class PostPreferenceFragment extends PreferenceFragmentCompat { setPreferencesFromResource(R.xml.post_preferences, rootKey); ListPreference defaultPostLayoutList = findPreference(SharedPreferencesUtils.DEFAULT_POST_LAYOUT_KEY); + ListPreference defaultLinkPostLayoutList = findPreference(SharedPreferencesUtils.DEFAULT_LINK_POST_LAYOUT_KEY); SwitchPreference showDividerInCompactLayoutSwitch = findPreference(SharedPreferencesUtils.SHOW_DIVIDER_IN_COMPACT_LAYOUT); SwitchPreference showThumbnailOnTheRightInCompactLayoutSwitch = findPreference(SharedPreferencesUtils.SHOW_THUMBNAIL_ON_THE_LEFT_IN_COMPACT_LAYOUT); SwitchPreference showAbsoluteNumberOfVotesSwitch = findPreference(SharedPreferencesUtils.SHOW_ABSOLUTE_NUMBER_OF_VOTES); SwitchPreference longPressToHideToolbarInCompactLayoutSwitch = findPreference(SharedPreferencesUtils.LONG_PRESS_TO_HIDE_TOOLBAR_IN_COMPACT_LAYOUT); SwitchPreference postCompactLayoutToolbarHiddenByDefaultSwitch = findPreference(SharedPreferencesUtils.POST_COMPACT_LAYOUT_TOOLBAR_HIDDEN_BY_DEFAULT); SwitchPreference hidePostTypeSwitch = findPreference(SharedPreferencesUtils.HIDE_POST_TYPE); + SwitchPreference hidePostFlairSwitch = findPreference(SharedPreferencesUtils.HIDE_POST_FLAIR); SwitchPreference hideTheNumberOfAwardsSwitch = findPreference(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_AWARDS); SwitchPreference hideSubredditAndUserPrefixSwitch = findPreference(SharedPreferencesUtils.HIDE_SUBREDDIT_AND_USER_PREFIX); SwitchPreference hideTheNumberOfVotesSwitch = findPreference(SharedPreferencesUtils.HIDE_THE_NUMBER_OF_VOTES); @@ -48,6 +52,13 @@ public class PostPreferenceFragment extends PreferenceFragmentCompat { }); } + if (defaultLinkPostLayoutList != null) { + defaultLinkPostLayoutList.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeDefaultLinkPostLayoutEvent(Integer.parseInt((String) newValue))); + return true; + }); + } + if (showDividerInCompactLayoutSwitch != null) { showDividerInCompactLayoutSwitch.setOnPreferenceChangeListener((preference, newValue) -> { EventBus.getDefault().post(new ShowDividerInCompactLayoutPreferenceEvent((Boolean) newValue)); @@ -90,6 +101,13 @@ public class PostPreferenceFragment extends PreferenceFragmentCompat { }); } + if (hidePostFlairSwitch != null) { + hidePostFlairSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeHidePostFlairEvent((Boolean) newValue)); + return true; + }); + } + if (hideTheNumberOfAwardsSwitch != null) { hideTheNumberOfAwardsSwitch.setOnPreferenceChangeListener((preference, newValue) -> { EventBus.getDefault().post(new ChangeHideTheNumberOfAwardsEvent((Boolean) newValue)); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SecurityPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SecurityPreferenceFragment.java index cb6917c8..c4dd2b16 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SecurityPreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SecurityPreferenceFragment.java @@ -1,5 +1,8 @@ package ml.docilealligator.infinityforreddit.settings; +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; +import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; + import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; @@ -18,14 +21,12 @@ import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; -import ml.docilealligator.infinityforreddit.events.ChangeRequireAuthToAccountSectionEvent; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.events.ChangeRequireAuthToAccountSectionEvent; +import ml.docilealligator.infinityforreddit.events.ToggleSecureModeEvent; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; -import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; - public class SecurityPreferenceFragment extends PreferenceFragmentCompat { private AppCompatActivity activity; @@ -40,6 +41,7 @@ public class SecurityPreferenceFragment extends PreferenceFragmentCompat { ((Infinity) activity.getApplication()).getAppComponent().inject(this); SwitchPreference requireAuthToAccountSectionSwitch = findPreference(SharedPreferencesUtils.REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER); + SwitchPreference secureModeSwitch = findPreference(SharedPreferencesUtils.SECURE_MODE); if (requireAuthToAccountSectionSwitch != null) { requireAuthToAccountSectionSwitch.setOnPreferenceChangeListener((preference, newValue) -> { @@ -47,6 +49,13 @@ public class SecurityPreferenceFragment extends PreferenceFragmentCompat { return true; }); } + + if (secureModeSwitch != null) { + secureModeSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ToggleSecureModeEvent((Boolean) newValue)); + return true; + }); + } } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java index fba59d25..0e0a8c7d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java @@ -1,10 +1,17 @@ package ml.docilealligator.infinityforreddit.settings; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; + import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; @@ -19,24 +26,23 @@ import androidx.preference.SwitchPreference; import org.greenrobot.eventbus.EventBus; +import java.util.concurrent.Executor; + import javax.inject.Inject; +import javax.inject.Named; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.activities.CustomThemeListingActivity; import ml.docilealligator.infinityforreddit.activities.CustomizeThemeActivity; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeViewModel; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.MaterialYouUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; - /** * A simple {@link Fragment} subclass. */ @@ -44,9 +50,23 @@ public class ThemePreferenceFragment extends PreferenceFragmentCompat { private AppCompatActivity activity; @Inject + @Named("default") + SharedPreferences sharedPreferences; + @Inject + @Named("light_theme") + SharedPreferences lightThemeSharedPreferences; + @Inject + @Named("dark_theme") + SharedPreferences darkThemeSharedPreferences; + @Inject + @Named("amoled_theme") + SharedPreferences amoledThemeSharedPreferences; + @Inject RedditDataRoomDatabase redditDataRoomDatabase; @Inject CustomThemeWrapper customThemeWrapper; + @Inject + Executor executor; public CustomThemeViewModel customThemeViewModel; @Override @@ -61,6 +81,8 @@ public class ThemePreferenceFragment extends PreferenceFragmentCompat { Preference customizeDarkThemePreference = findPreference(SharedPreferencesUtils.CUSTOMIZE_DARK_THEME); Preference customizeAmoledThemePreference = findPreference(SharedPreferencesUtils.CUSTOMIZE_AMOLED_THEME); Preference selectAndCustomizeThemePreference = findPreference(SharedPreferencesUtils.MANAGE_THEMES); + SwitchPreference enableMaterialYouSwitchPreference = findPreference(SharedPreferencesUtils.ENABLE_MATERIAL_YOU); + Preference applyMaterialYouPreference = findPreference(SharedPreferencesUtils.APPLY_MATERIAL_YOU); boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; if (themePreference != null && amoledDarkSwitch != null) { @@ -151,6 +173,32 @@ public class ThemePreferenceFragment extends PreferenceFragmentCompat { }); } + if (enableMaterialYouSwitchPreference != null && applyMaterialYouPreference != null) { + applyMaterialYouPreference.setVisible( + sharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_MATERIAL_YOU, false)); + + enableMaterialYouSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { + if ((Boolean) newValue) { + MaterialYouUtils.changeTheme(activity, executor, new Handler(), + redditDataRoomDatabase, customThemeWrapper, + lightThemeSharedPreferences, darkThemeSharedPreferences, + amoledThemeSharedPreferences, null); + applyMaterialYouPreference.setVisible(true); + } else { + applyMaterialYouPreference.setVisible(false); + } + return true; + }); + + applyMaterialYouPreference.setOnPreferenceClickListener(preference -> { + MaterialYouUtils.changeTheme(activity, executor, new Handler(), + redditDataRoomDatabase, customThemeWrapper, + lightThemeSharedPreferences, darkThemeSharedPreferences, + amoledThemeSharedPreferences, null); + return true; + }); + } + customThemeViewModel = new ViewModelProvider(this, new CustomThemeViewModel.Factory(redditDataRoomDatabase)) .get(CustomThemeViewModel.class); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Translation.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Translation.java index 84b8bd11..53ca6735 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Translation.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Translation.java @@ -18,30 +18,31 @@ public class Translation { public static ArrayList<Translation> getTranslationContributors() { ArrayList<Translation> translationContributors = new ArrayList<>(); translationContributors.add(new Translation("български", "Iliqiliev373, zerw, Кристиян", R.drawable.flag_bulgaria)); - translationContributors.add(new Translation("简体中文", "1, 3273676671, AaronFeng, Angela Thayer, Bitlabwzh, cdggqa, deluxghost, Dwhite, Gloria, History_exe, Justin, Ray, Steps, Tunicar, wert", R.drawable.flag_china)); - translationContributors.add(new Translation("繁體中文", "1, Angela Thayer, Ray", R.drawable.flag_china)); - translationContributors.add(new Translation("Hrvatski", "Josip", R.drawable.flag_croatia)); + translationContributors.add(new Translation("简体中文", "1, 3273676671, AaronFeng, Angela Thayer, Bitlabwzh, cdggqa, deluxghost, Dwhite, Gloria, gzwoyikythba, History_exe, Justin, Ray, Steps, Tunicar, wert", R.drawable.flag_china)); + translationContributors.add(new Translation("繁體中文", "1, Angela Thayer, Hbhuh, Ray", R.drawable.flag_china)); + translationContributors.add(new Translation("Hrvatski", "Andrej Ivanusec, Josip", R.drawable.flag_croatia)); translationContributors.add(new Translation("Nederlands", "KevinHF, Khawkfist, Mert", R.drawable.flag_netherlands)); translationContributors.add(new Translation("Esperanto", "AnimatorzPolski", -1)); translationContributors.add(new Translation("Française", "367, Darlene Sonalder, escatrag, Finn Olmsted, Imperator, Johan, Kerim Demirkaynak, oursonbleu, Owen, pinembour", R.drawable.flag_france)); - translationContributors.add(new Translation("Deutsche", "adth03, ducc1, Jan, Joe, Jorge, Kerim Demirkaynak, Netto Hikari, Nikodiamond3, NotABot34, translatewingman, translatorwiz", R.drawable.flag_germany)); + translationContributors.add(new Translation("Deutsche", "adth03, ducc1, Jan, Joe, Jorge, Kerim Demirkaynak, Lm41, Netto Hikari, Nikodiamond3, NotABot34, Tischleindeckdich, translatewingman, translatorwiz", R.drawable.flag_germany)); translationContributors.add(new Translation("Ελληνικά", "fresh, Marios, Viktor", R.drawable.flag_greece)); + translationContributors.add(new Translation("עִברִית", "Yuval", R.drawable.flag_israel)); translationContributors.add(new Translation("हिंदी", "a, Arya, charu, EnArvy, Harshit S Lawaniya, Mrigendra Bhandari, Nikhilcaddilac, prat, raghav, Sachin, Ved", R.drawable.flag_india)); - translationContributors.add(new Translation("Magyar", "Balázs, Bro momento, ekaktusz, Zoltan", R.drawable.flag_hungary)); - translationContributors.add(new Translation("Italiana", "Daniele Basso, DanOlivaw, Enri. braga, Gianni00palmieri, Gillauino, Giovanni, Giovanni Donisi, Matisse, Simoneg. work, ztiaa", R.drawable.flag_italy)); + translationContributors.add(new Translation("Magyar", "Balázs, Bro momento, ekaktusz, trebron, Zoltan", R.drawable.flag_hungary)); + translationContributors.add(new Translation("Italiana", "Daniele Basso, DanOlivaw, Enri. braga, Gianni00palmieri, Gillauino, Gio. gavio01, Giovanni, Giovanni Donisi, Lorenzo, Matisse, Simoneg. work, ztiaa", R.drawable.flag_italy)); translationContributors.add(new Translation("日本語", "Hira, Issa, Kerim Demirkaynak, Mrigendra Bhandari, Ryan", R.drawable.flag_japan)); translationContributors.add(new Translation("한국어", "noname", R.drawable.flag_south_korea)); translationContributors.add(new Translation("norsk", "", R.drawable.flag_norway)); - translationContributors.add(new Translation("Polskie", "Chupacabra, Erax, Kajetan, Maks, quark", R.drawable.flag_poland)); + translationContributors.add(new Translation("Polskie", "Chupacabra, Erax, Kajetan, Maks, quark, ultrakox", R.drawable.flag_poland)); translationContributors.add(new Translation("Português", "., Bruno Guerreiro, Gabriel, Henry, Lucas, Ricky", R.drawable.flag_portugal)); - translationContributors.add(new Translation("Português (BR)", "., Asfuri, Davy, Laura Vasconcellos Pereira Felippe, luccipriano, Raul S., Ricardo, Ricky, Super_Iguanna, T. tony. br01, vsc", R.drawable.flag_brazil)); - translationContributors.add(new Translation("Română", "Loading Official", R.drawable.flag_romania)); - translationContributors.add(new Translation("русский язык", "Angela Thayer, Arseniy Tsekh, aveblazer, CaZzzer, Coolant, Draer, elena, flexagoon, Georgiy, Overseen, Vova", R.drawable.flag_russia)); + translationContributors.add(new Translation("Português (BR)", "., Asfuri, Davy, Júlia Angst Coelho, John Seila, Laura Vasconcellos Pereira Felippe, luccipriano, Raul S., Ricardo, Ricky, Super_Iguanna, T. tony. br01, vsc", R.drawable.flag_brazil)); + translationContributors.add(new Translation("Română", "Loading Official, RabdăInimăȘiTace", R.drawable.flag_romania)); + translationContributors.add(new Translation("русский язык", "Angela Thayer, Anon, Arseniy Tsekh, aveblazer, CaZzzer, Coolant, Craysy, Draer, elena, flexagoon, Georgiy, Overseen, Stambro, Tysontl2007, Vova", R.drawable.flag_russia)); translationContributors.add(new Translation("Soomaali", "Nadir Nour", R.drawable.flag_somalia)); - translationContributors.add(new Translation("Español", "Alejandro, Alfredo, Angel, Angela Thayer, Gaynus, Jorge, Luis Antonio, Miguel, mvstermoe, Nana Snixx, Sergio, Sofia Flores, Theofficialdork", R.drawable.flag_spain)); + translationContributors.add(new Translation("Español", "Agustin, Alejandro, Alfredo, Angel, Angela Thayer, Canutolab, Gaynus, Jorge, Luis Antonio, Meh, Miguel, mvstermoe, Nana Snixx, Sergio, Sofia Flores, Theofficialdork, Tirso Carranza", R.drawable.flag_spain)); translationContributors.add(new Translation("svenska", "Marcus Nordberg", R.drawable.flag_sweden)); translationContributors.add(new Translation("Türkçe", "adth03, Berk Bakır \"Faoiltiarna\", Emir481, Faoiltiarna, Kerim Demirkaynak, Mehmet Yavuz, Mert, Serif", R.drawable.flag_turkey)); - translationContributors.add(new Translation("Tiếng Việt", "Kai, Laezzy, Lmao, Ryan, viecdet69", R.drawable.flag_vietnam)); + translationContributors.add(new Translation("Tiếng Việt", "bruh, Kai, Laezzy, Lmao, Ryan, viecdet69", R.drawable.flag_vietnam)); return translationContributors; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TranslationFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TranslationFragment.java index a0f9cd1e..62f5c50a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TranslationFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TranslationFragment.java @@ -9,7 +9,6 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import javax.inject.Inject; @@ -44,7 +43,6 @@ public class TranslationFragment extends Fragment { ButterKnife.bind(this, rootView); TranslationFragmentRecyclerViewAdapter adapter = new TranslationFragmentRecyclerViewAdapter(activity, customThemeWrapper); - recyclerView.setLayoutManager(new LinearLayoutManager(activity)); recyclerView.setAdapter(adapter); return rootView; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/VideoPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/VideoPreferenceFragment.java index f7941534..6a89dcd6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/VideoPreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/VideoPreferenceFragment.java @@ -22,6 +22,7 @@ import javax.inject.Named; import ml.docilealligator.infinityforreddit.events.ChangeAutoplayNsfwVideosEvent; import ml.docilealligator.infinityforreddit.events.ChangeMuteAutoplayingVideosEvent; import ml.docilealligator.infinityforreddit.events.ChangeMuteNSFWVideoEvent; +import ml.docilealligator.infinityforreddit.events.ChangeRememberMutingOptionInPostFeedEvent; import ml.docilealligator.infinityforreddit.events.ChangeStartAutoplayVisibleAreaOffsetEvent; import ml.docilealligator.infinityforreddit.events.ChangeVideoAutoplayEvent; import ml.docilealligator.infinityforreddit.Infinity; @@ -43,6 +44,7 @@ public class VideoPreferenceFragment extends PreferenceFragmentCompat { ListPreference videoAutoplayListPreference = findPreference(SharedPreferencesUtils.VIDEO_AUTOPLAY); SwitchPreference muteAutoplayingVideosSwitchPreference = findPreference(SharedPreferencesUtils.MUTE_AUTOPLAYING_VIDEOS); + SwitchPreference rememberMutingOptionInPostFeedSwitchPreference = findPreference(SharedPreferencesUtils.REMEMBER_MUTING_OPTION_IN_POST_FEED); SwitchPreference muteNSFWVideosSwitchPreference = findPreference(SharedPreferencesUtils.MUTE_NSFW_VIDEO); SwitchPreference autoplayNsfwVideosSwitchPreference = findPreference(SharedPreferencesUtils.AUTOPLAY_NSFW_VIDEOS); SeekBarPreference startAutoplayVisibleAreaOffsetPortrait = findPreference(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_PORTRAIT); @@ -74,6 +76,13 @@ public class VideoPreferenceFragment extends PreferenceFragmentCompat { }); } + if (rememberMutingOptionInPostFeedSwitchPreference != null) { + rememberMutingOptionInPostFeedSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeRememberMutingOptionInPostFeedEvent((Boolean) newValue)); + return true; + }); + } + int orientation = getResources().getConfiguration().orientation; if (startAutoplayVisibleAreaOffsetPortrait != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/ParseSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/ParseSubredditData.java index d673647d..694d5900 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/ParseSubredditData.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/ParseSubredditData.java @@ -13,12 +13,12 @@ import java.util.ArrayList; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.Utils; -class ParseSubredditData { - static void parseSubredditData(String response, ParseSubredditDataListener parseSubredditDataListener) { +public class ParseSubredditData { + public static void parseSubredditData(String response, ParseSubredditDataListener parseSubredditDataListener) { new ParseSubredditDataAsyncTask(response, parseSubredditDataListener).execute(); } - static void parseSubredditListingData(String response, boolean nsfw, ParseSubredditListingDataListener parseSubredditListingDataListener) { + public static void parseSubredditListingData(String response, boolean nsfw, ParseSubredditListingDataListener parseSubredditListingDataListener) { new ParseSubredditListingDataAsyncTask(response, nsfw, parseSubredditListingDataListener).execute(); } @@ -70,7 +70,7 @@ class ParseSubredditData { void onParseSubredditDataFail(); } - interface ParseSubredditListingDataListener { + public interface ParseSubredditListingDataListener { void onParseSubredditListingDataSuccess(ArrayList<SubredditData> subredditData, String after); void onParseSubredditListingDataFail(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditSubscription.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditSubscription.java index 7302dd6a..242edf18 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditSubscription.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditSubscription.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.concurrent.Executor; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; import ml.docilealligator.infinityforreddit.utils.APIUtils; @@ -129,7 +130,7 @@ public class SubredditSubscription { subredditData.getIconUrl(), accountName, false); if (accountName.equals("-")) { if (!redditDataRoomDatabase.accountDao().isAnonymousAccountInserted()) { - redditDataRoomDatabase.accountDao().insertAnonymousAccount(); + redditDataRoomDatabase.accountDao().insert(Account.getAnonymousAccount()); } } redditDataRoomDatabase.subscribedSubredditDao().insert(subscribedSubredditData); @@ -144,7 +145,7 @@ public class SubredditSubscription { executor.execute(() -> { if (accountName.equals("-")) { if (!redditDataRoomDatabase.accountDao().isAnonymousAccountInserted()) { - redditDataRoomDatabase.accountDao().insertAnonymousAccount(); + redditDataRoomDatabase.accountDao().insert(Account.getAnonymousAccount()); } } redditDataRoomDatabase.subscribedSubredditDao().deleteSubscribedSubreddit(subredditName, accountName); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java index fb49b49e..465a31eb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java @@ -22,6 +22,7 @@ public class APIUtils { public static final String REDGIFS_API_BASE_URI = "https://api.redgifs.com/v1/gfycats/"; public static final String IMGUR_API_BASE_URI = "https://api.imgur.com/3/"; public static final String PUSHSHIFT_API_BASE_URI = "https://api.pushshift.io/"; + public static final String STRAPI_BASE_URI = "https://strapi.reddit.com"; public static final String CLIENT_ID_KEY = "client_id"; public static final String CLIENT_ID = "NOe2iKrPPzwscA"; @@ -72,6 +73,7 @@ public class APIUtils { public static final String SPOILER_KEY = "spoiler"; public static final String NSFW_KEY = "nsfw"; public static final String CROSSPOST_FULLNAME_KEY = "crosspost_fullname"; + public static final String SEND_REPLIES_KEY = "sendreplies"; public static final String KIND_KEY = "kind"; public static final String KIND_SELF = "self"; public static final String KIND_LINK = "link"; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java index 8ba23bf4..b76f198e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java @@ -135,4 +135,40 @@ public class JSONUtils { public static final String WEBM_URL_KEY = "webmUrl"; public static final String UPVOTE_RATIO_KEY = "upvote_ratio"; public static final String INBOX_COUNT_KEY = "inbox_count"; + public static final String NEXT_CURSOR_KEY = "next_cursor"; + public static final String POST_KEY = "post"; + public static final String STYLES_KEY = "styles"; + public static final String AUTHOR_INFO_KEY= "authorInfo"; + public static final String VOTE_STATE_KEY = "voteState"; + public static final String UPVOTE_RATIO_CAMEL_CASE_KEY = "upvoteRatio"; + public static final String OUTBOUND_LINK_KEY = "outboundLink"; + public static final String IS_NSFW_KEY = "isNsfw"; + public static final String IS_LOCKED_KEY = "isLocked"; + public static final String IS_ARCHIVED_KEY = "isArchived"; + public static final String IS_SPOILER = "isSpoiler"; + public static final String SUGGESTED_COMMENT_SORT_CAMEL_CASE_KEY = "suggestedCommentSort"; + public static final String LIVE_COMMENTS_WEBSOCKET_KEY = "liveCommentsWebsocket"; + public static final String ICON_KEY = "icon"; + public static final String STREAM_KEY = "stream"; + public static final String STREAM_ID_KEY = "stream_id"; + public static final String THUMBNAIL_KEY = "thumbnail"; + public static final String PUBLISH_AT_KEY = "publish_at"; + public static final String STATE_KEY = "state"; + public static final String UPVOTES_KEY = "upvotes"; + public static final String DOWNVOTES_KEY = "downvotes"; + public static final String UNIQUE_WATCHERS_KEY = "unique_watchers"; + public static final String CONTINUOUS_WATCHERS_KEY = "continuous_watchers"; + public static final String TOTAL_CONTINUOUS_WATCHERS_KEY = "total_continuous_watchers"; + public static final String CHAT_DISABLED_KEY = "chat_disabled"; + public static final String BROADCAST_TIME_KEY = "broadcast_time"; + public static final String ESTIMATED_REMAINING_TIME_KEY = "estimated_remaining_time"; + public static final String PAYLOAD_KEY = "payload"; + public static final String AUTHOR_ICON_IMAGE = "author_icon_img"; + public static final String ASSET_KEY = "asset"; + public static final String ASSET_ID_KEY = "asset_id"; + public static final String TRENDING_SEARCHES_KEY = "trending_searches"; + public static final String QUERY_STRING_KEY = "query_string"; + public static final String DISPLAY_STRING_KEY = "display_string"; + public static final String RESULTS_KEY = "results"; + public static final String CONTENT_MD_KEY = "content_md"; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/MaterialYouUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/MaterialYouUtils.java new file mode 100644 index 00000000..d470e1d0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/MaterialYouUtils.java @@ -0,0 +1,155 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.app.WallpaperColors; +import android.app.WallpaperManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.os.Build; +import android.os.Handler; + +import androidx.annotation.ColorInt; +import androidx.annotation.Nullable; + +import org.greenrobot.eventbus.EventBus; + +import java.util.concurrent.Executor; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; + +public class MaterialYouUtils { + public interface CheckThemeNameListener { + void themeNotExists(); + void themeExists(); + } + + public static void checkThemeName(Executor executor, Handler handler, + RedditDataRoomDatabase redditDataRoomDatabase, + CheckThemeNameListener checkThemeNameListener) { + executor.execute(() -> { + if (redditDataRoomDatabase.customThemeDao().getCustomTheme("Material You") != null + || redditDataRoomDatabase.customThemeDao().getCustomTheme("Material You Dark") != null + || redditDataRoomDatabase.customThemeDao().getCustomTheme("Material You Amoled") != null) { + handler.post(checkThemeNameListener::themeExists); + } else { + handler.post(checkThemeNameListener::themeNotExists); + } + }); + } + + public static void changeTheme(Context context, Executor executor, Handler handler, + RedditDataRoomDatabase redditDataRoomDatabase, + CustomThemeWrapper customThemeWrapper, + SharedPreferences lightThemeSharedPreferences, + SharedPreferences darkThemeSharedPreferences, + SharedPreferences amoledThemeSharedPreferences, + @Nullable MaterialYouListener materialYouListener) { + executor.execute(() -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + WallpaperManager wallpaperManager = WallpaperManager.getInstance(context); + WallpaperColors wallpaperColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM); + + if (wallpaperColors != null) { + int colorPrimaryInt = lightenColor(wallpaperColors.getPrimaryColor().toArgb(), 0.4); + int colorPrimaryDarkInt = darkenColor(colorPrimaryInt, 0.3); + int backgroundColor = lightenColor(colorPrimaryInt, 0.2); + int cardViewBackgroundColor = lightenColor(colorPrimaryInt, 0.6); + Color colorAccent = wallpaperColors.getSecondaryColor(); + int colorAccentInt = lightenColor(colorAccent == null ? customThemeWrapper.getColorAccent() : colorAccent.toArgb(), 0.4); + + int colorPrimaryAppropriateTextColor = getAppropriateTextColor(colorPrimaryInt); + int backgroundColorAppropriateTextColor = getAppropriateTextColor(backgroundColor); + + CustomTheme lightTheme = CustomThemeWrapper.getIndigo(context); + CustomTheme darkTheme = CustomThemeWrapper.getIndigoDark(context); + CustomTheme amoledTheme = CustomThemeWrapper.getIndigoAmoled(context); + + lightTheme.colorPrimary = colorPrimaryInt; + lightTheme.colorPrimaryDark = colorPrimaryDarkInt; + lightTheme.colorAccent = colorAccentInt; + lightTheme.colorPrimaryLightTheme = colorPrimaryInt; + lightTheme.backgroundColor = backgroundColor; + lightTheme.cardViewBackgroundColor = cardViewBackgroundColor; + lightTheme.commentBackgroundColor = cardViewBackgroundColor; + lightTheme.awardedCommentBackgroundColor = cardViewBackgroundColor; + lightTheme.bottomAppBarBackgroundColor = colorPrimaryInt; + lightTheme.navBarColor = colorPrimaryInt; + lightTheme.primaryTextColor = backgroundColorAppropriateTextColor; + lightTheme.secondaryTextColor = backgroundColorAppropriateTextColor == Color.BLACK ? Color.parseColor("#8A000000") : Color.parseColor("#B3FFFFFF"); + lightTheme.bottomAppBarIconColor = colorPrimaryAppropriateTextColor; + lightTheme.primaryIconColor = backgroundColorAppropriateTextColor; + lightTheme.fabIconColor = colorPrimaryAppropriateTextColor; + lightTheme.toolbarPrimaryTextAndIconColor = colorPrimaryAppropriateTextColor; + lightTheme.toolbarSecondaryTextColor = colorPrimaryAppropriateTextColor; + lightTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = colorPrimaryAppropriateTextColor; + lightTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = colorPrimaryAppropriateTextColor; + lightTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = colorPrimaryInt; + lightTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = colorPrimaryInt; + lightTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = colorPrimaryAppropriateTextColor; + lightTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = colorPrimaryAppropriateTextColor; + lightTheme.circularProgressBarBackground = colorPrimaryInt; + lightTheme.dividerColor = backgroundColorAppropriateTextColor == Color.BLACK ? Color.parseColor("#E0E0E0") : Color.parseColor("69666C"); + lightTheme.isLightStatusBar = colorPrimaryAppropriateTextColor == Color.BLACK; + lightTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = + (lightTheme.isLightStatusBar && getAppropriateTextColor(cardViewBackgroundColor) == Color.WHITE) + || (!lightTheme.isLightStatusBar && getAppropriateTextColor(cardViewBackgroundColor) == Color.BLACK); + lightTheme.name = "Material You"; + + darkTheme.colorAccent = colorPrimaryInt; + darkTheme.colorPrimaryLightTheme = colorPrimaryInt; + darkTheme.name = "Material You Dark"; + + amoledTheme.colorAccent = colorPrimaryInt; + amoledTheme.colorPrimaryLightTheme = colorPrimaryInt; + amoledTheme.name = "Material You Amoled"; + + redditDataRoomDatabase.customThemeDao().unsetLightTheme(); + redditDataRoomDatabase.customThemeDao().unsetDarkTheme(); + redditDataRoomDatabase.customThemeDao().unsetAmoledTheme(); + + redditDataRoomDatabase.customThemeDao().insert(lightTheme); + redditDataRoomDatabase.customThemeDao().insert(darkTheme); + redditDataRoomDatabase.customThemeDao().insert(amoledTheme); + + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(lightTheme, lightThemeSharedPreferences); + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(darkTheme, darkThemeSharedPreferences); + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(amoledTheme, amoledThemeSharedPreferences); + + handler.post(() -> { + if (materialYouListener != null) { + materialYouListener.applied(); + } + EventBus.getDefault().post(new RecreateActivityEvent()); + }); + } + } + }); + } + + private static int lightenColor(int color, double ratio) { + return Color.argb(Color.alpha(color), (int) (Color.red(color) + (255 - Color.red(color)) * ratio), + (int) (Color.green(color) + (255 - Color.green(color)) * ratio), + (int) (Color.blue(color) + (255 - Color.blue(color)) * ratio)); + } + + private static int darkenColor(int color, double ratio) { + return Color.argb(Color.alpha(color), (int) (Color.red(color) * (1 - ratio)), + (int) (Color.green(color) * (1 - ratio)), + (int) (Color.blue(color) * (1 - ratio))); + + } + + @ColorInt + public static int getAppropriateTextColor(@ColorInt int color) { + // Counting the perceptive luminance - human eye favors green color... + double luminance = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255; + return luminance < 0.5 ? Color.BLACK : Color.WHITE; + } + + public interface MaterialYouListener { + void applied(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java index 3c3255de..5552271f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java @@ -22,11 +22,14 @@ public class NotificationUtils { public static final String CHANNEL_DOWNLOAD_IMAGE = "Download Image"; public static final String CHANNEL_ID_DOWNLOAD_GIF = "download_gif"; public static final String CHANNEL_DOWNLOAD_GIF = "Download Gif"; + public static final String CHANNEL_ID_MATERIAL_YOU = "material_you"; + public static final String CHANNEL_MATERIAL_YOU = "Material You"; public static final int SUBMIT_POST_SERVICE_NOTIFICATION_ID = 10000; public static final int DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID = 20000; public static final int DOWNLOAD_VIDEO_NOTIFICATION_ID = 30000; public static final int DOWNLOAD_IMAGE_NOTIFICATION_ID = 40000; public static final int DOWNLOAD_GIF_NOTIFICATION_ID = 50000; + public static final int MATERIAL_YOU_NOTIFICATION_ID = 60000; private static final int SUMMARY_BASE_ID_UNREAD_MESSAGE = 0; private static final int NOTIFICATION_BASE_ID_UNREAD_MESSAGE = 1; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java index dc585d93..f3247d99 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java @@ -87,6 +87,7 @@ public class SharedPreferencesUtils { public static final String NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT_GALLERY_LAYOUT = "number_of_columns_in_post_feed_portrait_gallery_layout"; public static final String NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE_GALLERY_LAYOUT = "number_of_columns_in_post_feed_landscape_gallery_layout"; public static final String SWIPE_RIGHT_TO_GO_BACK = "swipe_to_go_back_from_post_detail"; + public static final String SWIPE_VERTICALLY_TO_GO_BACK_FROM_MEDIA = "swipe_vertically_to_go_back_from_media"; public static final String VOLUME_KEYS_NAVIGATE_COMMENTS = "volume_keys_navigate_comments"; public static final String VOLUME_KEYS_NAVIGATE_POSTS = "volume_keys_navigate_posts"; public static final String MUTE_VIDEO = "mute_video"; @@ -165,6 +166,7 @@ public class SharedPreferencesUtils { public static final String USER_DEFAULT_SORT_TIME = "user_default_sort_time"; public static final String CLICK_TO_SHOW_MEDIA_IN_GALLERY_LAYOUT = "click_to_show_media_in_gallery_layout"; public static final String HIDE_POST_TYPE = "hide_post_type"; + public static final String HIDE_POST_FLAIR = "hide_post_flair"; public static final String HIDE_THE_NUMBER_OF_AWARDS = "hide_the_number_of_awards"; public static final String HIDE_SUBREDDIT_AND_USER_PREFIX = "hide_subreddit_and_user_prefix"; public static final String HIDE_THE_NUMBER_OF_VOTES = "hide_the_number_of_votes"; @@ -177,6 +179,14 @@ public class SharedPreferencesUtils { public static final String NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT_CARD_LAYOUT_2 = "number_of_columns_in_post_feed_portrait_card_layout_2"; public static final String NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE_CARD_LAYOUT_2 = "number_of_columns_in_post_feed_landscape_card_layout_2"; public static final String DISABLE_NSFW_FOREVER = "disable_nsfw_forever"; + public static final String SHOW_ONLY_ONE_COMMENT_LEVEL_INDICATOR = "show_only_one_comment_level_indicator"; + public static final String ENABLE_MATERIAL_YOU = "enable_material_you"; + public static final String APPLY_MATERIAL_YOU = "apply_material_you"; + public static final String VIDEO_PLAYER_AUTOMATIC_LANDSCAPE_ORIENTATION = "video_player_automatic_landscape_orientation"; + public static final String REMEMBER_MUTING_OPTION_IN_POST_FEED = "remember_muting_option_in_post_feed"; + public static final String DEFAULT_LINK_POST_LAYOUT_KEY = "default_link_post_layout"; + public static final String USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER = "use_bottom_toolbar_in_media_viewer"; + public static final String SECURE_MODE = "secure_mode"; public static final String DEFAULT_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit_preferences"; public static final String MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.main_page_tabs"; @@ -202,6 +212,8 @@ public class SharedPreferencesUtils { public static final int MAIN_PAGE_TAB_POST_TYPE_HIDDEN = 8; public static final int MAIN_PAGE_TAB_POST_TYPE_SAVED = 9; public static final int MAIN_PAGE_TAB_POST_TYPE_GILDED = 10; + public static final String MAIN_PAGE_SHOW_MULTIREDDITS = "_main_page_show_multireddits"; + public static final String MAIN_PAGE_SHOW_FAVORITE_MULTIREDDITS = "_main_page_show_favorite_multireddits"; public static final String MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS = "_main_page_show_subscribed_subreddits"; public static final String MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS = "_main_page_show_favorite_subscribed_subreddits"; @@ -301,6 +313,7 @@ public class SharedPreferencesUtils { public static final String NAVIGATION_DRAWER_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.navigation_drawer"; public static final String COLLAPSE_ACCOUNT_SECTION = "collapse_account_section"; + public static final String COLLAPSE_REDDIT_SECTION = "collapse_reddit_section"; public static final String COLLAPSE_POST_SECTION = "collapse_post_section"; public static final String COLLAPSE_PREFERENCES_SECTION = "collapse_preferences_section"; public static final String COLLAPSE_FAVORITE_SUBREDDITS_SECTION = "collapse_favorite_subreddits_section"; @@ -308,6 +321,10 @@ public class SharedPreferencesUtils { public static final String HIDE_FAVORITE_SUBREDDITS_SECTION = "hide_favorite_subreddits_sections"; public static final String HIDE_SUBSCRIBED_SUBREDDITS_SECTIONS = "hide_subscribed_subreddits_sections"; + public static final String POST_DETAILS_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.post_details"; + public static final String SEPARATE_POST_AND_COMMENTS_IN_PORTRAIT_MODE = "separate_post_and_comments_in_portrait_mode"; + public static final String SEPARATE_POST_AND_COMMENTS_IN_LANDSCAPE_MODE = "separate_post_and_comments_in_landscape_mode"; + //Legacy Settings public static final String MAIN_PAGE_TAB_1_TITLE_LEGACY = "main_page_tab_1_title"; public static final String MAIN_PAGE_TAB_2_TITLE_LEGACY = "main_page_tab_2_title"; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/UploadImageUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/UploadImageUtils.java new file mode 100644 index 00000000..c7b5f728 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/UploadImageUtils.java @@ -0,0 +1,107 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.graphics.Bitmap; + +import androidx.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class UploadImageUtils { + @Nullable + public static String uploadImage(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + String accessToken, Bitmap image) throws IOException, JSONException, XmlPullParserException { + return uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, image, false); + } + + @Nullable + public static String uploadImage(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + String accessToken, Bitmap image, boolean returnResponseForGallerySubmission) throws IOException, JSONException, XmlPullParserException { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Map<String, String> uploadImageParams = new HashMap<>(); + uploadImageParams.put(APIUtils.FILEPATH_KEY, "post_image.jpg"); + uploadImageParams.put(APIUtils.MIMETYPE_KEY, "image/jpeg"); + + Call<String> uploadImageCall = api.uploadImage(APIUtils.getOAuthHeader(accessToken), uploadImageParams); + Response<String> uploadImageResponse = uploadImageCall.execute(); + if (uploadImageResponse.isSuccessful()) { + Map<String, RequestBody> nameValuePairsMap = parseJSONResponseFromAWS(uploadImageResponse.body()); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + image.compress(Bitmap.CompressFormat.JPEG, 100, stream); + byte[] byteArray = stream.toByteArray(); + + RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), byteArray); + MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_image.jpg", fileBody); + + RedditAPI uploadMediaToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); + Call<String> uploadMediaToAWS = uploadMediaToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); + Response<String> uploadMediaToAWSResponse = uploadMediaToAWS.execute(); + if (uploadMediaToAWSResponse.isSuccessful()) { + if (returnResponseForGallerySubmission) { + return uploadImageResponse.body(); + } + return parseXMLResponseFromAWS(uploadMediaToAWSResponse.body()); + } else { + return "Error: " + uploadMediaToAWSResponse.code(); + } + } else { + return "Error: " + uploadImageResponse.message(); + } + } + + @Nullable + public static String parseXMLResponseFromAWS(String response) throws XmlPullParserException, IOException { + XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser(); + xmlPullParser.setInput(new StringReader(response)); + + boolean isLocationTag = false; + int eventType = xmlPullParser.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + if (xmlPullParser.getName().equals("Location")) { + isLocationTag = true; + } + } else if (eventType == XmlPullParser.TEXT) { + if (isLocationTag) { + return xmlPullParser.getText(); + } + } + eventType = xmlPullParser.next(); + } + + return null; + } + + public static Map<String, RequestBody> parseJSONResponseFromAWS(String response) throws JSONException { + JSONObject responseObject = new JSONObject(response); + JSONArray nameValuePairs = responseObject.getJSONObject(JSONUtils.ARGS_KEY).getJSONArray(JSONUtils.FIELDS_KEY); + + Map<String, RequestBody> nameValuePairsMap = new HashMap<>(); + for (int i = 0; i < nameValuePairs.length(); i++) { + nameValuePairsMap.put(nameValuePairs.getJSONObject(i).getString(JSONUtils.NAME_KEY), + APIUtils.getRequestBody(nameValuePairs.getJSONObject(i).getString(JSONUtils.VALUE_KEY))); + } + + return nameValuePairsMap; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java index 1044f49c..ad2b7405 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java @@ -1,32 +1,53 @@ package ml.docilealligator.infinityforreddit.utils; import android.app.Activity; +import android.content.ContentResolver; import android.content.Context; +import android.database.Cursor; +import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; +import android.net.Uri; import android.os.Build; +import android.os.Handler; +import android.provider.OpenableColumns; import android.text.Spannable; import android.util.DisplayMetrics; import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.text.HtmlCompat; +import com.bumptech.glide.Glide; +import com.google.android.material.snackbar.Snackbar; + +import org.json.JSONException; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Calendar; import java.util.Locale; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; import java.util.regex.Matcher; import java.util.regex.Pattern; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.UploadedImage; +import retrofit2.Retrofit; public class Utils { public static final int NETWORK_TYPE_OTHER = -1; @@ -199,15 +220,17 @@ public class Utils { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Network nw = connMgr.getActiveNetwork(); if (nw == null) return NETWORK_TYPE_OTHER; - NetworkCapabilities actNw = connMgr.getNetworkCapabilities(nw); - if (actNw != null) { - if (actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { - return NETWORK_TYPE_WIFI; + try { + NetworkCapabilities actNw = connMgr.getNetworkCapabilities(nw); + if (actNw != null) { + if (actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { + return NETWORK_TYPE_WIFI; + } + if (actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { + return NETWORK_TYPE_CELLULAR; + } } - if (actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - return NETWORK_TYPE_CELLULAR; - } - } + } catch (SecurityException ignore) {} return NETWORK_TYPE_OTHER; } else { boolean isWifi = false; @@ -290,6 +313,13 @@ public class Utils { } public static void hideKeyboard(Activity activity) { + /*if (activity.getCurrentFocus() == null || !(activity.getCurrentFocus() instanceof EditText)) { + editText.requestFocus(); + } + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);*/ + InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); if (inputMethodManager != null && activity.getCurrentFocus() != null) { inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0); @@ -311,4 +341,61 @@ public class Utils { return null; } + + public static void uploadImageToReddit(Context context, Executor executor, Retrofit oauthRetrofit, + Retrofit uploadMediaRetrofit, String accessToken, EditText editText, + CoordinatorLayout coordinatorLayout, Uri imageUri, + ArrayList<UploadedImage>uploadedImages) { + Toast.makeText(context, R.string.uploading_image, Toast.LENGTH_SHORT).show(); + Handler handler = new Handler(); + executor.execute(() -> { + try { + Bitmap bitmap = Glide.with(context).asBitmap().load(imageUri).submit().get(); + String imageUrlOrError = UploadImageUtils.uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, bitmap); + handler.post(() -> { + if (imageUrlOrError != null && !imageUrlOrError.startsWith("Error: ")) { + String fileName = Utils.getFileName(context, imageUri); + if (fileName == null) { + fileName = imageUrlOrError; + } + uploadedImages.add(new UploadedImage(fileName, imageUrlOrError)); + + int start = Math.max(editText.getSelectionStart(), 0); + int end = Math.max(editText.getSelectionEnd(), 0); + editText.getText().replace(Math.min(start, end), Math.max(start, end), + "[" + fileName + "](" + imageUrlOrError + ")", + 0, "[]()".length() + fileName.length() + imageUrlOrError.length()); + Snackbar.make(coordinatorLayout, R.string.upload_image_success, Snackbar.LENGTH_LONG).show(); + } else { + Toast.makeText(context, R.string.upload_image_failed, Toast.LENGTH_LONG).show(); + } + }); + } catch (ExecutionException | InterruptedException e) { + e.printStackTrace(); + handler.post(() -> Toast.makeText(context, R.string.get_image_bitmap_failed, Toast.LENGTH_LONG).show()); + } catch (XmlPullParserException | JSONException | IOException e) { + e.printStackTrace(); + handler.post(() -> Toast.makeText(context, R.string.error_processing_image, Toast.LENGTH_LONG).show()); + } + }); + } + + @Nullable + public static String getFileName(Context context, Uri uri) { + ContentResolver contentResolver = context.getContentResolver(); + if (contentResolver != null) { + Cursor cursor = contentResolver.query(uri, null, null, null, null); + if (cursor != null) { + int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + cursor.moveToFirst(); + String fileName = cursor.getString(nameIndex); + if(fileName != null && fileName.contains(".")) { + fileName = fileName.substring(0, fileName.lastIndexOf('.')); + } + return fileName; + } + } + + return null; + } } diff --git a/app/src/main/res/drawable-night/ic_gallery_24dp.xml b/app/src/main/res/drawable-night/ic_gallery_24dp.xml index 74716ba7..d54dba10 100644 --- a/app/src/main/res/drawable-night/ic_gallery_24dp.xml +++ b/app/src/main/res/drawable-night/ic_gallery_24dp.xml @@ -1,4 +1,4 @@ -<vector android:height="24dp" android:tint="#000000" +<vector android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@android:color/white" android:pathData="M20,4v12L8,16L8,4h12m0,-2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM11.5,11.67l1.69,2.26 2.48,-3.1L19,15L9,15zM2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6L2,6z"/> diff --git a/app/src/main/res/drawable-night/ic_gallery_reverse_color_24dp.xml b/app/src/main/res/drawable-night/ic_gallery_reverse_color_24dp.xml new file mode 100644 index 00000000..74716ba7 --- /dev/null +++ b/app/src/main/res/drawable-night/ic_gallery_reverse_color_24dp.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#000000" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20,4v12L8,16L8,4h12m0,-2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM11.5,11.67l1.69,2.26 2.48,-3.1L19,15L9,15zM2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6L2,6z"/> +</vector> diff --git a/app/src/main/res/drawable-night/ic_outline_add_a_photo_day_night_24dp.xml b/app/src/main/res/drawable-night/ic_outline_add_a_photo_day_night_24dp.xml new file mode 100644 index 00000000..57869fc5 --- /dev/null +++ b/app/src/main/res/drawable-night/ic_outline_add_a_photo_day_night_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FFFFFF" + android:pathData="M21,6h-3.17L16,4h-6v2h5.12l1.83,2L21,8v12L5,20v-9L3,11v9c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L23,8c0,-1.1 -0.9,-2 -2,-2zM8,14c0,2.76 2.24,5 5,5s5,-2.24 5,-5 -2.24,-5 -5,-5 -5,2.24 -5,5zM13,11c1.65,0 3,1.35 3,3s-1.35,3 -3,3 -3,-1.35 -3,-3 1.35,-3 3,-3zM5,6h3L8,4L5,4L5,1L3,1v3L0,4v2h3v3h2z"/> +</vector> diff --git a/app/src/main/res/drawable-night/ic_outline_select_photo_day_night_24dp.xml b/app/src/main/res/drawable-night/ic_outline_select_photo_day_night_24dp.xml new file mode 100644 index 00000000..136ace9f --- /dev/null +++ b/app/src/main/res/drawable-night/ic_outline_select_photo_day_night_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FFFFFF" + android:pathData="M18,20L4,20L4,6h9L13,4L4,4c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-9h-2v9zM10.21,16.83l-1.96,-2.36L5.5,18h11l-3.54,-4.71zM20,4L20,1h-2v3h-3c0.01,0.01 0,2 0,2h3v2.99c0.01,0.01 2,0 2,0L20,6h3L23,4h-3z"/> +</vector> diff --git a/app/src/main/res/drawable-night/ic_rpan_24dp.xml b/app/src/main/res/drawable-night/ic_rpan_24dp.xml new file mode 100644 index 00000000..1c8156c1 --- /dev/null +++ b/app/src/main/res/drawable-night/ic_rpan_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M21,6h-7.59l3.29,-3.29L16,2l-4,4 -4,-4 -0.71,0.71L10.59,6L3,6c-1.1,0 -2,0.89 -2,2v12c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,8c0,-1.11 -0.9,-2 -2,-2zM21,20L3,20L3,8h18v12zM9,10v8l7,-4z"/> +</vector> diff --git a/app/src/main/res/drawable-night/ic_trending_24dp.xml b/app/src/main/res/drawable-night/ic_trending_24dp.xml new file mode 100644 index 00000000..d441a7f7 --- /dev/null +++ b/app/src/main/res/drawable-night/ic_trending_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M16,6l2.29,2.29 -4.88,4.88 -4,-4L2,16.59 3.41,18l6,-6 4,4 6.3,-6.29L22,12V6z"/> +</vector> diff --git a/app/src/main/res/drawable/background_autoplay.xml b/app/src/main/res/drawable/background_autoplay.xml index 8859f467..fd34b51c 100644 --- a/app/src/main/res/drawable/background_autoplay.xml +++ b/app/src/main/res/drawable/background_autoplay.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > - <solid - android:color="#80000000" /> + <solid + android:color="#40000000" /> - <corners - android:topLeftRadius="16dp" - android:topRightRadius="16dp" /> + <corners + android:topLeftRadius="16dp" + android:topRightRadius="16dp" /> -</shape> +</shape>
\ No newline at end of file diff --git a/app/src/main/res/drawable/exo_player_control_button_circular_background.xml b/app/src/main/res/drawable/exo_player_control_button_circular_background.xml new file mode 100644 index 00000000..363fffc1 --- /dev/null +++ b/app/src/main/res/drawable/exo_player_control_button_circular_background.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > + <size android:width="16dp" android:height="16dp"/> + <solid + android:color="#40000000" /> +</shape>
\ No newline at end of file diff --git a/app/src/main/res/drawable/flag_israel.xml b/app/src/main/res/drawable/flag_israel.xml new file mode 100644 index 00000000..45f3e257 --- /dev/null +++ b/app/src/main/res/drawable/flag_israel.xml @@ -0,0 +1,18 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="512dp" + android:height="512dp" + android:viewportWidth="512" + android:viewportHeight="512"> + <path + android:pathData="M256,256m-256,0a256,256 0,1 1,512 0a256,256 0,1 1,-512 0" + android:fillColor="#F0F0F0"/> + <path + android:pathData="M352.393,200.348H288.13L256,144.696l-32.129,55.652h-64.264L191.741,256l-32.134,55.652h64.264L256,367.304l32.13,-55.652h64.263L320.259,256L352.393,200.348zM295.475,256l-19.736,34.188h-39.475L216.525,256l19.738,-34.188h39.475L295.475,256zM256,187.623l7.346,12.724h-14.69L256,187.623zM196.786,221.812h14.692l-7.346,12.724L196.786,221.812zM196.786,290.188l7.347,-12.724l7.346,12.724H196.786zM256,324.376l-7.345,-12.724h14.691L256,324.376zM315.214,290.188h-14.692l7.347,-12.724L315.214,290.188zM300.522,221.812h14.692l-7.346,12.724L300.522,221.812z" + android:fillColor="#0052B4"/> + <path + android:pathData="M415.357,55.652H96.643c-23.363,18.608 -43.399,41.21 -59.069,66.783h436.852C458.755,96.863 438.719,74.26 415.357,55.652z" + android:fillColor="#0052B4"/> + <path + android:pathData="M96.643,456.348h318.713c23.363,-18.608 43.399,-41.21 59.069,-66.783H37.574C53.245,415.137 73.281,437.74 96.643,456.348z" + android:fillColor="#0052B4"/> +</vector> diff --git a/app/src/main/res/drawable/ic_close_24dp.xml b/app/src/main/res/drawable/ic_close_24dp.xml new file mode 100644 index 00000000..a20716a2 --- /dev/null +++ b/app/src/main/res/drawable/ic_close_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_fullscreen_white_rounded_18dp.xml b/app/src/main/res/drawable/ic_fullscreen_white_rounded_24dp.xml index 9977b60f..0dbedfee 100644 --- a/app/src/main/res/drawable/ic_fullscreen_white_rounded_18dp.xml +++ b/app/src/main/res/drawable/ic_fullscreen_white_rounded_24dp.xml @@ -1,9 +1,9 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="18dp" - android:height="18dp" + android:width="24dp" + android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path - android:pathData="M6,14c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1h3c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L7,17v-2c0,-0.55 -0.45,-1 -1,-1zM6,10c0.55,0 1,-0.45 1,-1L7,7h2c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L6,5c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1zM17,17h-2c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h3c0.55,0 1,-0.45 1,-1v-3c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v2zM14,6c0,0.55 0.45,1 1,1h2v2c0,0.55 0.45,1 1,1s1,-0.45 1,-1L19,6c0,-0.55 -0.45,-1 -1,-1h-3c-0.55,0 -1,0.45 -1,1z" - android:fillColor="#FFFFFF"/> + android:fillColor="@android:color/white" + android:pathData="M6,14c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1h3c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L7,17v-2c0,-0.55 -0.45,-1 -1,-1zM6,10c0.55,0 1,-0.45 1,-1L7,7h2c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L6,5c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1zM17,17h-2c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h3c0.55,0 1,-0.45 1,-1v-3c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v2zM14,6c0,0.55 0.45,1 1,1h2v2c0,0.55 0.45,1 1,1s1,-0.45 1,-1L19,6c0,-0.55 -0.45,-1 -1,-1h-3c-0.55,0 -1,0.45 -1,1z"/> </vector> diff --git a/app/src/main/res/drawable/ic_gallery_24dp.xml b/app/src/main/res/drawable/ic_gallery_24dp.xml index d54dba10..74716ba7 100644 --- a/app/src/main/res/drawable/ic_gallery_24dp.xml +++ b/app/src/main/res/drawable/ic_gallery_24dp.xml @@ -1,4 +1,4 @@ -<vector android:height="24dp" android:tint="#FFFFFF" +<vector android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@android:color/white" android:pathData="M20,4v12L8,16L8,4h12m0,-2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM11.5,11.67l1.69,2.26 2.48,-3.1L19,15L9,15zM2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6L2,6z"/> diff --git a/app/src/main/res/drawable/ic_gallery_reverse_color_24dp.xml b/app/src/main/res/drawable/ic_gallery_reverse_color_24dp.xml new file mode 100644 index 00000000..d54dba10 --- /dev/null +++ b/app/src/main/res/drawable/ic_gallery_reverse_color_24dp.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#FFFFFF" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20,4v12L8,16L8,4h12m0,-2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM11.5,11.67l1.69,2.26 2.48,-3.1L19,15L9,15zM2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6L2,6z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_mute_white_rounded_18dp.xml b/app/src/main/res/drawable/ic_mute_white_rounded_24dp.xml index b4f8f660..bc45d400 100644 --- a/app/src/main/res/drawable/ic_mute_white_rounded_18dp.xml +++ b/app/src/main/res/drawable/ic_mute_white_rounded_24dp.xml @@ -1,9 +1,9 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="18dp" - android:height="18dp" + android:width="24dp" + android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path - android:pathData="M3.63,3.63c-0.39,0.39 -0.39,1.02 0,1.41L7.29,8.7 7,9L4,9c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1h3l3.29,3.29c0.63,0.63 1.71,0.18 1.71,-0.71v-4.17l4.18,4.18c-0.49,0.37 -1.02,0.68 -1.6,0.91 -0.36,0.15 -0.58,0.53 -0.58,0.92 0,0.72 0.73,1.18 1.39,0.91 0.8,-0.33 1.55,-0.77 2.22,-1.31l1.34,1.34c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L5.05,3.63c-0.39,-0.39 -1.02,-0.39 -1.42,0zM19,12c0,0.82 -0.15,1.61 -0.41,2.34l1.53,1.53c0.56,-1.17 0.88,-2.48 0.88,-3.87 0,-3.83 -2.4,-7.11 -5.78,-8.4 -0.59,-0.23 -1.22,0.23 -1.22,0.86v0.19c0,0.38 0.25,0.71 0.61,0.85C17.18,6.54 19,9.06 19,12zM10.29,5.71l-0.17,0.17L12,7.76L12,6.41c0,-0.89 -1.08,-1.33 -1.71,-0.7zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v1.79l2.48,2.48c0.01,-0.08 0.02,-0.16 0.02,-0.24z" - android:fillColor="#ffffff"/> + android:fillColor="@android:color/white" + android:pathData="M3.63,3.63c-0.39,0.39 -0.39,1.02 0,1.41L7.29,8.7 7,9L4,9c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1h3l3.29,3.29c0.63,0.63 1.71,0.18 1.71,-0.71v-4.17l4.18,4.18c-0.49,0.37 -1.02,0.68 -1.6,0.91 -0.36,0.15 -0.58,0.53 -0.58,0.92 0,0.72 0.73,1.18 1.39,0.91 0.8,-0.33 1.55,-0.77 2.22,-1.31l1.34,1.34c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L5.05,3.63c-0.39,-0.39 -1.02,-0.39 -1.42,0zM19,12c0,0.82 -0.15,1.61 -0.41,2.34l1.53,1.53c0.56,-1.17 0.88,-2.48 0.88,-3.87 0,-3.83 -2.4,-7.11 -5.78,-8.4 -0.59,-0.23 -1.22,0.23 -1.22,0.86v0.19c0,0.38 0.25,0.71 0.61,0.85C17.18,6.54 19,9.06 19,12zM10.29,5.71l-0.17,0.17L12,7.76L12,6.41c0,-0.89 -1.08,-1.33 -1.71,-0.7zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v1.79l2.48,2.48c0.01,-0.08 0.02,-0.16 0.02,-0.24z"/> </vector> diff --git a/app/src/main/res/drawable/ic_outline_add_a_photo_day_night_24dp.xml b/app/src/main/res/drawable/ic_outline_add_a_photo_day_night_24dp.xml new file mode 100644 index 00000000..98c1ac80 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_add_a_photo_day_night_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M21,6h-3.17L16,4h-6v2h5.12l1.83,2L21,8v12L5,20v-9L3,11v9c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L23,8c0,-1.1 -0.9,-2 -2,-2zM8,14c0,2.76 2.24,5 5,5s5,-2.24 5,-5 -2.24,-5 -5,-5 -5,2.24 -5,5zM13,11c1.65,0 3,1.35 3,3s-1.35,3 -3,3 -3,-1.35 -3,-3 1.35,-3 3,-3zM5,6h3L8,4L5,4L5,1L3,1v3L0,4v2h3v3h2z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_outline_select_photo_day_night_24dp.xml b/app/src/main/res/drawable/ic_outline_select_photo_day_night_24dp.xml new file mode 100644 index 00000000..9551f621 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_select_photo_day_night_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M18,20L4,20L4,6h9L13,4L4,4c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-9h-2v9zM10.21,16.83l-1.96,-2.36L5.5,18h11l-3.54,-4.71zM20,4L20,1h-2v3h-3c0.01,0.01 0,2 0,2h3v2.99c0.01,0.01 2,0 2,0L20,6h3L23,4h-3z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_pause_white_rounded_18dp.xml b/app/src/main/res/drawable/ic_pause_white_rounded_24dp.xml index 479c57b0..a5e498b5 100644 --- a/app/src/main/res/drawable/ic_pause_white_rounded_18dp.xml +++ b/app/src/main/res/drawable/ic_pause_white_rounded_24dp.xml @@ -1,9 +1,9 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="18dp" - android:height="18dp" + android:width="24dp" + android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path - android:pathData="M8,19c1.1,0 2,-0.9 2,-2L10,7c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2v10c0,1.1 0.9,2 2,2zM14,7v10c0,1.1 0.9,2 2,2s2,-0.9 2,-2L18,7c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2z" - android:fillColor="#ffffff"/> + android:fillColor="@android:color/white" + android:pathData="M8,19c1.1,0 2,-0.9 2,-2L10,7c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2v10c0,1.1 0.9,2 2,2zM14,7v10c0,1.1 0.9,2 2,2s2,-0.9 2,-2L18,7c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2z"/> </vector> diff --git a/app/src/main/res/drawable/ic_play_arrow_white_rounded_18dp.xml b/app/src/main/res/drawable/ic_play_arrow_white_rounded_24dp.xml index 3400b3ac..78fbfbba 100644 --- a/app/src/main/res/drawable/ic_play_arrow_white_rounded_18dp.xml +++ b/app/src/main/res/drawable/ic_play_arrow_white_rounded_24dp.xml @@ -1,9 +1,9 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="18dp" - android:height="18dp" + android:width="24dp" + android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path - android:pathData="M8,6.82v10.36c0,0.79 0.87,1.27 1.54,0.84l8.14,-5.18c0.62,-0.39 0.62,-1.29 0,-1.69L9.54,5.98C8.87,5.55 8,6.03 8,6.82z" - android:fillColor="#ffffff"/> + android:fillColor="@android:color/white" + android:pathData="M8,6.82v10.36c0,0.79 0.87,1.27 1.54,0.84l8.14,-5.18c0.62,-0.39 0.62,-1.29 0,-1.69L9.54,5.98C8.87,5.55 8,6.03 8,6.82z"/> </vector> diff --git a/app/src/main/res/drawable/ic_rpan_24dp.xml b/app/src/main/res/drawable/ic_rpan_24dp.xml new file mode 100644 index 00000000..bb61e6ff --- /dev/null +++ b/app/src/main/res/drawable/ic_rpan_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/black" + android:pathData="M21,6h-7.59l3.29,-3.29L16,2l-4,4 -4,-4 -0.71,0.71L10.59,6L3,6c-1.1,0 -2,0.89 -2,2v12c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,8c0,-1.11 -0.9,-2 -2,-2zM21,20L3,20L3,8h18v12zM9,10v8l7,-4z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_trending_24dp.xml b/app/src/main/res/drawable/ic_trending_24dp.xml new file mode 100644 index 00000000..b237138b --- /dev/null +++ b/app/src/main/res/drawable/ic_trending_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/black" + android:pathData="M16,6l2.29,2.29 -4.88,4.88 -4,-4L2,16.59 3.41,18l6,-6 4,4 6.3,-6.29L22,12V6z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_unmute_white_rounded_18dp.xml b/app/src/main/res/drawable/ic_unmute_white_rounded_24dp.xml index 90b8f85d..3afb6532 100644 --- a/app/src/main/res/drawable/ic_unmute_white_rounded_18dp.xml +++ b/app/src/main/res/drawable/ic_unmute_white_rounded_24dp.xml @@ -1,9 +1,9 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="18dp" - android:height="18dp" + android:width="24dp" + android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path - android:pathData="M3,10v4c0,0.55 0.45,1 1,1h3l3.29,3.29c0.63,0.63 1.71,0.18 1.71,-0.71L12,6.41c0,-0.89 -1.08,-1.34 -1.71,-0.71L7,9L4,9c-0.55,0 -1,0.45 -1,1zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,4.45v0.2c0,0.38 0.25,0.71 0.6,0.85C17.18,6.53 19,9.06 19,12s-1.82,5.47 -4.4,6.5c-0.36,0.14 -0.6,0.47 -0.6,0.85v0.2c0,0.63 0.63,1.07 1.21,0.85C18.6,19.11 21,15.84 21,12s-2.4,-7.11 -5.79,-8.4c-0.58,-0.23 -1.21,0.22 -1.21,0.85z" - android:fillColor="#ffffff"/> + android:fillColor="@android:color/white" + android:pathData="M3,10v4c0,0.55 0.45,1 1,1h3l3.29,3.29c0.63,0.63 1.71,0.18 1.71,-0.71L12,6.41c0,-0.89 -1.08,-1.34 -1.71,-0.71L7,9L4,9c-0.55,0 -1,0.45 -1,1zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,4.45v0.2c0,0.38 0.25,0.71 0.6,0.85C17.18,6.53 19,9.06 19,12s-1.82,5.47 -4.4,6.5c-0.36,0.14 -0.6,0.47 -0.6,0.85v0.2c0,0.63 0.63,1.07 1.21,0.85C18.6,19.11 21,15.84 21,12s-2.4,-7.11 -5.79,-8.4c-0.58,-0.23 -1.21,0.22 -1.21,0.85z"/> </vector> diff --git a/app/src/main/res/drawable/ic_wallpaper_white_24dp.xml b/app/src/main/res/drawable/ic_wallpaper_white_24dp.xml new file mode 100644 index 00000000..9db92d6f --- /dev/null +++ b/app/src/main/res/drawable/ic_wallpaper_white_24dp.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4,4h7L11,2L4,2c-1.1,0 -2,0.9 -2,2v7h2L4,4zM10,13l-4,5h12l-3,-4 -2.03,2.71L10,13zM17,8.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S14,7.67 14,8.5s0.67,1.5 1.5,1.5S17,9.33 17,8.5zM20,2h-7v2h7v7h2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,20h-7v2h7c1.1,0 2,-0.9 2,-2v-7h-2v7zM4,13L2,13v7c0,1.1 0.9,2 2,2h7v-2L4,20v-7z"/> +</vector> diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml index 92abf9f0..378cf16f 100644 --- a/app/src/main/res/drawable/side_nav_bar.xml +++ b/app/src/main/res/drawable/side_nav_bar.xml @@ -2,8 +2,8 @@ android:shape="rectangle"> <gradient android:angle="135" - android:centerColor="#1565C0" - android:endColor="#0D47A1" - android:startColor="#1976D2" + android:centerColor="#0336FF" + android:endColor="#002BF0" + android:startColor="#5954FF" android:type="linear" /> </shape>
\ No newline at end of file diff --git a/app/src/main/res/drawable/trending_search_title_background.xml b/app/src/main/res/drawable/trending_search_title_background.xml new file mode 100644 index 00000000..8bcd7150 --- /dev/null +++ b/app/src/main/res/drawable/trending_search_title_background.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <gradient android:startColor="#323232" + android:endColor="@android:color/transparent" + android:angle="90" + android:type="linear" + android:useLevel="true" /> +</shape>
\ No newline at end of file diff --git a/app/src/main/res/layout-land/fragment_view_post_detail.xml b/app/src/main/res/layout-land/fragment_view_post_detail.xml new file mode 100644 index 00000000..3b35b38b --- /dev/null +++ b/app/src/main/res/layout-land/fragment_view_post_detail.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + tools:context=".fragments.ViewPostDetailFragment"> + + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + android:id="@+id/swipe_refresh_layout_view_post_detail_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clickable="true" + android:focusable="true"> + + <ml.docilealligator.infinityforreddit.customviews.CustomToroContainer + android:id="@+id/post_detail_recycler_view_view_post_detail_fragment" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:clipToPadding="false" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/comments_recycler_view_view_post_detail_fragment" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:paddingBottom="144dp" + android:clipToPadding="false" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> + + </LinearLayout> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> + + <LinearLayout + android:id="@+id/fetch_post_info_linear_layout_view_post_detail_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:orientation="vertical" + android:visibility="gone"> + + <ImageView + android:id="@+id/fetch_post_info_image_view_view_post_detail_fragment" + android:layout_width="150dp" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/fetch_post_info_text_view_view_post_detail_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + </LinearLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout-sw600dp/fragment_view_post_detail.xml b/app/src/main/res/layout-sw600dp/fragment_view_post_detail.xml new file mode 100644 index 00000000..d1637b0c --- /dev/null +++ b/app/src/main/res/layout-sw600dp/fragment_view_post_detail.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + tools:context=".fragments.ViewPostDetailFragment"> + + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + android:id="@+id/swipe_refresh_layout_view_post_detail_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clickable="true" + android:focusable="true"> + + <ml.docilealligator.infinityforreddit.customviews.CustomToroContainer + android:id="@+id/post_detail_recycler_view_view_post_detail_fragment" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:clipToPadding="false" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/comments_recycler_view_view_post_detail_fragment" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:paddingBottom="144dp" + android:clipToPadding="false" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> + + </LinearLayout> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> + + <LinearLayout + android:id="@+id/fetch_post_info_linear_layout_view_post_detail_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:orientation="vertical" + android:visibility="gone"> + + <ImageView + android:id="@+id/fetch_post_info_image_view_view_post_detail_fragment" + android:layout_width="150dp" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/fetch_post_info_text_view_view_post_detail_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + </LinearLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_comment_full_markdown.xml b/app/src/main/res/layout/activity_comment_full_markdown.xml index 509ad624..e1f89252 100644 --- a/app/src/main/res/layout/activity_comment_full_markdown.xml +++ b/app/src/main/res/layout/activity_comment_full_markdown.xml @@ -14,7 +14,6 @@ android:theme="@style/AppTheme.AppBarOverlay"> <com.google.android.material.appbar.CollapsingToolbarLayout - android:id="@+id/collapsing_toolbar_layout_comment_full_markdown_activity" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|enterAlways" @@ -37,6 +36,8 @@ android:id="@+id/content_markdown_view_comment_full_markdown_activity" android:layout_width="match_parent" android:layout_height="match_parent" + android:paddingStart="16dp" + android:paddingEnd="16dp" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_custom_theme_listing.xml b/app/src/main/res/layout/activity_custom_theme_listing.xml index 92a200af..e0d88d70 100644 --- a/app/src/main/res/layout/activity_custom_theme_listing.xml +++ b/app/src/main/res/layout/activity_custom_theme_listing.xml @@ -37,6 +37,7 @@ android:id="@+id/recycler_view_customize_theme_listing_activity" android:layout_width="match_parent" android:layout_height="match_parent" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <com.google.android.material.floatingactionbutton.FloatingActionButton diff --git a/app/src/main/res/layout/activity_customize_theme.xml b/app/src/main/res/layout/activity_customize_theme.xml index c7183da9..bd67a775 100644 --- a/app/src/main/res/layout/activity_customize_theme.xml +++ b/app/src/main/res/layout/activity_customize_theme.xml @@ -38,6 +38,7 @@ android:id="@+id/recycler_view_customize_theme_activity" android:layout_width="match_parent" android:layout_height="match_parent" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_inbox.xml b/app/src/main/res/layout/activity_inbox.xml index b65c0d89..256fee87 100644 --- a/app/src/main/res/layout/activity_inbox.xml +++ b/app/src/main/res/layout/activity_inbox.xml @@ -26,6 +26,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" + app:layout_collapseMode="pin" + app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/AppTheme.PopupOverlay" app:navigationIcon="?attr/homeAsUpIndicator" /> @@ -45,7 +47,7 @@ </com.google.android.material.appbar.AppBarLayout> - <androidx.viewpager.widget.ViewPager + <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager_inbox_activity" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/app/src/main/res/layout/activity_look_screen.xml b/app/src/main/res/layout/activity_look_screen.xml new file mode 100644 index 00000000..ff5c4fc4 --- /dev/null +++ b/app/src/main/res/layout/activity_look_screen.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".activities.LockScreenActivity"> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_post_gallery.xml b/app/src/main/res/layout/activity_post_gallery.xml new file mode 100644 index 00000000..150870e0 --- /dev/null +++ b/app/src/main/res/layout/activity_post_gallery.xml @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/coordinator_layout_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:application=".PostImageActivity"> + + <com.google.android.material.appbar.AppBarLayout + android:id="@+id/appbar_layout_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?attr/actionBarSize" + app:navigationIcon="?attr/homeAsUpIndicator" + app:popupTheme="@style/AppTheme.PopupOverlay" /> + + </com.google.android.material.appbar.AppBarLayout> + + <androidx.core.widget.NestedScrollView + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="16dp" + android:paddingTop="8dp" + android:paddingEnd="16dp" + android:paddingBottom="8dp"> + + <pl.droidsonroids.gif.GifImageView + android:id="@+id/subreddit_icon_gif_image_view_post_gallery_activity" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_alignParentStart="true" + android:layout_centerVertical="true" /> + + <TextView + android:id="@+id/subreddit_name_text_view_post_gallery_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_marginStart="32dp" + android:layout_marginEnd="16dp" + android:layout_toStartOf="@id/rules_button_post_gallery_activity" + android:layout_toEndOf="@id/subreddit_icon_gif_image_view_post_gallery_activity" + android:text="@string/choose_a_subreddit" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.button.MaterialButton + android:id="@+id/rules_button_post_gallery_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:text="@string/rules" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + </RelativeLayout> + + <View + android:id="@+id/divider_1_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <com.libRG.CustomTextView + android:id="@+id/flair_custom_text_view_post_gallery_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:padding="4dp" + android:text="@string/flair" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + android:visibility="gone" + app:lib_setRadius="3dp" + app:lib_setRoundedView="true" + app:lib_setShape="rectangle" /> + + <com.libRG.CustomTextView + android:id="@+id/spoiler_custom_text_view_post_gallery_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:padding="4dp" + android:text="@string/spoiler" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + app:lib_setRadius="3dp" + app:lib_setRoundedView="true" + app:lib_setShape="rectangle" /> + + <com.libRG.CustomTextView + android:id="@+id/nsfw_custom_text_view_post_gallery_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:padding="4dp" + android:text="@string/nsfw" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + app:lib_setRadius="3dp" + app:lib_setRoundedView="true" + app:lib_setShape="rectangle" /> + + </LinearLayout> + + <View + android:id="@+id/divider_2_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + + <LinearLayout + android:id="@+id/receive_post_reply_notifications_linear_layout_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="8dp" + android:paddingBottom="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:id="@+id/receive_post_reply_notifications_text_view_post_gallery_activity" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:layout_marginEnd="16dp" + android:text="@string/receive_post_reply_notifications" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/receive_post_reply_notifications_switch_material_post_gallery_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:checked="true" /> + + </LinearLayout> + + <View + android:id="@+id/divider_3_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + + <EditText + android:id="@+id/post_title_edit_text_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="#00000000" + android:gravity="top" + android:hint="@string/post_title_hint" + android:inputType="textCapSentences|textMultiLine" + android:padding="16dp" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/title_font_18" + android:fontFamily="?attr/title_font_family" /> + + <View + android:id="@+id/divider_4_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/images_recycler_view_post_gallery_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="16dp" + android:paddingStart="8dp" + android:paddingEnd="8dp" + app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" + app:spanCount="2" /> + + </LinearLayout> + + </androidx.core.widget.NestedScrollView> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_post_image.xml b/app/src/main/res/layout/activity_post_image.xml index cacfd04c..2e66a7ea 100644 --- a/app/src/main/res/layout/activity_post_image.xml +++ b/app/src/main/res/layout/activity_post_image.xml @@ -61,7 +61,7 @@ android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> - <Button + <com.google.android.material.button.MaterialButton android:id="@+id/rules_button_post_image_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -132,6 +132,43 @@ android:layout_width="match_parent" android:layout_height="1dp" /> + <LinearLayout + android:id="@+id/receive_post_reply_notifications_linear_layout_post_image_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="8dp" + android:paddingBottom="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:id="@+id/receive_post_reply_notifications_text_view_post_image_activity" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:layout_marginEnd="16dp" + android:text="@string/receive_post_reply_notifications" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/receive_post_reply_notifications_switch_material_post_image_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:checked="true" /> + + </LinearLayout> + + <View + android:id="@+id/divider_3_post_image_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + <EditText android:id="@+id/post_title_edit_text_post_image_activity" android:layout_width="match_parent" @@ -146,7 +183,7 @@ android:fontFamily="?attr/title_font_family" /> <View - android:id="@+id/divider_3_post_image_activity" + android:id="@+id/divider_4_post_image_activity" android:layout_width="match_parent" android:layout_height="1dp" /> diff --git a/app/src/main/res/layout/activity_post_link.xml b/app/src/main/res/layout/activity_post_link.xml index 1e16bada..427b8306 100644 --- a/app/src/main/res/layout/activity_post_link.xml +++ b/app/src/main/res/layout/activity_post_link.xml @@ -61,7 +61,7 @@ android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> - <Button + <com.google.android.material.button.MaterialButton android:id="@+id/rules_button_post_link_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -133,6 +133,43 @@ android:layout_height="1dp" /> <LinearLayout + android:id="@+id/receive_post_reply_notifications_linear_layout_post_link_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="8dp" + android:paddingBottom="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:id="@+id/receive_post_reply_notifications_text_view_post_link_activity" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:layout_marginEnd="16dp" + android:text="@string/receive_post_reply_notifications" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/receive_post_reply_notifications_switch_material_post_link_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:checked="true" /> + + </LinearLayout> + + <View + android:id="@+id/divider_3_post_link_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingStart="0dp" @@ -158,12 +195,14 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:text="@string/suggest_title" /> + android:text="@string/suggest_title" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> </LinearLayout> <View - android:id="@+id/divider_3_post_link_activity" + android:id="@+id/divider_4_post_link_activity" android:layout_width="match_parent" android:layout_height="1dp" /> diff --git a/app/src/main/res/layout/activity_post_text.xml b/app/src/main/res/layout/activity_post_text.xml index d9b02754..f18bf667 100644 --- a/app/src/main/res/layout/activity_post_text.xml +++ b/app/src/main/res/layout/activity_post_text.xml @@ -48,26 +48,26 @@ android:paddingBottom="8dp"> <pl.droidsonroids.gif.GifImageView - android:id="@+id/subreddit_icon_gif_image_view_search_activity" + android:id="@+id/subreddit_icon_gif_image_view_post_text_activity" android:layout_width="24dp" android:layout_height="24dp" android:layout_alignParentStart="true" android:layout_centerVertical="true" /> <TextView - android:id="@+id/subreddit_name_text_view_search_activity" + android:id="@+id/subreddit_name_text_view_post_text_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginStart="32dp" android:layout_marginEnd="16dp" android:layout_toStartOf="@id/rules_button_post_text_activity" - android:layout_toEndOf="@id/subreddit_icon_gif_image_view_search_activity" + android:layout_toEndOf="@id/subreddit_icon_gif_image_view_post_text_activity" android:text="@string/choose_a_subreddit" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> - <Button + <com.google.android.material.button.MaterialButton android:id="@+id/rules_button_post_text_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -95,7 +95,6 @@ android:layout_margin="16dp" android:padding="4dp" android:text="@string/flair" - android:textColor="?attr/primaryTextColor" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" android:visibility="gone" @@ -110,7 +109,6 @@ android:layout_margin="16dp" android:padding="4dp" android:text="@string/spoiler" - android:textColor="?attr/primaryTextColor" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" app:lib_setRadius="3dp" @@ -124,7 +122,6 @@ android:layout_margin="16dp" android:padding="4dp" android:text="@string/nsfw" - android:textColor="?attr/primaryTextColor" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" app:lib_setRadius="3dp" @@ -138,6 +135,43 @@ android:layout_width="match_parent" android:layout_height="1dp" /> + <LinearLayout + android:id="@+id/receive_post_reply_notifications_linear_layout_post_text_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="8dp" + android:paddingBottom="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:id="@+id/receive_post_reply_notifications_text_view_post_text_activity" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:layout_marginEnd="16dp" + android:text="@string/receive_post_reply_notifications" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/receive_post_reply_notifications_switch_material_post_text_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:checked="true" /> + + </LinearLayout> + + <View + android:id="@+id/divider_3_post_text_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + <EditText android:id="@+id/post_title_edit_text_post_text_activity" android:layout_width="match_parent" @@ -147,12 +181,11 @@ android:hint="@string/post_title_hint" android:inputType="textCapSentences|textMultiLine" android:padding="16dp" - android:textColor="?attr/primaryTextColor" android:textSize="?attr/title_font_18" android:fontFamily="?attr/title_font_family" /> <View - android:id="@+id/divider_3_post_text_activity" + android:id="@+id/divider_4_post_text_activity" android:layout_width="match_parent" android:layout_height="1dp" /> @@ -165,7 +198,6 @@ android:hint="@string/post_text_content_hint" android:inputType="textCapSentences|textMultiLine" android:padding="16dp" - android:textColor="?attr/primaryTextColor" android:textSize="?attr/content_font_18" android:fontFamily="?attr/content_font_family" /> diff --git a/app/src/main/res/layout/activity_post_video.xml b/app/src/main/res/layout/activity_post_video.xml index c50c8be1..e1c297cb 100644 --- a/app/src/main/res/layout/activity_post_video.xml +++ b/app/src/main/res/layout/activity_post_video.xml @@ -61,7 +61,7 @@ android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> - <Button + <com.google.android.material.button.MaterialButton android:id="@+id/rules_button_post_video_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -132,6 +132,43 @@ android:layout_width="match_parent" android:layout_height="1dp" /> + <LinearLayout + android:id="@+id/receive_post_reply_notifications_linear_layout_post_video_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="8dp" + android:paddingBottom="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:id="@+id/receive_post_reply_notifications_text_view_post_video_activity" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:layout_marginEnd="16dp" + android:text="@string/receive_post_reply_notifications" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/receive_post_reply_notifications_switch_material_post_video_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:checked="true" /> + + </LinearLayout> + + <View + android:id="@+id/divider_3_post_video_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + <EditText android:id="@+id/post_title_edit_text_post_video_activity" android:layout_width="match_parent" @@ -146,7 +183,7 @@ android:fontFamily="?attr/title_font_family" /> <View - android:id="@+id/divider_3_post_video_activity" + android:id="@+id/divider_4_post_video_activity" android:layout_width="match_parent" android:layout_height="1dp" /> diff --git a/app/src/main/res/layout/activity_report.xml b/app/src/main/res/layout/activity_report.xml index ff8ecb4b..a0d114b6 100644 --- a/app/src/main/res/layout/activity_report.xml +++ b/app/src/main/res/layout/activity_report.xml @@ -27,6 +27,7 @@ android:id="@+id/recycler_view_report_activity" android:layout_width="match_parent" android:layout_height="match_parent" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_rpanactivity.xml b/app/src/main/res/layout/activity_rpanactivity.xml new file mode 100644 index 00000000..b7e22b40 --- /dev/null +++ b/app/src/main/res/layout/activity_rpanactivity.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#000000" + android:id="@+id/coordinator_layout_rpan_activity" + android:keepScreenOn="true" + tools:context=".activities.RPANActivity"> + + <androidx.viewpager2.widget.ViewPager2 + android:id="@+id/view_pager_2_rpan_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <ProgressBar + android:id="@+id/progress_bar_rpan_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" /> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_rules.xml b/app/src/main/res/layout/activity_rules.xml index 377c4fe1..0cb088b2 100644 --- a/app/src/main/res/layout/activity_rules.xml +++ b/app/src/main/res/layout/activity_rules.xml @@ -44,6 +44,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <TextView diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml index 9418ce8f..29b5b94f 100644 --- a/app/src/main/res/layout/activity_search.xml +++ b/app/src/main/res/layout/activity_search.xml @@ -23,7 +23,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" - app:navigationIcon="?attr/homeAsUpIndicator" app:popupTheme="@style/AppTheme.PopupOverlay" /> <com.ferfalk.simplesearchview.SimpleSearchView @@ -92,20 +91,12 @@ android:layout_height="1dp" android:visibility="gone" /> - <TextView - android:id="@+id/recent_summary_text_view_search_activity" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="16dp" - android:text="@string/recent_searches" - android:fontFamily="?attr/font_family" - android:visibility="gone" /> - <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view_search_activity" android:layout_width="match_parent" android:layout_height="wrap_content" - android:visibility="gone" /> + android:visibility="gone" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> </LinearLayout> diff --git a/app/src/main/res/layout/activity_submit_crosspost.xml b/app/src/main/res/layout/activity_submit_crosspost.xml index ec5b1f42..b4e555d1 100644 --- a/app/src/main/res/layout/activity_submit_crosspost.xml +++ b/app/src/main/res/layout/activity_submit_crosspost.xml @@ -61,7 +61,7 @@ android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> - <Button + <com.google.android.material.button.MaterialButton android:id="@+id/rules_button_submit_crosspost_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -132,6 +132,43 @@ android:layout_width="match_parent" android:layout_height="1dp" /> + <LinearLayout + android:id="@+id/receive_post_reply_notifications_linear_layout_submit_crosspost_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="8dp" + android:paddingBottom="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:id="@+id/receive_post_reply_notifications_text_view_submit_crosspost_activity" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:layout_marginEnd="16dp" + android:text="@string/receive_post_reply_notifications" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/receive_post_reply_notifications_switch_material_submit_crosspost_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:checked="true" /> + + </LinearLayout> + + <View + android:id="@+id/divider_3_submit_crosspost_activity" + android:layout_width="match_parent" + android:layout_height="1dp" /> + <EditText android:id="@+id/post_title_edit_text_submit_crosspost_activity" android:layout_width="match_parent" @@ -146,7 +183,7 @@ android:fontFamily="?attr/title_font_family" /> <View - android:id="@+id/divider_3_submit_crosspost_activity" + android:id="@+id/divider_4_submit_crosspost_activity" android:layout_width="match_parent" android:layout_height="1dp" /> diff --git a/app/src/main/res/layout/activity_subscribed_thing_listing.xml b/app/src/main/res/layout/activity_subscribed_thing_listing.xml index d1f49996..109d3f74 100644 --- a/app/src/main/res/layout/activity_subscribed_thing_listing.xml +++ b/app/src/main/res/layout/activity_subscribed_thing_listing.xml @@ -45,7 +45,7 @@ </com.google.android.material.appbar.AppBarLayout> - <androidx.viewpager.widget.ViewPager + <ml.docilealligator.infinityforreddit.customviews.ViewPagerBugFixed android:id="@+id/view_pager_subscribed_thing_listing_activity" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/app/src/main/res/layout/activity_theme_preview.xml b/app/src/main/res/layout/activity_theme_preview.xml index 6ca8a0b0..f2504287 100644 --- a/app/src/main/res/layout/activity_theme_preview.xml +++ b/app/src/main/res/layout/activity_theme_preview.xml @@ -7,7 +7,7 @@ android:id="@+id/coordinator_layout_theme_preview_activity" tools:context=".activities.CustomThemePreviewActivity"> - <androidx.viewpager.widget.ViewPager + <ml.docilealligator.infinityforreddit.customviews.ViewPagerBugFixed android:id="@+id/view_pager_theme_preview_activity" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -194,6 +194,7 @@ android:background="?attr/selectableItemBackgroundBorderless" /> </LinearLayout> + </com.google.android.material.bottomappbar.BottomAppBar> <com.google.android.material.floatingactionbutton.FloatingActionButton diff --git a/app/src/main/res/layout/activity_trending.xml b/app/src/main/res/layout/activity_trending.xml new file mode 100644 index 00000000..9bfe6798 --- /dev/null +++ b/app/src/main/res/layout/activity_trending.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/coordinator_layout_trending_activity" + tools:context=".activities.TrendingActivity"> + + <com.google.android.material.appbar.AppBarLayout + android:id="@+id/appbar_layout_trending_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <com.google.android.material.appbar.CollapsingToolbarLayout + android:id="@+id/collapsing_toolbar_layout_trending_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_scrollFlags="scroll|enterAlways" + app:titleEnabled="false" + app:toolbarId="@+id/toolbar_trending_activity"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar_trending_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?attr/actionBarSize" + app:popupTheme="@style/AppTheme.PopupOverlay" + app:navigationIcon="?attr/homeAsUpIndicator" /> + + </com.google.android.material.appbar.CollapsingToolbarLayout> + + </com.google.android.material.appbar.AppBarLayout> + + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + android:id="@+id/swipe_refresh_layout_trending_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/recycler_view_trending_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> + + <LinearLayout + android:id="@+id/fetch_trending_search_linear_layout_trending_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginTop="48dp" + android:layout_marginBottom="48dp" + android:gravity="center" + android:orientation="vertical" + android:visibility="gone"> + + <ImageView + android:id="@+id/fetch_trending_search_image_view_trending_activity" + android:layout_width="150dp" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/fetch_trending_search_text_view_trending_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + </LinearLayout> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_view_image_or_gif.xml b/app/src/main/res/layout/activity_view_image_or_gif.xml index 4ecd9fda..fa0a5aa8 100644 --- a/app/src/main/res/layout/activity_view_image_or_gif.xml +++ b/app/src/main/res/layout/activity_view_image_or_gif.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/hauler_view_view_image_or_gif_activity" @@ -12,7 +12,7 @@ android:id="@+id/progress_bar_view_image_or_gif_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_centerInParent="true" /> + android:layout_gravity="center" /> <com.github.piasy.biv.view.BigImageView android:id="@+id/image_view_view_image_or_gif_activity" @@ -40,4 +40,61 @@ </LinearLayout> -</RelativeLayout> + <com.google.android.material.bottomappbar.BottomAppBar + android:id="@+id/bottom_navigation_view_image_or_gif_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:backgroundTint="#80000000" + android:visibility="gone" + style="@style/Widget.MaterialComponents.BottomAppBar"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/title_text_view_view_image_or_gif_activity" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:gravity="center_vertical" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:textColor="#FFFFFF" + android:textSize="?attr/font_20" + android:fontFamily="?attr/font_family" + android:maxLines="1" + android:ellipsize="end" /> + + <ImageView + android:id="@+id/download_image_view_view_image_or_gif_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="16dp" + android:src="@drawable/ic_file_download_toolbar_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + <ImageView + android:id="@+id/share_image_view_view_image_or_gif_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="16dp" + android:src="@drawable/ic_share_toolbar_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + <ImageView + android:id="@+id/wallpaper_image_view_view_image_or_gif_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:padding="16dp" + android:src="@drawable/ic_wallpaper_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + </LinearLayout> + + </com.google.android.material.bottomappbar.BottomAppBar> + +</androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/activity_view_imgur_media.xml b/app/src/main/res/layout/activity_view_imgur_media.xml index 0b29fb8b..408ddff4 100644 --- a/app/src/main/res/layout/activity_view_imgur_media.xml +++ b/app/src/main/res/layout/activity_view_imgur_media.xml @@ -23,10 +23,10 @@ android:layout_height="wrap_content" android:layout_centerInParent="true" /> - <androidx.viewpager.widget.ViewPager + <ml.docilealligator.infinityforreddit.customviews.ViewPagerBugFixed + android:id="@+id/view_pager_view_imgur_media_activity" android:layout_width="match_parent" - android:layout_height="match_parent" - android:id="@+id/view_pager_view_imgur_media_activity" /> + android:layout_height="match_parent" /> <LinearLayout android:id="@+id/load_image_error_linear_layout_view_imgur_media_activity" diff --git a/app/src/main/res/layout/activity_view_post_detail.xml b/app/src/main/res/layout/activity_view_post_detail.xml index d16899f3..da98158d 100644 --- a/app/src/main/res/layout/activity_view_post_detail.xml +++ b/app/src/main/res/layout/activity_view_post_detail.xml @@ -47,4 +47,77 @@ app:tint="@android:color/white" app:srcCompat="@drawable/ic_keyboard_arrow_down_24dp" /> + <com.google.android.material.card.MaterialCardView + android:id="@+id/search_panel_material_card_view_view_post_detail_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:visibility="gone" + app:cardElevation="16dp"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="0dp" + android:paddingEnd="8dp"> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/search_text_input_layout_view_post_detail_activity" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"> + + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/search_text_input_edit_text_view_post_detail_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fontFamily="?attr/font_family" + android:textSize="?attr/font_default" + android:hint="@string/search_comments" + android:maxLines="1" /> + + </com.google.android.material.textfield.TextInputLayout> + + <ImageView + android:id="@+id/previous_result_image_view_view_post_detail_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:padding="8dp" + android:src="@drawable/ic_arrow_upward_black_24dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" /> + + <ImageView + android:id="@+id/next_result_image_view_view_post_detail_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:padding="8dp" + android:src="@drawable/ic_arrow_downward_black_24dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" /> + + <ImageView + android:id="@+id/close_search_panel_image_view_view_post_detail_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:padding="8dp" + android:src="@drawable/ic_close_black_24dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" /> + + </LinearLayout> + + </com.google.android.material.card.MaterialCardView> + </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_view_reddit_gallery.xml b/app/src/main/res/layout/activity_view_reddit_gallery.xml index d0bff7c2..6027fce2 100644 --- a/app/src/main/res/layout/activity_view_reddit_gallery.xml +++ b/app/src/main/res/layout/activity_view_reddit_gallery.xml @@ -13,7 +13,7 @@ android:layout_height="match_parent" android:fillViewport="true"> - <androidx.viewpager.widget.ViewPager + <ml.docilealligator.infinityforreddit.customviews.ViewPagerBugFixed android:id="@+id/view_pager_view_reddit_gallery_activity" android:layout_width="match_parent" android:layout_height="match_parent" /> diff --git a/app/src/main/res/layout/activity_wiki.xml b/app/src/main/res/layout/activity_wiki.xml new file mode 100644 index 00000000..c8f49864 --- /dev/null +++ b/app/src/main/res/layout/activity_wiki.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/coordinator_layout_comment_wiki_activity" + tools:context=".activities.WikiActivity"> + + <com.google.android.material.appbar.AppBarLayout + android:id="@+id/appbar_layout_comment_wiki_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <com.google.android.material.appbar.CollapsingToolbarLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_scrollFlags="scroll|enterAlways" + app:titleEnabled="false" + app:toolbarId="@+id/toolbar_comment_wiki_activity"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar_comment_wiki_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?attr/actionBarSize" + app:popupTheme="@style/AppTheme.PopupOverlay" + app:navigationIcon="?attr/homeAsUpIndicator" /> + + </com.google.android.material.appbar.CollapsingToolbarLayout> + + </com.google.android.material.appbar.AppBarLayout> + + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + android:id="@+id/swipe_refresh_layout_wiki_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/content_markdown_view_comment_wiki_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingStart="16dp" + android:paddingEnd="16dp" /> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> + + <LinearLayout + android:id="@+id/fetch_wiki_linear_layout_wiki_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginTop="48dp" + android:layout_marginBottom="48dp" + android:gravity="center" + android:orientation="vertical" + android:visibility="gone" + app:layout_behavior="@string/appbar_scrolling_view_behavior" > + + <ImageView + android:id="@+id/fetch_wiki_image_view_wiki_activity" + android:layout_width="150dp" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/fetch_wiki_text_view_wiki_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + </LinearLayout> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/dialog_go_to_thing_edit_text.xml b/app/src/main/res/layout/dialog_go_to_thing_edit_text.xml index 2175b284..707f4d55 100644 --- a/app/src/main/res/layout/dialog_go_to_thing_edit_text.xml +++ b/app/src/main/res/layout/dialog_go_to_thing_edit_text.xml @@ -1,23 +1,38 @@ <?xml version="1.0" encoding="utf-8"?> -<com.google.android.material.textfield.TextInputLayout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingStart="16dp" - android:paddingTop="8dp" - android:paddingEnd="16dp" - android:paddingBottom="8dp" - app:boxStrokeColor="?attr/primaryTextColor" - app:hintTextColor="?attr/primaryTextColor"> + android:orientation="vertical"> - <com.google.android.material.textfield.TextInputEditText - android:id="@+id/text_input_edit_text_go_to_thing_edit_text" + <com.google.android.material.textfield.TextInputLayout + style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" android:layout_width="match_parent" android:layout_height="wrap_content" - android:fontFamily="?attr/font_family" - android:hint="@string/go_to_thing_hint" - android:textColor="?attr/primaryTextColor" - android:textSize="?attr/font_default" /> + android:paddingStart="16dp" + android:paddingTop="8dp" + android:paddingEnd="16dp" + android:paddingBottom="8dp" + app:boxStrokeColor="?attr/primaryTextColor" + app:hintTextColor="?attr/primaryTextColor"> -</com.google.android.material.textfield.TextInputLayout>
\ No newline at end of file + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/text_input_edit_text_go_to_thing_edit_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fontFamily="?attr/font_family" + android:hint="@string/go_to_thing_hint" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_default" + android:singleLine="true" + android:imeOptions="actionDone"/> + + </com.google.android.material.textfield.TextInputLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/recycler_view_go_to_thing_edit_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> + +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/exo_autoplay_playback_control_view.xml b/app/src/main/res/layout/exo_autoplay_playback_control_view.xml index 42382179..4f7020c4 100644 --- a/app/src/main/res/layout/exo_autoplay_playback_control_view.xml +++ b/app/src/main/res/layout/exo_autoplay_playback_control_view.xml @@ -1,90 +1,122 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/linear_layout_exo_playback_control_view" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingStart="8dp" - android:paddingEnd="8dp" + android:layout_height="match_parent" android:layout_gravity="bottom" - android:orientation="vertical" - android:background="@drawable/background_autoplay"> + android:orientation="vertical"> - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <TextView - android:id="@id/exo_position" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentStart="true" - android:layout_centerVertical="true" - android:includeFontPadding="false" - android:layout_marginStart="8dp" - android:textColor="#FFFFFF" - android:textSize="12sp" - android:textStyle="bold" - android:fontFamily="?attr/font_family" /> + <ImageView + android:id="@+id/mute_exo_playback_control_view" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="8dp" + android:layout_toStartOf="@id/fullscreen_exo_playback_control_view" + android:src="@drawable/ic_mute_white_rounded_24dp" + android:background="@drawable/exo_player_control_button_circular_background" + android:clickable="true" + android:focusable="true" + android:visibility="gone" + tools:visibility="visible" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@id/frame_layout" /> - <TextView - android:id="@+id/slash" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toEndOf="@id/exo_position" - android:layout_centerVertical="true" - android:text="/" - android:textColor="#FFFFFF" - android:textSize="12sp" - android:textStyle="bold" - android:fontFamily="?attr/font_family" /> + <ImageView + android:id="@+id/fullscreen_exo_playback_control_view" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="8dp" + android:layout_alignParentEnd="true" + android:src="@drawable/ic_fullscreen_white_rounded_24dp" + android:background="@drawable/exo_player_control_button_circular_background" + android:clickable="true" + android:focusable="true" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/frame_layout" + app:layout_constraintEnd_toEndOf="parent" /> - <TextView android:id="@id/exo_duration" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toEndOf="@id/slash" - android:layout_centerVertical="true" - android:includeFontPadding="false" - android:textColor="#FFFFFF" - android:textSize="12sp" - android:textStyle="bold" - android:fontFamily="?attr/font_family" /> + <FrameLayout + android:id="@+id/frame_layout" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"> <ImageView android:id="@id/exo_play" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="8dp" android:layout_centerInParent="true" - android:src="@drawable/ic_play_arrow_white_rounded_18dp" /> + android:src="@drawable/ic_play_arrow_white_rounded_24dp" + android:background="@drawable/exo_player_control_button_circular_background" + android:clickable="true" + android:focusable="true" /> <ImageView android:id="@id/exo_pause" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="8dp" android:layout_centerInParent="true" - android:src="@drawable/ic_pause_white_rounded_18dp" /> + android:src="@drawable/ic_pause_white_rounded_24dp" + android:background="@drawable/exo_player_control_button_circular_background" + android:clickable="true" + android:focusable="true" /> + + </FrameLayout> - <ImageView - android:id="@+id/mute_exo_playback_control_view" + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="16dp" + android:background="@drawable/background_autoplay" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"> + + <TextView + android:id="@id/exo_position" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:padding="8dp" - android:layout_toStartOf="@id/fullscreen_exo_playback_control_view" - android:src="@drawable/ic_mute_white_rounded_18dp" - android:visibility="gone" /> + android:includeFontPadding="false" + android:layout_marginStart="16dp" + android:textColor="#FFFFFF" + android:textSize="?attr/font_default" + android:textStyle="bold" + android:fontFamily="?attr/font_family" + app:layout_constraintBottom_toTopOf="@id/exo_progress" + app:layout_constraintStart_toStartOf="parent" /> - <ImageView - android:id="@+id/fullscreen_exo_playback_control_view" + <TextView android:id="@id/exo_duration" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:padding="8dp" - android:layout_alignParentEnd="true" - android:src="@drawable/ic_fullscreen_white_rounded_18dp" /> + android:includeFontPadding="false" + android:layout_marginEnd="16dp" + android:textColor="#FFFFFF" + android:textSize="?attr/font_default" + android:textStyle="bold" + android:fontFamily="?attr/font_family" + app:layout_constraintBottom_toTopOf="@id/exo_progress" + app:layout_constraintEnd_toEndOf="parent" /> - </RelativeLayout> + <com.google.android.exoplayer2.ui.DefaultTimeBar + android:id="@id/exo_progress" + android:layout_width="match_parent" + android:layout_height="24dp" + android:layout_marginBottom="8dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:bar_height="2dp" /> - <com.google.android.exoplayer2.ui.DefaultTimeBar - android:id="@id/exo_progress" - android:layout_width="wrap_content" - android:layout_height="26dp"/> + </androidx.constraintlayout.widget.ConstraintLayout> -</LinearLayout>
\ No newline at end of file +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/exo_playback_control_view.xml b/app/src/main/res/layout/exo_playback_control_view.xml index 611c5e06..b81b5026 100644 --- a/app/src/main/res/layout/exo_playback_control_view.xml +++ b/app/src/main/res/layout/exo_playback_control_view.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/linear_layout_exo_playback_control_view" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -57,14 +58,17 @@ android:paddingLeft="4dp" android:paddingRight="4dp" android:includeFontPadding="false" - android:textColor="#FFBEBEBE" + android:textColor="#FFFFFF" android:fontFamily="?attr/font_family" /> <com.google.android.exoplayer2.ui.DefaultTimeBar android:id="@id/exo_progress" android:layout_width="0dp" android:layout_weight="1" - android:layout_height="26dp"/> + android:layout_height="26dp" + app:bar_height="2dp" + app:scrubber_color="@color/colorAccent" + app:played_color="@color/colorAccent" /> <TextView android:id="@id/exo_duration" android:layout_width="wrap_content" @@ -74,9 +78,49 @@ android:paddingLeft="4dp" android:paddingRight="4dp" android:includeFontPadding="false" - android:textColor="#FFBEBEBE" + android:textColor="#FFFFFF" android:fontFamily="?attr/font_family" /> </LinearLayout> + <com.google.android.material.bottomappbar.BottomAppBar + android:id="@+id/bottom_navigation_exo_playback_control_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:backgroundTint="#80000000" + android:visibility="gone" + style="@style/Widget.MaterialComponents.BottomAppBar"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/title_text_view_exo_playback_control_view" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:gravity="center_vertical" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:textColor="#FFFFFF" + android:textSize="?attr/font_20" + android:fontFamily="?attr/font_family" + android:maxLines="1" + android:ellipsize="end" /> + + <ImageView + android:id="@+id/download_image_view_exo_playback_control_view" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="16dp" + android:src="@drawable/ic_file_download_toolbar_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + </LinearLayout> + + </com.google.android.material.bottomappbar.BottomAppBar> + </LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/exo_rpan_broadcast_playback_control_view.xml b/app/src/main/res/layout/exo_rpan_broadcast_playback_control_view.xml new file mode 100644 index 00000000..7922dc7a --- /dev/null +++ b/app/src/main/res/layout/exo_rpan_broadcast_playback_control_view.xml @@ -0,0 +1,192 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#44000000" + android:id="@+id/constraint_layout_exo_rpan_broadcast_playback_control_view" + android:focusableInTouchMode="true" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="16dp" + android:paddingEnd="16dp" + app:layout_constraintBottom_toTopOf="@id/title_text_view_exo_rpan_broadcast_playback_control_view" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="1"> + + <ImageView + android:id="@+id/subreddit_icon_image_view_exo_rpan_broadcast_playback_control_view" + android:layout_width="24dp" + android:layout_height="24dp" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + + <TextView + android:id="@+id/subreddit_name_text_view_exo_rpan_broadcast_playback_control_view" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:paddingBottom="4dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:textColor="@color/colorAccent" + app:layout_constraintBottom_toTopOf="@id/username_text_view_exo_rpan_broadcast_playback_control_view" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toEndOf="@id/barrier5" /> + + <TextView + android:id="@+id/username_text_view_exo_rpan_broadcast_playback_control_view" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:textColor="#02BAEE" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/barrier5" /> + + <androidx.constraintlayout.widget.Barrier + android:id="@+id/barrier5" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierDirection="end" + app:constraint_referenced_ids="subreddit_icon_image_view_exo_rpan_broadcast_playback_control_view" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + + <TextView + android:id="@+id/title_text_view_exo_rpan_broadcast_playback_control_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="16dp" + android:textColor="#FFFFFF" + android:textSize="20sp" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toTopOf="@id/control_linear_layout" + app:layout_constraintVertical_bias="1" /> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/control_linear_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:orientation="horizontal" + android:paddingTop="4dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <ImageButton + android:id="@+id/hd_exo_rpan_broadcast_playback_control_view" + style="@style/ExoMediaButton" + android:src="@drawable/ic_video_quality_24dp" + android:visibility="gone" + app:layout_constraintEnd_toStartOf="@+id/exo_rew" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintHorizontal_chainStyle="spread_inside" + app:layout_constraintStart_toStartOf="parent" + tools:layout_editor_absoluteY="4dp" /> + + <ImageButton + android:id="@id/exo_rew" + style="@style/ExoMediaButton.Rewind" + app:layout_constraintEnd_toStartOf="@+id/exo_play" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/hd_exo_rpan_broadcast_playback_control_view" + tools:layout_editor_absoluteY="4dp" /> + + <ImageButton + android:id="@id/exo_play" + style="@style/ExoMediaButton.Play" + app:layout_constraintEnd_toStartOf="@+id/exo_pause" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/exo_rew" + tools:layout_editor_absoluteY="4dp" /> + + <ImageButton + android:id="@id/exo_pause" + style="@style/ExoMediaButton.Pause" + app:layout_constraintEnd_toStartOf="@+id/exo_ffwd" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/exo_play" + tools:layout_editor_absoluteY="4dp" /> + + <ImageButton + android:id="@id/exo_ffwd" + style="@style/ExoMediaButton.FastForward" + app:layout_constraintEnd_toStartOf="@+id/mute_exo_rpan_broadcast_playback_control_view" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/exo_pause" + tools:layout_editor_absoluteY="4dp" /> + + <ImageButton + android:id="@+id/mute_exo_rpan_broadcast_playback_control_view" + style="@style/ExoMediaButton" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/exo_ffwd" + tools:layout_editor_absoluteY="4dp" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/recycler_view_exo_rpan_broadcast_playback_control_view" + android:layout_width="match_parent" + android:layout_height="0dp" + android:paddingTop="16dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + app:layout_constraintTop_toBottomOf="@id/control_linear_layout" + app:layout_constraintBottom_toTopOf="@id/time_bar_linear_layout" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> + + <LinearLayout + android:id="@+id/time_bar_linear_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:padding="16dp" + android:gravity="center_vertical" + android:orientation="horizontal" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"> + + <TextView android:id="@id/exo_position" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textStyle="bold" + android:paddingStart="0dp" + android:paddingEnd="4dp" + android:includeFontPadding="false" + android:textColor="#FFFFFF" + android:fontFamily="?attr/font_family" /> + + <com.google.android.exoplayer2.ui.DefaultTimeBar + android:id="@id/exo_progress" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="26dp" + app:bar_height="2dp" + app:scrubber_color="@color/colorAccent" + app:played_color="@color/colorAccent" /> + + <TextView android:id="@id/exo_duration" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textStyle="bold" + android:paddingStart="4dp" + android:paddingEnd="0dp" + android:includeFontPadding="false" + android:textColor="#FFFFFF" + android:fontFamily="?attr/font_family" /> + + </LinearLayout> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_crash_reports.xml b/app/src/main/res/layout/fragment_crash_reports.xml index bc87d22c..3756ef57 100644 --- a/app/src/main/res/layout/fragment_crash_reports.xml +++ b/app/src/main/res/layout/fragment_crash_reports.xml @@ -3,4 +3,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" tools:context=".settings.CrashReportsFragment" />
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_customize_main_page_tabs.xml b/app/src/main/res/layout/fragment_customize_main_page_tabs.xml index 85297183..2a5f19d0 100644 --- a/app/src/main/res/layout/fragment_customize_main_page_tabs.xml +++ b/app/src/main/res/layout/fragment_customize_main_page_tabs.xml @@ -463,6 +463,68 @@ app:drawableStartCompat="@drawable/ic_info_preference_24dp" /> <LinearLayout + android:id="@+id/show_favorite_multireddits_linear_layout_customize_main_page_tabs_fragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="4dp" + android:paddingBottom="4dp" + android:paddingStart="72dp" + android:paddingEnd="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_marginEnd="16dp" + android:layout_gravity="center_vertical" + android:text="@string/settings_more_tabs_show_favorite_multireddits_title" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_16" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/show_favorite_multireddits_switch_material_customize_main_page_tabs_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" /> + + </LinearLayout> + + <LinearLayout + android:id="@+id/show_multireddits_linear_layout_customize_main_page_tabs_fragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="4dp" + android:paddingBottom="4dp" + android:paddingStart="72dp" + android:paddingEnd="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_marginEnd="16dp" + android:layout_gravity="center_vertical" + android:text="@string/settings_more_tabs_show_multireddits_title" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_16" + android:fontFamily="?attr/font_family" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/show_multireddits_switch_material_customize_main_page_tabs_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" /> + + </LinearLayout> + + <LinearLayout android:id="@+id/show_favorite_subscribed_subreddits_linear_layout_customize_main_page_tabs_fragment" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/app/src/main/res/layout/fragment_flair_bottom_sheet.xml b/app/src/main/res/layout/fragment_flair_bottom_sheet.xml index 41a12ab8..f3ed6751 100644 --- a/app/src/main/res/layout/fragment_flair_bottom_sheet.xml +++ b/app/src/main/res/layout/fragment_flair_bottom_sheet.xml @@ -3,14 +3,19 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" tools:application=".FlairBottomSheetFragment"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" - android:padding="16dp" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingStart="32dp" + android:paddingEnd="32dp" android:text="@string/flair" + android:textColor="?attr/primaryTextColor" android:textSize="?attr/font_18" android:fontFamily="?attr/font_family" /> @@ -35,6 +40,7 @@ <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view_bottom_sheet_fragment" android:layout_width="match_parent" - android:layout_height="match_parent" /> + android:layout_height="match_parent" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> </LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_inbox.xml b/app/src/main/res/layout/fragment_inbox.xml index 3fcaecbf..7b45b676 100644 --- a/app/src/main/res/layout/fragment_inbox.xml +++ b/app/src/main/res/layout/fragment_inbox.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" @@ -22,7 +22,7 @@ android:id="@+id/fetch_messages_info_linear_layout_inbox_fragment" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_centerInParent="true" + android:layout_gravity="center" android:gravity="center" android:orientation="vertical" android:visibility="gone"> @@ -43,4 +43,4 @@ </LinearLayout> -</RelativeLayout>
\ No newline at end of file +</FrameLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_post_type_bottom_sheet.xml b/app/src/main/res/layout/fragment_post_type_bottom_sheet.xml index e89e36a2..7138d814 100644 --- a/app/src/main/res/layout/fragment_post_type_bottom_sheet.xml +++ b/app/src/main/res/layout/fragment_post_type_bottom_sheet.xml @@ -86,6 +86,25 @@ android:focusable="true" android:background="?attr/selectableItemBackground" /> + <TextView + android:id="@+id/gallery_type_linear_layout_post_type_bottom_sheet_fragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingStart="32dp" + android:paddingEnd="32dp" + android:text="@string/bottom_sheet_post_gallery" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + android:drawableStart="@drawable/ic_gallery_24dp" + android:drawablePadding="48dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground" /> + </LinearLayout> </androidx.core.widget.NestedScrollView>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_select_or_capture_image_bottom_sheet.xml b/app/src/main/res/layout/fragment_select_or_capture_image_bottom_sheet.xml new file mode 100644 index 00000000..55f60691 --- /dev/null +++ b/app/src/main/res/layout/fragment_select_or_capture_image_bottom_sheet.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="8dp" + android:overScrollMode="never"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <TextView + android:id="@+id/select_image_text_view_select_or_capture_image_bottom_sheet_fragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingStart="32dp" + android:paddingEnd="32dp" + android:text="@string/select_image" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + android:drawableStart="@drawable/ic_outline_select_photo_day_night_24dp" + android:drawablePadding="48dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground" /> + + <TextView + android:id="@+id/capture_image_text_view_select_or_capture_image_bottom_sheet_fragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingStart="32dp" + android:paddingEnd="32dp" + android:text="@string/capture" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + android:drawableStart="@drawable/ic_outline_add_a_photo_day_night_24dp" + android:drawablePadding="48dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground" /> + + </LinearLayout> + +</androidx.core.widget.NestedScrollView>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_translation.xml b/app/src/main/res/layout/fragment_translation.xml index a4a58ed6..a0cb2ea7 100644 --- a/app/src/main/res/layout/fragment_translation.xml +++ b/app/src/main/res/layout/fragment_translation.xml @@ -3,5 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/recycler_view_translation_fragment" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" tools:context=".settings.TranslationFragment" />
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_uploaded_images_bottom_sheet.xml b/app/src/main/res/layout/fragment_uploaded_images_bottom_sheet.xml new file mode 100644 index 00000000..f3e96ef5 --- /dev/null +++ b/app/src/main/res/layout/fragment_uploaded_images_bottom_sheet.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:orientation="vertical" + tools:context=".bottomsheetfragments.UploadedImagesBottomSheetFragment"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingTop="16dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:text="@string/uploaded_images" + android:fontFamily="?attr/font_family" + android:textSize="?attr/font_18" + android:textColor="?attr/primaryTextColor" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="end"> + + <com.google.android.material.button.MaterialButton + android:id="@+id/capture_button_uploaded_images_bottom_sheet_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:backgroundTint="@color/colorPrimary" + android:textColor="#FFFFFF" + android:text="@string/capture" /> + + <com.google.android.material.button.MaterialButton + android:id="@+id/upload_button_uploaded_images_bottom_sheet_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:backgroundTint="@color/colorPrimary" + android:textColor="#FFFFFF" + android:text="@string/select_image" /> + + </LinearLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/recycler_view_uploaded_images_bottom_sheet" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> + +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_view_imgur_image.xml b/app/src/main/res/layout/fragment_view_imgur_image.xml new file mode 100644 index 00000000..78bde93d --- /dev/null +++ b/app/src/main/res/layout/fragment_view_imgur_image.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/constraintLayout" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".fragments.ViewImgurImageFragment"> + + <ProgressBar + android:id="@+id/progress_bar_view_imgur_image_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" /> + + <com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView + android:id="@+id/image_view_view_imgur_image_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <LinearLayout + android:id="@+id/load_image_error_linear_layout_view_imgur_image_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:drawableTop="@drawable/ic_error_outline_white_24dp" + android:layout_gravity="center" + android:gravity="center" + android:textColor="@android:color/white" + android:text="@string/error_loading_image_tap_to_retry" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + </LinearLayout> + + <com.google.android.material.bottomappbar.BottomAppBar + android:id="@+id/bottom_navigation_view_imgur_image_fragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:backgroundTint="#80000000" + android:visibility="gone" + style="@style/Widget.MaterialComponents.BottomAppBar"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/title_text_view_view_imgur_image_fragment" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:gravity="center_vertical" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:textColor="#FFFFFF" + android:textSize="?attr/font_20" + android:fontFamily="?attr/font_family" + android:maxLines="1" + android:ellipsize="end" /> + + <ImageView + android:id="@+id/download_image_view_view_imgur_image_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="16dp" + android:src="@drawable/ic_file_download_toolbar_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + <ImageView + android:id="@+id/share_image_view_view_imgur_image_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="16dp" + android:src="@drawable/ic_share_toolbar_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + <ImageView + android:id="@+id/wallpaper_image_view_view_imgur_image_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:padding="16dp" + android:src="@drawable/ic_wallpaper_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + </LinearLayout> + + </com.google.android.material.bottomappbar.BottomAppBar> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_view_imgur_images.xml b/app/src/main/res/layout/fragment_view_imgur_images.xml deleted file mode 100644 index 7a658b92..00000000 --- a/app/src/main/res/layout/fragment_view_imgur_images.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:id="@+id/constraintLayout" - android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context=".fragments.ViewImgurImageFragment"> - - <ProgressBar - android:id="@+id/progress_bar_view_imgur_image_fragment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_centerInParent="true" /> - - <com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView - android:id="@+id/image_view_view_imgur_image_fragment" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - - <LinearLayout - android:id="@+id/load_image_error_linear_layout_view_imgur_image_fragment" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:visibility="gone"> - - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:drawableTop="@drawable/ic_error_outline_white_24dp" - android:layout_gravity="center" - android:gravity="center" - android:textColor="@android:color/white" - android:text="@string/error_loading_image_tap_to_retry" - android:textSize="?attr/font_default" - android:fontFamily="?attr/font_family" /> - - </LinearLayout> - -</RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_view_imgur_video.xml b/app/src/main/res/layout/fragment_view_imgur_video.xml index 19331536..824a6b02 100644 --- a/app/src/main/res/layout/fragment_view_imgur_video.xml +++ b/app/src/main/res/layout/fragment_view_imgur_video.xml @@ -1,15 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +<com.google.android.exoplayer2.ui.PlayerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:id="@+id/player_view_view_imgur_video_fragment" xmlns:app="http://schemas.android.com/apk/res-auto" - tools:context=".fragments.ViewImgurVideoFragment"> - - <com.google.android.exoplayer2.ui.PlayerView - android:id="@+id/player_view_view_imgur_video_fragment" - android:layout_width="match_parent" - android:layout_height="match_parent" - app:controller_layout_id="@layout/exo_playback_control_view"/> - -</RelativeLayout>
\ No newline at end of file + app:controller_layout_id="@layout/exo_playback_control_view" + tools:context=".fragments.ViewImgurVideoFragment" />
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_view_post_detail.xml b/app/src/main/res/layout/fragment_view_post_detail.xml index 7b2c314a..72b9e3d0 100644 --- a/app/src/main/res/layout/fragment_view_post_detail.xml +++ b/app/src/main/res/layout/fragment_view_post_detail.xml @@ -13,11 +13,12 @@ app:layout_behavior="@string/appbar_scrolling_view_behavior"> <ml.docilealligator.infinityforreddit.customviews.CustomToroContainer - android:id="@+id/recycler_view_view_post_detail_fragment" + android:id="@+id/post_detail_recycler_view_view_post_detail_fragment" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:paddingBottom="144dp" - android:clipToPadding="false" /> + android:clipToPadding="false" + app:layoutManager=".customviews.LinearLayoutManagerBugFixed" /> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> diff --git a/app/src/main/res/layout/fragment_view_reddit_gallery_image_or_gif.xml b/app/src/main/res/layout/fragment_view_reddit_gallery_image_or_gif.xml index 7f27835d..b41c5600 100644 --- a/app/src/main/res/layout/fragment_view_reddit_gallery_image_or_gif.xml +++ b/app/src/main/res/layout/fragment_view_reddit_gallery_image_or_gif.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/constraintLayout" @@ -11,7 +11,7 @@ android:id="@+id/progress_bar_view_reddit_gallery_image_or_gif_fragment" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_centerInParent="true" /> + android:layout_gravity="center" /> <com.github.piasy.biv.view.BigImageView android:id="@+id/image_view_view_reddit_gallery_image_or_gif_fragment" @@ -39,4 +39,61 @@ </LinearLayout> -</RelativeLayout>
\ No newline at end of file + <com.google.android.material.bottomappbar.BottomAppBar + android:id="@+id/bottom_navigation_view_reddit_gallery_image_or_gif_fragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:backgroundTint="#80000000" + android:visibility="gone" + style="@style/Widget.MaterialComponents.BottomAppBar"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/title_text_view_view_reddit_gallery_image_or_gif_fragment" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:gravity="center_vertical" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:textColor="#FFFFFF" + android:textSize="?attr/font_20" + android:fontFamily="?attr/font_family" + android:maxLines="1" + android:ellipsize="end" /> + + <ImageView + android:id="@+id/download_image_view_view_reddit_gallery_image_or_gif_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="16dp" + android:src="@drawable/ic_file_download_toolbar_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + <ImageView + android:id="@+id/share_image_view_view_reddit_gallery_image_or_gif_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="16dp" + android:src="@drawable/ic_share_toolbar_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + <ImageView + android:id="@+id/wallpaper_image_view_view_reddit_gallery_image_or_gif_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:padding="16dp" + android:src="@drawable/ic_wallpaper_white_24dp" + android:background="?attr/selectableItemBackgroundBorderless" /> + + </LinearLayout> + + </com.google.android.material.bottomappbar.BottomAppBar> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_view_rpan_broadcast.xml b/app/src/main/res/layout/fragment_view_rpan_broadcast.xml new file mode 100644 index 00000000..abab4f52 --- /dev/null +++ b/app/src/main/res/layout/fragment_view_rpan_broadcast.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + tools:context=".fragments.ViewRPANBroadcastFragment"> + + <com.google.android.exoplayer2.ui.PlayerView + android:id="@+id/player_view_view_rpan_broadcast_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:controller_layout_id="@layout/exo_rpan_broadcast_playback_control_view" /> + +</FrameLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_comment.xml b/app/src/main/res/layout/item_comment.xml index 1e4740eb..f72eadc0 100644 --- a/app/src/main/res/layout/item_comment.xml +++ b/app/src/main/res/layout/item_comment.xml @@ -3,227 +3,220 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:background="?attr/cardViewBackgroundColor"> + android:layout_height="wrap_content"> + + <ml.docilealligator.infinityforreddit.customviews.CommentIndentationView + android:id="@+id/vertical_block_indentation_item_comment" + android:layout_width="wrap_content" + android:layout_height="match_parent" /> <LinearLayout + android:id="@+id/linear_layout_item_comment" android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <ml.docilealligator.infinityforreddit.customviews.CommentIndentationView - android:id="@+id/vertical_block_indentation_item_comment" - android:layout_width="wrap_content" - android:layout_height="match_parent" /> + android:layout_height="wrap_content" + android:layout_marginTop="12dp" + android:orientation="vertical" + android:animateLayoutChanges="true"> - <LinearLayout + <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="12dp" - android:orientation="vertical" - android:animateLayoutChanges="true"> + android:paddingStart="16dp" + android:paddingEnd="16dp"> - <androidx.constraintlayout.widget.ConstraintLayout - android:layout_width="match_parent" + <TextView + android:id="@+id/author_text_view_item_post_comment" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingStart="16dp" - android:paddingEnd="16dp"> - - <TextView - android:id="@+id/author_text_view_item_post_comment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:drawablePadding="4dp" - android:textSize="?attr/font_default" - android:fontFamily="?attr/font_family" - app:layout_constraintBottom_toTopOf="@id/author_flair_text_view_item_post_comment" - app:layout_constraintEnd_toStartOf="@+id/barrier" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:layout_constrainedWidth="true" - app:layout_constraintHorizontal_bias="0" /> - - <TextView - android:id="@+id/author_flair_text_view_item_post_comment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:fontFamily="?attr/font_family" - android:textSize="?attr/font_12" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/barrier" - app:layout_constraintHorizontal_bias="0" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/author_text_view_item_post_comment" - app:layout_constrainedWidth="true" - tools:visibility="visible" /> - - <TextView - android:id="@+id/top_score_text_view_item_post_comment" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:gravity="end" - android:textSize="?attr/font_default" - android:fontFamily="?attr/font_family" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@id/comment_time_text_view_item_post_comment" - app:layout_constraintTop_toTopOf="parent" /> - - <TextView - android:id="@+id/comment_time_text_view_item_post_comment" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:gravity="end" - android:textSize="?attr/font_default" - android:fontFamily="?attr/font_family" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <androidx.constraintlayout.widget.Barrier - android:id="@+id/barrier" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:barrierDirection="start" - app:constraint_referenced_ids="top_score_text_view_item_post_comment" /> - - </androidx.constraintlayout.widget.ConstraintLayout> + android:layout_marginEnd="8dp" + android:drawablePadding="4dp" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + app:layout_constraintBottom_toTopOf="@id/author_flair_text_view_item_post_comment" + app:layout_constraintEnd_toStartOf="@+id/barrier" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constrainedWidth="true" + app:layout_constraintHorizontal_bias="0" /> <TextView - android:id="@+id/awards_text_view_item_comment" + android:id="@+id/author_flair_text_view_item_post_comment" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:paddingStart="16dp" - android:paddingEnd="16dp" + android:layout_marginEnd="8dp" + android:fontFamily="?attr/font_family" + android:textSize="?attr/font_12" android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/barrier" + app:layout_constraintHorizontal_bias="0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/author_text_view_item_post_comment" + app:layout_constrainedWidth="true" + tools:visibility="visible" /> + + <TextView + android:id="@+id/top_score_text_view_item_post_comment" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginEnd="8dp" + android:gravity="end" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" - tools:visibility="visible" /> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/comment_time_text_view_item_post_comment" + app:layout_constraintTop_toTopOf="parent" /> <TextView - android:id="@+id/comment_markdown_view_item_post_comment" + android:id="@+id/comment_time_text_view_item_post_comment" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:gravity="end" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <androidx.constraintlayout.widget.Barrier + android:id="@+id/barrier" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:layout_marginBottom="8dp" - android:textColor="?attr/primaryTextColor" - android:textSize="?attr/content_font_default" - android:fontFamily="?attr/content_font_family" /> - - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/bottom_constraint_layout_item_post_comment" - android:layout_width="match_parent" + app:barrierDirection="start" + app:constraint_referenced_ids="top_score_text_view_item_post_comment" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + + <TextView + android:id="@+id/awards_text_view_item_comment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:visibility="gone" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + tools:visibility="visible" /> + + <TextView + android:id="@+id/comment_markdown_view_item_post_comment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="8dp" + android:textColor="?attr/primaryTextColor" + android:textSize="?attr/content_font_default" + android:fontFamily="?attr/content_font_family" /> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/bottom_constraint_layout_item_post_comment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="4dp" + android:paddingEnd="4dp"> + + <ImageView + android:id="@+id/up_vote_button_item_post_comment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="8dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" + android:src="@drawable/ic_arrow_upward_grey_24dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" /> + + <TextView + android:id="@+id/score_text_view_item_post_comment" + android:layout_width="64dp" + android:layout_height="wrap_content" + android:gravity="center" + android:textSize="?attr/font_12" + android:textStyle="bold" + android:fontFamily="?attr/font_family" + app:layout_constraintStart_toEndOf="@+id/up_vote_button_item_post_comment" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + + <ImageView + android:id="@+id/down_vote_button_item_post_comment" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingStart="4dp" - android:paddingEnd="4dp"> - - <ImageView - android:id="@+id/up_vote_button_item_post_comment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="8dp" - android:background="?actionBarItemBackground" - android:clickable="true" - android:focusable="true" - android:src="@drawable/ic_arrow_upward_grey_24dp" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" /> - - <TextView - android:id="@+id/score_text_view_item_post_comment" - android:layout_width="64dp" - android:layout_height="wrap_content" - android:gravity="center" - android:textSize="?attr/font_12" - android:textStyle="bold" - android:fontFamily="?attr/font_family" - app:layout_constraintStart_toEndOf="@+id/up_vote_button_item_post_comment" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent"/> - - <ImageView - android:id="@+id/down_vote_button_item_post_comment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="8dp" - android:background="?actionBarItemBackground" - android:clickable="true" - android:focusable="true" - android:src="@drawable/ic_arrow_downward_grey_24dp" - app:layout_constraintStart_toEndOf="@+id/score_text_view_item_post_comment" - app:layout_constraintEnd_toStartOf="@id/more_button_item_post_comment" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintHorizontal_bias="0" /> - - <ImageView - android:id="@+id/more_button_item_post_comment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="8dp" - android:background="?actionBarItemBackground" - android:clickable="true" - android:focusable="true" - android:src="@drawable/ic_more_vert_grey_24dp" - app:layout_constraintEnd_toStartOf="@+id/expand_button_item_post_comment" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent"/> - - <ImageView - android:id="@+id/expand_button_item_post_comment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="8dp" - android:background="?actionBarItemBackground" - android:clickable="true" - android:focusable="true" - android:src="@drawable/ic_expand_less_grey_24dp" - android:visibility="gone" - app:layout_constraintEnd_toStartOf="@+id/save_button_item_post_comment" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent"/> - - <ImageView - android:id="@+id/save_button_item_post_comment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="8dp" - android:background="?actionBarItemBackground" - android:clickable="true" - android:focusable="true" - app:layout_constraintEnd_toStartOf="@+id/reply_button_item_post_comment" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent"/> - - <ImageView - android:id="@+id/reply_button_item_post_comment" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="8dp" - android:background="?actionBarItemBackground" - android:clickable="true" - android:focusable="true" - android:src="@drawable/ic_reply_grey_24dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent"/> - - </androidx.constraintlayout.widget.ConstraintLayout> - - <View - android:id="@+id/divider_item_comment" - android:layout_width="match_parent" - android:layout_height="1dp" - android:visibility="gone" /> - - </LinearLayout> + android:padding="8dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" + android:src="@drawable/ic_arrow_downward_grey_24dp" + app:layout_constraintStart_toEndOf="@+id/score_text_view_item_post_comment" + app:layout_constraintEnd_toStartOf="@id/more_button_item_post_comment" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintHorizontal_bias="0" /> + + <ImageView + android:id="@+id/more_button_item_post_comment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="8dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" + android:src="@drawable/ic_more_vert_grey_24dp" + app:layout_constraintEnd_toStartOf="@+id/expand_button_item_post_comment" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + + <ImageView + android:id="@+id/expand_button_item_post_comment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="8dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" + android:src="@drawable/ic_expand_less_grey_24dp" + android:visibility="gone" + app:layout_constraintEnd_toStartOf="@+id/save_button_item_post_comment" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + + <ImageView + android:id="@+id/save_button_item_post_comment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="8dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" + app:layout_constraintEnd_toStartOf="@+id/reply_button_item_post_comment" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + + <ImageView + android:id="@+id/reply_button_item_post_comment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="8dp" + android:background="?actionBarItemBackground" + android:clickable="true" + android:focusable="true" + android:src="@drawable/ic_reply_grey_24dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + + </androidx.constraintlayout.widget.ConstraintLayout> + + <View + android:id="@+id/divider_item_comment" + android:layout_width="match_parent" + android:layout_height="1dp" + android:visibility="gone" /> </LinearLayout> diff --git a/app/src/main/res/layout/item_flair.xml b/app/src/main/res/layout/item_flair.xml index de10c3dd..d6b0c239 100644 --- a/app/src/main/res/layout/item_flair.xml +++ b/app/src/main/res/layout/item_flair.xml @@ -9,19 +9,24 @@ <TextView android:id="@+id/flair_text_view_item_flair" - android:layout_width="wrap_content" + android:layout_width="0dp" android:layout_height="wrap_content" - android:padding="16dp" + android:layout_weight="1" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingStart="32dp" + android:paddingEnd="32dp" android:textColor="?attr/primaryTextColor" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> <ImageView android:id="@+id/edit_flair_image_view_item_flair" - android:layout_width="24dp" - android:layout_height="24dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_gravity="center_vertical|end" - android:layout_marginStart="32dp" + android:paddingStart="32dp" + android:paddingEnd="32dp" android:src="@drawable/ic_edit_24dp" android:visibility="gone" app:tint="?attr/primaryTextColor" diff --git a/app/src/main/res/layout/item_post_card_2_video_autoplay.xml b/app/src/main/res/layout/item_post_card_2_video_autoplay.xml index da85dcea..8cb3ef10 100644 --- a/app/src/main/res/layout/item_post_card_2_video_autoplay.xml +++ b/app/src/main/res/layout/item_post_card_2_video_autoplay.xml @@ -29,8 +29,8 @@ android:id="@+id/player_view_item_post_card_2_video_autoplay" android:layout_width="match_parent" android:layout_height="match_parent" - app:controller_layout_id="@layout/exo_autoplay_playback_control_view" - android:animateLayoutChanges="true" /> + app:show_timeout="1000" + app:controller_layout_id="@layout/exo_autoplay_playback_control_view" /> <pl.droidsonroids.gif.GifImageView android:id="@+id/preview_image_view_item_post_card_2_video_autoplay" diff --git a/app/src/main/res/layout/item_post_card_2_with_preview.xml b/app/src/main/res/layout/item_post_card_2_with_preview.xml index 777be8ae..0accab55 100644 --- a/app/src/main/res/layout/item_post_card_2_with_preview.xml +++ b/app/src/main/res/layout/item_post_card_2_with_preview.xml @@ -28,12 +28,12 @@ <ImageView android:id="@+id/video_or_gif_indicator_image_view_item_post_card_2_with_preview" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="36dp" + android:layout_height="36dp" android:layout_margin="16dp" android:layout_gravity="start" + android:scaleType="center" android:background="@drawable/play_button_round_background" - android:src="@drawable/ic_play_circle_36dp" android:visibility="gone" /> <ProgressBar @@ -46,7 +46,6 @@ android:id="@+id/load_image_error_relative_layout_item_post_card_2_with_preview" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_gravity="center" android:visibility="gone"> <TextView @@ -54,8 +53,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableTop="@drawable/ic_error_outline_black_24dp" - android:layout_gravity="center" - android:gravity="center" + android:layout_centerInParent="true" + android:paddingStart="16dp" + android:paddingEnd="16dp" android:text="@string/error_loading_image_tap_to_retry" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> diff --git a/app/src/main/res/layout/item_post_compact.xml b/app/src/main/res/layout/item_post_compact.xml index 309eedb5..06c00131 100644 --- a/app/src/main/res/layout/item_post_compact.xml +++ b/app/src/main/res/layout/item_post_compact.xml @@ -31,7 +31,6 @@ android:layout_marginStart="16dp" android:layout_marginEnd="8dp" android:fontFamily="?attr/font_family" - android:textColor="#E91E63" android:textSize="?attr/font_default" app:layout_constraintHorizontal_bias="0" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/item_post_compact_right_thumbnail.xml b/app/src/main/res/layout/item_post_compact_right_thumbnail.xml index 3fbe55e6..6b1b7abf 100644 --- a/app/src/main/res/layout/item_post_compact_right_thumbnail.xml +++ b/app/src/main/res/layout/item_post_compact_right_thumbnail.xml @@ -3,7 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical"> + android:orientation="vertical" + android:animateLayoutChanges="true"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" @@ -30,7 +31,6 @@ android:layout_marginStart="16dp" android:layout_marginEnd="8dp" android:fontFamily="?attr/font_family" - android:textColor="#E91E63" android:textSize="?attr/font_default" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/stickied_post_image_view_item_post_compact_right_thumbnail" diff --git a/app/src/main/res/layout/item_post_detail_gallery.xml b/app/src/main/res/layout/item_post_detail_gallery.xml index 2b3a0e99..712a7725 100644 --- a/app/src/main/res/layout/item_post_detail_gallery.xml +++ b/app/src/main/res/layout/item_post_detail_gallery.xml @@ -208,12 +208,27 @@ android:layout_height="wrap_content" android:visibility="gone"> - <ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView - android:id="@+id/image_view_item_post_detail_gallery" + <FrameLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:adjustViewBounds="true" - android:scaleType="fitStart" /> + android:layout_height="wrap_content"> + + <ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView + android:id="@+id/image_view_item_post_detail_gallery" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:adjustViewBounds="true" + android:scaleType="fitStart" /> + + <ImageView + android:layout_width="36dp" + android:layout_height="36dp" + android:layout_margin="16dp" + android:layout_gravity="start" + android:scaleType="center" + android:background="@drawable/play_button_round_background" + android:src="@drawable/ic_gallery_reverse_color_24dp" /> + + </FrameLayout> <RelativeLayout android:id="@+id/load_wrapper_item_post_detail_gallery" diff --git a/app/src/main/res/layout/item_post_detail_video_and_gif_preview.xml b/app/src/main/res/layout/item_post_detail_video_and_gif_preview.xml index ed2a28d9..c2930a41 100644 --- a/app/src/main/res/layout/item_post_detail_video_and_gif_preview.xml +++ b/app/src/main/res/layout/item_post_detail_video_and_gif_preview.xml @@ -217,8 +217,8 @@ android:scaleType="fitStart" /> <ImageView - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="36dp" + android:layout_height="36dp" android:layout_margin="16dp" android:layout_gravity="start" android:background="@drawable/play_button_round_background" diff --git a/app/src/main/res/layout/item_post_detail_video_autoplay.xml b/app/src/main/res/layout/item_post_detail_video_autoplay.xml index 5202299d..78396e50 100644 --- a/app/src/main/res/layout/item_post_detail_video_autoplay.xml +++ b/app/src/main/res/layout/item_post_detail_video_autoplay.xml @@ -213,8 +213,8 @@ android:id="@+id/player_view_item_post_detail_video_autoplay" android:layout_width="match_parent" android:layout_height="match_parent" - app:controller_layout_id="@layout/exo_autoplay_playback_control_view" - android:animateLayoutChanges="true" /> + app:show_timeout="1000" + app:controller_layout_id="@layout/exo_autoplay_playback_control_view" /> <pl.droidsonroids.gif.GifImageView android:id="@+id/preview_image_view_item_post_detail_video_autoplay" diff --git a/app/src/main/res/layout/item_post_gallery.xml b/app/src/main/res/layout/item_post_gallery.xml index 3d32cd04..19a2e418 100644 --- a/app/src/main/res/layout/item_post_gallery.xml +++ b/app/src/main/res/layout/item_post_gallery.xml @@ -3,6 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" + xmlns:tools="http://schemas.android.com/tools" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" app:cardElevation="2dp" @@ -43,16 +44,17 @@ android:id="@+id/load_image_error_relative_layout_item_post_gallery" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_gravity="center" - android:visibility="gone"> + android:visibility="gone" + tools:visibility="visible"> <TextView android:id="@+id/load_image_error_text_view_item_gallery" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingStart="16dp" + android:paddingEnd="16dp" app:drawableTopCompat="@drawable/ic_error_outline_black_24dp" - android:layout_gravity="center" - android:gravity="center" + android:layout_centerInParent="true" android:text="@string/error_loading_image_tap_to_retry" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> diff --git a/app/src/main/res/layout/item_post_video_type_autoplay.xml b/app/src/main/res/layout/item_post_video_type_autoplay.xml index 3b78eb27..0d83ca9f 100644 --- a/app/src/main/res/layout/item_post_video_type_autoplay.xml +++ b/app/src/main/res/layout/item_post_video_type_autoplay.xml @@ -206,8 +206,8 @@ android:id="@+id/player_view_item_post_video_type_autoplay" android:layout_width="match_parent" android:layout_height="match_parent" - app:controller_layout_id="@layout/exo_autoplay_playback_control_view" - android:animateLayoutChanges="true" /> + app:show_timeout="1000" + app:controller_layout_id="@layout/exo_autoplay_playback_control_view" /> <pl.droidsonroids.gif.GifImageView android:id="@+id/preview_image_view_item_post_video_type_autoplay" diff --git a/app/src/main/res/layout/item_post_with_preview.xml b/app/src/main/res/layout/item_post_with_preview.xml index 3d2f09b3..b3ef0a9b 100644 --- a/app/src/main/res/layout/item_post_with_preview.xml +++ b/app/src/main/res/layout/item_post_with_preview.xml @@ -221,12 +221,12 @@ <ImageView android:id="@+id/video_or_gif_indicator_image_view_item_post_with_preview" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="36dp" + android:layout_height="36dp" android:layout_margin="16dp" android:layout_gravity="start" + android:scaleType="center" android:background="@drawable/play_button_round_background" - android:src="@drawable/ic_play_circle_36dp" android:visibility="gone" /> <ProgressBar diff --git a/app/src/main/res/layout/item_reddit_gallery_submission_add_image.xml b/app/src/main/res/layout/item_reddit_gallery_submission_add_image.xml new file mode 100644 index 00000000..ebb89953 --- /dev/null +++ b/app/src/main/res/layout/item_reddit_gallery_submission_add_image.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/fab_item_gallery_submission_add_image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_outline_select_photo_24dp" + android:layout_gravity="center" /> + +</FrameLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_reddit_gallery_submission_image.xml b/app/src/main/res/layout/item_reddit_gallery_submission_image.xml new file mode 100644 index 00000000..c6d42e81 --- /dev/null +++ b/app/src/main/res/layout/item_reddit_gallery_submission_image.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView + android:id="@+id/aspect_ratio_gif_image_view_item_reddit_gallery_submission_image" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:scaleType="centerCrop" /> + + <ProgressBar + android:id="@+id/progress_bar_item_reddit_gallery_submission_image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" /> + + <ImageView + android:id="@+id/close_image_view_item_reddit_gallery_submission_image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:layout_gravity="top|end" + android:background="@drawable/play_button_round_background" + android:src="@drawable/ic_close_24dp" + android:visibility="gone" /> + +</FrameLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_rpan_comment.xml b/app/src/main/res/layout/item_rpan_comment.xml new file mode 100644 index 00000000..54ace9c5 --- /dev/null +++ b/app/src/main/res/layout/item_rpan_comment.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp"> + + <ImageView + android:id="@+id/icon_image_view_item_rpan_comment" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="center_vertical" /> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:layout_marginStart="16dp" + android:layout_marginEnd="0dp" + android:orientation="vertical"> + + <TextView + android:id="@+id/author_text_view_item_rpan_comment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="#02BAEE" /> + + <TextView + android:id="@+id/content_text_view_item_rpan_comment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:textColor="#FFFFFF" /> + + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_subreddit_listing.xml b/app/src/main/res/layout/item_subreddit_listing.xml index bae636fe..e756edf1 100644 --- a/app/src/main/res/layout/item_subreddit_listing.xml +++ b/app/src/main/res/layout/item_subreddit_listing.xml @@ -45,7 +45,7 @@ android:visibility="gone"/> <com.google.android.material.checkbox.MaterialCheckBox - android:id="@+id/checkbox__item_subreddit_listing" + android:id="@+id/checkbox_item_subreddit_listing" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/item_trending_search.xml b/app/src/main/res/layout/item_trending_search.xml new file mode 100644 index 00000000..d1cdbded --- /dev/null +++ b/app/src/main/res/layout/item_trending_search.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + app:cardCornerRadius="16dp" + app:cardElevation="2dp"> + + <RelativeLayout + android:id="@+id/image_wrapper_relative_layout_item_trending_search" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone"> + + <ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView + android:id="@+id/image_view_item_trending_search" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:adjustViewBounds="true" + android:scaleType="fitStart" /> + + <ProgressBar + android:id="@+id/progress_bar_item_trending_search" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerInParent="true" /> + + <RelativeLayout + android:id="@+id/load_image_error_relative_layout_item_trending_search" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_centerInParent="true" + android:visibility="gone"> + + <TextView + android:id="@+id/load_image_error_text_view_item_trending_search" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:drawableTop="@drawable/ic_error_outline_black_24dp" + android:layout_gravity="center" + android:gravity="center" + android:text="@string/error_loading_image_tap_to_retry" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" /> + + </RelativeLayout> + + </RelativeLayout> + + <ImageView + android:id="@+id/image_view_no_preview_gallery_item_trending_search" + android:layout_width="match_parent" + android:layout_height="150dp" + android:scaleType="center" + android:src="@drawable/ic_image_24dp" + android:visibility="gone" /> + + <TextView + android:id="@+id/title_text_view_item_trending_search" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:padding="16dp" + android:background="@drawable/trending_search_title_background" + android:maxLines="2" + android:textColor="#FFFFFF" + android:textSize="?attr/title_font_20" + android:fontFamily="?attr/title_font_family" + android:textStyle="bold" /> + +</com.google.android.material.card.MaterialCardView>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_uploaded_image.xml b/app/src/main/res/layout/item_uploaded_image.xml new file mode 100644 index 00000000..6fb4b589 --- /dev/null +++ b/app/src/main/res/layout/item_uploaded_image.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> + + <TextView + android:id="@+id/image_name_item_uploaded_image" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fontFamily="?attr/font_family" + android:textSize="?attr/font_16" + android:textColor="?attr/primaryTextColor" /> + + <TextView + android:id="@+id/image_url_item_uploaded_image" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:fontFamily="?attr/font_family" + android:textSize="?attr/font_12" + android:textColor="?attr/secondaryTextColor" /> + +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/menu/full_markdown_activity.xml b/app/src/main/res/menu/full_markdown_activity.xml new file mode 100644 index 00000000..ef700721 --- /dev/null +++ b/app/src/main/res/menu/full_markdown_activity.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/action_send_full_markdown_activity" + android:orderInCategory="1" + android:title="@string/action_send" + android:icon="@drawable/ic_send_toolbar_24dp" + app:showAsAction="ifRoom" /> +</menu>
\ No newline at end of file diff --git a/app/src/main/res/menu/post_gallery_activity.xml b/app/src/main/res/menu/post_gallery_activity.xml new file mode 100644 index 00000000..4bdcff54 --- /dev/null +++ b/app/src/main/res/menu/post_gallery_activity.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/action_send_post_gallery_activity" + android:orderInCategory="1" + android:title="@string/action_send" + android:icon="@drawable/ic_send_toolbar_24dp" + app:showAsAction="ifRoom" /> +</menu>
\ No newline at end of file diff --git a/app/src/main/res/menu/rpan_activity.xml b/app/src/main/res/menu/rpan_activity.xml new file mode 100644 index 00000000..bb165fd4 --- /dev/null +++ b/app/src/main/res/menu/rpan_activity.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/action_share_rpan_link_rpan_activity" + android:orderInCategory="1" + android:title="@string/action_share_rpan_link" + app:showAsAction="never" /> + + <item + android:id="@+id/action_share_post_link_rpan_activity" + android:orderInCategory="1" + android:title="@string/action_share_post_link" + app:showAsAction="never" /> +</menu>
\ No newline at end of file diff --git a/app/src/main/res/menu/trending_activity.xml b/app/src/main/res/menu/trending_activity.xml new file mode 100644 index 00000000..2bd2db1c --- /dev/null +++ b/app/src/main/res/menu/trending_activity.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/action_refresh_trending_activity" + android:orderInCategory="1" + android:title="@string/action_refresh" + android:icon="@drawable/ic_refresh_24dp" + app:showAsAction="ifRoom" /> +</menu>
\ No newline at end of file diff --git a/app/src/main/res/menu/view_post_detail_fragment.xml b/app/src/main/res/menu/view_post_detail_fragment.xml index 437355e0..5f732534 100644 --- a/app/src/main/res/menu/view_post_detail_fragment.xml +++ b/app/src/main/res/menu/view_post_detail_fragment.xml @@ -2,8 +2,15 @@ <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item - android:id="@+id/action_comment_view_post_detail_fragment" + android:id="@+id/action_search_view_post_detail_fragment" android:orderInCategory="1" + android:title="@string/action_search" + android:icon="@drawable/ic_search_toolbar_24dp" + app:showAsAction="ifRoom" /> + + <item + android:id="@+id/action_comment_view_post_detail_fragment" + android:orderInCategory="2" android:title="@string/action_add_comment" android:icon="@drawable/ic_comment_toolbar_24dp" app:showAsAction="ifRoom" @@ -11,98 +18,98 @@ <item android:id="@+id/action_save_view_post_detail_fragment" - android:orderInCategory="2" + android:orderInCategory="3" android:title="@string/action_save_post" app:showAsAction="ifRoom" android:visible="false" /> <item android:id="@+id/action_sort_view_post_detail_fragment" - android:orderInCategory="3" + android:orderInCategory="4" android:title="@string/action_sort" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_refresh_view_post_detail_fragment" - android:orderInCategory="4" + android:orderInCategory="5" android:title="@string/action_refresh" app:showAsAction="never" /> <item android:id="@+id/action_view_crosspost_parent_view_post_detail_fragment" - android:orderInCategory="5" + android:orderInCategory="6" android:title="@string/action_view_crosspost_parent" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_hide_view_post_detail_fragment" - android:orderInCategory="6" + android:orderInCategory="7" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_edit_view_post_detail_fragment" - android:orderInCategory="7" + android:orderInCategory="8" android:title="@string/action_edit_post" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_delete_view_post_detail_fragment" - android:orderInCategory="8" + android:orderInCategory="9" android:title="@string/action_delete_post" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_nsfw_view_post_detail_fragment" - android:orderInCategory="9" + android:orderInCategory="10" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_spoiler_view_post_detail_fragment" - android:orderInCategory="10" + android:orderInCategory="11" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_edit_flair_view_post_detail_fragment" - android:orderInCategory="11" + android:orderInCategory="12" android:title="@string/action_edit_flair" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_give_award_view_post_detail_fragment" - android:orderInCategory="12" + android:orderInCategory="13" android:title="@string/action_give_award" app:showAsAction="never" /> <item android:id="@+id/action_report_view_post_detail_fragment" - android:orderInCategory="13" + android:orderInCategory="14" android:title="@string/action_report" app:showAsAction="never" /> <item android:id="@+id/action_see_removed_view_post_detail_fragment" - android:orderInCategory="14" + android:orderInCategory="15" android:title="@string/action_see_removed" app:showAsAction="never" android:visible="false" /> <item android:id="@+id/action_crosspost_view_post_detail_fragment" - android:orderInCategory="15" + android:orderInCategory="16" android:title="@string/action_crosspost" app:showAsAction="never" /> <item android:id="@+id/action_add_to_post_filter_view_post_detail_fragment" - android:orderInCategory="16" + android:orderInCategory="17" android:title="@string/action_add_to_post_filter" app:showAsAction="never" /> </menu> diff --git a/app/src/main/res/menu/view_subreddit_detail_activity.xml b/app/src/main/res/menu/view_subreddit_detail_activity.xml index 3521819a..c1631814 100644 --- a/app/src/main/res/menu/view_subreddit_detail_activity.xml +++ b/app/src/main/res/menu/view_subreddit_detail_activity.xml @@ -48,8 +48,14 @@ app:showAsAction="never" /> <item - android:id="@+id/action_share_view_subreddit_detail_activity" + android:id="@+id/action_add_to_post_filter_view_subreddit_detail_activity" android:orderInCategory="8" + android:title="@string/action_add_to_post_filter" + app:showAsAction="never" /> + + <item + android:id="@+id/action_share_view_subreddit_detail_activity" + android:orderInCategory="9" android:title="@string/action_share" app:showAsAction="never" /> </menu> diff --git a/app/src/main/res/menu/view_user_detail_activity.xml b/app/src/main/res/menu/view_user_detail_activity.xml index 05e4c3cb..8d89ff08 100644 --- a/app/src/main/res/menu/view_user_detail_activity.xml +++ b/app/src/main/res/menu/view_user_detail_activity.xml @@ -51,12 +51,18 @@ app:showAsAction="never" /> <item - android:id="@+id/action_report_view_user_detail_activity" + android:id="@+id/action_add_to_post_filter_view_user_detail_activity" android:orderInCategory="9" + android:title="@string/action_add_to_post_filter" + app:showAsAction="never" /> + + <item + android:id="@+id/action_report_view_user_detail_activity" + android:orderInCategory="10" android:title="@string/action_report" /> <item android:id="@+id/action_block_user_view_user_detail_activity" - android:orderInCategory="10" + android:orderInCategory="11" android:title="@string/action_block_user" /> </menu> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index dfb251d0..b8227553 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -71,36 +71,44 @@ <string name="parse_user_info_error">"Ein Fehler trat beim Abruf der Benutzerinformationen auf"</string> <string name="no_system_webview_error">"Fehler beim Öffnen des System-WebView"</string> <string name="error_loading_image_tap_to_retry">"Fehler beim Laden des Bildes. Tippen für Neuversuch."</string> - <string name="load_posts_error">"Fehler beim Laden der Beiträge. Tippen für Neuversuch."</string> + <string name="load_posts_error">"Fehler beim Laden der Beiträge. +Tippen für Neuversuch."</string> <string name="load_more_posts_error">"Fehler beim Laden der Beiträge."</string> - <string name="load_post_error">"Fehler beim Laden des Beitrags. Tippen für Neuversuch."</string> - <string name="search_subreddits_error">"Fehler beim Suchen von Subreddits. Tippen für Neuversuch."</string> - <string name="search_users_error">"Fehler beim Suchen nach Benutzern. Tippen für Neuversuch."</string> + <string name="load_post_error">"Fehler beim Laden des Beitrags. +Tippen für Neuversuch."</string> + <string name="search_subreddits_error">"Fehler beim Suchen von Subreddits. +Tippen für Neuversuch."</string> + <string name="search_users_error">"Fehler beim Suchen nach Benutzern. +Tippen für Neuversuch."</string> <string name="no_posts">"Keine Beiträge gefunden"</string> <string name="no_comments">"Keine Kommentare gefunden"</string> <string name="no_subreddits">"Keine Subreddits gefunden"</string> <string name="no_users">"Keine Benutzer gefunden"</string> <string name="no_multi_reddits">"Keine Multireddits gefunden"</string> <string name="no_storage_permission">"Keine Speicherberechtigung, um diese Datei zu speichern"</string> - <string name="load_comments_failed">"Fehler beim Laden der Kommentare. Berühren, um es erneut zu versuchen."</string> + <string name="load_comments_failed">"Fehler beim Laden der Kommentare. +Tippen für Neuversuch."</string> <string name="retry">"Wiederholen"</string> <string name="comments">"Kommentare"</string> <string name="no_comments_yet">"Noch keine Kommentare. Einen Kommentar schreiben?"</string> <string name="vote_failed">"Abstimmung fehlgeschlagen"</string> <string name="refresh_post_failed">"Fehler beim Aktualisieren des Beitrags"</string> - <string name="load_messages_failed">"Fehler beim Laden der Nachrichten. Berühren, um es erneut zu versuchen."</string> + <string name="load_messages_failed">"Fehler beim Laden der Nachrichten. +Tippen für Neuversuch."</string> <string name="no_messages">"Leer"</string> <string name="nsfw">"NSFW"</string> <string name="karma_info">"Karma: %1$d"</string> - <string name="karma_info_user_detail">"Karma: %1$d (%2$d + %3$d)"</string> - <string name="cakeday_info">"Cake Day: %1$s"</string> + <string name="karma_info_user_detail">"Karma: +%1$d (%2$d + %3$d)"</string> + <string name="cakeday_info">"Cake Day: +%1$s"</string> <string name="since">"Seit:"</string> <string name="profile">"Profil"</string> <string name="subscriptions">"Abonnements"</string> <string name="multi_reddit">"Multireddit"</string> <string name="inbox">"Posteingang"</string> - <string name="upvoted">"Upgevoted"</string> - <string name="downvoted">"Downgevoted"</string> + <string name="upvoted">"Upgevotet"</string> + <string name="downvoted">"Downgevotet"</string> <string name="hidden">"Versteckt"</string> <string name="saved">"Gespeichert"</string> <string name="gilded">"Vergoldet"</string> @@ -135,7 +143,7 @@ <string name="send_comment_success">"Kommentar gesendet"</string> <string name="send_comment_failed">"Konnte diesen Kommentar nicht senden"</string> <string name="send_message_username_hint">"Benutzer"</string> - <string name="send_message_subject_hint">"Betreff"</string> + <string name="send_message_subject_hint">"Betreff (maximal 100 Zeichen)"</string> <string name="send_message_content_hint">"Nachricht"</string> <string name="reply_message_failed">"Konnte nicht auf diese Nachricht antworten"</string> <string name="error_getting_message">"Fehler beim Abrufen dieser Nachricht"</string> @@ -181,9 +189,11 @@ <string name="flair">"Flair"</string> <string name="spoiler">"Spoiler"</string> <string name="no_flair">"Kein Flair"</string> - <string name="error_loading_flairs">"Fehler beim Laden der Flairs. Berühren, um es erneut zu versuchen."</string> + <string name="error_loading_flairs">"Fehler beim Laden der Flairs. +Tippen für Neuversuch."</string> <string name="no_rule">"Keine Regel"</string> - <string name="error_loading_rules">"Fehler beim Laden der Regeln. Berühren, um es erneut zu versuchen."</string> + <string name="error_loading_rules">"Fehler beim Laden der Regeln. +Tippen für Neuversuch."</string> <string name="error_loading_rules_without_retry">"Fehler beim Laden der Regeln"</string> <string name="search_in">"Suchen in"</string> <string name="all_subreddits">"Alle Subreddits"</string> @@ -220,11 +230,13 @@ <string name="image">"BILD"</string> <string name="video">"VIDEO"</string> <string name="gif">"GIF"</string> - <string name="gallery">"GALLERIE"</string> + <string name="gallery">"GALERIE"</string> <string name="best">"Beste"</string> <string name="search">"Suchen"</string> <string name="posting_video">"Poste Video"</string> <string name="posting_image">"Poste Bild"</string> + + <!-- Fuzzy --> <string name="please_wait">"Bitte warten."</string> <string name="add_account">"Konto hinzufügen"</string> <string name="anonymous_account">"Anonym"</string> @@ -311,8 +323,7 @@ <string name="settings_immersive_interface_title">"Immersive Oberfläche"</string> <!-- Fuzzy --> - <string name="settings_immersive_interface_summary">"Funktioniert nicht auf allen Seiten -Funktioniert vielleicht nicht auf Android 11"</string> + <string name="settings_immersive_interface_summary">"Funktioniert nicht auf allen Seiten"</string> <string name="settings_immersive_interface_ignore_nav_bar_title">"Navigationsleiste in der immersiven Oberfläche ignorieren"</string> <string name="settings_immersive_interface_ignore_nav_bar_summary">"Weniger Abstand für die untere Navigationsleiste"</string> <string name="settings_customize_tabs_in_main_page_title">"Reiter auf der Hauptseite anpassen"</string> @@ -324,6 +335,8 @@ Funktioniert vielleicht nicht auf Android 11"</string> <string name="settings_volume_keys_navigate_posts_title">"Lautstärketasten nutzen, um durch Beiträge zu navigieren"</string> <string name="settings_mute_video_title">"Videos stummschalten"</string> <string name="settings_mute_nsfw_video_title">"NSFW-Videos stummschalten"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"Automatisch versuchen, Redgifs abzurufen, falls Videos auf Gfycat entfernt wurden."</string> <string name="settings_video_player_ignore_nav_bar_title">"Navigationsleiste im Video-Player ignorieren"</string> <string name="settings_video_player_ignore_nav_bar_summary">"Kein extra Rand beim Video-Controller"</string> @@ -405,7 +418,7 @@ Funktioniert vielleicht nicht auf Android 11"</string> <string name="settings_customize_dark_theme_title">"Dunkles Thema"</string> <string name="settings_customize_amoled_theme_title">"AMOLED-Thema"</string> <string name="settings_manage_themes_title">"Themen verwalten"</string> - <string name="settings_custom_theme_cannot_apply_to_settings_page_summary">"Benutzerdefiniterte Themen können nicht auf die Einstellungs-Seite angewandt werden (ausgenommen Werkzeug-, Status- und Navigationsleiste)"</string> + <string name="settings_custom_theme_cannot_apply_to_settings_page_summary">"Benutzerdefinierte Themen können nicht auf die Einstellungs-Seite angewandt werden (ausgenommen Werkzeug-, Status- und Navigationsleiste)."</string> <string name="settings_advanced_master_title">"Erweitert"</string> <string name="settings_delete_all_subreddits_data_in_database_title">"Alle Subreddits aus der Datenbank löschen"</string> <string name="settings_delete_all_users_data_in_database_title">"Alle Benutzer aus der Datenbank löschen"</string> @@ -461,7 +474,8 @@ Funktioniert vielleicht nicht auf Android 11"</string> <string name="error_getting_multi_reddit_data">"Fehler beim Abrufen der Multireddit-Daten"</string> <string name="error_loading_multi_reddit_list">"Kann Multireddits nicht synchronisieren"</string> <string name="error_loading_subscriptions">"Kann Abonnements nicht synchronisieren"</string> - <string name="share_this_app">"Schau dir Infinity for Reddit an, ein super Reddit-Client! https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit"</string> + <string name="share_this_app">"Schau dir Infinity for Reddit an, ein super Reddit-Client! +https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit"</string> <string name="error_getting_subreddit_name">"Fehler beim Abrufen des Subreddit-Namens"</string> <string name="share_post_link">"Beitrags-Link teilen"</string> <string name="share_image_link">"Bild-Link teilen"</string> @@ -484,7 +498,7 @@ Funktioniert vielleicht nicht auf Android 11"</string> <string name="exit_app">"Verlassen?"</string> <string name="light_theme">"Helles Thema"</string> <string name="dark_theme">"Dunkles Thema"</string> - <string name="multi_reddit_name_hint">"Name (Max. 50 Zeichen)"</string> + <string name="multi_reddit_name_hint">"Name (Maximal 50 Zeichen)"</string> <string name="multi_reddit_description_hint">"Beschreibung"</string> <string name="private_multi_reddit">"Privat"</string> <string name="no_multi_reddit_name">"Wo ist der Name?"</string> @@ -553,7 +567,7 @@ Funktioniert vielleicht nicht auf Android 11"</string> <string name="theme_item_bottom_app_bar_background_color">"Farbe für untere Navigationsleiste"</string> <string name="theme_item_bottom_app_bar_background_color_detail">"Angewandt auf: Untere Navigationsleiste"</string> <string name="theme_item_primary_icon_color">"Primäre Symbolfarbe"</string> - <string name="theme_item_primary_icon_color_detail">"Angewandt auf: Symbole in der Navigationsleiste"</string> + <string name="theme_item_primary_icon_color_detail">"Angewandt auf: Symbole in der Navigationsleiste."</string> <string name="theme_item_bottom_app_bar_icon_color">"Symbolfarbe für untere Navigationsleiste"</string> <string name="theme_item_bottom_app_bar_icon_color_detail">"Angewandt auf: Symbole in der unteren Navigationsleiste"</string> <string name="theme_item_post_icon_and_info_color">"Farbe für Beitragssymbol und Information"</string> @@ -584,10 +598,10 @@ Funktioniert vielleicht nicht auf Android 11"</string> <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color_detail">"Angewandt auf: Textfarbe im Reiterlayout (eingeklappte Werkzeugleiste)"</string> <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator">"Indikatorfarbe für Reiterlayout in der eingeklappten Werkzeugleiste"</string> <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator_detail">"Angewandt auf: Indikatorfarbe im Reiterlayout (eingeklappte Werkzeugleiste)"</string> - <string name="theme_item_upvoted_color">"Upgevoted Farbe"</string> - <string name="theme_item_upvoted_color_detail">"Angewandt auf: Abstimmungs-Knöpfe und Punktzahlen (upgevoted)"</string> - <string name="theme_item_downvoted_color">"Downgevoted Farbe"</string> - <string name="theme_item_downvoted_color_detail">"Angewandt auf: Abstimmungs-Knöpfe und Punktzahlen (downgevoted)"</string> + <string name="theme_item_upvoted_color">"Upgevotet Farbe"</string> + <string name="theme_item_upvoted_color_detail">"Angewandt auf: Abstimmungs-Knöpfe und Punktzahlen (upgevotet)"</string> + <string name="theme_item_downvoted_color">"Downgevotet Farbe"</string> + <string name="theme_item_downvoted_color_detail">"Angewandt auf: Abstimmungs-Knöpfe und Punktzahlen (downgevotet)"</string> <string name="theme_item_post_type_background_color">"Hintergrundfarbe für Beitragsart"</string> <string name="theme_item_post_type_background_color_detail">"Angewandt auf: Hintergrund der Beitragsart (BILD, TEXT, VIDEO, GIF, LINK)"</string> <string name="theme_item_post_type_text_color">"Textfarbe für Beitragsart"</string> @@ -681,7 +695,7 @@ Funktioniert vielleicht nicht auf Android 11"</string> <string name="create_light_theme">"Erstelle ein helles Thema basierend auf dem Indigo-Thema"</string> <string name="create_dark_theme">"Erstelle ein dunkles Thema basierend auf dem Indigo-Dunkel-Thema"</string> <string name="create_amoled_theme">"Erstelle ein AMOLED-Thema basierend auf dem Indigo-AMOLED-Thema"</string> - <string name="create_theme_info">"Wenn du stattdessen ein Thema basierend auf einem anderen Thema erstellen möchtest, klicke auf den \"+\"-Knopf auf einem Thema"</string> + <string name="create_theme_info">"Wenn du stattdessen ein Thema basierend auf einem anderen Thema erstellen möchtest, klicke auf den \"+\"-Knopf auf einem Thema."</string> <string name="edit_theme_name">"Thema-Name bearbeiten"</string> <string name="edit_theme">"Thema bearbeiten"</string> <string name="delete_theme">"Thema löschen"</string> @@ -838,7 +852,10 @@ Reiter könnten den Inhalt verlieren, wenn zu anderen gewechselt wird. Selbes Ve <string name="settings_data_saving_mode">"Datensparmodus"</string> <!-- Fuzzy --> - <string name="settings_data_saving_mode_info_summary">"Im Datensparmodus werden Vorschaubilder mit geringerer Auflösung geladen."</string> + <string name="settings_data_saving_mode_info_summary">"Im Datensparmodus: +Vorschaubilder haben eine geringere Auflösung. +Reddit-Videos haben eine geringere Auflösung. +Automatisches Abspielen von Videos ist deaktiviert."</string> <string name="settings_translation_title">"Übersetzung"</string> <string name="settings_translation_summary">"Übersetze diese App auf POEditor. Danke an alle Beitragenden."</string> <string name="settings_credits_national_flags">"Nationalflaggen"</string> @@ -868,12 +885,12 @@ Reiter könnten den Inhalt verlieren, wenn zu anderen gewechselt wird. Selbes Ve <string name="anonymous">"Anonym"</string> <!-- Fuzzy --> - <string name="give_award_error_message">"Code: %1$d/ Nachricht: %2$s"</string> + <string name="give_award_error_message">"Code: %1$d/ +Nachricht: %2$s"</string> <string name="give_award_success">"Auszeichnung verliehen"</string> <string name="give_award_failed">"Fehlgeschlagen"</string> - <string name="recent_searches">"Kürzliche Suchanfragen"</string> <string name="warning">"Warnung"</string> - <string name="this_is_a_nsfw_subreddit">"Dieses ist ein NSFW-Subreddit"</string> + <string name="this_is_a_nsfw_subreddit">"Dies ist ein NSFW-Subreddit."</string> <string name="this_user_has_nsfw_content">"Dieser Nutzer hat NSFW-Inhalte"</string> <string name="dismiss">"Verwerfen"</string> <string name="leave">"Verlassen"</string> @@ -992,4 +1009,104 @@ Reiter könnten den Inhalt verlieren, wenn zu anderen gewechselt wird. Selbes Ve <string name="add_subreddit_or_user_to_multireddit_success">"%1$s wurde zu Multireddit %2$s hinzugefügt"</string> <string name="add_subreddit_or_user_to_multireddit_failed">"Konnte %1$s nicht zu Multireddit %2$s hinzufügen"</string> <string name="choose_a_user">"Wähle einen Benutzer"</string> + <string name="settings_click_to_show_media_in_gallery_layout">"Antippen, um die Medien in der Galerie-Ansicht anzuzeigen"</string> + <string name="settings_hide_post_type">"Beitragsart verstecken"</string> + <string name="settings_hide_the_number_of_awards">"Anzahl der Auszeichnungen verstecken"</string> + <string name="settings_hide_subreddit_and_user_prefix">"Subreddit und Benutzerpräfix verstecken"</string> + <string name="settings_hide_the_number_of_votes">"Anzahl der Abstimmungen verstecken"</string> + <string name="settings_hide_the_number_of_comments">"Anzahl der Kommentare verstecken"</string> + <string name="post_layout_gallery">"Galerie-Ansicht"</string> + <string name="post_layout_card_2">"Karten-Ansicht 2"</string> + <string name="have_trouble_login_title">"Probleme beim Anmelden"</string> + <string name="have_trouble_login_message">"Möchtest du eine andere Anmeldungs-Art versuchen?"</string> + <string name="vote">"Abstimmen"</string> + <string name="action_share_link">"Link teilen"</string> + <string name="action_copy_link">"Link kopieren"</string> + <string name="action_add_to_post_filter">"Zum Beitrags-Filter hinzufügen"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"NSFW-Bilder in NSFW-Subreddits nicht verwischen"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Avatar links anzeigen"</string> + <string name="settings_backup_settings_title">"Einstellungen sichern"</string> + <string name="settings_restore_settings_title">"Einstellungen wiederherstellen"</string> + <string name="settings_credits_love_animation_title">"Liebes-Animation"</string> + <string name="settings_swipe_between_posts_title">"Zwischen Beiträgen wischen"</string> + <string name="settings_navigation_drawer_title">"Navigationsmenü"</string> + <string name="settings_collapse_account_section_title">"Sektion für Konten zusammenklappen"</string> + <string name="settings_collapse_post_section_title">"Sektion für Beiträge zusammenklappen"</string> + <string name="settings_collapse_preferences_section_title">"Sektion für Einstellungen zusammenklappen"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"Sektion für favorisierte Subreddits zusammenklappen"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"Sektion für abonnierte Subreddits zusammenklappen"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Sektion für favorisierte Subreddits verstecken"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Sektion für abonnierte Subreddits verstecken"</string> + <string name="settings_default_search_result_tab">"Standard-Reiter für Suchergebnisse"</string> + <string name="device_default">"Gerätestandard"</string> + <string name="set_by_battery_saver">"Durch Akkuspar-Dienst gesetzt"</string> + <string name="theme_item_upvote_ratio_icon_tint">"Symbolfarbe für das Abstimmungsverhältnis"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"Angewendet auf: Symbolfarbe für das Abstimmungsverhältnis"</string> + <string name="theme_item_current_user_color">"Aktueller Benutzer"</string> + <string name="theme_item_current_user_color_detail">"Angewendet auf: Aktueller Benutzer in den Kommentaren"</string> + <string name="exclude_domains_hint">"Domains ausschließen"</string> + <string name="anonymous_front_page_no_subscriptions">"Beginne, indem du einem Subreddit beitrittst!"</string> + + <!-- Fuzzy --> + <string name="backup_settings_success">"Die Einstellungen wurden erfolgreich in den Zielordner exportiert. Das Passwort der generierten ZIP-Datei ist 123321. Die ZIP-Datei bitte nicht bearbeiten."</string> + <string name="create_zip_in_destination_directory_failed">"Konnte keine ZIP-Datei im Zielordner erstellen"</string> + <string name="backup_some_settings_failed">"Nicht alle Einstellungen konnten exportiert werden, aber alle anderen wurden erfolgreich in den Zielordner exportiert"</string> + <string name="restore_settings_success">"Einstellungen erfolgreich wiederhergestellt. Starte die Anwendung neu, um die Änderungen zu sehen."</string> + <string name="restore_settings_partially_failed">"Einige Einstellungen wurden vielleicht nicht erfolgreich wiederhergestellt. Starte die Anwendung neu, um die Änderungen zu sehen."</string> + <string name="restore_settings_failed_file_corrupted">"Die Einstellungen konnten nicht wiederhergestellt werden. Die Datei könnte korrupt sein."</string> + <string name="restore_settings_failed_cannot_get_file">"Kann nicht auf die Datei zugreifen"</string> + <string name="suicide_prevention_quote">"Wenn du nach einem Zeichen suchst, dich nicht zu töten, dann ist es dies.\u2764"</string> + <string name="do_not_show_this_again">"Dies nicht erneut anzeigen"</string> + <string name="continue_suicide_prevention_activity">"Fortfahren"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"Konnte Video von v.redd.it nicht abrufen: Video-URL nicht abrufbar"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"Konnte Video von v.redd.it nicht abrufen: Beitrag nicht abrufbar"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"Konnte Video von v.redd.it nicht abrufen: Post-ID nicht abrufbar"</string> + <string name="always_on">"Immer an"</string> + <string name="only_on_wifi">"Nur bei WLAN"</string> + <string name="never">"Niemals"</string> + <string name="normal">"Normal"</string> + <string name="extra_large">"Sehr groß"</string> + <string name="enormously_large">"Emorm groß"</string> + <string name="default_in_array">"Standard"</string> + <string name="off">"Aus"</string> + <string name="only_on_cellular_data">"Nur bei mobilen Daten"</string> + <string name="upvote">"Upvoten"</string> + <string name="downvote">"Downvoten"</string> + <string name="select">"Auswählen"</string> + <string name="exclude_subreddit">"Dieses Subreddit ausschließen"</string> + <string name="exclude_user">"Diesen Benutzer ausschließen"</string> + <string name="exclude_flair">"Dieses Flair ausschließen"</string> + <string name="contain_flair">"Dieses Flair einbeziehen"</string> + <string name="exclude_domain">"Diese Domain ausschließen"</string> + <string name="suggest_title">"Titel vorschlagen"</string> + <string name="suggest_title_failed">"Konnte Titel nicht vorschlagen"</string> + <string name="action_delete_logs">"Logs löschen"</string> + <string name="inbox_with_count">"Posteingang (%1$d)"</string> + <string name="comment_continue_thread">"Thread fortsetzen"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"Vertikal wischen, um zurück zu den Medien zu gelangen"</string> + <string name="settings_hide_post_flair">"Beitragsflair verstecken"</string> + <string name="settings_crash_reports_title">"Absturzmeldungen"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"Gefährlich"</string> + <string name="settings_disable_nsfw_forever_title">"NSFW dauerhaft deaktivieren"</string> + <string name="settings_show_only_one_comment_level_indicator">"Nur einen Indikator für die Kommentarebene anzeigen"</string> + <string name="save_comment">"Speichern"</string> + <string name="unsave_comment">"Nicht mehr speichern"</string> + <string name="copy_multi_reddit_path">"Pfad des Multireddit kopieren"</string> + <string name="copy_multi_reddit_path_failed">"Pfad des Multireddit kann nicht kopiert werden"</string> + <string name="crash_reports_deleted">"Absturzmeldungen werden gelöscht"</string> + <string name="disable_nsfw_forever_message">"Wenn du diese Option aktivierst, wird NSFW dauerhaft deaktiviert, egal ob die NSFW-Option ein- oder ausgeschaltet ist. Diese Option ist irreversibel, wenn du NSFW wieder einschalten willst, müssen die Daten der App gelöscht werden. + +Möchtest du trotzdem fortfahren?"</string> + <string name="reply">"Antworten"</string> + <string name="rpan_activity_label">"RPAN"</string> + <string name="post_gallery_activity_label">"Galeriebeitrag"</string> + <string name="action_share_rpan_link">"Teile RPAN-Link"</string> + <string name="action_share_post_link">"Teile Beitragslink"</string> + <string name="rpan">"RPAN"</string> + <string name="bottom_sheet_post_gallery">"Galerie"</string> + <string name="label_reddit">"Reddit"</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 38d400e6..5b3d3b12 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1,39 +1,39 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="login_activity_label">"Iniciar sesión"</string> - <string name="comment_activity_label">"Enviar comentario"</string> + <string name="login_activity_label">"Iniciar Sesión"</string> + <string name="comment_activity_label">"Enviar Comentario"</string> <string name="comment_activity_label_is_replying">"Responder"</string> <string name="post_text_activity_label">"Texto"</string> <string name="subreddit_selection_activity_label">"Elige un Subreddit"</string> <string name="post_link_activity_label">"Enlace"</string> - <string name="post_image_activity_label">"Imagén"</string> + <string name="post_image_activity_label">"Imágen"</string> <string name="post_video_activity_label">"Vídeo"</string> <string name="rules_activity_label">"Reglas"</string> <string name="search_subreddits_activity_label">"Subreddits"</string> - <string name="edit_post_activity_label">"Editar publicación"</string> - <string name="edit_comment_activity_label">"Editar comentario"</string> + <string name="edit_post_activity_label">"Editar Publicación"</string> + <string name="edit_comment_activity_label">"Editar Comentario"</string> <!-- Bandeja de Entrada --> <string name="view_message_activity_label">"Inbox"</string> <string name="settings_activity_label">"Configuración"</string> <string name="account_saved_thing_activity_label">"Guardado"</string> <string name="create_multi_reddit_activity_label">"Crear Multireddit"</string> - <string name="subreddit_multiselection_activity_label">"Selecciona Subreddits"</string> - <string name="custom_theme_listing_activity_label">"Temas"</string> + <string name="subreddit_multiselection_activity_label">"Seleccionar Subreddits"</string> + <string name="custom_theme_listing_activity_label">"Temas Personalizados"</string> <string name="customize_theme_activity_label">"Personalizar Tema"</string> - <string name="customize_theme_activity_create_theme_label">"Crear un Tema"</string> - <string name="theme_preview_activity_label">"Previsualizar"</string> + <string name="customize_theme_activity_create_theme_label">"Crear Tema"</string> + <string name="theme_preview_activity_label">"Previsualizar Tema"</string> <string name="edit_multi_reddit_activity_label">"Editar MultiReddit"</string> - <string name="selected_subeddits_activity_label">"Subreddits seleccionados"</string> + <string name="selected_subeddits_activity_label">"Subreddits Seleccionados"</string> <string name="report_activity_label">"Reportar"</string> - <string name="view_imgur_media_activity_image_label">"Imagen %1$d/%2$d"</string> + <string name="view_imgur_media_activity_image_label">"Imágen %1$d/%2$d"</string> <string name="view_imgur_media_activity_video_label">"Vídeo %1$d/%2$d"</string> - <string name="send_private_message_activity_label">"Enviar PM"</string> - <string name="view_reddit_gallery_activity_image_label">"Imagen %1$d/%2$d"</string> + <string name="send_private_message_activity_label">"Enviar MP"</string> + <string name="view_reddit_gallery_activity_image_label">"Imágen %1$d/%2$d"</string> <string name="view_reddit_gallery_activity_gif_label">"Gif %1$d/%2$d"</string> <string name="view_reddit_gallery_activity_video_label">"Vídeo %1$d/%2$d"</string> - <string name="navigation_drawer_open">"Abrir barra de navegación"</string> - <string name="navigation_drawer_close">"Cerrar barra de navegación"</string> + <string name="navigation_drawer_open">"Abrir cajón de navegación"</string> + <string name="navigation_drawer_close">"Cerrar cajón de navegación"</string> <string name="action_download">"Descargar"</string> <string name="action_refresh">"Actualizar"</string> <string name="action_add_comment">"Añadir un comentario"</string> @@ -43,55 +43,60 @@ <string name="action_start_lazy_mode">"Iniciar modo automático"</string> <string name="action_stop_lazy_mode">"Detener modo automático"</string> <string name="action_send">"Enviar"</string> - <string name="action_sort">"Ordenar por"</string> - <string name="action_hide_post">"Ocultar publicación"</string> - <string name="action_unhide_post">"Mostrar publicación"</string> - <string name="action_edit_post">"Editar publicación"</string> - <string name="action_delete_post">"Borrar publicación"</string> + <string name="action_sort">"Ordenar"</string> + <string name="action_hide_post">"Ocultar Publicación"</string> + <string name="action_unhide_post">"Mostrar Publicación"</string> + <string name="action_edit_post">"Editar Publicación"</string> + <string name="action_delete_post">"Borrar Publicación"</string> <string name="action_mark_nsfw">"Marcar como NSFW"</string> <string name="action_unmark_nsfw">"Desmarcar como NSFW"</string> <string name="action_mark_spoiler">"Marcar como Spoiler"</string> <string name="action_unmark_spoiler">"Desmarcar como Spoiler"</string> <string name="action_edit_flair">"Editar Etiqueta Temática"</string> - <string name="action_change_post_layout">"Cambiar diseño"</string> + <string name="action_change_post_layout">"Cambiar Diseño"</string> <string name="action_save">"Guardar"</string> <string name="action_edit_multi_reddit">"Editar MultiReddit"</string> <string name="action_delete_multi_reddit">"Borrar Multireddit"</string> <string name="action_share">"Compartir"</string> <string name="action_preview">"Previsualizar"</string> <string name="action_report">"Reportar"</string> - <string name="action_see_removed">"Ver eliminados"</string> - <string name="action_set_wallpaper">"Fijar como fondo de pantalla"</string> - <string name="action_send_private_message">"Enviar mensaje privado"</string> - <string name="action_block_user">"Bloquear usuario"</string> - <string name="parse_json_response_error">"Ocurrió un error al comprobar la respuesta JSON"</string> - <string name="retrieve_token_error">"Ocurrió un error al recuperar el token"</string> + <string name="action_see_removed">"Ver Eliminados"</string> + <string name="action_set_wallpaper">"Fijar como Fondo de Pantalla"</string> + <string name="action_send_private_message">"Enviar Mensaje Privado"</string> + <string name="action_block_user">"Bloquear Usuario"</string> + <string name="parse_json_response_error">"Ocurrió un error al processar la respuesta JSON"</string> + <string name="retrieve_token_error">"Error al recuperar el token"</string> <string name="something_went_wrong">"Ocurrió un error. Inténtalo más tarde."</string> <string name="access_denied">"Acceso denegado"</string> - <string name="parse_user_info_error">"Ocurrió un error al comprobar la información del usuario"</string> - <string name="no_system_webview_error">"Ocurrió un error iniciando System WebView."</string> - <string name="error_loading_image_tap_to_retry">"Ocurrió un error cargando la imagen. Toca para reintentar."</string> - <string name="load_posts_error">"Ocurrió un error al cargar las publicaciones. Toca para reintentar."</string> - <string name="load_more_posts_error">"Ocurrió un error al cargar más publicaciones."</string> - <string name="load_post_error">"Ocurrió un error al cargar la publicación. Toca para reintentar."</string> + <string name="parse_user_info_error">"Ocurrió un error al processar la información del usuario"</string> + <string name="no_system_webview_error">"Error iniciando WebView del Sistema"</string> + <string name="error_loading_image_tap_to_retry">"Error cargando la imagen. Toca para reintentar."</string> + <string name="load_posts_error">"Error al cargar las publicaciones. +Toca para reintentar."</string> + <string name="load_more_posts_error">"Error al cargar más publicaciones."</string> + <string name="load_post_error">"Error al cargar la publicación. +Toca para reintentar."</string> <string name="search_subreddits_error">"Error al buscar subreddits. Toca para reintentar."</string> - <string name="search_users_error">"Ocurrió un error al iniciar la búsqueda. Toca para reintentar."</string> + <string name="search_users_error">"Error al buscar usuarios. +Toca para reintentar."</string> <string name="no_posts">"No se encontraron publicaciones"</string> <string name="no_comments">"No se encontraron comentarios"</string> <string name="no_subreddits">"No se encontraron subreddits"</string> <string name="no_users">"No se encontraron usuarios"</string> <string name="no_multi_reddits">"No se encontraron Multireddits"</string> - <string name="no_storage_permission">"Se requieren permisos de almacenamiento para realizar esta acción."</string> - <string name="load_comments_failed">"Ocurrió un error cargando los comentarios. Toca para reintentar."</string> + <string name="no_storage_permission">"Se requieren permisos de almacenamiento para realizar esta acción"</string> + <string name="load_comments_failed">"Error cargando los comentarios. +Toca para reintentar."</string> <string name="retry">"Reintentar"</string> <string name="comments">"Comentarios"</string> - <string name="no_comments_yet">"No hay comentarios. ¿Escribimos uno?"</string> - <string name="vote_failed">"Error al votar"</string> + <string name="no_comments_yet">"No hay comentarios aún. ¿Escribir uno?"</string> + <string name="vote_failed">"Error al Votar"</string> <!-- Ocurrió un error al actualizar la publicación --> - <string name="refresh_post_failed">"Ocurrió un error al recargar la publicación"</string> - <string name="load_messages_failed">"Ocurrió un error al cargar los comentarios. Toca para reintentar."</string> + <string name="refresh_post_failed">"Error al refrescar la publicación"</string> + <string name="load_messages_failed">"Error al cargar los mensajes. +Toca para reintentar."</string> <string name="no_messages">"Vacío"</string> <string name="nsfw">"NSFW"</string> <string name="karma_info">"Karma: %1$d"</string> @@ -106,46 +111,46 @@ Toca para reintentar."</string> <!-- Bandeja de Entrada --> <string name="inbox">"Bandeja de Entrada"</string> - <string name="upvoted">"Votado a favor"</string> - <string name="downvoted">"Votado en contra"</string> + <string name="upvoted">"Upvoted"</string> + <string name="downvoted">"Downvoted"</string> <string name="hidden">"Oculto"</string> <string name="saved">"Guardado"</string> <string name="gilded">"Premiado"</string> <string name="settings">"Configuración"</string> - <string name="subscribers_number_detail">"Subscriptores: %1$d"</string> + <string name="subscribers_number_detail">"Suscriptores: %1$d"</string> <string name="online_subscribers_number_detail">"En línea: %1$d"</string> - <string name="cannot_fetch_subreddit_info">"Ocurrió un error al obtener información del subreddit"</string> - <string name="cannot_fetch_user_info">"Ocurrió un error al obtener información del usuario"</string> - <string name="cannot_fetch_sidebar">"Ocurrió un error al obtener la barra lateral"</string> - <string name="cannot_fetch_multireddit">"Ocurrió un error al obtener información del multireddit"</string> - <string name="subscribe">"Subscribirse"</string> + <string name="cannot_fetch_subreddit_info">"Error al obtener información del subreddit"</string> + <string name="cannot_fetch_user_info">"Error al obtener información del usuario"</string> + <string name="cannot_fetch_sidebar">"Error al obtener la barra lateral"</string> + <string name="cannot_fetch_multireddit">"Error al obtener información del multireddit"</string> + <string name="subscribe">"Suscribirse"</string> <string name="unsubscribe">"Desuscribirse"</string> <string name="subscribed">"Suscrito"</string> - <string name="subscribe_failed">"Suscripción fallida"</string> - <string name="unsubscribed">"Anulado"</string> - <string name="unsubscribe_failed">"Falló la cancelación"</string> + <string name="subscribe_failed">"Error al suscribirse"</string> + <string name="unsubscribed">"Desuscrito"</string> + <string name="unsubscribe_failed">"Error al desuscribirse"</string> <string name="follow">"Seguir"</string> <string name="unfollow">"Dejar de seguir"</string> <string name="followed">"Siguiendo"</string> <string name="follow_failed">"Ocurrió un error al seguir"</string> - <string name="unfollowed">"Dejado de Seguir"</string> - <string name="unfollow_failed">"Ocurrió un error anulando el seguimiento"</string> - <string name="content_description_banner_imageview">"Imagen de portada del Subreddit"</string> + <string name="unfollowed">"Dejó de Seguir"</string> + <string name="unfollow_failed">"Error al dejar de seguir"</string> + <string name="content_description_banner_imageview">"Imagen de Portada del Subreddit"</string> <string name="app_label">"Infinity"</string> <string name="search_hint">"Busca cualquier cosa"</string> <string name="no_posts_no_lazy_mode">"No hay publicaciones disponibles"</string> <string name="lazy_mode_start">"El modo automático empieza en %1$.1fs"</string> <string name="lazy_mode_stop">"Se ha detenido el modo automático"</string> <string name="write_comment_hint">"Escribe tus ideas aquí"</string> - <string name="comment_content_required">"Tu comentario requiere contenido"</string> + <string name="comment_content_required">"Dónde está tu pensamiento interesante?"</string> <string name="sending_comment">"Enviando"</string> - <string name="send_comment_success">"Enviado"</string> - <string name="send_comment_failed">"Ocurrió un error. Comentario no enviado"</string> + <string name="send_comment_success">"Comentario enviado"</string> + <string name="send_comment_failed">"Error al enviar el comentario"</string> <string name="send_message_username_hint">"Usuario"</string> - <string name="send_message_subject_hint">"Asunto (Max. 100 caracteres)"</string> + <string name="send_message_subject_hint">"Asunto (max 100 caracteres)"</string> <string name="send_message_content_hint">"Mensaje"</string> - <string name="reply_message_failed">"Ocurrió un error al responder"</string> - <string name="error_getting_message">"Ocurrió un error obteniendo el mensaje"</string> + <string name="reply_message_failed">"Error al responder el mensaje"</string> + <string name="error_getting_message">"Error al obtener el mensaje"</string> <string name="message_username_required">"¿A quien quieres enviar este mensaje?"</string> <string name="message_subject_required">"Tu mensaje requiere un asunto"</string> <string name="message_content_required">"Tu mensaje requiere contenido"</string> @@ -154,13 +159,13 @@ Toca para reintentar."</string> <string name="send_message_failed">"No se pudo enviar el mensaje"</string> <string name="select_a_subreddit">"Selecciona un subreddit primero"</string> <string name="title_required">"Se requiere un título"</string> - <string name="link_required">"Se requiere un enlace"</string> + <string name="link_required">"Hey where is the link?"</string> <string name="select_an_image">"Selecciona una imagen"</string> - <string name="posting">"Enviando"</string> - <string name="post_failed">"Ocurrió un error. Publicación cancelada"</string> - <string name="error_processing_image">"Ocurrió un error procesando la imagen"</string> - <string name="error_processing_video">"Ocurrió un error procesando el vídeo"</string> - <string name="download_started">"Descargando... Mira la notificación para más detalles."</string> + <string name="posting">"Publicando"</string> + <string name="post_failed">"Error al publicar"</string> + <string name="error_processing_image">"Error procesando la imagen"</string> + <string name="error_processing_video">"Error procesando el vídeo"</string> + <string name="download_started">"Descarga iniciada. Verifique el progreso en la notificación."</string> <string name="comment_load_more_comments">"Cargar más comentarios"</string> <string name="comment_load_more_comments_failed">"Error al cargar. Toca para reintentar."</string> <string name="loading">"Cargando"</string> @@ -174,24 +179,26 @@ Toca para reintentar."</string> <string name="multi_reddits">"MultiReddits"</string> <string name="bottom_sheet_post_text">"Texto"</string> <string name="bottom_sheet_post_link">"Enlace"</string> - <string name="bottom_sheet_post_image">"Imagen"</string> + <string name="bottom_sheet_post_image">"Imágen"</string> <string name="bottom_sheet_post_video">"Vídeo"</string> - <string name="select_from_gallery">"Elige una imagen"</string> + <string name="select_from_gallery">"Elige una imágen"</string> <string name="select_again">"Elige otra vez"</string> - <string name="error_getting_image">"Ocurrió un error obteniendo la imagen"</string> - <string name="error_getting_video">"Ocurrió un error obteniendo el vídeo"</string> + <string name="error_getting_image">"Error obteniendo la imagen"</string> + <string name="error_getting_video">"Error obteniendo el vídeo"</string> <string name="no_camera_available">"No se encontró una aplicación de cámara"</string> - <string name="error_creating_temp_file">"Ocurrió un error creando el archivo temporal"</string> - <string name="video_is_processing">"Cargando vídeo. Por favor espera."</string> - <string name="image_is_processing">"Cargando imagen. Por favor espera."</string> - <string name="gif_is_processing">"Cargando gif. Por favor espera."</string> + <string name="error_creating_temp_file">"Error creando el archivo temporal"</string> + <string name="video_is_processing">"Procesando vídeo. Por favor espera."</string> + <string name="image_is_processing">"Procesando imagen. Por favor espera."</string> + <string name="gif_is_processing">"Procesando Gif. Por favor espera."</string> <string name="flair">"Etiqueta Temática"</string> <string name="spoiler">"Spoiler"</string> <string name="no_flair">"No hay Etiqueta Temática"</string> - <string name="error_loading_flairs">"Ocurrió un error cargando las etiquetas temáticas. Toca para reintentar."</string> + <string name="error_loading_flairs">"Error cargando las etiquetas temáticas. +Toca para reintentar."</string> <string name="no_rule">"Sin regla"</string> - <string name="error_loading_rules">"Ocurrió un error cargando las reglas. Toca para reintentar."</string> - <string name="error_loading_rules_without_retry">"Ocurrió un error al cargar las reglas"</string> + <string name="error_loading_rules">"Error cargando las reglas. +Toca para reintentar."</string> + <string name="error_loading_rules_without_retry">"Error cargando las reglas"</string> <string name="search_in">"Buscar en"</string> <string name="all_subreddits">"Todos los subreddits"</string> <string name="sort_best">"Lo mejor"</string> @@ -215,8 +222,8 @@ Toca para reintentar."</string> <string name="sort_time_year">"Año"</string> <string name="sort_time_all_time">"Todo el tiempo"</string> <string name="no_activity_found_for_share">"No se encontró ninguna aplicación para compartir"</string> - <string name="archived_post_vote_unavailable">"Publicación archivada. Votar no está disponible"</string> - <string name="archived_post_comment_unavailable">"Publicación archivada. Comentar no está disponible "</string> + <string name="archived_post_vote_unavailable">"Publicación archivada. Votar no está disponible."</string> + <string name="archived_post_comment_unavailable">"Publicación archivada. Comentar no está disponible."</string> <string name="archived_post_reply_unavailable">"Publicación archivada. Responder no disponible."</string> <string name="locked_post_comment_unavailable">"Publicación bloqueada. Comentar no disponible."</string> <string name="locked_post_reply_unavailable">"Publicación bloqueada. Responder no disponible."</string> @@ -230,7 +237,9 @@ Toca para reintentar."</string> <string name="search">"Buscar"</string> <string name="posting_video">"Publicando vídeo"</string> <string name="posting_image">"Publicando imagen"</string> - <string name="please_wait">"Por favor espera."</string> + + <!-- Fuzzy --> + <string name="please_wait">"Por favor espera"</string> <string name="add_account">"Añadir cuenta"</string> <string name="anonymous_account">"Anónimo"</string> <string name="log_out">"Cerrar sesión"</string> @@ -295,7 +304,7 @@ Toca para reintentar."</string> <!-- Galardón means award Premio means prize, so it's better suited the first word instead of the second one --> <string name="notification_summary_award">"Galardón"</string> - <string name="notification_new_messages">"%1$d nuevos mensajes"</string> + <string name="notification_new_messages">"%1$d Nuevos Mensajes"</string> <string name="label_account">"Cuenta"</string> <string name="label_post">"Publicación"</string> <string name="label_preferences">"Preferencias"</string> @@ -321,7 +330,7 @@ Premio means prize, so it's better suited the first word instead of the second o <string name="settings_immersive_interface_title">"Interfaz Inmersiva"</string> <!-- Fuzzy --> - <string name="settings_immersive_interface_summary">"No Aplica a Todas las Páginas (Podría No Funcionar con Android 11)"</string> + <string name="settings_immersive_interface_summary">"No Aplica a Todas las Páginas"</string> <string name="settings_immersive_interface_ignore_nav_bar_title">"Ignorar la Barra de Navegación en la Interfaz Inmersiva"</string> <string name="settings_immersive_interface_ignore_nav_bar_summary">"Bloquear la Barra de Navegación de Tener Margen Extra"</string> <string name="settings_customize_tabs_in_main_page_title">"Personalizar las Pestañas de la Página Principal"</string> @@ -333,7 +342,9 @@ Premio means prize, so it's better suited the first word instead of the second o <string name="settings_volume_keys_navigate_posts_title">"Usar las Teclas de Volumen para Navegar Publicaciones"</string> <string name="settings_mute_video_title">"Silenciar Vídeos"</string> <string name="settings_mute_nsfw_video_title">"Silenciar Vídeos NSFW"</string> - <string name="settings_automatically_try_redgifs_title">"Abrir Vídeos en Redgifs Automáticamente Si No Están Disponibles en Gfycat."</string> + + <!-- Fuzzy --> + <string name="settings_automatically_try_redgifs_title">"Intente acceder automáticamente a Redgifs si se eliminan los videos en Gfycat"</string> <string name="settings_video_player_ignore_nav_bar_title">"Ignorar la Barra de Navegación en el Reproductor de Vídeo"</string> <string name="settings_video_player_ignore_nav_bar_summary">"Bloquear al Controlador de Vídeo Para que No Tenga Extra Margen"</string> <string name="settings_confirm_to_exit">"Confirmar para Salir"</string> @@ -416,7 +427,7 @@ Premio means prize, so it's better suited the first word instead of the second o <string name="settings_advanced_master_title">"Avanzado"</string> <string name="settings_delete_all_subreddits_data_in_database_title">"Borrar Todos los Subreddits Guardados"</string> <string name="settings_delete_all_users_data_in_database_title">"Borrar Todos los Usuarios Guardados"</string> - <string name="settings_delete_all_sort_type_data_in_database_title">"Borrar Todos los \"Ordenar por:\" Guardados"</string> + <string name="settings_delete_all_sort_type_data_in_database_title">"Borrar Todos los Ordenar por Guardados"</string> <string name="settings_delete_all_post_layout_data_in_database_title">"Borrar Todos los Diseños de Publicación de la Base de Datos"</string> <string name="settings_delete_all_themes_in_database_title">"Borrar Todos los Temas Guardados"</string> <string name="settings_delete_front_page_scrolled_positions_in_database_title">"Borrar Todas las Posiciones Guardadas de la Página Principal de la Base de Datos"</string> @@ -498,10 +509,10 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="exit_app">"¿Salir?"</string> <string name="light_theme">"Tema Claro"</string> <string name="dark_theme">"Tema Oscuro"</string> - <string name="multi_reddit_name_hint">"Nombre (Max. 50 Caracteres)"</string> + <string name="multi_reddit_name_hint">"Nombre (Max 50 Caracteres)"</string> <string name="multi_reddit_description_hint">"Descripción"</string> <string name="private_multi_reddit">"Privado"</string> - <string name="no_multi_reddit_name">"Introduce un nombre"</string> + <string name="no_multi_reddit_name">"Donde esta el nombre?"</string> <string name="create_multi_reddit_failed">"Ocurrió un error creando este multireddit"</string> <string name="duplicate_multi_reddit">"Este multireddit ya existe"</string> <string name="edit_multi_reddit_failed">"Ocurrió un error al editar el multireddit"</string> @@ -514,9 +525,9 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="cannot_save_image">"Ocurrió un error guardando la imagen"</string> <string name="cannot_save_gif">"Ocurrió un error guardando el gif"</string> <string name="cannot_get_storage">"Ocurrió un error al acceder al almacenamiento de la app"</string> - <string name="save_image_first">"Guardando... Por favor espera."</string> - <string name="save_gif_first">"Guardando... Por favor espera."</string> - <string name="theme_name_description">"Toca para cambiar el nombre del tema"</string> + <string name="save_image_first">"Guardando. Por favor espera."</string> + <string name="save_gif_first">"Guardando. Por favor espera."</string> + <string name="theme_name_description">"Toca para cambiar el nombre del tema."</string> <string name="theme_item_is_light_theme">"Establecer como Tema Claro"</string> <string name="theme_item_is_dark_theme">"Establecer como Tema Oscuro"</string> <string name="theme_item_is_amoled_theme">"Establecer como Tema AMOLED"</string> @@ -565,7 +576,7 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="theme_item_bottom_app_bar_background_color">"Color de la Barra de Navegación Inferior"</string> <string name="theme_item_bottom_app_bar_background_color_detail">"Aplicado a: Barra de Navegación Inferior"</string> <string name="theme_item_primary_icon_color">"Color de Ícono Primario"</string> - <string name="theme_item_primary_icon_color_detail">"Aplicado a: Íconos en el Cajón de Navegación"</string> + <string name="theme_item_primary_icon_color_detail">"Aplicado a: Íconos en el Cajón de Navegación."</string> <string name="theme_item_bottom_app_bar_icon_color">"Color de los Íconos de la Barra de Navegación Inferior"</string> <string name="theme_item_bottom_app_bar_icon_color_detail">"Aplicado a: Íconos de la Barra de Navegación Inferior"</string> <string name="theme_item_post_icon_and_info_color">"Color de los Íconos de Información de Publicación y Comentario"</string> @@ -584,22 +595,22 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="theme_item_toolbar_secondary_text_color_detail">"Aplicado a: Texto secundario en barras de herramienta"</string> <string name="theme_item_circular_progress_bar_background_color">"Color del Fondo de la Barra de Progreso Circular"</string> <string name="theme_item_circular_progress_bar_background_color_detail">"Aplicado a: Fondo de la Barra de Progreso Circular"</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background">"Color del Fondo del Grupo de Pestañas (Extendido)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background">"Color de fondo del Diseño de la Pestaña en la barra de herramientas Expandida"</string> <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background_detail">"Aplicado a: Fondo del Grupo de Pestañas (Extendido)"</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color">"Color del Texto del Grupo de Pestañas (Extendido)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color">"Color del texto del Diseño de la Pestaña en la Barra de Herramientas Expandida"</string> <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color_detail">"Aplicado a: Texto del Grupo de Pestañas (Extendido)"</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator">"Color del Indicador del Grupo de Pestañas (Extendido)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator">"Color del Indicador de Pestaña del Diseño de Pestaña en la Barra de Herramientas Expandida"</string> <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator_detail">"Aplicado a: Indicador del grupo de pestañas (Extendido)"</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background">"Color del Fondo del Grupo de Pestañas (Colapsado)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background">"Color de Fondo del Diseño de la Pestaña en la Barra de Herramientas Colapsada"</string> <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background_detail">"Aplicado a: Fondo del grupo de pestañas (Colapsado)"</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color">"Color del Texto del Grupo de Pestañas (Colapsado)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color">"Color del Texto del Diseño de la Pestaña en la Barra de Herramientas Colapsada"</string> <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color_detail">"Aplicado a: Texto del grupo de pestañas (Colapsado)"</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator">"Color del Indicador del Grupo de Pestañas (Colapsado)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator">"Color del Indicador de Pestaña del Diseño de Pestaña en la Barra de Herramientas Colapsada"</string> <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator_detail">"Aplicado a: Indicador del Grupo de Pestañas (Colapsado)"</string> - <string name="theme_item_upvoted_color">"Color de Voto a Favor"</string> - <string name="theme_item_upvoted_color_detail">"Aplicado a: Botones de voto y puntuación (voto a favor)"</string> - <string name="theme_item_downvoted_color">"Color de Voto en Contra"</string> - <string name="theme_item_downvoted_color_detail">"Aplicado a: Botones de voto y puntuación (voto en contra)"</string> + <string name="theme_item_upvoted_color">"Color de Upvotes"</string> + <string name="theme_item_upvoted_color_detail">"Aplicado a: Botones de voto y puntuación (upvote)"</string> + <string name="theme_item_downvoted_color">"Color de Downvote"</string> + <string name="theme_item_downvoted_color_detail">"Aplicado a: Botones de voto y puntuación (downvote)"</string> <string name="theme_item_post_type_background_color">"Color de Fondo de Tipo de Publicación"</string> <string name="theme_item_post_type_background_color_detail">"Aplicado a: Fondo de Tipo de Publicación (IMAGEN, TEXTO, VÍDEO, GIF, ENLACE)"</string> <string name="theme_item_post_type_text_color">"Color de Texto de Tipo de Publicación"</string> @@ -666,32 +677,32 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="theme_item_comment_vertical_bar_color_7_detail">"Aplicado a: Barra Vertical de Comentario (Nivel 7)"</string> <string name="theme_item_nav_bar_color">"Color de la barra de navegación"</string> <string name="theme_item_nav_bar_color_detail">"Aplicado a: Barra de navegación"</string> - <string name="theme_item_light_status_bar">"Barra de Estado Oscura: Color del Ícono"</string> - <string name="theme_item_light_nav_bar">"Barra de Navegación Oscura: Color del Ícono"</string> - <string name="theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface">"Cambiar Color de Barra de Estado: Color del Ícono Después de que la Barra de Herramientas Colapse en la Interfaz Inmersiva"</string> + <string name="theme_item_light_status_bar">"Color del Icono de la Barra de Estado Oscura"</string> + <string name="theme_item_light_nav_bar">"Color del Icono de la Barra de Navegación Oscura"</string> + <string name="theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface">"Cambiar el Color del Icono de la Barra de Estado Después de que la Barra de Herramientas se Contraiga en la Interfaz Inmersiva"</string> <string name="theme_item_available_on_android_8">"Solo para Android 8.0 o superior."</string> <string name="theme_item_available_on_android_6">"Solo para Android 6.0 o superior."</string> <string name="predefined_themes">"Temas Predefinidos"</string> <string name="user_themes">"Tus Temas"</string> - <string name="no_theme_name">"Introduce un nombre"</string> + <string name="no_theme_name">"Cual es el nombre de este tema?"</string> <string name="theme_name_hint">"Nombre del tema"</string> <string name="theme_name_indigo">"Indigo"</string> <string name="theme_name_indigo_dark">"Indigo Oscuro"</string> <string name="theme_name_indigo_amoled">"Indigo OLED"</string> <string name="theme_name_white">"Blanco"</string> <string name="theme_name_white_dark">"Blanco Oscuro"</string> - <string name="theme_name_white_amoled">"Blanco OLED"</string> + <string name="theme_name_white_amoled">"Blanco AMOLED"</string> <string name="theme_name_red">"Rojo"</string> <string name="theme_name_red_dark">"Rojo Oscuro"</string> <string name="theme_name_red_amoled">"Rojo OLED"</string> <string name="theme_name_dracula">"Dracula"</string> <string name="theme_name_calm_pastel">"Pastel Ligero"</string> - <string name="create_light_theme">"Crear un tema claro -Base: Indigo"</string> - <string name="create_dark_theme">"Crear un tema oscuro -Base: Indigo Oscuro"</string> - <string name="create_amoled_theme">"Crear un tema OLED -Base: Indigo OLED"</string> + <string name="create_light_theme">"Crear un Tema Claro +Basado en Tema Índigo"</string> + <string name="create_dark_theme">"Crear un Tema Oscuro +Basado en Tema Índigo Oscuro"</string> + <string name="create_amoled_theme">"Crear un Tema Amoled +Basado en Tema Índigo Amoled"</string> <string name="create_theme_info">"Si deseas crear un tema basado en otro predefinido, toca \"+\" en ese tema."</string> <string name="edit_theme_name">"Renombrar Tema"</string> <string name="edit_theme">"Editar Tema"</string> @@ -699,7 +710,7 @@ Base: Indigo OLED"</string> <string name="delete_theme_dialog_message">"¿Seguro que quieres borrar %1$s?"</string> <string name="share_theme">"Compartir Tema"</string> <string name="change_theme_name">"Renombrar"</string> - <string name="theme_copied">"Enlace copiado"</string> + <string name="theme_copied">"Copiado! Pégalo y compártelo con otras personas."</string> <string name="copy_theme_faied">"Ocurrió un error al copiar la configuración del tema"</string> <string name="cannot_find_theme">"No se ha encontrado el tema"</string> <string name="import_theme">"Importar Tema"</string> @@ -722,7 +733,7 @@ Base: Indigo OLED"</string> <string name="delete_all_users_success">"Se han eliminado todos los usuarios"</string> <!-- Fuzzy --> - <string name="delete_all_sort_types_success">"Se han eliminado todos los \"ordenar por\""</string> + <string name="delete_all_sort_types_success">"Se han eliminado todos los tipos de clasificación con éxito"</string> <!-- Fuzzy --> <string name="delete_all_post_layouts_success">"Se han eliminado todos los diseños de publicación"</string> @@ -745,7 +756,8 @@ Base: Indigo OLED"</string> <string name="flair_preview">"Etiqueta Temática"</string> <string name="awards_preview">"4 Premios"</string> <string name="author_flair_preview">"Etiqueta de Autor Temática"</string> - <string name="comment_content_preview">"Le dí a mi novia una tarjeta de esas que dicen \"Que te mejores\". No está enferma ni nada por el estilo, pero podría mejorar muchísimo."</string> + <string name="comment_content_preview">"Le compré a mi novia una tarjeta de \"Mejora pronto cariño\". +No está enferma ni nada, pero definitivamente podría mejorar."</string> <string name="edit_multi_reddit">"Editar MultiReddit"</string> <string name="delete_multi_reddit">"Borrar Multireddit"</string> <string name="n_awards">"%1$d Premios"</string> @@ -766,7 +778,7 @@ Base: Indigo OLED"</string> <string name="message">"Mensaje"</string> <string name="fetch_gfycat_video_failed">"Ocurrió un error obteniendo el vídeo de Gfycat"</string> <string name="fetch_redgifs_video_failed">"Ocurrió un error obteniendo el vídeo de Redgifs"</string> - <string name="fetching_video_info_please_wait">"Obteniendo información del vídeo, espera..."</string> + <string name="fetching_video_info_please_wait">"Obteniendo información del vídeo. Por favor espera."</string> <string name="error_fetching_imgur_media">"Ocurrió un error cargando las imágenes"</string> <string name="downloading_reddit_video">"Descargando Track Vídeo"</string> <string name="downloading_reddit_video_audio_track">"Descargando Track Audio"</string> @@ -789,14 +801,16 @@ Base: Indigo OLED"</string> <string name="default_font_font_preview">"Por defecto"</string> <string name="load_video_in_redgifs">"Intenta cargando el vídeo en Redgifs"</string> <string name="top_score">"%1$s puntos"</string> - <string name="login_activity_2fa_prompt">"Si cuentas con verificación en dos pasos por favor escribe tu contraseña de la siguiente manera: <contraseña>:<código-de-verificación> + <string name="login_activity_2fa_prompt">"Si tiene habilitada la autenticación de 2 factores, por favor escriba su contraseña como la siguiente: <contraseña>:<código 2FA>. Ejemplo: contraseña:123456"</string> <string name="block_user">"Bloquear usuario"</string> <string name="block_user_success">"Bloqueado"</string> <string name="block_user_failed">"Ocurrió un error al bloquear al usuario"</string> - <string name="give_award_activity_label">"Dar premio"</string> + <string name="submit_crosspost_activity_label">"Crosspost"</string> + <string name="give_award_activity_label">"Premiar"</string> + <string name="action_crosspost">"Crosspost"</string> <string name="action_select_user_flair">"Seleccione categoría de usuario"</string> - <string name="action_give_award">"Dar premio"</string> + <string name="action_give_award">"Premiar"</string> <string name="posts">"Publicaciones"</string> <string name="sidebar">"Barra lateral"</string> <string name="only_for_logged_in_user">"Solo para usuarios registrados"</string> @@ -809,6 +823,8 @@ Ejemplo: contraseña:123456"</string> <string name="settings_tab_count">"Número de tabs"</string> <string name="settings_show_tab_names">"Mostrar nombres de las categorías"</string> <string name="settings_more_tabs_summary">"Más categorías"</string> + <string name="settings_more_tabs_info_summary">"Activar las siguientes opciones cauará un comportamiento imprevisto: +Las pestañas pueden perder el contenido tras cambiar a otras. Es lo mismo que al recargar la página."</string> <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">"Mostrar Subreddits favoritos, suscritos"</string> <string name="settings_more_tabs_show_subscribed_subreddits_title">"Mostrar Subreddits suscritos"</string> <string name="settings_download_location_title">"Ubicación de descarga"</string> @@ -819,12 +835,16 @@ Ejemplo: contraseña:123456"</string> <string name="settings_swipe_action_title">"Acción de deslizó"</string> <string name="settings_disable_swiping_between_tabs_title">"Desabilitar el deslizar entre categorías"</string> <string name="settings_enable_swipe_action_title">"Activar opción para deslizar"</string> + <string name="settings_swipe_action_threshold">"Umbral"</string> <string name="settings_pull_to_refresh_title">"Jale para refrescar"</string> <string name="settings_security_title">"Seguridad"</string> + <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Requerir autenticación al ir a la sección de cuentas en el cajón de navegación"</string> + <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Mantener pulsado para ocultar la barra de herramientas"</string> <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">"Ocultar Barra de Herramientas por defecto"</string> <string name="settings_customize_bottom_app_bar_title">"Personalizar Barra de Navegación Inferior"</string> <string name="settings_main_activity_bottom_app_bar_group_summary">"Página principal"</string> <string name="settings_other_activities_bottom_app_bar_group_summary">"Otras páginas"</string> + <string name="settings_bottom_app_bar_option_count">"Número de opciones"</string> <string name="settings_bottom_app_bar_option_1">"Opción 1"</string> <string name="settings_bottom_app_bar_option_2">"Opción 2"</string> <string name="settings_bottom_app_bar_option_3">"Opción 3"</string> @@ -834,15 +854,24 @@ Ejemplo: contraseña:123456"</string> <!-- Fuzzy --> <string name="settings_data_saving_mode_info_summary">"En modo de ahorro de datos: -Imágenes previsualizadas están en menor resolución -Videos de Reddit están en menor resolución"</string> +Las imágenes de vista previa tienen una resolución más baja. +Los videos de Reddit tienen una resolución más baja. +La reproducción automática de video está deshabilitada."</string> <string name="settings_translation_title">"Traducción"</string> <string name="settings_translation_summary">"Traduzca esta app en POEditor. Grácias a todos los contribuyentes."</string> <string name="settings_credits_national_flags">"Banderas Nacionales"</string> <string name="settings_credits_national_flags_summary">"Icono hecho por Freepik desde www.flaticon.com"</string> <string name="copy_failed">"Copia fallida"</string> + <string name="delete_all_legacy_settings_success">"Se han borrado todos los ajustes de legado"</string> <string name="downloading_media_finished">"Descargado"</string> + <string name="downloading_image_or_gif_failed_cannot_get_destination_directory">"Descarga fallida: directorio de destino inaccesible"</string> <string name="downloading_media_failed_cannot_download_media">"Descarga fallida"</string> + <string name="downloading_media_failed_cannot_save_to_destination_directory">"Descarga fallida: no se puede guardar el archivo al directorio de destino"</string> + + <!-- Ver Markdown completo --> + <string name="view_full_comment_markdown">"Ver la reducción completa"</string> + <string name="select_user_flair_success">"Etiqueta de usuario seleccionada"</string> + <string name="select_this_user_flair">"Seleccionar esta etiqueta de usuario?"</string> <string name="select_header_size">"Seleccionar tamaño de encabezado"</string> <string name="large">"Grande"</string> <string name="small">"Pequeño"</string> @@ -855,13 +884,19 @@ Videos de Reddit están en menor resolución"</string> <string name="refresh">"Refrescar"</string> <string name="change_sort_type">"Cambiar modo de organización"</string> <string name="change_post_layout">"Cambiar organización de las publicaciones"</string> - <string name="give_award_dialog_title">"Dar premio?"</string> + <string name="give_award_dialog_title">"Premiar?"</string> <string name="anonymous">"Anónimo"</string> + + <!-- Código: %1$d/ +Mensaje: %2$s + +https://s3.eu-west-1.amazonaws.com/po-pub/i/hJAe7sMhrfJzqjhp9VkDQOVC.PNG --> + <string name="give_award_error_message">"Código: %1$d/ +Mensaje: %2$s"</string> <string name="give_award_success">"Premio entregado"</string> <string name="give_award_failed">"Falló"</string> - <string name="recent_searches">"Búsquedas recientes"</string> <string name="warning">"Precaución"</string> - <string name="this_is_a_nsfw_subreddit">"Este es un Subreddit NSFW"</string> + <string name="this_is_a_nsfw_subreddit">"Este es un Subreddit NSFW."</string> <string name="this_user_has_nsfw_content">"Este usuario tiene contenido NSFW"</string> <string name="dismiss">"Descartar"</string> <string name="leave">"Salir"</string> @@ -881,11 +916,24 @@ Videos de Reddit están en menor resolución"</string> <string name="downloading">"Descargando"</string> <string name="subreddit_filter_popular_and_all_activity_label">"r/all y r/popular"</string> <string name="settings_miscellaneous_title">"Misceláneo"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_title">"Respetar el orden de clasificación de comentario recomendado de Subreddit"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_summary">"La ordenación de los comentarios no se guardará"</string> + + <!-- Ocultar Subreddits --> + <string name="settings_subreddit_filter_category">"Ocultar Subreddits"</string> + <string name="settings_subreddit_filter_popular_and_all">"En r/popular y r/all"</string> + <string name="settings_credits_ufo_capturing_animation_title">"Animación de capturar OVNI"</string> <string name="select_video_quality">"Seleccione calidad del video"</string> + <string name="settings_swipe_action_haptic_feedback_title">"Retroalimentación háptica"</string> <string name="settings_hide_subreddit_description_title">"Ocultar Descripción del Subreddit"</string> <string name="settings_disable_image_preview_title">"Deshabilitar Vista Previa de Imagen en Modo Ahorro de Datos"</string> <string name="settings_swipe_action_swipe_left_title">"Deslizar a la izquierda"</string> <string name="settings_swipe_action_swipe_right_title">"Deslizar a la derecha"</string> + <string name="settings_swipe_action_info_summary">"No se aplica a publicaciones con más de una columna o detalles de publicaciones."</string> + <string name="theme_item_no_preview_post_type_icon_tint">"Color de icono de tipo de publicación sin vista previa"</string> + <string name="theme_item_no_preview_post_type_icon_tint_detail">"Aplicado a: Icono que indica el tipo de publicación cuando no hay vista previa disponible"</string> + <string name="theme_item_no_preview_post_type_background_color">"Color de Fondo Tipo de Publicación Sin Vista Previa"</string> + <string name="theme_item_no_preview_post_type_background_color_detail">"Aplicado a: Marcador de posición que indica el tipo de publicación cuando no hay una vista previa disponible"</string> <string name="settings_language_title">"Lenguaje"</string> <string name="customize_post_filter_activity_label">"Personalizar Filtro de Publicaciones"</string> <string name="filtered_posts_activity_subtitle">"Publicaciones filtradas"</string> @@ -897,9 +945,209 @@ Videos de Reddit están en menor resolución"</string> <string name="action_add_to_multireddit">"Añadir a Multireddit"</string> <string name="search_only_subreddits_hint">"Buscar subreddits"</string> <string name="search_only_users_hint">"Buscar usuarios"</string> + <string name="post_type_gif">"Gif"</string> <string name="post_type_gallery">"Galería"</string> - <string name="settings_privacy_policy_title">"Política de privacidad -"</string> + <string name="settings_disable_immersive_interface_in_landscape_mode">"Desactivar la Interfaz Inmersiva en el Modo Horizontal"</string> + <string name="settings_privacy_policy_title">"Política de privacidad"</string> + <string name="settings_delete_read_posts_in_database_title">"Borrar Todas las Publicaciones Leídas en la Base de Datos"</string> + <string name="settings_post_filter_title">"Filtro de Publicación"</string> + <string name="settings_only_disable_preview_in_video_and_gif_posts_title">"Desactivar previsualización en posts de vídeos y gifs"</string> + <string name="settings_enable_search_history_title">"Activar historial de búsqueda"</string> + <string name="settings_post_history_title">"Histórico de publicación"</string> + <string name="settings_mark_posts_as_read_title">"Marcar publicaciones como leídas"</string> + <string name="settings_mark_posts_as_read_after_voting_title">"Marcar publicaciones como leídas después de votar"</string> + <string name="settings_mark_posts_as_read_on_scroll_title">"Marcar posts como leídos al hacer scroll"</string> + <string name="settings_hide_read_posts_automatically_title">"Ocultar posts leídos automáticamente"</string> + <string name="settings_sort_type_title">"Tipo de ordenación"</string> + <string name="settings_save_sort_type_title">"Guardar Tipo de ordenación"</string> + <string name="settings_subreddit_default_sort_type_title">"Tipo de ordenación por defecto de Subreddits"</string> + <string name="settings_subreddit_default_sort_time_title">"Hora de clasificación predeterminada de subreddit"</string> + <string name="settings_user_default_sort_type_title">"Tipo de orden predeterminada del usuario"</string> + <string name="settings_user_default_sort_time_title">"Tipo de tiempo predeterminada del usuario"</string> <string name="open_link">"Abrir Link"</string> <string name="select_subreddits_and_users">"Seleccionar Subreddits y Usuarios"</string> + <string name="theme_item_read_post_title_color">"Color de título de posts leídos"</string> + <string name="theme_item_read_post_title_color_detail">"Aplicado a: Leer el título de la publicación"</string> + <string name="theme_item_read_post_content_color">"Leer el color del contenido de la publicación"</string> + <string name="theme_item_read_post_content_color_detail">"Aplicado a: Leer contenido de publicaciones"</string> + <string name="theme_item_read_post_card_view_background_color">"Leer color de fondo de la vista de tarjeta"</string> + <string name="theme_item_read_post_card_view_background_color_detail">"Aplicado a: Leer Fondo de publicación"</string> + <string name="delete_all_read_posts_success">"Todas las publicaciones leídas han sido eliminadas"</string> + <string name="hide_read_posts">"Ocultar posts leídos"</string> + <string name="filter_posts">"Filtrar posts"</string> + <string name="only_nsfw">"Solo NSFW"</string> + <string name="only_spoiler">"Solo spoilers"</string> + <string name="title_excludes_strings_hint">"Título: excluir palabras clave (palabra1, palabra2)"</string> + <string name="title_excludes_regex_hint">"Título: excluye regex"</string> + <string name="exclude_subreddits_hint">"Excluir subreddits (p.ej. funny,AskReddit)"</string> + <string name="exclude_users_hint">"Excluir usuarios (p.ej. Hostilenemy,random)"</string> + <string name="exclude_flairs_hint">"Excluir etiquetas de usuario (p.ej. etiqueta1,etiqueta2)"</string> + <string name="contain_flairs_hint">"Contiene etiquetas (p.ej. etiqueta1,etiqueta2)"</string> + <string name="min_vote_hint">"Votos mínimos (-1: sin restricción)"</string> + <string name="max_vote_hint">"Votos máximos (-1: sin restricción)"</string> + <string name="min_comments_hint">"Comentarios mínimos (-1: sin restricción)"</string> + <string name="max_comments_hint">"Comentarios máximos (-1: sin restricción)"</string> + <string name="min_awards_hint">"Premios mínimos (-1: sin restricción)"</string> + <string name="max_awards_hint">"Premios máximos (-1: sin restricción)"</string> + <string name="post_filter_name_hint">"Nombre de Filtro de Publicación"</string> + <string name="post_filter_requires_a_name">"¿Cuál es el nombre del filtro de esta publicación?"</string> + <string name="duplicate_post_filter_dialog_title">"'%1$s' Ya Existe"</string> + <string name="duplicate_post_filter_dialog_message">"¿Sobreescribir?"</string> + <string name="apply_post_filter_to">"Aplicar a"</string> + <string name="post_filter_usage_home">"Inicio"</string> + <string name="post_filter_usage_subreddit">"Subreddit: %1$s"</string> + <string name="post_filter_usage_subreddit_all">"Subreddit"</string> + <string name="post_filter_usage_user">"Usuario: %1$s"</string> + <string name="post_filter_usage_user_all">"Usuario"</string> + <string name="post_filter_usage_multireddit">"MultiReddit: %1$s"</string> + <string name="post_filter_usage_multireddit_all">"MultiReddit"</string> + <string name="post_filter_usage_search">"Búsqueda"</string> + <string name="subreddit">"Subreddit"</string> + <string name="user">"Usuario"</string> + <string name="edit_post_filter_name_of_usage_info">"Dejar vacío para aplicar este filtro de posts a todos los subreddits / usuarios / multireddits"</string> + <string name="read_all_messages_time_limit">"Estas haciendo esto muy frecuentemente. Inténtalo mas tarde. Esto es debido a el limite de tasa de la API de Reddit."</string> + <string name="read_all_messages_success">"Todos los mensajes leídos correctamente"</string> + <string name="read_all_messages_failed">"Imposible leer todos los mensajes"</string> + <string name="add_subreddit_or_user_to_multireddit_success">"%1$s ha sido añadido a MultiReddit %2$s"</string> + <string name="add_subreddit_or_user_to_multireddit_failed">"Imposible añadir %1$s a MultiReddit %2$s"</string> + <string name="choose_a_user">"Elige un usuario"</string> + <string name="settings_click_to_show_media_in_gallery_layout">"Pulsa para Mostrar los Medios en la Disposición de Galeria"</string> + <string name="settings_hide_post_type">"Ocultar el Tipo de Publicación"</string> + <string name="settings_hide_the_number_of_awards">"Ocultar el Número de Premios"</string> + <string name="settings_hide_subreddit_and_user_prefix">"Ocultar el Prefijo del Subreddit y del Usuario"</string> + <string name="settings_hide_the_number_of_votes">"Ocultar el Número de Votos"</string> + <string name="settings_hide_the_number_of_comments">"Ocultar el Número de Comentarios"</string> + <string name="post_layout_gallery">"Disposición de Galeria"</string> + <string name="post_layout_card_2">"Disposición de Tarjeta 2"</string> + <string name="have_trouble_login_title">"Problemas para Iniciar Sesión"</string> + <string name="have_trouble_login_message">"¿Quieres probar otra manera de iniciar sesión?"</string> + <string name="vote">"Votar"</string> + <string name="action_share_link">"Compartir enlace"</string> + <string name="action_copy_link">"Copiar enlace"</string> + <string name="action_add_to_post_filter">"Añadir al Filtro de Publicación"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"No difuminar Imágenes NSFW en Subreddits NSFW"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Mostrar Avatar a la Izquierda"</string> + <string name="settings_backup_settings_title">"Respaldar ajustes"</string> + <string name="settings_restore_settings_title">"Restablecer ajustes"</string> + <string name="settings_credits_love_animation_title">"Animación de Amor"</string> + <string name="settings_swipe_between_posts_title">"Deslizar entre posts"</string> + <string name="settings_navigation_drawer_title">"Cajón de navegación"</string> + <string name="settings_collapse_account_section_title">"Contraer Sección de Cuentas"</string> + <string name="settings_collapse_post_section_title">"Colapsar sección Posts"</string> + <string name="settings_collapse_preferences_section_title">"Contraer Sección de Ajustes"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"Contraer la Sección de Subreddits Favoritos"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"Contraer la Sección de Subreddits Subscritos"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Ocultar sección Subreddits favoritos"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Ocultar la Sección de Subreddits Subscritos"</string> + <string name="settings_default_search_result_tab">"Tabla de Resultados de Búsqueda Predeterminada"</string> + <string name="device_default">"Por defecto del dispositivo"</string> + <string name="set_by_battery_saver">"Activado por Ahorra de batería"</string> + <string name="theme_item_upvote_ratio_icon_tint">"Color del Icono de la Proporción de Upvotes"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"Aplicado a: Icono de la proporción de upvotes"</string> + <string name="theme_item_current_user_color">"Usuario actual"</string> + <string name="theme_item_current_user_color_detail">"Aplicado a: Usuario actual en los comentarios"</string> + <string name="exclude_domains_hint">"Excluir dominios"</string> + <string name="anonymous_front_page_no_subscriptions">"¡Comienza uniéndote a un subreddit!"</string> + + <!-- Fuzzy --> + <string name="backup_settings_success">"Configuración exportada con éxito al directorio de destino. La contraseña del archivo zip generado es 123321. Por favor no modifique el archivo zip."</string> + <string name="create_zip_in_destination_directory_failed">"No se ha podido crear el zip del respaldo en el directorio de destino"</string> + <string name="backup_some_settings_failed">"No se ha podido respaldar algunos ajustes pero otros fueron respaldados correctamente al directorio de destino"</string> + <string name="restore_settings_success">"Ajustes restaurados correctamente. Reinicia la aplicación para ver los cambios."</string> + <string name="restore_settings_partially_failed">"Algunos ajustes pueden no haber sido restaurados correctamente. Reinicia la aplicación para ver los cambios."</string> + <string name="restore_settings_failed_file_corrupted">"Imposible restaurar la configuración. El archivo puede estar corrupto."</string> + <string name="restore_settings_failed_cannot_get_file">"Imposible acceder al archivo"</string> + <string name="suicide_prevention_quote">"Si estas buscando un cartel para no suicidarte, aquí esta.\u2764"</string> + <string name="do_not_show_this_again">"No mostrar esto de nuevo"</string> + <string name="continue_suicide_prevention_activity">"Continuar"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"Error al recuperar el video de v.redd.it: No se puede conseguir la url de redirección"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"Error al recuperar el video de v.redd.it: No se puede encontrar la publicación"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"Error al recuperar el video de v.redd.it: No se puede encontrar el id de la publicación"</string> + <string name="always_on">"Siempre encendido"</string> + <string name="only_on_wifi">"Solo con wifi"</string> + <string name="never">"Nunca"</string> + <string name="normal">"Normal"</string> + <string name="extra_large">"Extra grande"</string> + <string name="enormously_large">"Enormemente grande"</string> + <string name="default_in_array">"Por defecto"</string> + <string name="off">"Apagado"</string> + <string name="only_on_cellular_data">"Solo con datos móviles"</string> + <string name="upvote">"Upvote"</string> + <string name="downvote">"Downvote"</string> + <string name="select">"Seleccionar"</string> + <string name="exclude_subreddit">"Excluir este subreddit"</string> + <string name="exclude_user">"Excluir este usuario"</string> + <string name="exclude_flair">"Excluir esta etiqueta"</string> + <string name="contain_flair">"Contiene esta etiqueta"</string> + <string name="exclude_domain">"Excluir dominio"</string> + <string name="suggest_title">"Sugerir título"</string> + <string name="suggest_title_failed">"Sugerencia de título fallida"</string> + <string name="action_delete_logs">"Eliminar registros"</string> + <string name="inbox_with_count">"Inbox (%1$d)"</string> + <string name="comment_continue_thread">"Continuar hilo"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"Deslizar Verticalmente para Regresar del Medio"</string> + <string name="settings_hide_post_flair">"Ocultar la Etiqueta de la Publicación"</string> + <string name="settings_crash_reports_title">"Informes de fallos"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"Peligroso"</string> + <string name="settings_disable_nsfw_forever_title">"Desactivar NSFW para siempre"</string> + <string name="settings_show_only_one_comment_level_indicator">"Mostrar solo un indicador de nivel de comentario"</string> + <string name="save_comment">"Guardar"</string> + <string name="unsave_comment">"No guardar"</string> + <string name="copy_multi_reddit_path">"Copiar la Ruta de MultiReddit"</string> + <string name="copy_multi_reddit_path_failed">"Imposible copiar la ruta de MultiReddit"</string> + <string name="crash_reports_deleted">"Los informes de fallos han sido eliminados"</string> + <string name="disable_nsfw_forever_message">"Una vez activado, NSFW será permanentemente desactivado, independientemente de si la opción de NFSW esta activada o no. Esta opción es irreversible, la única manera de reactivar NSFW es borrando los datos de la aplicación. + +¿Seguro que quieres activarlo?"</string> + <string name="reply">"Responder"</string> + <string name="rpan_activity_label">"RPAN"</string> + <string name="post_gallery_activity_label">"Publicación de galería"</string> + <string name="trending_activity_label">"Tendencias"</string> + <string name="action_share_rpan_link">"Compartir Link de RPAN"</string> + <string name="action_share_post_link">"Compartir enlace de publicación"</string> + <string name="rpan">"RPAN"</string> + <string name="trending">"Tendencias"</string> + <string name="receive_post_reply_notifications">"Recibir notificaciones de respuesta a publicaciones"</string> + <string name="bottom_sheet_post_gallery">"Galería"</string> + <string name="posting_gallery">"Posteo de Galería"</string> + <string name="label_reddit">"Reddit"</string> + <string name="settings_default_link_post_layout">"Diseño predeterminado de publicación de enlace"</string> + <string name="settings_category_material_you_title">"Material You"</string> + <string name="settings_enable_material_you_warning_summary">"Asegúrate de no tener temas nombrados +\"Material You\", +\"Material You Dark\" or +\"Material You Amoled\". +De lo contrario, cambiales el nombre antes de habilitar Material You."</string> + <string name="settings_enable_material_you_title">"Habilitar Material You"</string> + <string name="settings_enable_material_you_summary">"Personalizar Infinity basado en tu fondo de pantalla"</string> + <string name="settings_apply_material_you_title">"Aplicar Material You"</string> + <string name="settings_apply_material_you_summary">"En caso que Infinity no haya cambiado el tema"</string> + <string name="settings_more_tabs_show_favorite_multireddits_title">"Mostrar Multireddits Favoritos"</string> + <string name="settings_more_tabs_show_multireddits_title">"Mostrar Multireddits"</string> + <string name="settings_collapse_reddit_section_title">"Contraer sección de Reddit"</string> + <string name="settings_video_player_automatic_landscape_orientation">"Cambiar a orientación horizontal en el reproductor de video automáticamente"</string> + <string name="settings_remember_muting_option_in_post_feed">"Recordar opción de silenciar en el feed de publicaciones"</string> + <string name="link_post_layout_auto">"Auto"</string> + <string name="uploaded_images">"Imágenes subidas"</string> + <string name="select_image">"Seleccionar una imágen"</string> + <string name="capture">"Capturar"</string> + <string name="uploading_image">"Subiendo"</string> + <string name="upload_image_success">"Imagen subida correctamente. Haga clic en el botón de imagen nuevamente para ver las imágenes cargadas."</string> + <string name="get_image_bitmap_failed">"No se puede obtener el mapa de bits de la imagen"</string> + <string name="upload_image_failed">"No se pudo subir la imagen"</string> + <string name="load_rpan_broadcasts_failed">"No se pueden cargar transmisiones RPAN"</string> + <string name="parse_rpan_broadcasts_failed">"No se pueden analizar las difusiones RPAN"</string> + <string name="parse_rpan_broadcast_failed">"No se pueden analizar transmisiones RPAN"</string> + <string name="search_comments">"Buscar comentarios"</string> + <string name="please_wait_image_is_uploading">"Aún se está cargando una imagen. Espere por favor."</string> + <string name="error_fetch_trending_search">"Falló la obtención de las búsquedas de tendencias. +Toque para volver a intentarlo."</string> + <string name="error_parse_trending_search">"Falló el análisis de las búsquedas de tendencias. +Toque para volver a intentarlo."</string> + <string name="no_trending_search">"No se encontraron búsquedas de tendencias. +Toque para volver a intentarlo."</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 485bc042..fb2f576f 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -243,6 +243,8 @@ Appuyez pour réessayer."</string> <string name="search">"Rechercher"</string> <string name="posting_video">"Publication de la vidéo"</string> <string name="posting_image">"Publication de l'image"</string> + + <!-- Fuzzy --> <string name="please_wait">"Veuillez patienter."</string> <string name="add_account">"Ajouter un compte"</string> <string name="anonymous_account">"Anonyme"</string> @@ -360,6 +362,8 @@ peut ne pas fonctionner sur Android 11"</string> <string name="settings_volume_keys_navigate_posts_title">"Utiliser les Boutons de Volume pour Naviguer dans les Publications"</string> <string name="settings_mute_video_title">"Couper le Son des Vidéos"</string> <string name="settings_mute_nsfw_video_title">"Couper le Son des Vidéos NSFW"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"Essayez d'Accéder Automatiquement aux Redgifs si les Vidéos sur Gfycat sont Supprimées."</string> <string name="settings_video_player_ignore_nav_bar_title">"Ignorer la Barre de Navigation dans le Lecteur Vidéo"</string> <string name="settings_video_player_ignore_nav_bar_summary">"Empêcher le Contrôleur Vidéo de créer une Marge Supplémentaire"</string> @@ -918,7 +922,6 @@ Les onglets pourraient perdre tout leur contenu quand vous passez d'un onglet à <string name="give_award_error_message">"Erreur: %2$s, code: %1$d/"</string> <string name="give_award_success">"Succès ! "</string> <string name="give_award_failed">"Échec de la récompense. "</string> - <string name="recent_searches">"Recherches récentes"</string> <string name="warning">"Avertissement "</string> <string name="this_is_a_nsfw_subreddit">"Cette Subreddit est PSPT (Pas Sécurisé Pour le Travail) "</string> <string name="this_user_has_nsfw_content">"Cet utilisateur poste du contenu NSFW"</string> @@ -951,13 +954,24 @@ Les onglets pourraient perdre tout leur contenu quand vous passez d'un onglet à <string name="filtered_posts_activity_subtitle">"Posts filtrés"</string> <string name="post_filter_preference_activity_label">"Filtre des posts"</string> <string name="search_users_result_activity_label">"Utilisateurs"</string> + <string name="action_save_to_database">"Sauvegarder dans la base de données"</string> + <string name="action_read_all_messages">"Lire tous les messages"</string> + <string name="search_only_subreddits_hint">"Chercher des subreddits"</string> + <string name="search_only_users_hint">"Chercher des utilisateurs"</string> + <string name="post_type_gif">"Gif"</string> <string name="post_type_gallery">"Gallerie"</string> <string name="settings_privacy_policy_title">"Politique de confidentialité"</string> + <string name="settings_delete_read_posts_in_database_title">"Supprimer tous les messages lus de la base de données"</string> <string name="settings_post_history_title">"Historique des posts"</string> <string name="settings_mark_posts_as_read_after_voting_title">"Marquer les posts comme lus après avoir voté"</string> <string name="settings_hide_read_posts_automatically_title">"Cacher les posts lus automatiquement"</string> <string name="open_link">"Ouvrir le lien"</string> + <string name="theme_item_read_post_title_color_detail">"Lire le Titre du Post"</string> + <string name="theme_item_read_post_content_color">"Lire la couleur du contenu du post"</string> + <string name="theme_item_read_post_content_color_detail">"Appliqué à: Lire le contenu du post"</string> + <string name="delete_all_read_posts_success">"Suppression de tous les post lus avec succès"</string> <string name="hide_read_posts">"Cacher les posts lus"</string> + <string name="filter_posts">"Filtrer les posts"</string> <string name="only_nsfw">"Seulement NSFW"</string> <string name="only_spoiler">"Seulement Spoiler"</string> <string name="exclude_subreddits_hint">"Exclure des subreddits (e.g. funny, AskReddit)"</string> @@ -969,4 +983,34 @@ Les onglets pourraient perdre tout leur contenu quand vous passez d'un onglet à <string name="post_filter_usage_user_all">"Utilisateur"</string> <string name="read_all_messages_time_limit">"You faites cela trop fréquemment. Essayez plus tard. C'est le taux limite de l'Api Reddit."</string> <string name="choose_a_user">"Choisir un utilisateur"</string> + <string name="settings_hide_the_number_of_votes">"Cacher le Nombre de Votes"</string> + <string name="settings_hide_the_number_of_comments">"Cacher le Nombre de Commentaires"</string> + <string name="have_trouble_login_message">"Voulez vous essayer un autre moyen d'identification ?"</string> + <string name="vote">"Vote"</string> + <string name="action_share_link">"Partager le Lien"</string> + <string name="action_copy_link">"Copier le Lien"</string> + <string name="action_add_to_post_filter">"Ajouter aux Filtres de Post"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"Ne pas cacher les images NSFW dans les Subreddits"</string> + <string name="settings_show_avatar_on_the_right">"Voir l'avatar à droite"</string> + <string name="settings_backup_settings_title">"Paramètres de Sauvegarde"</string> + <string name="settings_restore_settings_title">"Restaurer les Paramètres"</string> + <string name="settings_navigation_drawer_title">"Onglet de Navigation"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Cacher la section de subreddits favoris"</string> + <string name="device_default">"Appareil par defaut"</string> + <string name="theme_item_current_user_color">"Utilisateur actuel"</string> + <string name="theme_item_current_user_color_detail">"Appliqué à : Utilisateurs en commentaires"</string> + <string name="anonymous_front_page_no_subscriptions">"Commence en rejoignant un subreddit !"</string> + <string name="create_zip_in_destination_directory_failed">"Impossible de créer un zip de sauvegarde dans ce dossier"</string> + <string name="restore_settings_success">"Paramètres restaurés avec succès. Redémarre l'application pour voir les changements"</string> + <string name="do_not_show_this_again">"Ne plus voir ça"</string> + <string name="continue_suicide_prevention_activity">"Continuer"</string> + <string name="inbox_with_count">"Boîte de Réception (%1$d)"</string> + <string name="reply">"Répondre"</string> + <string name="uploaded_images">"Image uploadée"</string> + <string name="select_image">"Sélectionner une image"</string> + <string name="uploading_image">"En train d'uploader"</string> + <string name="upload_image_success">"Image uploadée avec succès. Clique sur le bouton image de nouveau pour voir les images uploadées."</string> + <string name="upload_image_failed">"Impossible d'uploader l'image"</string> + <string name="search_comments">"Chercher des commentaires"</string> + <string name="please_wait_image_is_uploading">"Une image est toujours sn train d'être uploadée. Merci d'attendre"</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 10be455b..2454fe06 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -252,6 +252,8 @@ Behavior --> <string name="search">"खोज "</string> <string name="posting_video">"वीडियो पोस्ट हो रही है "</string> <string name="posting_image">"चित्र पोस्ट हो रहा है "</string> + + <!-- Fuzzy --> <string name="please_wait">"कृपया इंतजार करें "</string> <string name="add_account">"खाता जोड़ें "</string> <string name="anonymous_account">"अज्ञात "</string> @@ -354,6 +356,8 @@ Behavior --> <!-- Are those commands or a state? Like 'search' is a state in 'search opration' but is a command in 'search something'. Hindi has different appraoch for these two. --> <string name="settings_mute_nsfw_video_title">"मौन NSFW वीडियोज"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"स्वतः ही Redgifs खोलने का प्रयास यदि Gfycat पर वीडियोज हटा दी गयी हों "</string> <string name="settings_video_player_ignore_nav_bar_title">"वीडियो प्लेयर में नेवीगेशन बार का छिपना"</string> <string name="settings_video_player_ignore_nav_bar_summary">"वीडियो कंट्रोलर द्वारा अतिरिक्त हाशिया लेने पर रोक "</string> @@ -901,7 +905,6 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd संदेश: %2$s"</string> <string name="give_award_success">"पुरस्कार दे दिया गया "</string> <string name="give_award_failed">"असफल "</string> - <string name="recent_searches">"हाल ही की खोजें "</string> <string name="warning">"चेतावनी "</string> <string name="this_is_a_nsfw_subreddit">"यह एक NSFW सबरैडिट है "</string> <string name="this_user_has_nsfw_content">"इस यूजर के पास NSFW सामग्री है। "</string> diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index d6532663..b3244b35 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -36,9 +36,6 @@ <string name="action_refresh">"Osvježi"</string> <string name="action_add_comment">"Komentiraj"</string> <string name="action_save_post">"Spremi objavu"</string> - - <!-- Fuzzy --> - <string name="action_view_crosspost_parent">"Roditeljska objava crossposta"</string> <string name="action_search">"Pretraži"</string> <!-- Would you like Lazy mode to be translated or should it be kept in English to emphasize it is a special feature? --> @@ -227,7 +224,6 @@ <string name="search">"Pretraživanje"</string> <string name="posting_video">"Objavljivanje videozapisa"</string> <string name="posting_image">"Objavljivanje slike"</string> - <string name="please_wait">"Molim pričekajte."</string> <string name="add_account">"Dodajte račun"</string> <string name="anonymous_account">"Anonimno"</string> <string name="log_out">"Odjava"</string> @@ -255,30 +251,12 @@ <string name="show_removed_post_failed">"Nismo uspjeli pronaći uklonjenu objavu"</string> <string name="cancel">"Otkaži"</string> <string name="ok">"U redu"</string> - - <!-- Fuzzy --> - <string name="edit_success">"Uspješno uređeno"</string> <string name="delete_post_success">"Uspješno obrisano"</string> <string name="delete_post_failed">"Brisanje nije uspjelo"</string> - - <!-- Fuzzy --> - <string name="mark_nsfw_success">"Uspješno označeno kao NSFW"</string> <string name="mark_nsfw_failed">"Označavanje kao NSFW nije uspjelo"</string> - - <!-- Fuzzy --> - <string name="unmark_nsfw_success">"Uspješno odznačeno kao NSFW"</string> <string name="unmark_nsfw_failed">"Odznačavanje kao NSFW nije uspjelo"</string> - - <!-- Fuzzy --> - <string name="mark_spoiler_success">"Uspješno označeno kao Spojler"</string> <string name="mark_spoiler_failed">"Označavanje kao Spojler nije uspjelo"</string> - - <!-- Fuzzy --> - <string name="unmark_spoiler_success">"Uspješno odznačeno kao Spojler"</string> <string name="unmark_spoiler_failed">"Odznačavanje kao Spojler nije uspjelo"</string> - - <!-- Fuzzy --> - <string name="update_flair_success">"Flair uspješno ažuriran"</string> <string name="update_flair_failed">"Flair nije ažuriran"</string> <string name="edit_flair">"Uredi Flair"</string> <string name="only_allow_64_chars">"Dopusti manje od 64 znaka"</string> @@ -311,10 +289,6 @@ <string name="settings_start_autoplay_visible_area_offset_landscape_title">"Pomak vidljivog područja kod automatski pokrenutog videozapisa (Pejzažno)"</string> <string name="settings_start_autoplay_visible_area_offset_landscape_summary">"Započni automatski pokretati videozapise kada ih je %1$d%% vidljivo"</string> <string name="settings_immersive_interface_title">"Imerzivno sučelje"</string> - - <!-- Fuzzy --> - <string name="settings_immersive_interface_summary">"Ne odnosi se na sve stranice -Možda ne radi na Androidu 11"</string> <string name="settings_immersive_interface_ignore_nav_bar_title">"Ignoriraj navigacijsku traku u imerzivnom sučelju"</string> <string name="settings_immersive_interface_ignore_nav_bar_summary">"Onemogući dodatnu podlogu na donjoj navigacijskoj traci"</string> <string name="settings_customize_tabs_in_main_page_title">"Uredi kartice na Glavnoj stranici"</string> @@ -326,7 +300,6 @@ Možda ne radi na Androidu 11"</string> <string name="settings_volume_keys_navigate_posts_title">"Koristi tipke za glasnoću pri navigaciji objava"</string> <string name="settings_mute_video_title">"Isključi ton na videozapisima"</string> <string name="settings_mute_nsfw_video_title">"Isključi ton na NSFW videozapisima"</string> - <string name="settings_automatically_try_redgifs_title">"Automatski pokušaj pristupiti Redgifs ako su videozapisi na Gfycat-u uklonjeni."</string> <string name="settings_video_player_ignore_nav_bar_title">"Ignoriraj navigacijsku traku u video playeru"</string> <string name="settings_video_player_ignore_nav_bar_summary">"Onemogući dodatnu marginu na video kontroleru"</string> <string name="settings_confirm_to_exit">"Potvrdi izlaz"</string> @@ -341,12 +314,6 @@ Možda ne radi na Androidu 11"</string> <string name="settings_time_format_title">"Vremenski format"</string> <string name="settings_category_post_title">"Objava"</string> <string name="settings_default_post_layout">"Zadani raspored objave"</string> - - <!-- Fuzzy --> - <string name="settings_show_divider_in_compact_layout">"Prikaži razdjelnik u Kompaktnom rasporedu"</string> - - <!-- Fuzzy --> - <string name="settings_show_thumbnail_on_the_left_in_compact_layout">"Prikaži sličicu na lijevoj strani u Kompaktnom rasporedu"</string> <string name="settings_swap_tap_and_long_title">"Zamijeni kratki i dugi dodir u komentarima"</string> <string name="settings_swipe_to_go_back_title">"Prelazak prstom u desno za natrag"</string> <string name="settings_swipe_to_go_back_summary">"Ne primjenjuje se na sve stranice"</string> @@ -689,9 +656,6 @@ Baziraj na Indigo Amoled temi"</string> <string name="cannot_find_theme">"Nije moguće pronaći tu temu"</string> <string name="import_theme">"Uvezi temu"</string> <string name="no_data_in_clipboard">"Nije moguće pronaći podatke u međuspremniku"</string> - - <!-- Fuzzy --> - <string name="import_theme_success">"Uvoz teme uspješan"</string> <string name="parse_theme_failed">"Rasčlana teme nije uspjela"</string> <string name="duplicate_theme_name_dialog_title">"Pronađen je duplikat teme"</string> <string name="duplicate_theme_name_dialog_message">"U bazi podataka već postoji tema pod imenom %1$s. Želite li promijeniti ime uvezene teme?"</string> @@ -699,27 +663,6 @@ Baziraj na Indigo Amoled temi"</string> <string name="override">"Nadglasati"</string> <string name="color_picker">"Birać boja"</string> <string name="invalid_color">"Neispravna boja"</string> - - <!-- Fuzzy --> - <string name="delete_all_subreddits_success">"Brisanje svih podreddita uspješno"</string> - - <!-- Fuzzy --> - <string name="delete_all_users_success">"Brisanje svih korisnika uspješno"</string> - - <!-- Fuzzy --> - <string name="delete_all_sort_types_success">"Brisanje svih vrsti sortiranja uspješno"</string> - - <!-- Fuzzy --> - <string name="delete_all_post_layouts_success">"Brisanje svih rasporeda objava uspješno"</string> - - <!-- Fuzzy --> - <string name="delete_all_themes_success">"Brisanje svih tema uspješno"</string> - - <!-- Fuzzy --> - <string name="delete_all_front_page_scrolled_positions_success">"Brisanje svih pozicija na početnoj strani uspješno"</string> - - <!-- Fuzzy --> - <string name="reset_all_settings_success">"Resertiranje svih postavki uspješno"</string> <string name="username_preview">"u/Hostilenemy"</string> <string name="subreddit_preview">"r/Infinity_For_Reddit"</string> <string name="primary_text_preview">"Primarni tekst"</string> @@ -758,9 +701,6 @@ Baziraj na Indigo Amoled temi"</string> <string name="downloading_reddit_video_muxing">"Multipleksiranje videa i audija"</string> <string name="downloading_reddit_video_save_file_to_public_dir">"Spremanje videa"</string> <string name="downloading_reddit_video_finished">"Preuzeto"</string> - - <!-- Fuzzy --> - <string name="downloading_reddit_video_failed_cannot_get_cache_directory">"Preuzimanje nije uspjelo: nije moguće pristupiti predmemoriji"</string> <string name="downloading_reddit_video_failed_cannot_download_video">"Preuzimanje nije uspjelo: nije moguće preuzeti videozapis"</string> <string name="downloading_reddit_video_failed_cannot_save_video">"Preuzimanje nije uspjelo: nije moguće spremiti videozapis u predmemoriju"</string> <string name="downloading_reddit_video_failed_cannot_save_audio">"Preuzimanje nije uspjelo: nije moguće spremiti audio zapis u predmemoriju"</string> @@ -810,12 +750,6 @@ Baziraj na Indigo Amoled temi"</string> <string name="settings_pull_to_refresh_title">"Povuci za ovježavanje"</string> <string name="settings_security_title">"Sigurnost"</string> <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Zatraži autentikaciju pri ulasku u Račun u navigacijskoj ladici"</string> - - <!-- Fuzzy --> - <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Dugo pritisni za skrivanje alatne trake u Kompaktnom rasporedu"</string> - - <!-- Fuzzy --> - <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">"Alatna traka u Kompaktnom rasporedu je zadano skrivena"</string> <string name="settings_customize_bottom_app_bar_title">"Uredi donju navigacijsku traku"</string> <string name="settings_main_activity_bottom_app_bar_group_summary">"Glavna stranica"</string> <string name="settings_other_activities_bottom_app_bar_group_summary">"Druge stranice"</string> @@ -826,11 +760,6 @@ Baziraj na Indigo Amoled temi"</string> <string name="settings_bottom_app_bar_option_4">"Opcija 4"</string> <string name="settings_bottom_app_bar_fab">"Plutajući akcijski gumb"</string> <string name="settings_data_saving_mode">"Način uštede podataka"</string> - - <!-- Fuzzy --> - <string name="settings_data_saving_mode_info_summary">"U načinu uštede podataka: -Slike predpregleda su niže rezolucije. -Reddit videi su niže rezolucije."</string> <string name="settings_translation_title">"Prijevod"</string> <string name="settings_translation_summary">"Prevedi ovu aplikaciju na POEditor-u. Hvala svim prinosnicima."</string> <string name="settings_credits_national_flags">"Zastave država"</string> @@ -858,24 +787,13 @@ Reddit videi su niže rezolucije."</string> <string name="change_post_layout">"Promjeni raspored objava"</string> <string name="give_award_dialog_title">"Nagraditi?"</string> <string name="anonymous">"Anonimno"</string> - - <!-- Fuzzy --> - <string name="give_award_error_message">"Kod: %1$d/ -Poruka: %2$s"</string> <string name="give_award_success">"Nagrađeno"</string> <string name="give_award_failed">"Nagrađivanje nije uspjelo"</string> - <string name="recent_searches">"Nedavne pretrage"</string> <string name="warning">"Upozorenje"</string> <string name="this_is_a_nsfw_subreddit">"Ovo je NSFW podreddit."</string> <string name="this_user_has_nsfw_content">"Ovaj korisnik ima NSFW sadržaj"</string> <string name="dismiss">"Odbaci"</string> <string name="leave">"Napusti"</string> - - <!-- Fuzzy --> - <string name="go_to_subreddit">"Idi na podreddit"</string> - - <!-- Fuzzy --> - <string name="go_to_user">"Idi na profil korisnika"</string> <string name="go_to_thing_hint">"Ime"</string> <string name="random">"Nasumično"</string> <string name="random_subreddit">"Nasumični podreddit"</string> @@ -895,10 +813,221 @@ Poruka: %2$s"</string> <string name="settings_swipe_action_haptic_feedback_title">"Haptična povratna informacija"</string> <string name="settings_hide_subreddit_description_title">"Sakri opis podreddita"</string> <string name="settings_disable_image_preview_title">"Onemogući predpregled slike u "</string> + <string name="settings_swipe_action_swipe_left_title">"Povuci lijevo"</string> <string name="settings_swipe_action_swipe_right_title">"Prelazak prstom u desno"</string> <string name="theme_item_no_preview_post_type_icon_tint">"Boja ikone objave bez predpregleda"</string> <string name="theme_item_no_preview_post_type_icon_tint_detail">"Primjenjeno na: Ikonu koja ukazuje vrstu objave kada nema predpregleda"</string> <string name="theme_item_no_preview_post_type_background_color">"Boja pozadine objave bez predpregleda"</string> <string name="theme_item_no_preview_post_type_background_color_detail">"Primjenjeno na: Zamjena koja prikazuje vrstu objave kada nema predpregleda"</string> <string name="settings_language_title">"Jezik"</string> + <string name="customize_post_filter_activity_label">"Uredi filter objava"</string> + <string name="filtered_posts_activity_subtitle">"Filtrirane objave"</string> + <string name="post_filter_preference_activity_label">"Filter objava"</string> + <string name="search_users_result_activity_label">"Korisnici"</string> + <string name="multireddit_selection_activity_label">"Izaberi multireddit"</string> + <string name="action_save_to_database">"Spremi u bazu podataka"</string> + <string name="action_read_all_messages">"Procitaj sve poruke"</string> + <string name="action_add_to_multireddit">"Dodaj u multireddit"</string> + <string name="search_only_subreddits_hint">"Pretrazi subreddite"</string> + <string name="search_only_users_hint">"Trazi korisnike"</string> + <string name="post_type_gif">"Gif"</string> + <string name="post_type_gallery">"Galerija"</string> + <string name="settings_disable_immersive_interface_in_landscape_mode">"Onemogućite imerzivno sučelje u pejzažnom načinu"</string> + <string name="settings_privacy_policy_title">"Politika privatnosti"</string> + <string name="settings_delete_read_posts_in_database_title">"Obriši sve isčitane objave u bazi podataka"</string> + <string name="settings_post_filter_title">"Filter objava"</string> + <string name="settings_only_disable_preview_in_video_and_gif_posts_title">"Iskljuci pregled u videima i GIF objavama"</string> + <string name="settings_enable_search_history_title">"Uključi povijest pretraživanja"</string> + <string name="settings_post_history_title">"Povijest objava"</string> + <string name="settings_mark_posts_as_read_title">"Označi objave kao pročitano"</string> + <string name="settings_mark_posts_as_read_after_voting_title">"Označi objave kao pročitano nakon glasanja"</string> + <string name="settings_mark_posts_as_read_on_scroll_title"></string> + <string name="settings_hide_read_posts_automatically_title">"Sakrij pročitane objave automatski"</string> + <string name="settings_sort_type_title">"Vrsta sortiranja"</string> + <string name="settings_save_sort_type_title">"Spremi vrstu sortiranja"</string> + <string name="settings_subreddit_default_sort_type_title">"Zadana vrsta sortiranja subreddit-a"</string> + <string name="settings_subreddit_default_sort_time_title">"Zadano vrijeme sortiranja subreddit-a"</string> + <string name="settings_user_default_sort_time_title">"Zadano vrijeme sortiranja korisnika"</string> + <string name="open_link">"Otvori link"</string> + <string name="select_subreddits_and_users"></string> + <string name="theme_item_read_post_title_color"></string> + <string name="theme_item_read_post_title_color_detail"></string> + <string name="theme_item_read_post_content_color"></string> + <string name="theme_item_read_post_content_color_detail"></string> + <string name="theme_item_read_post_card_view_background_color"></string> + <string name="theme_item_read_post_card_view_background_color_detail"></string> + <string name="delete_all_read_posts_success"></string> + <string name="hide_read_posts"></string> + <string name="filter_posts"></string> + <string name="only_nsfw"></string> + <string name="only_spoiler"></string> + <string name="title_excludes_strings_hint"></string> + <string name="title_excludes_regex_hint"></string> + <string name="exclude_subreddits_hint"></string> + <string name="exclude_users_hint"></string> + <string name="exclude_flairs_hint"></string> + <string name="contain_flairs_hint"></string> + <string name="min_vote_hint"></string> + <string name="max_vote_hint"></string> + <string name="min_comments_hint"></string> + <string name="max_comments_hint"></string> + <string name="min_awards_hint"></string> + <string name="max_awards_hint"></string> + <string name="post_filter_name_hint"></string> + <string name="post_filter_requires_a_name">"Koje je ime filtera objave"</string> + <string name="duplicate_post_filter_dialog_title"></string> + <string name="duplicate_post_filter_dialog_message">"Poništi?"</string> + <string name="apply_post_filter_to"></string> + <string name="post_filter_usage_home">"Home"</string> + <string name="post_filter_usage_subreddit"></string> + <string name="post_filter_usage_subreddit_all">"Subreddit"</string> + <string name="post_filter_usage_user"></string> + <string name="post_filter_usage_user_all"></string> + <string name="post_filter_usage_multireddit"></string> + <string name="post_filter_usage_multireddit_all"></string> + <string name="post_filter_usage_search"></string> + <string name="subreddit">"Subreddit"</string> + <string name="user">"Korisnik"</string> + <string name="edit_post_filter_name_of_usage_info"></string> + <string name="read_all_messages_time_limit"></string> + <string name="read_all_messages_success"></string> + <string name="read_all_messages_failed"></string> + <string name="add_subreddit_or_user_to_multireddit_success"></string> + <string name="add_subreddit_or_user_to_multireddit_failed"></string> + <string name="choose_a_user">"Odaberi korisnika"</string> + <string name="settings_click_to_show_media_in_gallery_layout">"Klikni da prikažeš medij u obliku galerije"</string> + <string name="settings_hide_post_type">"Sakrij vrstu objave"</string> + <string name="settings_hide_the_number_of_awards">"Sakrij broj nagrada"</string> + <string name="settings_hide_subreddit_and_user_prefix"></string> + <string name="settings_hide_the_number_of_votes">"Sakrij broj glasanja"</string> + <string name="settings_hide_the_number_of_comments">"Sakrij broj komentara"</string> + <string name="post_layout_gallery">"Izgled galerije"</string> + <string name="post_layout_card_2">"Izgled karte 2"</string> + <string name="have_trouble_login_title"></string> + <string name="have_trouble_login_message">"Želite li se prijaviti na drugi način?"</string> + <string name="vote">"Glasaj"</string> + <string name="action_share_link">"Podjeli link"</string> + <string name="action_copy_link">"Kopiraj link"</string> + <string name="action_add_to_post_filter">"Dodaj u vrstu objave"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"Nemoj blurati NSFW slike u NSFW Subredditima"</string> + <string name="settings_backup_settings_title"></string> + <string name="settings_restore_settings_title">"Vrati postavke"</string> + <string name="settings_credits_love_animation_title"></string> + <string name="settings_swipe_between_posts_title"></string> + <string name="settings_navigation_drawer_title"></string> + <string name="settings_collapse_account_section_title"></string> + <string name="settings_collapse_post_section_title"></string> + <string name="settings_collapse_preferences_section_title"></string> + <string name="settings_collapse_favorite_subreddits_section_title"></string> + <string name="settings_collapse_subscribed_subreddits_section_title"></string> + <string name="settings_hide_favorite_subreddits_sections_title"></string> + <string name="settings_hide_subscribed_subreddits_sections_title"></string> + <string name="settings_default_search_result_tab"></string> + <string name="device_default"></string> + <string name="set_by_battery_saver"></string> + <string name="theme_item_upvote_ratio_icon_tint"></string> + <string name="theme_item_upvote_ratio_icon_tint_detail"></string> + <string name="theme_item_current_user_color"></string> + <string name="theme_item_current_user_color_detail"></string> + <string name="exclude_domains_hint"></string> + <string name="anonymous_front_page_no_subscriptions"></string> + <string name="backup_settings_success"></string> + <string name="create_zip_in_destination_directory_failed"></string> + <string name="backup_some_settings_failed"></string> + <string name="restore_settings_success"></string> + <string name="restore_settings_partially_failed"></string> + <string name="restore_settings_failed_file_corrupted"></string> + <string name="restore_settings_failed_cannot_get_file"></string> + <string name="suicide_prevention_quote"></string> + <string name="do_not_show_this_again"></string> + <string name="continue_suicide_prevention_activity"></string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url"></string> + <string name="error_fetching_v_redd_it_video_cannot_get_post"></string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id"></string> + <string name="always_on"></string> + <string name="only_on_wifi"></string> + <string name="never"></string> + <string name="normal"></string> + <string name="extra_large"></string> + <string name="enormously_large"></string> + <string name="default_in_array"></string> + <string name="off"></string> + <string name="only_on_cellular_data"></string> + <string name="upvote"></string> + <string name="downvote"></string> + <string name="select"></string> + <string name="exclude_subreddit"></string> + <string name="exclude_user"></string> + <string name="exclude_flair"></string> + <string name="contain_flair"></string> + <string name="exclude_domain"></string> + <string name="suggest_title"></string> + <string name="suggest_title_failed"></string> + <string name="action_delete_logs"></string> + <string name="inbox_with_count"></string> + <string name="comment_continue_thread"></string> + <string name="settings_swipe_vertically_to_go_back_from_media_title"></string> + <string name="settings_hide_post_flair"></string> + <string name="settings_crash_reports_title"></string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title"></string> + <string name="settings_disable_nsfw_forever_title"></string> + <string name="settings_show_only_one_comment_level_indicator"></string> + <string name="save_comment"></string> + <string name="unsave_comment"></string> + <string name="copy_multi_reddit_path"></string> + <string name="copy_multi_reddit_path_failed"></string> + <string name="crash_reports_deleted"></string> + <string name="disable_nsfw_forever_message"></string> + <string name="reply"></string> + <string name="rpan_activity_label"></string> + <string name="post_gallery_activity_label"></string> + <string name="trending_activity_label"></string> + <string name="action_share_rpan_link"></string> + <string name="action_share_post_link"></string> + <string name="rpan"></string> + <string name="trending"></string> + <string name="receive_post_reply_notifications"></string> + <string name="bottom_sheet_post_gallery"></string> + <string name="posting_gallery"></string> + <string name="label_reddit"></string> + <string name="settings_default_link_post_layout"></string> + <string name="settings_category_material_you_title"></string> + <string name="settings_enable_material_you_warning_summary"></string> + <string name="settings_enable_material_you_title"></string> + <string name="settings_enable_material_you_summary"></string> + <string name="settings_apply_material_you_title"></string> + <string name="settings_apply_material_you_summary"></string> + <string name="settings_more_tabs_show_favorite_multireddits_title"></string> + <string name="settings_more_tabs_show_multireddits_title"></string> + <string name="settings_collapse_reddit_section_title"></string> + <string name="settings_video_player_automatic_landscape_orientation"></string> + <string name="settings_remember_muting_option_in_post_feed"></string> + <string name="link_post_layout_auto"></string> + <string name="uploaded_images"></string> + <string name="select_image"></string> + <string name="capture"></string> + <string name="uploading_image"></string> + <string name="upload_image_success"></string> + <string name="get_image_bitmap_failed"></string> + <string name="upload_image_failed"></string> + <string name="load_rpan_broadcasts_failed"></string> + <string name="parse_rpan_broadcasts_failed"></string> + <string name="parse_rpan_broadcast_failed"></string> + <string name="search_comments"></string> + <string name="please_wait_image_is_uploading"></string> + <string name="error_fetch_trending_search"></string> + <string name="error_parse_trending_search"></string> + <string name="no_trending_search"></string> + <string name="wiki_activity_label"></string> + <string name="settings_post_details_title"></string> + <string name="settings_separate_post_and_comments_in_portrait_mode_title"></string> + <string name="settings_separate_post_and_comments_in_landscape_mode_title"></string> + <string name="settings_separate_post_and_comments_summary"></string> + <string name="settings_use_bottom_toolbar_in_media_viewer_title"></string> + <string name="settings_secure_mode_title"></string> + <string name="settings_secure_mode_summary"></string> + <string name="discard_dialog_button"></string> + <string name="error_loading_wiki"></string> + <string name="no_wiki"></string> + <string name="material_you_notification_title"></string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index f138fc36..83b9b4c6 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -223,6 +223,8 @@ <string name="search">"Keresés"</string> <string name="posting_video">"Videó posztolása"</string> <string name="posting_image">"Kép posztolása"</string> + + <!-- Fuzzy --> <string name="please_wait">"Kérlek várj."</string> <string name="add_account">"Fiók hozzáadása"</string> <string name="anonymous_account">"Anoním"</string> @@ -309,6 +311,8 @@ <string name="settings_volume_keys_navigate_posts_title">"Hangerőgombok használata posztok navigálására"</string> <string name="settings_mute_video_title">"Videók némítása"</string> <string name="settings_mute_nsfw_video_title">"NSFW videók némítása"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"Próbálja autómatikusan elérni a Redgifeket, ha a videók Gfycat-en el vannak távolítva."</string> <string name="settings_video_player_ignore_nav_bar_title">"Navigációs sáv ignorálása videó lejátszóban"</string> <string name="settings_video_player_ignore_nav_bar_summary">"Annak megelőzése, hogy a videó kontrollernek extra szegélye legyen"</string> @@ -835,7 +839,6 @@ Videó autómatikus lejátszása le van tiltva."</string> Üzenet %2$s"</string> <string name="give_award_success">"Kitüntetés megadva"</string> <string name="give_award_failed">"Nem sikerült"</string> - <string name="recent_searches">"Utóbbi keresések"</string> <string name="warning">"Figyelem"</string> <string name="this_is_a_nsfw_subreddit">"Ez egy NSFW subreddit."</string> <string name="this_user_has_nsfw_content">"Ennek a felhasználónak van NSFW tartlama"</string> diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 8e210e0b..53f31dfa 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -4,9 +4,9 @@ <string name="comment_activity_label">"Invia commento"</string> <string name="comment_activity_label_is_replying">"Rispondi"</string> <string name="post_text_activity_label">"Post testuale"</string> - <string name="subreddit_selection_activity_label">"Seleziona Subreddit"</string> - <string name="post_link_activity_label">"Post Link"</string> - <string name="post_image_activity_label">"Post di Immagine"</string> + <string name="subreddit_selection_activity_label">"Seleziona subreddit"</string> + <string name="post_link_activity_label">"Post link"</string> + <string name="post_image_activity_label">"Post immagine"</string> <string name="post_video_activity_label">"Post video"</string> <string name="rules_activity_label">"Regole"</string> <string name="search_subreddits_activity_label">"Subreddit"</string> @@ -14,10 +14,10 @@ <string name="edit_comment_activity_label">"Modifica commento"</string> <string name="view_message_activity_label">"Posta"</string> <string name="settings_activity_label">"Impostazioni"</string> - <string name="account_saved_thing_activity_label">"Salvato"</string> + <string name="account_saved_thing_activity_label">"Post salvati"</string> <string name="create_multi_reddit_activity_label">"Crea Multireddit"</string> <string name="subreddit_multiselection_activity_label">"Seleziona Subreddit"</string> - <string name="custom_theme_listing_activity_label">"Tema personalizzato"</string> + <string name="custom_theme_listing_activity_label">"Temi personalizzati"</string> <string name="customize_theme_activity_label">"Personalizza tema"</string> <string name="customize_theme_activity_create_theme_label">"Crea tema"</string> <string name="theme_preview_activity_label">"Anteprima tema"</string> @@ -26,15 +26,11 @@ <string name="report_activity_label">"Segnala"</string> <string name="view_imgur_media_activity_image_label">"Immagine %1$d/%2$d"</string> <string name="view_imgur_media_activity_video_label">"Video %1$d/%2$d"</string> - <string name="send_private_message_activity_label">"Invia PM"</string> + <string name="send_private_message_activity_label">"Invia messaggio privato"</string> <string name="view_reddit_gallery_activity_image_label">"Immagine %1$d/%2$d"</string> <string name="view_reddit_gallery_activity_gif_label">"Gif %1$d/%2$d"</string> <string name="view_reddit_gallery_activity_video_label">"Video %1$d/%2$d"</string> - - <!-- Fuzzy --> <string name="navigation_drawer_open">"Apri drawer navigazione"</string> - - <!-- Fuzzy --> <string name="navigation_drawer_close">"Chiudi drawer navigazione"</string> <string name="action_download">"Scarica"</string> <string name="action_refresh">"Ricarica"</string> @@ -42,17 +38,17 @@ <string name="action_save_post">"Salva post"</string> <string name="action_view_crosspost_parent">"Mostra origine del crosspost"</string> <string name="action_search">"Cerca"</string> - <string name="action_start_lazy_mode">"Inizia Modalità pigra"</string> - <string name="action_stop_lazy_mode">"Ferma Modalità pigra"</string> + <string name="action_start_lazy_mode">"Attiva la modalità pigra"</string> + <string name="action_stop_lazy_mode">"Disattiva la modalità pigra"</string> <string name="action_send">"Invia"</string> <string name="action_sort">"Ordina"</string> - <string name="action_hide_post">"Nascondi Post"</string> - <string name="action_unhide_post">"Visualizza Post"</string> + <string name="action_hide_post">"Nascondi"</string> + <string name="action_unhide_post">"Rimuovi dai nascosti"</string> <string name="action_edit_post">"Modifica Post"</string> <string name="action_delete_post">"Elimina Post"</string> - <string name="action_mark_nsfw">"Seleziona NSFW"</string> + <string name="action_mark_nsfw">"Contrassegna NSFW"</string> <string name="action_unmark_nsfw">"Deseleziona NSFW"</string> - <string name="action_mark_spoiler">"Seleziona Spoiler"</string> + <string name="action_mark_spoiler">"Contrassegna Spoiler"</string> <string name="action_unmark_spoiler">"Deseleziona Spoiler"</string> <string name="action_edit_flair">"Modifica flair"</string> <string name="action_change_post_layout">"Cambia disposizione post"</string> @@ -64,7 +60,7 @@ <string name="action_report">"Segnala"</string> <string name="action_see_removed">"Visualizza Rimosso"</string> <string name="action_set_wallpaper">"Imposta come Sfondo"</string> - <string name="action_send_private_message">"Invia Messaggio Privato"</string> + <string name="action_send_private_message">"Invia Messaggio privato"</string> <string name="action_block_user">"Blocca utente"</string> <string name="parse_json_response_error">"Si è verificato un errore durante l'analisi della risposta JSON"</string> <string name="retrieve_token_error">"Errore durante il recupero del token"</string> @@ -72,38 +68,38 @@ <string name="access_denied">"Accesso negato"</string> <string name="parse_user_info_error">"Si è verificato un errore durante l'analisi delle informazioni dell'utente"</string> <string name="no_system_webview_error">"Errore apertura di System WebView"</string> - <string name="error_loading_image_tap_to_retry">"Errore durante il caricamento dell'immagine. Clicca per riprovare."</string> - <string name="load_posts_error">"Errore durante il caricamento dei post. Clicca per riprovare."</string> - <string name="load_more_posts_error">"Errore nel caricamento dei post."</string> + <string name="error_loading_image_tap_to_retry">"Errore durante il caricamento dell'immagine. Tocca per riprovare."</string> + <string name="load_posts_error">"Errore durante il caricamento dei post. Tocca per riprovare."</string> + <string name="load_more_posts_error">"Errore durante il caricamento dei post."</string> <string name="load_post_error">"Errore durante il caricamento di questo post. Clicca per riprovare."</string> <string name="search_subreddits_error">"Errore durante la ricerca dei subreddit. -Clicca per riprovare."</string> +Tocca per riprovare."</string> <string name="search_users_error">"Errore durante la ricerca degli utenti. -Clicca per riprovare."</string> +Tocca per riprovare."</string> <string name="no_posts">"Nessun post trovato"</string> <string name="no_comments">"Nessun commento trovato"</string> <string name="no_subreddits">"Nessun subreddit trovato"</string> <string name="no_users">"Nessun utente trovato"</string> <string name="no_multi_reddits">"Nessun Multireddit trovato"</string> - <string name="no_storage_permission">"Nessuna autorizzazione di archiviazione per salvare questo file"</string> - <string name="load_comments_failed">"Errore caricamento dei commenti. -Clicca per riprovare."</string> + <string name="no_storage_permission">"Autorizzazione allo spazio di archiviazione non consentita. Attivala per salvare questo file"</string> + <string name="load_comments_failed">"Errore nel caricamento dei commenti. +Tocca per riprovare."</string> <string name="retry">"Riprova"</string> <string name="comments">"Commenti"</string> - <string name="no_comments_yet">"Ancora nessun commento. Vuoi scriverne uno?"</string> - <string name="vote_failed">"Voto fallito"</string> + <string name="no_comments_yet">"Nessun commento presente. Vuoi scriverne uno tu?"</string> + <string name="vote_failed">"Voto non assegnato"</string> <string name="refresh_post_failed">"Errore nel ricaricamento del post"</string> - <string name="load_messages_failed">"Errore caricamento messaggi. Clicca per riprovare."</string> + <string name="load_messages_failed">"Errore durante il caricamento messaggi. Tocca per riprovare."</string> <string name="no_messages">"Vuoto"</string> <string name="nsfw">"NSFW"</string> <string name="karma_info">"Karma: %1$d"</string> <string name="karma_info_user_detail">"Karma: %1$d (%2$d + %3$d)"</string> - <string name="cakeday_info">"Compleanno: + <string name="cakeday_info">"Compleanno account: %1$s"</string> <string name="since">"Da:"</string> <string name="profile">"Profilo"</string> - <string name="subscriptions">"Sottoscrizioni"</string> + <string name="subscriptions">"Iscrizioni"</string> <string name="multi_reddit">"Multireddit"</string> <string name="inbox">"Posta"</string> <string name="upvoted">"Voto Positivo"</string> @@ -117,32 +113,32 @@ Clicca per riprovare."</string> <string name="subscribers_number_detail">"Iscritti: %1$d"</string> <string name="online_subscribers_number_detail">"Online: %1$d"</string> <string name="cannot_fetch_subreddit_info">"Impossibile recuperare le informazioni del subreddit"</string> - <string name="cannot_fetch_user_info">"Impossibile recuperare le informazioni utente"</string> - <string name="cannot_fetch_sidebar">"Impossibile recuperare la barra laterale"</string> + <string name="cannot_fetch_user_info">"Impossibile recuperare le informazioni dell'utente"</string> + <string name="cannot_fetch_sidebar">"Impossibile mostrare barra laterale"</string> <string name="cannot_fetch_multireddit">"Impossibile recuperare le informazioni multireddit"</string> <string name="subscribe">"Iscriviti"</string> <string name="unsubscribe">"Disiscriviti"</string> - <string name="subscribed">"Sottoscritto"</string> - <string name="subscribe_failed">"Sottoscrizione fallita"</string> + <string name="subscribed">"Iscritto"</string> + <string name="subscribe_failed">"Iscrizione non riuscita"</string> <string name="unsubscribed">"Disiscritto"</string> - <string name="unsubscribe_failed">"Disiscrizione fallita"</string> + <string name="unsubscribe_failed">"Disiscrizione non riuscita"</string> <string name="follow">"Segui"</string> <string name="unfollow">"Non seguire più"</string> <string name="followed">"Seguiti"</string> - <string name="follow_failed">"Errore nel seguire"</string> + <string name="follow_failed">"Errore nel seguire. Riprova"</string> <string name="unfollowed">"Smesso di seguire"</string> - <string name="unfollow_failed">"Disiscrizione Fallita"</string> - <string name="content_description_banner_imageview">"Immagine banner subreddit"</string> + <string name="unfollow_failed">"Disiscrizione non riuscita"</string> + <string name="content_description_banner_imageview">"Banner subreddit"</string> <string name="app_label">"Infinity"</string> - <string name="search_hint">"Cerca qualcosa"</string> + <string name="search_hint">"Cerca"</string> <string name="no_posts_no_lazy_mode">"Nessun post disponibile"</string> - <string name="lazy_mode_start">"Modalità Pigra parte in %1$.1fs"</string> - <string name="lazy_mode_stop">"Modalità Pigra fermata"</string> - <string name="write_comment_hint">"I tuoi pensieri interessanti qui"</string> + <string name="lazy_mode_start">"Modalità Pigra partirà tra %1$.1fs"</string> + <string name="lazy_mode_stop">"Modalità Pigra disattivata"</string> + <string name="write_comment_hint">"Commenta"</string> <string name="comment_content_required">"Dove sono i tuoi pensieri interessanti?"</string> - <string name="sending_comment">"Invio in corso"</string> + <string name="sending_comment">"Invio"</string> <string name="send_comment_success">"Commento inviato"</string> - <string name="send_comment_failed">"Impossibile inviare questo commento"</string> + <string name="send_comment_failed">"Impossibile inviare commento"</string> <string name="send_message_username_hint">"Utente"</string> <string name="send_message_subject_hint">"Oggetto (massimo 100 caratteri)"</string> <string name="send_message_content_hint">"Messaggio"</string> @@ -153,17 +149,17 @@ Clicca per riprovare."</string> <string name="message_content_required">"Devi dire qualcosa al destinatario"</string> <string name="sending_message">"Invio"</string> <string name="send_message_success">"Messaggio inviato"</string> - <string name="send_message_failed">"Impossibile inviare questo messaggio"</string> - <string name="select_a_subreddit">"Per favore prima seleziona un subreddit"</string> - <string name="title_required">"Il post ha bisogno di un buon titolo"</string> + <string name="send_message_failed">"Impossibile inviare messaggio"</string> + <string name="select_a_subreddit">"Seleziona un subreddit"</string> + <string name="title_required">"Al post manca il titolo"</string> <string name="link_required">"Hey dov'è il link?"</string> - <string name="select_an_image">"Per favore prima seleziona un'immagine"</string> + <string name="select_an_image">"Selezionare un'immagine"</string> <string name="posting">"Pubblicazione"</string> - <string name="post_failed">"Impossibile postare"</string> + <string name="post_failed">"Pubblicazione non riuscita"</string> <string name="error_processing_image">"Errore durante l'elaborazione dell'immagine"</string> <string name="error_processing_video">"Errore durante l'elaborazione del video"</string> - <string name="download_started">"Download avviato. Controlla la notifica per i progressi."</string> - <string name="comment_load_more_comments">"Carica più commenti"</string> + <string name="download_started">"Download avviato. Ulteriori dettagli nella notifica. "</string> + <string name="comment_load_more_comments">"Carica altri commenti"</string> <string name="comment_load_more_comments_failed">"Caricamento fallito. Tocca per riprovare."</string> <string name="loading">"Caricamento"</string> <string name="post_title_hint">"Titolo"</string> @@ -184,15 +180,15 @@ Clicca per riprovare."</string> <string name="error_getting_video">"Errore durante l'acquisizione del video"</string> <string name="no_camera_available">"Nessuna app disponibile per la fotocamera"</string> <string name="error_creating_temp_file">"Errore creazione file temp"</string> - <string name="video_is_processing">"Il video è in elaborazione. Attendere prego."</string> - <string name="image_is_processing">"L'immagine è in elaborazione. Attendere prego."</string> - <string name="gif_is_processing">"La gif è in elaborazione. Attendere prego."</string> + <string name="video_is_processing">"Video in elaborazione. Attendere."</string> + <string name="image_is_processing">"Immagine in elaborazione. Attendere. "</string> + <string name="gif_is_processing">"Gif in elaborazione. Attendere."</string> <string name="flair">"Flair"</string> <string name="spoiler">"Spoiler"</string> - <string name="no_flair">"Flair assente"</string> - <string name="error_loading_flairs">"Errore nel caricamento dei flair. Clicca per riprovare."</string> + <string name="no_flair">"Nessun flair"</string> + <string name="error_loading_flairs">"Errore nel caricamento dei flair. Tocca per riprovare."</string> <string name="no_rule">"Nessuna regola"</string> - <string name="error_loading_rules">"Errore caricamento regole. Clicca per riprovare."</string> + <string name="error_loading_rules">"Errore caricamento regole. Tocca per riprovare."</string> <string name="error_loading_rules_without_retry">"Errore caricamento regole"</string> <string name="search_in">"Cerca in"</string> <string name="all_subreddits">"Tutti i subreddit"</string> @@ -218,12 +214,12 @@ Clicca per riprovare."</string> <string name="sort_time_month">"Mese"</string> <string name="sort_time_year">"Anno"</string> <string name="sort_time_all_time">"Sempre"</string> - <string name="no_activity_found_for_share">"Non esiste un'app in grado di gestire l'azione di condivisione"</string> - <string name="archived_post_vote_unavailable">"Post archiviato. Non è possibile votare."</string> - <string name="archived_post_comment_unavailable">"Post archiviato. Non è possibile commentare."</string> - <string name="archived_post_reply_unavailable">"Post archiviato. Non è possibile rispondere."</string> - <string name="locked_post_comment_unavailable">"Post bloccato. Non è possibile commentare."</string> - <string name="locked_post_reply_unavailable">"Post bloccato. Non è possibile rispondere."</string> + <string name="no_activity_found_for_share">"Nessun'app in grado di condividere"</string> + <string name="archived_post_vote_unavailable">"Impossibile votare, il post è archiviato. "</string> + <string name="archived_post_comment_unavailable">"Impossibile commentare, il post è archiviato. "</string> + <string name="archived_post_reply_unavailable">"Impossibile rispondere, il post è archiviato."</string> + <string name="locked_post_comment_unavailable">"Impossibile commentare, il post è bloccato."</string> + <string name="locked_post_reply_unavailable">"Impossibile rispondere, il post è bloccato. "</string> <string name="text">"TESTO"</string> <string name="link">"LINK"</string> <string name="image">"IMMAGINE"</string> @@ -234,6 +230,8 @@ Clicca per riprovare."</string> <string name="search">"Cerca"</string> <string name="posting_video">"Pubblicazione del video"</string> <string name="posting_image">"Pubblicazione dell'immagine"</string> + + <!-- Fuzzy --> <string name="please_wait">"Attendere prego."</string> <string name="add_account">"Aggiungi account"</string> <string name="anonymous_account">"Anonimo"</string> @@ -267,27 +265,27 @@ Clicca per riprovare."</string> <string name="delete_post_failed">"Cancellazione fallita"</string> <!-- Fuzzy --> - <string name="mark_nsfw_success">"Seleziona come NSFW riuscito"</string> - <string name="mark_nsfw_failed">"Seleziona come NSFW non riuscito"</string> + <string name="mark_nsfw_success">"Contrassegnato come NSFW"</string> + <string name="mark_nsfw_failed">"Contrassegna come NSFW non riuscito"</string> <!-- Fuzzy --> - <string name="unmark_nsfw_success">"Deseleziona NSFW riuscito"</string> + <string name="unmark_nsfw_success">"Decontrassegnato come NSFW "</string> <string name="unmark_nsfw_failed">"Deselezionamento NSFW fallito"</string> - <string name="mark_spoiler_success">"Seleziona come spoiler riuscito"</string> + <string name="mark_spoiler_success">"Contrassegna come spoiler riuscito"</string> <string name="mark_spoiler_failed">"Seleziona come spoiler non riuscito"</string> <!-- Fuzzy --> - <string name="unmark_spoiler_success">"Deseleziona come spoiler riuscito"</string> + <string name="unmark_spoiler_success">"Spoiler decontrassegnato"</string> <string name="unmark_spoiler_failed">"Deselezionamento spoiler fallito"</string> <!-- Fuzzy --> - <string name="update_flair_success">"Aggiorna flair eseguito con successo"</string> + <string name="update_flair_success">"Flair aggiornato"</string> <string name="update_flair_failed">"Aggiorna flair fallito"</string> <string name="edit_flair">"Modifica flair"</string> <string name="only_allow_64_chars">"Consentire solo meno di 64 caratteri"</string> <string name="view_all_comments">"Clicca qui per sfogliare tutti i commenti"</string> <string name="notification_summary_account">"Account"</string> - <string name="notification_summary_message">"Nuovo Messaggio"</string> + <string name="notification_summary_message">"Nuovo messaggio"</string> <string name="notification_summary_subreddit">"Subreddit"</string> <string name="notification_summary_award">"Premio"</string> <string name="notification_new_messages">"%1$d Nuovi Messaggi"</string> @@ -296,8 +294,8 @@ Clicca per riprovare."</string> <string name="label_preferences">"Preferenze"</string> <string name="account_switched">"Account cambiato. Tutte le altre pagine non sono più disponibili."</string> <string name="settings_notification_master_title">"Notifiche"</string> - <string name="settings_notification_enable_notification_title">"Abilita Notifiche"</string> - <string name="settings_notification_interval_title">"Controlla Intervallo Notifiche"</string> + <string name="settings_notification_enable_notification_title">"Abilita notifiche"</string> + <string name="settings_notification_interval_title">"Controlla intervallo notifiche"</string> <string name="settings_theme_title">"Tema"</string> <string name="settings_amoled_dark_title">"Amoled (Scuro)"</string> <string name="settings_interface_title">"Interfaccia"</string> @@ -306,9 +304,9 @@ Clicca per riprovare."</string> <string name="settings_save_front_page_scrolled_position_summary">"Sfoglia i nuovi post dopo l'aggiornamento in HOME (pagina iniziale, tipo di ordinamento: migliore)"</string> <string name="settings_open_link_in_app_title">"Apri Link nell'App"</string> <string name="settigns_video_title">"Video"</string> - <string name="settings_video_autoplay_title">"Autoriproduzione Video"</string> - <string name="settings_mute_autoplaying_videos_title">"Muta Video Autoriprodotti"</string> - <string name="settings_autoplay_nsfw_videos_title">"Autoriproduzione Video NSFW"</string> + <string name="settings_video_autoplay_title">"Autoriproduzione video"</string> + <string name="settings_mute_autoplaying_videos_title">"Muta video autoriprodotti"</string> + <string name="settings_autoplay_nsfw_videos_title">"Autoriproduzione video NSFW"</string> <string name="settings_start_autoplay_visible_area_offset_portrait_title">"Offset area visibile video a riproduzione automatica (Verticale)"</string> <string name="settings_start_autoplay_visible_area_offset_portrait_summary">"Inizia autoriproduzione video quando %1$d%% di essi è visibile"</string> <string name="settings_start_autoplay_visible_area_offset_landscape_title">"Offset area visibile video a riproduzione automatica (Orizzontale)"</string> @@ -326,6 +324,8 @@ Clicca per riprovare."</string> <string name="settings_volume_keys_navigate_posts_title">"Usa i Tasti del Volume per Navigare i Post"</string> <string name="settings_mute_video_title">"Muta i video"</string> <string name="settings_mute_nsfw_video_title">"Metti in muto i video NSFW"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"Prova Automaticamente ad Accedere a Redgifs se i Video su Gfycat Vengono Rimossi."</string> <string name="settings_video_player_ignore_nav_bar_title">"Ignora la Barra di Navigazione nel Lettore Video"</string> <string name="settings_video_player_ignore_nav_bar_summary">"Impedisci ai controlli video di avere margine aggiuntivo"</string> @@ -484,7 +484,7 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="copy_all_raw_text">"Copia tutto il testo non formattato"</string> <string name="exit_app">"Uscire?"</string> <string name="light_theme">"Tema chiaro"</string> - <string name="dark_theme">"Tema Scuro"</string> + <string name="dark_theme">"Tema scuro"</string> <string name="multi_reddit_name_hint">"Nome (massimo 50 caratteri)"</string> <string name="multi_reddit_description_hint">"Descrizione"</string> <string name="private_multi_reddit">"Privato"</string> @@ -536,7 +536,7 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="theme_item_sent_message_text_color">"Colore del testo dei messaggi inviati"</string> <string name="theme_item_sent_message_text_color_detail">"Applicato a: Messaggi privati inviati"</string> <string name="theme_item_background_color">"Colore Sfondo"</string> - <string name="theme_item_background_color_detail">"Applicato a: Sfondo di ogni pagina e drawer di navigazione"</string> + <string name="theme_item_background_color_detail">"Applicato a: Sfondo di ogni pagina e drawer navigazione"</string> <string name="theme_item_card_view_background_color">"Colore di sfondo della visualizzazione a schede"</string> <string name="theme_item_card_view_background_color_detail">"Applicato a: Sfondo dei post e dei messaggi"</string> <string name="theme_item_comment_background_color">"Colore di sfondo dei commenti"</string> @@ -552,7 +552,7 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="theme_item_bottom_app_bar_background_color">"Colore barra di navigazione inferiore"</string> <string name="theme_item_bottom_app_bar_background_color_detail">"Applicato a: Barra di navigazione inferiore"</string> <string name="theme_item_primary_icon_color">"Colore Primario Icona"</string> - <string name="theme_item_primary_icon_color_detail">"Si applica a: Icone nel riquadro di navigazione a scomparsa."</string> + <string name="theme_item_primary_icon_color_detail">"Si applica a: Icone nel drawer navigazione."</string> <string name="theme_item_bottom_app_bar_icon_color">"Colore icona barra di navigazione inferiore"</string> <string name="theme_item_bottom_app_bar_icon_color_detail">"Applicato a: Icone nella barra di navigazione inferiore"</string> <string name="theme_item_post_icon_and_info_color">"Colore Icone Post e Info"</string> @@ -679,7 +679,7 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="create_theme_info">"Se vuoi creare un tema basato su un altro tema, clicca il pulsante \"+\" su un tema."</string> <string name="edit_theme_name">"Modifica il nome del tema"</string> <string name="edit_theme">"Modifica tema"</string> - <string name="delete_theme">"Cancella Tema"</string> + <string name="delete_theme">"Cancella tema"</string> <string name="delete_theme_dialog_message">"Vuoi veramente cancellare %1$s?"</string> <string name="share_theme">"Condividi il tema"</string> <string name="change_theme_name">"Cambia Nome"</string> @@ -690,13 +690,13 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="no_data_in_clipboard">"Non sono stato trovato dati copiati nella clipboard"</string> <!-- Fuzzy --> - <string name="import_theme_success">"Importazione del tema riuscita"</string> + <string name="import_theme_success">"Tema importato"</string> <string name="parse_theme_failed">"Analisi del tema non riuscita"</string> <string name="duplicate_theme_name_dialog_title">"È stato trovato un tema duplicato"</string> <string name="duplicate_theme_name_dialog_message">"Un tema nel database è già chiamato %1$s. Vuoi cambiare il nome del tema importato?"</string> <string name="rename">"Rinomina"</string> <string name="override">"Annullare"</string> - <string name="color_picker">"Selettore Colore"</string> + <string name="color_picker">"Selettore colore"</string> <string name="invalid_color">"Colore Non Valido"</string> <string name="delete_all_subreddits_success">"Tutti i subreddit eliminati con successo"</string> <string name="delete_all_users_success">"Tutti gli utenti eliminati con successo"</string> @@ -718,15 +718,16 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="primary_text_preview">"Testo Principale"</string> <string name="secondary_text_preview">"Testo Secondario"</string> <string name="post_title_preview">"Questo è un post"</string> - <string name="post_content_preview">"Questa battuta sulla gravità sta diventando un po' vecchia, ma mi innamoro ogni volta."</string> + + <!-- Fuzzy --> + <string name="post_content_preview">"Ci sono 10 tipi di persone al mondo: quelli che capiscono il codice binario, e quelli che non lo capiscono."</string> <string name="post_type_preview">"POST"</string> <string name="flair_preview">"Flair"</string> <string name="awards_preview">"4 Premi"</string> <string name="author_flair_preview">"Flair dell'autore"</string> <!-- Fuzzy --> - <string name="comment_content_preview">"Ho dato una cartolina alla mia ragazza con scritto \"Rimettiti presto\". -Non è malata o altro, ma potrebbe sicuramente stare meglio."</string> + <string name="comment_content_preview">"Non mi fido molto delle statistiche, perché un uomo con la testa nel forno acceso e i piedi nel congelatore statisticamente ha una temperatura media."</string> <string name="edit_multi_reddit">"Modifica multireddit"</string> <string name="delete_multi_reddit">"Cancella Multireddit"</string> <string name="n_awards">"%1$d premi"</string> @@ -772,7 +773,7 @@ Non è malata o altro, ma potrebbe sicuramente stare meglio."</string> <string name="top_score">"%1$s pts"</string> <string name="login_activity_2fa_prompt">"Se hai attivato l'autenticazione a due fattori, per favore inserisci la password come segue: <password>:<codice per l'autenticazione a due fattori>. Esempio: latuapassword:123456"</string> - <string name="block_user">"Blocca Utente"</string> + <string name="block_user">"Blocca utente"</string> <string name="block_user_success">"Bloccato"</string> <string name="block_user_failed">"Blocco utente fallito"</string> <string name="submit_crosspost_activity_label">"Crosspost"</string> @@ -815,7 +816,7 @@ Le schede possono perdere tutto il contenuto dopo il passaggio ad altre. Questo <string name="settings_swipe_action_threshold">"Soglia"</string> <string name="settings_pull_to_refresh_title">"Trascina per aggiornare"</string> <string name="settings_security_title">"Sicurezza"</string> - <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Richiedi autenticazione per andare nella sezione account nella barra di navigazione"</string> + <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Richiede autenticazione per andare nella sezione account nella barra di navigazione"</string> <!-- Fuzzy --> <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Premere a lungo per nascondere la barra degli strumenti nel layout compatto"</string> @@ -869,7 +870,6 @@ La riproduzione automatica video è disabilitata"</string> Messaggio: %2$s"</string> <string name="give_award_success">"Premio conferito"</string> <string name="give_award_failed">"Fallito"</string> - <string name="recent_searches">"Ricerche recenti"</string> <string name="warning">"Avvertimento"</string> <string name="this_is_a_nsfw_subreddit">"Questo è un subreddit marcato NSFW"</string> <string name="this_user_has_nsfw_content">"Questo utente è marcato NSFW"</string> @@ -993,4 +993,137 @@ La riproduzione automatica video è disabilitata"</string> <string name="have_trouble_login_title">"Problemi di accesso"</string> <string name="have_trouble_login_message">"Vuoi provare un altro metodo di accesso?"</string> <string name="vote">"Vota"</string> + <string name="action_share_link">"Condividi Link"</string> + <string name="action_copy_link">"Copia Link"</string> + <string name="action_add_to_post_filter">"Aggiungi al filtro dei post"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"Non oscurare immagini NSFW nei Subbreddits NSFW"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Mostra l'avatar a sinistra"</string> + <string name="settings_backup_settings_title">"Impostazioni Backup"</string> + <string name="settings_restore_settings_title">"Reimposta le impostazioni"</string> + <string name="settings_credits_love_animation_title">"Animazione amore"</string> + <string name="settings_swipe_between_posts_title">"Scorri tra i post"</string> + + <!-- I don't know how to translate this term, being a technical term I suppose it can be left as is --> + <!-- Fuzzy --> + <string name="settings_navigation_drawer_title">"Drawer Navigazione"</string> + <string name="settings_collapse_account_section_title">"Comprimi sezione Account"</string> + <string name="settings_collapse_post_section_title">"Comprimi sezione Post"</string> + <string name="settings_collapse_preferences_section_title">"Comprimi la sezione Preferenze"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"Comprimi la sezione Subreddit preferiti"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"Comprimi la sezione Subreddit sottoscritti"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Nascondi sezione Subreddit preferiti"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Nascondi la sezione Subreddit a cui sei iscritto"</string> + <string name="settings_default_search_result_tab">"Scheda predefinita dei risultati di ricerca"</string> + <string name="device_default">"Dispositivo predefinito"</string> + <string name="set_by_battery_saver">"Impostato dal risparmio batteria"</string> + <string name="theme_item_upvote_ratio_icon_tint">"Colore icona rapporto voti positivi"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"Applicato a: icona rapporto voti positivi"</string> + <string name="theme_item_current_user_color">"Utente corrente"</string> + <string name="theme_item_current_user_color_detail">"Applicato a: Utente corrente nei commenti"</string> + <string name="exclude_domains_hint">"Escludi domini"</string> + <string name="anonymous_front_page_no_subscriptions">"Inizia unendoti a un subreddit!"</string> + + <!-- Fuzzy --> + <string name="backup_settings_success">"Impostazioni esportate con successo nella directory di destinazione"</string> + <string name="create_zip_in_destination_directory_failed">"Non è stato possibile creare un backup zip nella directory destinazione"</string> + <string name="backup_some_settings_failed">"Impossibile eseguire il backup di alcune impostazioni ma altre sono state esportate correttamente nella directory di destinazione"</string> + <string name="restore_settings_success">"Impostazioni resettate con successo. Riavvia l'app per vedere i cambiamenti"</string> + <string name="restore_settings_partially_failed">"Alcune impostazioni non sono state ripristinate correttamente. Riavvia l'app per vedere i cambiamenti."</string> + <string name="restore_settings_failed_file_corrupted">"Impossibile ripristinare le impostazioni. Potrebbero essere corrotte."</string> + <string name="restore_settings_failed_cannot_get_file">"Impossibile accedere al file"</string> + <string name="suicide_prevention_quote">"Se stai cercando un segnale per non ucciderti, eccolo.\u2764"</string> + <string name="do_not_show_this_again">"Non mostrare di nuovo"</string> + <string name="continue_suicide_prevention_activity">"Continua"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"Errore durante il recupero del video di v.redd.it: impossibile ottenere l'url di reindirizzamento"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"Errore durante il recupero del video di v.redd.it: impossibile ottenere il post"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"Errore durante il recupero del video di v.redd.it: impossibile ottenere l'ID del post"</string> + <string name="always_on">"Sempre acceso"</string> + <string name="only_on_wifi">"Solo su Wifi"</string> + <string name="never">"Mai"</string> + + <!-- Fuzzy --> + <string name="normal">"Normal"</string> + <string name="extra_large">"Extra Grande"</string> + <string name="enormously_large">"Enormemente Grande"</string> + <string name="default_in_array">"Default"</string> + <string name="off">"Off"</string> + <string name="only_on_cellular_data">"Solo su dati mobili"</string> + <string name="upvote">"Voto Positivo"</string> + <string name="downvote">"Voto Negativo"</string> + <string name="select">"Seleziona"</string> + <string name="exclude_subreddit">"Escludi questo subreddit"</string> + <string name="exclude_user">"Escludi questo utente"</string> + <string name="exclude_flair">"Escludi questo flair"</string> + <string name="contain_flair">"Contiene questa flair"</string> + <string name="exclude_domain">"Escludi dominio"</string> + <string name="suggest_title">"Suggerisci titolo"</string> + <string name="suggest_title_failed">"Impossibile suggerire un titolo"</string> + <string name="action_delete_logs">"Cancella i log"</string> + <string name="inbox_with_count">"Posta (%1$d)"</string> + <string name="comment_continue_thread">"Continua thread"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"Scorri verticalmente per tornare indietro dai media"</string> + <string name="settings_hide_post_flair">"Nascondi i flair dei post"</string> + <string name="settings_crash_reports_title">"Rapporti sui crash"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"Pericoloso"</string> + <string name="settings_disable_nsfw_forever_title">"Disabilita permanentemente NSFW"</string> + <string name="settings_show_only_one_comment_level_indicator">"Mastra indicatori di un solo livello di commenti"</string> + <string name="save_comment">"Salva"</string> + <string name="unsave_comment">"Non salvare"</string> + <string name="copy_multi_reddit_path">"Copia il percorso del Multireddit"</string> + <string name="copy_multi_reddit_path_failed">"Impossibile copiare il percorso del Multireddit"</string> + <string name="crash_reports_deleted">"Rapporti sui crash cancellati"</string> + <string name="disable_nsfw_forever_message">"Una volta abilitata l'opzione, i contenuti NSFW saranno permanentemente disabilitati, indipendentemente dal fatto che l'impostazione NSFW sia abilitata o meno. Questa opzione è irreversibile, l'unico modo per riabilitare i contenuti NSFW è cancellare i dati dell'app. + +Vuoi comunque abilitare l'opzione?"</string> + <string name="reply">"Rispondi"</string> + <string name="rpan_activity_label">"RPAN"</string> + <string name="post_gallery_activity_label">"Galleria post"</string> + <string name="trending_activity_label">"Popolari"</string> + <string name="action_share_rpan_link">"Condividi link RPAN"</string> + <string name="action_share_post_link">"Condividi post link"</string> + <string name="rpan">"RPAN"</string> + <string name="trending">"Popolari"</string> + <string name="receive_post_reply_notifications">"Ricevi notifiche per le risposte"</string> + <string name="bottom_sheet_post_gallery">"Galleria"</string> + <string name="posting_gallery">"Galleria dei post"</string> + <string name="label_reddit">"Reddit"</string> + + <!-- Fuzzy --> + <string name="settings_default_link_post_layout">"Link Post Layout Predefinito"</string> + <string name="settings_category_material_you_title">"Personalizzazione automatica"</string> + <string name="settings_enable_material_you_warning_summary">"Per il corretto funzionamento assicurarsi che i tuoi temi non siano chiamati: +\"Materiale you\" +\"Materiale you Dark\" +\"Materiale you Amoled\" +Se hai dei temi con questi nomi devi cambiarli prima di attivare la Personalizzazione automatica"</string> + <string name="settings_enable_material_you_title">"Attiva personalizzazione automatica"</string> + <string name="settings_enable_material_you_summary">"Personalizza Infinity in base al tuo sfondo"</string> + <string name="settings_apply_material_you_title">"Applica personalizzazione"</string> + <string name="settings_apply_material_you_summary">"Nel caso Infinity non abbia cambiato il tema"</string> + <string name="settings_more_tabs_show_favorite_multireddits_title">"Mostra Multireddit preferiti"</string> + <string name="settings_more_tabs_show_multireddits_title">"Mostra Multireddit"</string> + <string name="settings_collapse_reddit_section_title">"Riduci sezione Reddit"</string> + <string name="settings_video_player_automatic_landscape_orientation">"Passa automaticamente all'orientamento orizzontale nel Player Video"</string> + <string name="settings_remember_muting_option_in_post_feed">"Ricorda l'opzione di disattivazione dell'audio nel feed dei post"</string> + <string name="link_post_layout_auto">"Auto"</string> + <string name="uploaded_images">"Immagini caricate"</string> + <string name="select_image">"Seleziona un'immagine"</string> + <string name="capture">"Cattura"</string> + <string name="uploading_image">"Caricamento"</string> + <string name="upload_image_success">"Immagine caricata. Clicca sul pulsante delle immagini per vedere le altre immagini caricate"</string> + <string name="get_image_bitmap_failed">"Impossibile prendere il bitmap dell'immagine"</string> + <string name="upload_image_failed">"Impossibile caricare l'immagine"</string> + <string name="load_rpan_broadcasts_failed">"Impossibile caricare RPAN"</string> + <string name="parse_rpan_broadcasts_failed">"Impossibile analizzare i broadcast RPAN"</string> + <string name="parse_rpan_broadcast_failed">"Impossibile analizzare il broadcast RPAN"</string> + <string name="search_comments">"Cerca tra i commenti"</string> + <string name="please_wait_image_is_uploading">"Attendere prego. Immagine in caricamento"</string> + <string name="error_fetch_trending_search">"Pagina non caricata. Tocca per riprovare"</string> + <string name="error_parse_trending_search">"Pagina non caricata. Tocca per riprovare"</string> + <string name="no_trending_search">"Nessuna ricerca di tendenza trovata. +Premi per riprovare."</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index d30e63d4..e8fcac65 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -252,6 +252,8 @@ <string name="search">"検索"</string> <string name="posting_video">"動画を投稿中"</string> <string name="posting_image">"画像を投稿中"</string> + + <!-- Fuzzy --> <string name="please_wait">"少々お待ちください。"</string> <string name="add_account">"アカウントを追加"</string> <string name="anonymous_account">"匿名"</string> @@ -352,6 +354,8 @@ <string name="settings_volume_keys_navigate_posts_title">"音量ボタンで投稿をナビゲート"</string> <string name="settings_mute_video_title">"動画をミュート再生"</string> <string name="settings_mute_nsfw_video_title">"NSFWの動画をミュート再生"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"Gfycatの動画が削除されていた場合、自動的にRedgifsでリトライ"</string> <string name="settings_video_player_ignore_nav_bar_title">"動画プレーヤーでナビゲーションバーを無視"</string> <string name="settings_video_player_ignore_nav_bar_summary">"動画コントローラーが余分な余白を使用することを防止します"</string> @@ -912,7 +916,6 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd メッセージ: %2$s"</string> <string name="give_award_success">"アワードを贈りました"</string> <string name="give_award_failed">"失敗しました"</string> - <string name="recent_searches">"検索履歴"</string> <string name="warning">"警告"</string> <string name="this_is_a_nsfw_subreddit">"このSubredditはNSFWです"</string> <string name="this_user_has_nsfw_content">"このユーザーはNSFWの投稿を含んでいます"</string> diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index d318aaa5..d97318ee 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -2,7 +2,7 @@ <resources> <color name="colorPrimary">#242424</color> <color name="colorPrimaryDark">#121212</color> - <color name="colorAccent">#FF4081</color> + <color name="colorAccent">#FF1868</color> <color name="transparentActionBarAndExoPlayerControllerColor">#88000000</color> <color name="backgroundColor">#121212</color> <color name="playButtonBackgroundColor">#FFFFFF</color> diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index e423e879..9216310c 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1,860 +1,893 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="login_activity_label">Inloggen</string> - <string name="comment_activity_label">Reactie Sturen</string> - <string name="comment_activity_label_is_replying">Antwoorden</string> - <string name="post_text_activity_label">Tekst Post</string> - <string name="subreddit_selection_activity_label">Subreddit Selecteren</string> - <string name="post_link_activity_label">Link Post</string> - <string name="post_image_activity_label">Afbeelding Post</string> - <string name="post_video_activity_label">Video Post</string> - <string name="rules_activity_label">Regels</string> - <string name="search_subreddits_activity_label">Subreddits</string> - <string name="edit_post_activity_label">Bericht Bewerken</string> - <string name="edit_comment_activity_label">Reactie Bewerken</string> - <string name="view_message_activity_label">Inbox</string> - <string name="settings_activity_label">Instellingen</string> - <string name="account_saved_thing_activity_label">Opgeslagen</string> - <string name="create_multi_reddit_activity_label">Multireddit Maken</string> - <string name="subreddit_multiselection_activity_label">Multireddit Selecteren</string> - <string name="custom_theme_listing_activity_label">Aangepaste Thema\'s</string> - <string name="customize_theme_activity_label">Thema Aanpassen</string> - <string name="customize_theme_activity_create_theme_label">Thema Maken</string> - <string name="theme_preview_activity_label">Thema Bekijken</string> - <string name="edit_multi_reddit_activity_label">Multireddit Bewerken</string> - <string name="selected_subeddits_activity_label">Gekozen Subreddits</string> - <string name="report_activity_label">Melden</string> - <string name="view_imgur_media_activity_image_label">Beeld %1$d/%2$d</string> - <string name="view_imgur_media_activity_video_label">Video %1$d/%2$d</string> - <string name="send_private_message_activity_label">Privébericht Sturen</string> - <string name="view_reddit_gallery_activity_image_label">Beeld %1$d/%2$d</string> - <string name="view_reddit_gallery_activity_gif_label">Gif %1$d/%2$d</string> - <string name="view_reddit_gallery_activity_video_label">Video %1$d/%2$d</string> - <string name="navigation_drawer_open">Navigatielade Openen</string> - <string name="navigation_drawer_close">Navigatielade Sluiten</string> - <string name="action_download">Downloaden</string> - <string name="action_refresh">Vernieuwen</string> - <string name="action_add_comment">Reactie Toevegen</string> - <string name="action_save_post">Post Opslaan</string> - <string name="action_view_crosspost_parent">Bovenliggende Crosspost Bekijken</string> - <string name="action_search">Zoeken</string> - <string name="action_start_lazy_mode">Start Luie Modus</string> - <string name="action_stop_lazy_mode">Stop Luie Modus</string> - <string name="action_send">Sturen</string> - <string name="action_sort">Sorteren</string> - <string name="action_hide_post">Post Verbergen</string> - <string name="action_unhide_post">Post Zichtbaar Maken</string> - <string name="action_edit_post">Post Bewerken</string> - <string name="action_delete_post">Post Verwijderen</string> - <string name="action_mark_nsfw">Markeer NSFW</string> - <string name="action_unmark_nsfw">NSFW markering ongedaan maken</string> - <string name="action_mark_spoiler">Markeer Spoiler</string> - <string name="action_unmark_spoiler">Spoiler markering ongedaan maken</string> - <string name="action_edit_flair">Flair Bewerken</string> - <string name="action_change_post_layout">Post Layout Wijzigen</string> - <string name="action_save">Opslaan</string> - <string name="action_edit_multi_reddit">MultiReddit Bewerken</string> - <string name="action_delete_multi_reddit">Multireddit Verwijderen</string> - <string name="action_share">Delen</string> - <string name="action_preview">Voorbeeld</string> - <string name="action_report">Rapporteren</string> - <string name="action_see_removed">Zie Verwijderd</string> - <string name="action_set_wallpaper">Als Bureaubladachtergrond Instellen</string> - <string name="action_send_private_message">Privebericht Sturen</string> - <string name="action_block_user">Blokkeer Gebruiker</string> - <string name="parse_json_response_error">Er is een fout opgetreden bij het parseren van het JSON-antwoord</string> - <string name="retrieve_token_error">Error bij het ophalen van het token</string> - <string name="something_went_wrong">Er is iets fouts gegaan. Probeer later nogmaals.</string> - <string name="access_denied">Toegang Geweigerd</string> - <string name="parse_user_info_error">Error opgetreden bij het parseren van de gebruikersinfo</string> - <string name="no_system_webview_error">Error by het openen van het Systeem-WebView</string> - <string name="error_loading_image_tap_to_retry">Error bij het laden van de afbeelding.\nTik om opnieuw te proberen.</string> - <string name="load_posts_error">Error bij het laden van berichten.\nTik om opnieuw te proberen.</string> - <string name="load_more_posts_error">Error bij het laden van berichten.</string> - <string name="load_post_error">Error bij het laden van dit bericht.\nTik om opnieuw te proberen.</string> - <string name="search_subreddits_error">Error bij het zoeken van subreddits.\nTik om opnieuw te proberen</string> - <string name="search_users_error">Error bij het zoeken van gebruikers.\nTik om opnieuw te proberen.</string> - <string name="no_posts">Geen Berichten Gevonden</string> - <string name="no_comments">Geen Opmerkingen Gevonden</string> - <string name="no_subreddits">Geen Subreddits Gevonden</string> - <string name="no_users">Geen Gebruikers Gevonden</string> - <string name="no_multi_reddits">Geen Multireddits Gevonden</string> - <string name="no_storage_permission">Geen opslagtoestemming om bestand op te slaan</string> - <string name="load_comments_failed">Error bij het laden van reacties.\nTik om opnieuw te proberen.</string> - <string name="retry">Opnieuw proberen</string> - <string name="comments">Reacties</string> - <string name="no_comments_yet">Nog geen reacties. Reactie opschrijven?</string> - <string name="vote_failed">Stemmen mislukt</string> - <string name="refresh_post_failed">Error bij het vernieuwen van de post.</string> - <string name="load_messages_failed">Error bij het laden van berichten.\nTik om opnieuw te proberen.</string> - <string name="no_messages">Leeg</string> - <string name="nsfw">NSFW</string> - <string name="karma_info">Karma: %1$d</string> - <string name="karma_info_user_detail">Karma:\n%1$d (%2$d + %3$d)</string> - <string name="cakeday_info">Taart dag:\n%1$s</string> - <string name="since">Sinds:</string> - <string name="profile">Profiel</string> - <string name="subscriptions">Abonnementen</string> - <string name="multi_reddit">Multireddit</string> - <string name="inbox">Inbox</string> - <string name="upvoted">Upvoten</string> - <string name="downvoted">Downvoten</string> - <string name="hidden">Verborgen</string> - <string name="saved">Opgeslagen</string> - <string name="gilded">Verguld</string> - <string name="settings">Instellingen</string> - <string name="subscribers_number_detail">Abonnees: %1$d</string> - <string name="online_subscribers_number_detail">Online %1$d</string> - <string name="cannot_fetch_subreddit_info">Kan subreddit-info niet ophalen</string> - <string name="cannot_fetch_user_info">Kan gebruikers-info niet ophalen</string> - <string name="cannot_fetch_sidebar">Kan zijbalk niet ophalen</string> - <string name="cannot_fetch_multireddit">Kan multireddit-info niet ophalen</string> - <string name="subscribe">Abonneren</string> - <string name="unsubscribe">Afmelden</string> - <string name="subscribed">Geabonneerd</string> - <string name="subscribe_failed">Abonneren Mislukt</string> - <string name="unsubscribed">Afgemeld</string> - <string name="unsubscribe_failed">Afmelden Mislukt</string> - <string name="follow">Volgen</string> - <string name="unfollow">Ontvolgen</string> - <string name="followed">Volgend</string> - <string name="follow_failed">Volgen Mislukt</string> - <string name="unfollowed">Ontvolgd</string> - <string name="unfollow_failed">Ontvolgen Mislukt</string> - <string name="content_description_banner_imageview">Subreddit Banner Afbeelding</string> - <string name="app_label">Infinity</string> - <string name="search_hint">Zoek iets</string> - <string name="no_posts_no_lazy_mode">Geen posts beschikbaar</string> - <string name="lazy_mode_start">Luie Modus begint in %1$.1fs</string> - <string name="lazy_mode_stop">Luie Modus Gestopt</string> - <string name="write_comment_hint">Jouw interessante gedachten hier</string> - <string name="comment_content_required">Waar zijn je interessante gedachten?</string> - <string name="sending_comment">Bezig met sturen</string> - <string name="send_comment_success">Opmerking gestuurd</string> - <string name="send_comment_failed">Kan deze opmerking niet verzenden</string> - <string name="send_message_username_hint">Gebruiker</string> - <string name="send_message_subject_hint">Onderwerp</string> - <string name="send_message_content_hint">Bericht Sturen</string> - <string name="reply_message_failed">Dit bericht kan niet worden beantwoord</string> - <string name="error_getting_message">Error bij het ontvangen van dit bericht</string> - <string name="message_username_required">Hey, naar wie wil je dit bericht sturen?</string> - <string name="message_subject_required">Uw bericht moet een onderwerp hebben</string> - <string name="message_content_required">U moet de ontvanger iets vertellen</string> - <string name="sending_message">Bezig met verzenden</string> - <string name="send_message_success">Bericht verzonden</string> - <string name="send_message_failed">Dit bericht kan niet verzonden worden</string> - <string name="select_a_subreddit">Selecteer eerst een subreddit aub</string> - <string name="title_required">De post heeft een goede titel nodig</string> - <string name="link_required">Hey, waar is de link?</string> - <string name="select_an_image">Selecteer eerst een afbeelding</string> - <string name="posting">Posten</string> - <string name="post_failed">Kan het niet posten</string> - <string name="error_processing_image">Error bij het verwerken van de afbeelding</string> - <string name="error_processing_video">Error bij het verwerken van de video</string> - <string name="download_started">Download gestart. Controleer de melding voor voortgang.</string> - <string name="comment_load_more_comments">Meer opmerkingen laden</string> - <string name="comment_load_more_comments_failed">Laden mislukt. Tik om opnieuw te proberen.</string> - <string name="loading">Bezig met laden</string> - <string name="post_title_hint">Titel</string> - <string name="post_text_content_hint">Inhoud</string> - <string name="choose_a_subreddit">Kies een subreddit</string> - <string name="rules">Regels</string> - <string name="post_link_hint">URL</string> - <string name="subreddits">Subreddits</string> - <string name="users">Gebruikers</string> - <string name="multi_reddits">MultiReddits</string> - <string name="bottom_sheet_post_text">Tekst</string> - <string name="bottom_sheet_post_link">Link</string> - <string name="bottom_sheet_post_image">Afbeelding</string> - <string name="bottom_sheet_post_video">Video</string> - <string name="select_from_gallery">Selecteer een foto</string> - <string name="select_again">Selecteer opnieuw</string> - <string name="error_getting_image">Error bij het ophalen van de afbeelding</string> - <string name="error_getting_video">Error bij het ophalen van de video</string> - <string name="no_camera_available">Geen camera-app beschikbaar</string> - <string name="error_creating_temp_file">Error bij het maken van tijdelijk bestand</string> - <string name="video_is_processing">Video wordt verwerkt. Even geduld aub.</string> - <string name="image_is_processing">Afbeelding wordt verwerkt. Even geduld aub.</string> - <string name="gif_is_processing">Gif wordt verwerkt. Even geduld aub.</string> - <string name="flair">Flair</string> - <string name="spoiler">Spoiler</string> - <string name="no_flair">Geen flair</string> - <string name="error_loading_flairs">Error bij het laden van flairs.\nTik om opnieuw te proberen</string> - <string name="no_rule">Geen regel</string> - <string name="error_loading_rules">Error bij het laden van regels.\nTik om opnieuw te proberen.</string> - <string name="error_loading_rules_without_retry">Error bij het laden van regels</string> - <string name="search_in">Zoeken in</string> - <string name="all_subreddits">Alle subreddits</string> - <string name="sort_best">Best</string> - <string name="sort_hot">Hot</string> - <string name="sort_new">Nieuw</string> - <string name="sort_random">Willekeurig</string> - <string name="sort_rising">Opkommend</string> - <string name="sort_top">Top</string> - <string name="sort_controversial">Controversieel</string> - <string name="sort_relevance">Relevantie</string> - <string name="sort_comments">Opmerkingen</string> - <string name="sort_activity">Activiteit</string> - <string name="sort_confidence">Vertrouwen</string> - <string name="sort_old">Oud</string> - <string name="sort_qa">QA</string> - <string name="sort_live">Live</string> - <string name="sort_time_hour">Uur</string> - <string name="sort_time_day">Dag</string> - <string name="sort_time_week">Week</string> - <string name="sort_time_month">Maand</string> - <string name="sort_time_year">Jaar</string> - <string name="sort_time_all_time">Aller Tijden</string> - <string name="no_activity_found_for_share">Er is geen app die de deelactie aankan</string> - <string name="archived_post_vote_unavailable">Gearchiveerd post. Stem niet beschikbaar.</string> - <string name="archived_post_comment_unavailable">Gearchiveerd post. Opmerking niet beschikbaar.</string> - <string name="archived_post_reply_unavailable">Gearchiveerd post. Antwoord niet beschikbaar.</string> - <string name="locked_post_comment_unavailable">Vergrendelde post. Opmerking niet beschikbaar.</string> - <string name="locked_post_reply_unavailable">Vergrendelde post. Antwoord niet beschikbaar.</string> - <string name="text">TEKST</string> - <string name="link">LINK</string> - <string name="image">AFBEELDING</string> - <string name="video">VIDEO</string> - <string name="gif">GIF</string> - <string name="gallery">GALERIJ</string> - <string name="best">Beste</string> - <string name="search">Zoeken</string> - <string name="posting_video">Video is aan het posten</string> - <string name="posting_image">Afbeelding is aan het posten</string> - <string name="please_wait">Even geduld aub.</string> - <string name="add_account">Account toevoegen</string> - <string name="anonymous_account">Anoniem</string> - <string name="log_out">Uitloggen</string> - <string name="press_here_to_login">Klik hier om in te loggen</string> - <string name="login_first">Eerst inloggen</string> - <string name="post_saved_success">Post opgeslagen</string> - <string name="post_saved_failed">Kan post niet opslaan</string> - <string name="post_unsaved_success">Post niet opgeslagen</string> - <string name="post_unsaved_failed">Kan post niet verwijderen</string> - <string name="post_hide_success">Post verborgen</string> - <string name="post_hide_failed">Kan post niet verbergen</string> - <string name="post_unhide_success">Post zichtbaar</string> - <string name="thing_favorite_failed">Favoriet maken mislukt</string> - <string name="thing_unfavorite_failed">Het verwijderen van favoriet is mislukt</string> - <string name="post_unhide_failed">Kan post niet zichtbaar maken</string> - <string name="delete_this_post">Verwijder Deze Post</string> - <string name="delete_this_comment">Verwijder Deze Opmerking</string> - <string name="are_you_sure">Ben je zeker?</string> - <string name="edit">Bewerken</string> - <string name="delete">Verwijderen</string> - <string name="see_removed_comment">Zie verwijderde opmerking</string> - <string name="fetching_removed_comment">Verwijderde opmerking ophalen</string> - <string name="show_removed_comment_failed">Kan de verwijderde opmerking niet vinden</string> - <string name="fetching_removed_post">Verwijderde post ophalen</string> - <string name="show_removed_post_failed">Kan de verwijderde post niet vinden</string> - <string name="cancel">Annuleren</string> - <string name="ok">OK</string> - <string name="edit_success">Bewerken succesvol</string> - <string name="delete_post_success">Verwijderen succesvol</string> - <string name="delete_post_failed">Verwijderen mislukt</string> - <string name="mark_nsfw_success">NSFW markeren succesvol</string> - <string name="mark_nsfw_failed">NSFW markeren mislukt</string> - <string name="unmark_nsfw_success">NSFW Markering ongedaan maken succesvol</string> - <string name="unmark_nsfw_failed">NSFW markering ongedaan maken mislukt</string> - <string name="mark_spoiler_success">Spoiler markeren succesvol</string> - <string name="mark_spoiler_failed">Spoiler markeren mislukt</string> - <string name="unmark_spoiler_success">Spoiler markering ongedaan maken succesvol</string> - <string name="unmark_spoiler_failed">Spoiler markering ongedaan maken mislukt</string> - <string name="update_flair_success">Flair update succesvol</string> - <string name="update_flair_failed">Flair update mislukt</string> - <string name="edit_flair">Flair Bewerken</string> - <string name="only_allow_64_chars">Alleen minder dan 64 tekens toegestaan</string> - <string name="view_all_comments">Klik hier om door alle opmerkingen te bladeren</string> - <string name="notification_summary_account">Account</string> - <string name="notification_summary_message">Nieuw Bericht</string> - <string name="notification_summary_subreddit">Subreddit</string> - <string name="notification_summary_award">Prijs</string> - <string name="notification_new_messages">%1$d Nieuwe Berichten</string> - <string name="label_account">Account</string> - <string name="label_post">Post</string> - <string name="label_preferences">Voorkeuren</string> - <string name="account_switched">Account omgeschakeld. Dus alle andere pagina\'s zijn verdwenen.</string> - <string name="settings_notification_master_title">Melding</string> - <string name="settings_notification_enable_notification_title">Meldingen Aanzetten</string> - <string name="settings_notification_interval_title">Controleer Meldingsinterval</string> - <string name="settings_theme_title">Thema</string> - <string name="settings_amoled_dark_title">Amoled Donker</string> - <string name="settings_interface_title">Interface</string> - <string name="settings_gestures_and_buttons_title">Gebaren & Knoppen</string> - <string name="settings_save_front_page_scrolled_position_title">Bewaar de schuifpositie in HOME</string> - <string name="settings_save_front_page_scrolled_position_summary">Blader door nieuwe posts na het vernieuwen in HOME (voorpagina, sorteertype: Beste)</string> - <string name="settings_open_link_in_app_title">Open Link In App</string> - <string name="settigns_video_title">Video</string> - <string name="settings_video_autoplay_title">Video Automatisch Afspelen</string> - <string name="settings_mute_autoplaying_videos_title">Demp Automatisch Afspelende Video\'s</string> - <string name="settings_autoplay_nsfw_videos_title">NSFW Videos Automatisch Afspelen</string> - <string name="settings_start_autoplay_visible_area_offset_portrait_title">Automatische Afspelende Video\'s Zichtbaar Gebied (Staand)</string> - <string name="settings_start_autoplay_visible_area_offset_portrait_summary">Begin automatisch afspelende video\'s wanneer %1$d%% daarvan zichtbaar is</string> - <string name="settings_start_autoplay_visible_area_offset_landscape_title">Automatische Afspelende Video\'s Zichtbaar Gebied (Liggend)</string> - <string name="settings_start_autoplay_visible_area_offset_landscape_summary">Begin automatisch afspelende video\'s wanneer %1$d%% daarvan zichtbaar is</string> - <string name="settings_immersive_interface_title">Meeslepende Interface</string> - <string name="settings_immersive_interface_summary">Is Niet van Toepassing op Alle Pagina\'s</string> - <string name="settings_immersive_interface_ignore_nav_bar_title">Negeer Navigatiebalk in Meeslepende Interface</string> - <string name="settings_immersive_interface_ignore_nav_bar_summary">Voorkom dat de Onderste Navigatiebalk Extra Opvulling Heeft</string> - <string name="settings_customize_tabs_in_main_page_title">Pas Tabbladen op de Hoofdpagina aan</string> - <string name="settings_enable_bottom_app_bar_title">Onderste Navigatiebalk Inschakelen</string> - <string name="settings_enable_bottom_app_bar_summary">Heeft Geen Effect in de Anonieme Modus</string> - <string name="settings_category_post_and_comment_title">Post en Reageer</string> - <string name="settings_vote_buttons_on_the_right_title">Stemknoppen aan de Rechterkant</string> - <string name="settings_volume_keys_navigate_comments_title">Gebruik Volumetoetsen om door Opmerkingen in Posts te Navigeren</string> - <string name="settings_volume_keys_navigate_posts_title">Gebruik Volumetoetsen om door Posts te Navigeren</string> - <string name="settings_mute_video_title">Video\'s Dempen</string> - <string name="settings_mute_nsfw_video_title">NSFW Video\'s Dempen</string> - <string name="settings_automatically_try_redgifs_title">Probeer Automatisch Redgifs te Openen als Video\'s op Gfycat zijn Verwijderd.</string> - <string name="settings_video_player_ignore_nav_bar_title">Negeer de Navigatiebalk in de Videospeler</string> - <string name="settings_video_player_ignore_nav_bar_summary">Voorkom dat de Videocontroller een Extra Marge Heeft</string> - <string name="settings_confirm_to_exit">Bevestig om af te sluiten</string> - <string name="settings_category_comment_title">Opmerking</string> - <string name="settings_show_top_level_comments_first_title">Toon Top-niveau Opmerkingen Eerst</string> - <string name="settings_show_comment_divider_title">Toon Commentaarverdeler</string> - <string name="settings_comment_toolbar_hide_on_click">Klik om de Werkbalk Opmerkingen te Tonen / Verbergen</string> - <string name="settings_fully_collapse_comment_title">Opmerking Volledig Instorten</string> - <string name="settings_comment_toolbar_hidden">De Werkbalk Opmerkingen is Standaard Verborgen</string> - <string name="settings_show_absolute_number_of_votes_title">Toon Absoluut Aantal Stemmen</string> - <string name="settings_show_elapsed_time">Verstreken Tijd Weergeven in Posts en Opmerkingen</string> - <string name="settings_time_format_title">Tijd Formaat</string> - <string name="settings_category_post_title">Post</string> - <string name="settings_default_post_layout">Standaard Post Layout</string> + <string name="login_activity_label">"Inloggen"</string> + <string name="comment_activity_label">"Reactie Sturen"</string> + <string name="comment_activity_label_is_replying">"Antwoorden"</string> + <string name="post_text_activity_label">"Tekst Post"</string> + <string name="subreddit_selection_activity_label">"Subreddit Selecteren"</string> + <string name="post_link_activity_label">"Link Post"</string> + <string name="post_image_activity_label">"Afbeelding Post"</string> + <string name="post_video_activity_label">"Video Post"</string> + <string name="rules_activity_label">"Regels"</string> + <string name="search_subreddits_activity_label">"Subreddits"</string> + <string name="edit_post_activity_label">"Bericht Bewerken"</string> + <string name="edit_comment_activity_label">"Reactie Bewerken"</string> + <string name="view_message_activity_label">"Inbox"</string> + <string name="settings_activity_label">"Instellingen"</string> + <string name="account_saved_thing_activity_label">"Opgeslagen"</string> + <string name="create_multi_reddit_activity_label">"Multireddit Maken"</string> + <string name="subreddit_multiselection_activity_label">"Multireddit Selecteren"</string> + <string name="custom_theme_listing_activity_label">"Aangepaste Thema's"</string> + <string name="customize_theme_activity_label">"Thema Aanpassen"</string> + <string name="customize_theme_activity_create_theme_label">"Thema Maken"</string> + <string name="theme_preview_activity_label">"Thema Bekijken"</string> + <string name="edit_multi_reddit_activity_label">"Multireddit Bewerken"</string> + <string name="selected_subeddits_activity_label">"Gekozen Subreddits"</string> + <string name="report_activity_label">"Melden"</string> + <string name="view_imgur_media_activity_image_label">"Beeld %1$d/%2$d"</string> + <string name="view_imgur_media_activity_video_label">"Video %1$d/%2$d"</string> + <string name="send_private_message_activity_label">"Privébericht Sturen"</string> + <string name="view_reddit_gallery_activity_image_label">"Beeld %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_gif_label">"Gif %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_video_label">"Video %1$d/%2$d"</string> + <string name="navigation_drawer_open">"Navigatielade Openen"</string> + <string name="navigation_drawer_close">"Navigatielade Sluiten"</string> + <string name="action_download">"Downloaden"</string> + <string name="action_refresh">"Vernieuwen"</string> + <string name="action_add_comment">"Reactie Toevegen"</string> + <string name="action_save_post">"Post Opslaan"</string> + <string name="action_view_crosspost_parent">"Bovenliggende Crosspost Bekijken"</string> + <string name="action_search">"Zoeken"</string> + <string name="action_start_lazy_mode">"Start Luie Modus"</string> + <string name="action_stop_lazy_mode">"Stop Luie Modus"</string> + <string name="action_send">"Sturen"</string> + <string name="action_sort">"Sorteren"</string> + <string name="action_hide_post">"Post Verbergen"</string> + <string name="action_unhide_post">"Post Zichtbaar Maken"</string> + <string name="action_edit_post">"Post Bewerken"</string> + <string name="action_delete_post">"Post Verwijderen"</string> + <string name="action_mark_nsfw">"Markeer NSFW"</string> + <string name="action_unmark_nsfw">"NSFW markering ongedaan maken"</string> + <string name="action_mark_spoiler">"Markeer Spoiler"</string> + <string name="action_unmark_spoiler">"Spoiler markering ongedaan maken"</string> + <string name="action_edit_flair">"Flair Bewerken"</string> + <string name="action_change_post_layout">"Post Layout Wijzigen"</string> + <string name="action_save">"Opslaan"</string> + <string name="action_edit_multi_reddit">"MultiReddit Bewerken"</string> + <string name="action_delete_multi_reddit">"Multireddit Verwijderen"</string> + <string name="action_share">"Delen"</string> + <string name="action_preview">"Voorbeeld"</string> + <string name="action_report">"Rapporteren"</string> + <string name="action_see_removed">"Zie Verwijderd"</string> + <string name="action_set_wallpaper">"Als Bureaubladachtergrond Instellen"</string> + <string name="action_send_private_message">"Privebericht Sturen"</string> + <string name="action_block_user">"Blokkeer Gebruiker"</string> + <string name="parse_json_response_error">"Er is een fout opgetreden bij het parseren van het JSON-antwoord"</string> + <string name="retrieve_token_error">"Error bij het ophalen van het token"</string> + <string name="something_went_wrong">"Er is iets fouts gegaan. Probeer later nogmaals."</string> + <string name="access_denied">"Toegang Geweigerd"</string> + <string name="parse_user_info_error">"Error opgetreden bij het parseren van de gebruikersinfo"</string> + <string name="no_system_webview_error">"Error by het openen van het Systeem-WebView"</string> + <string name="error_loading_image_tap_to_retry">"Error bij het laden van de afbeelding. +Tik om opnieuw te proberen."</string> + <string name="load_posts_error">"Error bij het laden van berichten. +Tik om opnieuw te proberen."</string> + <string name="load_more_posts_error">"Error bij het laden van berichten."</string> + <string name="load_post_error">"Error bij het laden van dit bericht. +Tik om opnieuw te proberen."</string> + <string name="search_subreddits_error">"Error bij het zoeken van subreddits. +Tik om opnieuw te proberen"</string> + <string name="search_users_error">"Error bij het zoeken van gebruikers. +Tik om opnieuw te proberen."</string> + <string name="no_posts">"Geen Berichten Gevonden"</string> + <string name="no_comments">"Geen Opmerkingen Gevonden"</string> + <string name="no_subreddits">"Geen Subreddits Gevonden"</string> + <string name="no_users">"Geen Gebruikers Gevonden"</string> + <string name="no_multi_reddits">"Geen Multireddits Gevonden"</string> + <string name="no_storage_permission">"Geen opslagtoestemming om bestand op te slaan"</string> + <string name="load_comments_failed">"Error bij het laden van reacties. +Tik om opnieuw te proberen."</string> + <string name="retry">"Opnieuw proberen"</string> + <string name="comments">"Reacties"</string> + <string name="no_comments_yet">"Nog geen reacties. Reactie opschrijven?"</string> + <string name="vote_failed">"Stemmen mislukt"</string> + <string name="refresh_post_failed">"Error bij het vernieuwen van de post."</string> + <string name="load_messages_failed">"Error bij het laden van berichten. +Tik om opnieuw te proberen."</string> + <string name="no_messages">"Leeg"</string> + <string name="nsfw">"NSFW"</string> + <string name="karma_info">"Karma: %1$d"</string> + <string name="karma_info_user_detail">"Karma: +%1$d (%2$d + %3$d)"</string> + <string name="cakeday_info">"Taart dag: +%1$s"</string> + <string name="since">"Sinds:"</string> + <string name="profile">"Profiel"</string> + <string name="subscriptions">"Abonnementen"</string> + <string name="multi_reddit">"Multireddit"</string> + <string name="inbox">"Inbox"</string> + <string name="upvoted">"Upvoten"</string> + <string name="downvoted">"Downvoten"</string> + <string name="hidden">"Verborgen"</string> + <string name="saved">"Opgeslagen"</string> + <string name="gilded">"Verguld"</string> + <string name="settings">"Instellingen"</string> + <string name="subscribers_number_detail">"Abonnees: %1$d"</string> + <string name="online_subscribers_number_detail">"Online %1$d"</string> + <string name="cannot_fetch_subreddit_info">"Kan subreddit-info niet ophalen"</string> + <string name="cannot_fetch_user_info">"Kan gebruikers-info niet ophalen"</string> + <string name="cannot_fetch_sidebar">"Kan zijbalk niet ophalen"</string> + <string name="cannot_fetch_multireddit">"Kan multireddit-info niet ophalen"</string> + <string name="subscribe">"Abonneren"</string> + <string name="unsubscribe">"Afmelden"</string> + <string name="subscribed">"Geabonneerd"</string> + <string name="subscribe_failed">"Abonneren Mislukt"</string> + <string name="unsubscribed">"Afgemeld"</string> + <string name="unsubscribe_failed">"Afmelden Mislukt"</string> + <string name="follow">"Volgen"</string> + <string name="unfollow">"Ontvolgen"</string> + <string name="followed">"Volgend"</string> + <string name="follow_failed">"Volgen Mislukt"</string> + <string name="unfollowed">"Ontvolgd"</string> + <string name="unfollow_failed">"Ontvolgen Mislukt"</string> + <string name="content_description_banner_imageview">"Subreddit Banner Afbeelding"</string> + <string name="app_label">"Infinity"</string> + <string name="search_hint">"Zoek iets"</string> + <string name="no_posts_no_lazy_mode">"Geen posts beschikbaar"</string> + <string name="lazy_mode_start">"Luie Modus begint in %1$.1fs"</string> + <string name="lazy_mode_stop">"Luie Modus Gestopt"</string> + <string name="write_comment_hint">"Jouw interessante gedachten hier"</string> + <string name="comment_content_required">"Waar zijn je interessante gedachten?"</string> + <string name="sending_comment">"Bezig met sturen"</string> + <string name="send_comment_success">"Opmerking gestuurd"</string> + <string name="send_comment_failed">"Kan deze opmerking niet verzenden"</string> + <string name="send_message_username_hint">"Gebruiker"</string> + <string name="send_message_subject_hint">"Onderwerp"</string> + <string name="send_message_content_hint">"Bericht Sturen"</string> + <string name="reply_message_failed">"Dit bericht kan niet worden beantwoord"</string> + <string name="error_getting_message">"Error bij het ontvangen van dit bericht"</string> + <string name="message_username_required">"Hey, naar wie wil je dit bericht sturen?"</string> + <string name="message_subject_required">"Uw bericht moet een onderwerp hebben"</string> + <string name="message_content_required">"U moet de ontvanger iets vertellen"</string> + <string name="sending_message">"Bezig met verzenden"</string> + <string name="send_message_success">"Bericht verzonden"</string> + <string name="send_message_failed">"Dit bericht kan niet verzonden worden"</string> + <string name="select_a_subreddit">"Selecteer eerst een subreddit aub"</string> + <string name="title_required">"De post heeft een goede titel nodig"</string> + <string name="link_required">"Hey, waar is de link?"</string> + <string name="select_an_image">"Selecteer eerst een afbeelding"</string> + <string name="posting">"Posten"</string> + <string name="post_failed">"Kan het niet posten"</string> + <string name="error_processing_image">"Error bij het verwerken van de afbeelding"</string> + <string name="error_processing_video">"Error bij het verwerken van de video"</string> + <string name="download_started">"Download gestart. Controleer de melding voor voortgang."</string> + <string name="comment_load_more_comments">"Meer opmerkingen laden"</string> + <string name="comment_load_more_comments_failed">"Laden mislukt. Tik om opnieuw te proberen."</string> + <string name="loading">"Bezig met laden"</string> + <string name="post_title_hint">"Titel"</string> + <string name="post_text_content_hint">"Inhoud"</string> + <string name="choose_a_subreddit">"Kies een subreddit"</string> + <string name="rules">"Regels"</string> + <string name="post_link_hint">"URL"</string> + <string name="subreddits">"Subreddits"</string> + <string name="users">"Gebruikers"</string> + <string name="multi_reddits">"MultiReddits"</string> + <string name="bottom_sheet_post_text">"Tekst"</string> + <string name="bottom_sheet_post_link">"Link"</string> + <string name="bottom_sheet_post_image">"Afbeelding"</string> + <string name="bottom_sheet_post_video">"Video"</string> + <string name="select_from_gallery">"Selecteer een foto"</string> + <string name="select_again">"Selecteer opnieuw"</string> + <string name="error_getting_image">"Error bij het ophalen van de afbeelding"</string> + <string name="error_getting_video">"Error bij het ophalen van de video"</string> + <string name="no_camera_available">"Geen camera-app beschikbaar"</string> + <string name="error_creating_temp_file">"Error bij het maken van tijdelijk bestand"</string> + <string name="video_is_processing">"Video wordt verwerkt. Even geduld aub."</string> + <string name="image_is_processing">"Afbeelding wordt verwerkt. Even geduld aub."</string> + <string name="gif_is_processing">"Gif wordt verwerkt. Even geduld aub."</string> + <string name="flair">"Flair"</string> + <string name="spoiler">"Spoiler"</string> + <string name="no_flair">"Geen flair"</string> + <string name="error_loading_flairs">"Error bij het laden van flairs. +Tik om opnieuw te proberen"</string> + <string name="no_rule">"Geen regel"</string> + <string name="error_loading_rules">"Error bij het laden van regels. +Tik om opnieuw te proberen."</string> + <string name="error_loading_rules_without_retry">"Error bij het laden van regels"</string> + <string name="search_in">"Zoeken in"</string> + <string name="all_subreddits">"Alle subreddits"</string> + <string name="sort_best">"Best"</string> + <string name="sort_hot">"Hot"</string> + <string name="sort_new">"Nieuw"</string> + <string name="sort_random">"Willekeurig"</string> + <string name="sort_rising">"Opkommend"</string> + <string name="sort_top">"Top"</string> + <string name="sort_controversial">"Controversieel"</string> + <string name="sort_relevance">"Relevantie"</string> + <string name="sort_comments">"Opmerkingen"</string> + <string name="sort_activity">"Activiteit"</string> + <string name="sort_confidence">"Vertrouwen"</string> + <string name="sort_old">"Oud"</string> + <string name="sort_qa">"QA"</string> + <string name="sort_live">"Live"</string> + <string name="sort_time_hour">"Uur"</string> + <string name="sort_time_day">"Dag"</string> + <string name="sort_time_week">"Week"</string> + <string name="sort_time_month">"Maand"</string> + <string name="sort_time_year">"Jaar"</string> + <string name="sort_time_all_time">"Aller Tijden"</string> + <string name="no_activity_found_for_share">"Er is geen app die de deelactie aankan"</string> + <string name="archived_post_vote_unavailable">"Gearchiveerd post. Stem niet beschikbaar."</string> + <string name="archived_post_comment_unavailable">"Gearchiveerd post. Opmerking niet beschikbaar."</string> + <string name="archived_post_reply_unavailable">"Gearchiveerd post. Antwoord niet beschikbaar."</string> + <string name="locked_post_comment_unavailable">"Vergrendelde post. Opmerking niet beschikbaar."</string> + <string name="locked_post_reply_unavailable">"Vergrendelde post. Antwoord niet beschikbaar."</string> + <string name="text">"TEKST"</string> + <string name="link">"LINK"</string> + <string name="image">"AFBEELDING"</string> + <string name="video">"VIDEO"</string> + <string name="gif">"GIF"</string> + <string name="gallery">"GALERIJ"</string> + <string name="best">"Beste"</string> + <string name="search">"Zoeken"</string> + <string name="posting_video">"Video is aan het posten"</string> + <string name="posting_image">"Afbeelding is aan het posten"</string> <!-- Fuzzy --> - <string name="settings_show_divider_in_compact_layout">Toon Verdeler in Compact Layout</string> + <string name="please_wait">"Even geduld aub."</string> + <string name="add_account">"Account toevoegen"</string> + <string name="anonymous_account">"Anoniem"</string> + <string name="log_out">"Uitloggen"</string> + <string name="press_here_to_login">"Klik hier om in te loggen"</string> + <string name="login_first">"Eerst inloggen"</string> + <string name="post_saved_success">"Post opgeslagen"</string> + <string name="post_saved_failed">"Kan post niet opslaan"</string> + <string name="post_unsaved_success">"Post niet opgeslagen"</string> + <string name="post_unsaved_failed">"Kan post niet verwijderen"</string> + <string name="post_hide_success">"Post verborgen"</string> + <string name="post_hide_failed">"Kan post niet verbergen"</string> + <string name="post_unhide_success">"Post zichtbaar"</string> + <string name="thing_favorite_failed">"Favoriet maken mislukt"</string> + <string name="thing_unfavorite_failed">"Het verwijderen van favoriet is mislukt"</string> + <string name="post_unhide_failed">"Kan post niet zichtbaar maken"</string> + <string name="delete_this_post">"Verwijder Deze Post"</string> + <string name="delete_this_comment">"Verwijder Deze Opmerking"</string> + <string name="are_you_sure">"Ben je zeker?"</string> + <string name="edit">"Bewerken"</string> + <string name="delete">"Verwijderen"</string> + <string name="see_removed_comment">"Zie verwijderde opmerking"</string> + <string name="fetching_removed_comment">"Verwijderde opmerking ophalen"</string> + <string name="show_removed_comment_failed">"Kan de verwijderde opmerking niet vinden"</string> + <string name="fetching_removed_post">"Verwijderde post ophalen"</string> + <string name="show_removed_post_failed">"Kan de verwijderde post niet vinden"</string> + <string name="cancel">"Annuleren"</string> + <string name="ok">"OK"</string> + <string name="edit_success">"Bewerken succesvol"</string> + <string name="delete_post_success">"Verwijderen succesvol"</string> + <string name="delete_post_failed">"Verwijderen mislukt"</string> + <string name="mark_nsfw_success">"NSFW markeren succesvol"</string> + <string name="mark_nsfw_failed">"NSFW markeren mislukt"</string> + <string name="unmark_nsfw_success">"NSFW Markering ongedaan maken succesvol"</string> + <string name="unmark_nsfw_failed">"NSFW markering ongedaan maken mislukt"</string> + <string name="mark_spoiler_success">"Spoiler markeren succesvol"</string> + <string name="mark_spoiler_failed">"Spoiler markeren mislukt"</string> + <string name="unmark_spoiler_success">"Spoiler markering ongedaan maken succesvol"</string> + <string name="unmark_spoiler_failed">"Spoiler markering ongedaan maken mislukt"</string> + <string name="update_flair_success">"Flair update succesvol"</string> + <string name="update_flair_failed">"Flair update mislukt"</string> + <string name="edit_flair">"Flair Bewerken"</string> + <string name="only_allow_64_chars">"Alleen minder dan 64 tekens toegestaan"</string> + <string name="view_all_comments">"Klik hier om door alle opmerkingen te bladeren"</string> + <string name="notification_summary_account">"Account"</string> + <string name="notification_summary_message">"Nieuw Bericht"</string> + <string name="notification_summary_subreddit">"Subreddit"</string> + <string name="notification_summary_award">"Prijs"</string> + <string name="notification_new_messages">"%1$d Nieuwe Berichten"</string> + <string name="label_account">"Account"</string> + <string name="label_post">"Post"</string> + <string name="label_preferences">"Voorkeuren"</string> + <string name="account_switched">"Account omgeschakeld. Dus alle andere pagina's zijn verdwenen."</string> + <string name="settings_notification_master_title">"Melding"</string> + <string name="settings_notification_enable_notification_title">"Meldingen Aanzetten"</string> + <string name="settings_notification_interval_title">"Controleer Meldingsinterval"</string> + <string name="settings_theme_title">"Thema"</string> + <string name="settings_amoled_dark_title">"Amoled Donker"</string> + <string name="settings_interface_title">"Interface"</string> + <string name="settings_gestures_and_buttons_title">"Gebaren & Knoppen"</string> + <string name="settings_save_front_page_scrolled_position_title">"Bewaar de scrollpositie in HOME"</string> + <string name="settings_save_front_page_scrolled_position_summary">"Blader door nieuwe posts na het vernieuwen in HOME (voorpagina, sorteertype: Beste)"</string> + <string name="settings_open_link_in_app_title">"Open Link In App"</string> + <string name="settigns_video_title">"Video"</string> + <string name="settings_video_autoplay_title">"Video Automatisch Afspelen"</string> + <string name="settings_mute_autoplaying_videos_title">"Demp Automatisch Afspelende Video's"</string> + <string name="settings_autoplay_nsfw_videos_title">"NSFW Videos Automatisch Afspelen"</string> + <string name="settings_start_autoplay_visible_area_offset_portrait_title">"Automatische Afspelende Video's Zichtbaar Gebied (Staand)"</string> + <string name="settings_start_autoplay_visible_area_offset_portrait_summary">"Begin automatisch afspelende video's wanneer %1$d%% daarvan zichtbaar is"</string> + <string name="settings_start_autoplay_visible_area_offset_landscape_title">"Automatische Afspelende Video's Zichtbaar Gebied (Liggend)"</string> + <string name="settings_start_autoplay_visible_area_offset_landscape_summary">"Begin automatisch afspelende video's wanneer %1$d%% daarvan zichtbaar is"</string> + <string name="settings_immersive_interface_title">"Meeslepende Interface"</string> + <string name="settings_immersive_interface_summary">"Is Niet van Toepassing op Alle Pagina's"</string> + <string name="settings_immersive_interface_ignore_nav_bar_title">"Negeer Navigatiebalk in Meeslepende Interface"</string> + <string name="settings_immersive_interface_ignore_nav_bar_summary">"Voorkom dat de Onderste Navigatiebalk Extra Opvulling Heeft"</string> + <string name="settings_customize_tabs_in_main_page_title">"Pas Tabbladen op de Hoofdpagina aan"</string> + <string name="settings_enable_bottom_app_bar_title">"Onderste Navigatiebalk Inschakelen"</string> + <string name="settings_enable_bottom_app_bar_summary">"Heeft Geen Effect in de Anonieme Modus"</string> + <string name="settings_category_post_and_comment_title">"Post en Reageer"</string> + <string name="settings_vote_buttons_on_the_right_title">"Stemknoppen aan de Rechterkant"</string> + <string name="settings_volume_keys_navigate_comments_title">"Gebruik Volumetoetsen om door Opmerkingen in Posts te Navigeren"</string> + <string name="settings_volume_keys_navigate_posts_title">"Gebruik Volumetoetsen om door Posts te Navigeren"</string> + <string name="settings_mute_video_title">"Video's Dempen"</string> + <string name="settings_mute_nsfw_video_title">"NSFW Video's Dempen"</string> <!-- Fuzzy --> - <string name="settings_show_thumbnail_on_the_left_in_compact_layout">Thumbnail aan de Linkerkant Weergeven in Compacte Layout</string> - <string name="settings_swap_tap_and_long_title">Wissel Tikken en Lang Indrukken in Opmerkingen</string> - <string name="settings_swipe_to_go_back_title">Veeg naar Rechts om Terug te Gaan</string> - <string name="settings_swipe_to_go_back_summary">Is Niet van Toepassing op Alle Pagina\'s</string> - <string name="settings_lock_jump_to_next_top_level_comment_button_title">Ga naar de Volgende Top-niveau Opmerking Knop Vergrendelen</string> - <string name="settings_lock_bottom_app_bar_title">Vergrendel de Onderste Navigatiebalk</string> - <string name="settings_swipe_up_to_hide_jump_to_next_top_level_comment_button_title">Veeg Omhoog om Ga naar de Volgende Top-Niveau Knop te Verbergen</string> - <string name="settings_lazy_mode_interval_title">Luie Modus Interval</string> - <string name="settings_font_title">Lettertype</string> - <string name="settings_preview_font_title">Lettertype Voorbeeld</string> - <string name="settings_font_summary">Lettertype</string> - <string name="settings_title_font_summary">Titel</string> - <string name="settings_content_font_summary">Inhoud</string> - <string name="settings_font_family_title">Lettertypefamilie</string> - <string name="settings_title_font_family_title">Titel Lettertypefamilie</string> - <string name="settings_content_font_family_title">Inhoud Lettertypefamilie</string> - <string name="settings_font_size_title">Lettergrootte</string> - <string name="settings_title_font_size_title">Titel Lettergrootte</string> - <string name="settings_content_font_size_title">Ingoud Lettergrootte</string> - <string name="settings_enable_nsfw_title">NSFW Inschakelen</string> - <string name="settings_blur_nsfw_title">NSFW-afbeeldingen Vervagen</string> - <string name="settings_blur_spoiler_title">Spoiler-afbeeldingen Vervagen</string> - <string name="settings_about_master_title">Over</string> - <string name="settings_acknowledgement_master_title">Erkenning</string> - <string name="settings_credits_master_title">Credits</string> - <string name="settings_credits_icon_foreground_title">Pictogram Voorgrond</string> - <string name="settings_credits_icon_foreground_summary">Technologie vector gemaakt door freepik - www.freepik.com</string> - <string name="settings_credits_icon_background_title">Pictogram Achtergrond</string> - <string name="settings_credits_icon_background_summary">Achtergrondvector gemaakt door freepik - www.freepik.com</string> - <string name="settings_credits_error_image_title">Error Afbeelding</string> - <string name="settings_credits_error_image_summary">Technologie vector gemaakt door freepik - www.freepik.com</string> - <string name="settings_credits_gilded_icon_title">Verguld Pictogram</string> - <string name="settings_credits_gilded_icon_summary">Pictogram gemaakt door Freepik van www.flaticon.com</string> - <string name="settings_credits_crosspost_icon_title">Crosspost Pictogram</string> - <string name="settings_credits_crosspost_icon_summary">Pictogram gemaakt door Freepik van www.flaticon.com</string> - <string name="settings_credits_thumbtack_icon_title">Thumbtack Pictogram</string> - <string name="settings_credits_thumbtack_icon_summary">Pictogram gemaakt door Freepik van www.flaticon.com</string> - <string name="settings_credits_best_rocket_icon_title">Raket Picotgram</string> - <string name="settings_credits_best_rocket_icon_summary">Pictogram gemaakt door Freepik van www.flaticon.com</string> - <string name="settings_credits_material_icons_title">Material Pictogrammen</string> - <string name="settings_open_source_title">Open Source</string> - <string name="settings_open_source_summary">Geef het een ster op Github als je deze app leuk vindt</string> - <string name="settings_rate_title">Beoordeel op Google Play</string> - <string name="settings_rate_summary">Geef me een 5-sterrenbeoordeling en ik zal heel blij zijn</string> - <string name="settings_email_title">Email</string> - <string name="settings_email_summary">docilealligator.app@gmail.com</string> - <string name="settings_reddit_account_title">Reddit Account</string> - <string name="settings_reddit_account_summary">u/Hostilenemy</string> - <string name="settings_subreddit_title">Subreddit</string> - <string name="settings_subreddit_summary">r/Infinity_For_Reddit</string> - <string name="settings_share_title">Delen</string> - <string name="settings_share_summary">Deel deze app met andere mensen als je ervan geniet</string> - <string name="settings_version_title">Infinity For Reddit</string> - <string name="settings_version_summary">Versie %s</string> - <string name="settings_category_customization_title">Aanpassingen</string> - <string name="settings_customize_light_theme_title">Licht Thema</string> - <string name="settings_customize_dark_theme_title">Donker Thema</string> - <string name="settings_customize_amoled_theme_title">Amoled Thema</string> - <string name="settings_manage_themes_title">Beheer Thema\'s</string> - <string name="settings_custom_theme_cannot_apply_to_settings_page_summary">Aangepaste thema\'s kunnen niet worden toegepast op de instellingenpagina (behalve werkbalk, statusbalk en navigatiebalk).</string> - <string name="settings_advanced_master_title">Geavanceerd</string> - <string name="settings_delete_all_subreddits_data_in_database_title">Verwijder Alle Subreddits in de Database</string> - <string name="settings_delete_all_users_data_in_database_title">Verwijder Alle Gebruikers in de Database</string> - <string name="settings_delete_all_sort_type_data_in_database_title">Verwijder Alle Sorteringstypen in de Database</string> - <string name="settings_delete_all_post_layout_data_in_database_title">Verwijder Alle Post Layouts in de Database</string> - <string name="settings_delete_all_themes_in_database_title">Verwijder Alle Thema\'s in de Database</string> - <string name="settings_delete_front_page_scrolled_positions_in_database_title">Verwijder alle voorpagina gescrolde posities in de database</string> - <string name="settings_reset_all_settings_title">Reset alle instellingen</string> - <string name="settings_tab_1_summary">Tabblad 1</string> - <string name="settings_tab_2_summary">Tabblad 2</string> - <string name="settings_tab_3_summary">Tabblad 3</string> - <string name="settings_tab_title">Titel</string> - <string name="settings_tab_post_type">Type</string> - <string name="settings_tab_subreddit_name">Subreddit Naam (Zonder r/ prefix)</string> - <string name="settings_tab_multi_reddit_name">Multireddit Naam</string> - <string name="settings_tab_username">Gebruikersnaam</string> - <string name="no_developer_easter_egg">Er zijn hier geen ontwikkelaarsopties</string> - <string name="no_link_available">Kan geen link verkrijgen</string> - <string name="exit_when_submit">Verlaten?</string> - <string name="exit_when_submit_post_detail">Het bericht wordt nog steeds verzonden, zelfs als je hier verlaat</string> - <string name="exit_when_edit_post_detail">Het bericht kan nog steeds worden verzonden, zelfs als je hier verlaat</string> - <string name="exit_when_edit_comment_detail">De reactie kan nog steeds worden ingediend, zelfs als je hier verlaat</string> - <string name="discard">Weggooien?</string> - <string name="discard_detail">Het concept wordt NIET opgeslagen</string> - <string name="yes">Ja</string> - <string name="no">Nee</string> - <string name="no_data_received">Geen data ontvangen</string> - <string name="no_image_path_received">Geen afbeeldingspad ontvangen</string> - <string name="no_video_path_received">Geen video</string> - <string name="cannot_handle_intent">Kan het deelverzoek niet verwerken</string> - <string name="share">Delen</string> - <string name="no_email_client">Geen e-mailservice gevonden</string> - <string name="no_app">Geen app beschikbaar</string> - <string name="comment_saved_success">Reactie opgeslagen</string> - <string name="comment_saved_failed">Niet mogelijk om reactie op te slaan</string> - <string name="comment_unsaved_success">Reactie niet opgeslagen</string> - <string name="comment_unsaved_failed">Niet mogelijk om reactie niet op te slaan</string> - <string name="favorites">Favorieten</string> - <string name="all">Alles</string> - <string name="post_layout_card">Kaart layout</string> - <string name="post_layout_compact">Compacte layout</string> - <string name="elapsed_time_just_now">Net Nu</string> - <string name="elapsed_time_a_minute_ago">1 Minuut</string> - <string name="elapsed_time_minutes_ago">%1$d Minuten</string> - <string name="elapsed_time_an_hour_ago">1 Uur</string> - <string name="elapsed_time_hours_ago">%1$d Uren</string> - <string name="elapsed_time_yesterday">Gisteren</string> - <string name="elapsed_time_days_ago">%1$d Dagen</string> - <string name="elapsed_time_a_month_ago">1 Maand</string> - <string name="elapsed_time_months_ago">%1$d Maanden</string> - <string name="elapsed_time_a_year_ago">1 Jaar</string> - <string name="elapsed_time_years_ago">%1$d Jaren</string> - <string name="error_getting_multi_reddit_data">Fout bij het ophalen van multireddit gegevens</string> - <string name="error_loading_multi_reddit_list">Kan multireddits niet synchroniseren</string> - <string name="error_loading_subscriptions">Kan abonnementen niet synchroniseren</string> - <string name="share_this_app">Bekijk Infinity voor Reddit, een geweldige Reddit client!</string> - <string name="error_getting_subreddit_name">Fout bij ophalen van subredditnaam</string> - <string name="share_post_link">Deel Post Link</string> - <string name="share_image_link">Deel Afbeelding Link</string> - <string name="share_gif_link">Deel GIF Link</string> - <string name="share_video_link">Deel Video Link</string> - <string name="share_link">Deel Link</string> - <string name="copy_post_link">Kopieer Post Link</string> - <string name="copy_image_link">Kopieer Afbeelding Link</string> - <string name="copy_gif_link">Kopieer GIF Link</string> - <string name="copy_video_link">Kopieer Video Link</string> - <string name="copy_link">Kopieer Link</string> - <string name="copy_success">Gekopieerd </string> - <string name="copy_link_failed">Kan de link niet kopiëren</string> - <string name="copy_text">Kopieer</string> - <string name="copy_all">Kopieer Alles</string> - <string name="copy_markdown">Kopieer Markdown</string> - <string name="copy_raw_text">Kopieer Onbewerkte Tekst</string> - <string name="copy_all_markdown">Kopieer Alle Markdown</string> - <string name="copy_all_raw_text">Kopieer Alle Onbewerkte Tekst</string> - <string name="exit_app">Verlaten?</string> - <string name="light_theme">Lichte Thema</string> - <string name="dark_theme">Donkere Thema</string> - <string name="multi_reddit_name_hint">Naam (Max. 50 Tekens)</string> - <string name="multi_reddit_description_hint">Beschrijving</string> - <string name="private_multi_reddit">Privé</string> - <string name="no_multi_reddit_name">Waar is de naam?</string> - <string name="create_multi_reddit_failed">Kan deze multireddit niet maken</string> - <string name="duplicate_multi_reddit">Deze multireddit bestaat al</string> - <string name="edit_multi_reddit_failed">Kan deze multireddit niet bewerken</string> - <string name="logged_out">Je bent uitgelogd</string> - <string name="delete_multi_reddit_success">Succesvol verwijderd</string> - <string name="delete_multi_reddit_failed">Verwijderen mislukt</string> - <string name="delete_multi_reddit_dialog_message">Weet je het zeker?</string> - <string name="enable_nsfw">Schakel NSFW in</string> - <string name="disable_nsfw">Schakel NSFW uit</string> - <string name="cannot_save_image">Kan de afbeelding niet opslaan</string> - <string name="cannot_save_gif">Kan de GIF niet opslaan</string> - <string name="cannot_get_storage">Geen toegang tot de app opslag</string> - <string name="save_image_first">De afbeelding opslaan. Even geduld aub.</string> - <string name="save_gif_first">De GIF opslaan. Even geduld aub.</string> - <string name="theme_name_description">Tik om de naam van dit thema te wijzigen.</string> - <string name="theme_item_is_light_theme">Instellen als lichte thema</string> - <string name="theme_item_is_dark_theme">Instellen als donkere thema</string> - <string name="theme_item_is_amoled_theme">Instelled als Amoled thema</string> - <string name="theme_item_color_primary">Primaire Kleur</string> - <string name="theme_item_color_primary_detail">Toegepast op: Werkbalk</string> - <string name="theme_item_color_primary_dark">Primaire Kleur Donker</string> - <string name="theme_item_color_primary_dark_detail">Toegepast op: Statusbalk</string> - <string name="theme_item_color_accent">Kleuraccent</string> - <string name="theme_item_color_accent_detail">Toegepast op: Voortgangsbalk</string> - <string name="theme_item_color_primary_light_theme">Primaire Kleur Lichte Thema</string> - <string name="theme_item_color_primary_light_theme_detail">Toegepast op: achtergrond van zwevende actieknop en knop</string> - <string name="theme_item_primary_text_color">Primaire Tekstkleur</string> - <string name="theme_item_primary_text_color_detail">Toegepast op: Primaire tekst</string> - <string name="theme_item_secondary_text_color">Secundaire Tekstkleur</string> - <string name="theme_item_secondary_text_color_detail">Toegepast op: Secundaire Tekstkleur</string> - <string name="theme_item_post_title_color">Post Titlekleur</string> - <string name="theme_item_post_title_color_detail">Toegepast op: Posttitel</string> - <string name="theme_item_post_content_color">Post Content Kleur</string> - <string name="theme_item_post_content_color_detail">Toegepast op: Post content</string> - <string name="theme_item_comment_color">Reactiekleur</string> - <string name="theme_item_comment_color_detail">Toegepast op: Reactie</string> - <string name="theme_item_button_text_color">Knop Tekstkleur</string> - <string name="theme_item_button_text_color_detail">Toegepast op: Tekst op knop</string> - <string name="theme_item_chip_text_color">Chip Tekstkleur</string> - <string name="theme_item_chip_text_color_detail">Toegepast op: Abonneerknop</string> - <string name="theme_item_link_color">Linkkleur</string> - <string name="theme_item_link_color_detail">Toegepast op: URL</string> - <string name="theme_item_received_message_text_color">Ontvangen Bericht Tekstkleur</string> - <string name="theme_item_received_message_text_color_detail">Toegepast op: Ontvangen Privéberichten</string> - <string name="theme_item_sent_message_text_color">Verzonden Bericht Tekstkleur</string> - <string name="theme_item_sent_message_text_color_detail">Toegepast op: Verzonden Privéberichten</string> - <string name="theme_item_background_color">Achtergrondkleur</string> - <string name="theme_item_background_color_detail">Toegepast op: Achtergrond van elke pagina en navigatielade</string> - <string name="theme_item_card_view_background_color">Kaartweergave Achtergrondkleur</string> - <string name="theme_item_card_view_background_color_detail">Toegepast op: Postachtergrond en Berichtachtergrond</string> - <string name="theme_item_comment_background_color">Reactie achtergrondkleur</string> - <string name="theme_item_comment_background_color_detail">Toegepast op: Reactie achtergrondkleur</string> - <string name="theme_item_fully_collapsed_comment_background_color">Volledig Samengevouwen Reactie Achtergrondkleur</string> - <string name="theme_item_fully_collapsed_comment_background_color_detail">Toegepast op: achtergrond van volledig samengevouwen opmerkingen</string> - <string name="theme_item_awarded_comment_background_color">Bekroonde Reactie Achtergrondkleur</string> - <string name="theme_item_awarded_comment_background_color_detail">Toegepast op: Achtergrond van bekroonde reacties</string> - <string name="theme_item_received_message_background_color">Ontvangen Bericht Achtergrondkleur</string> - <string name="theme_item_received_message_background_color_detail">Toegepast op: Achtergrond van ontvangen privéberichten</string> - <string name="theme_item_sent_message_background_color">Verzonden Bericht Achtergrondkleur</string> - <string name="theme_item_sent_message_background_color_detail">Toegepast op: Achtergrond van verzonden privéberichten</string> - <string name="theme_item_bottom_app_bar_background_color">Kleur Onderste Navigatiebalk</string> - <string name="theme_item_bottom_app_bar_background_color_detail">Toegepast op: Onderste navigatiebalk</string> - <string name="theme_item_primary_icon_color">Primaire Icoonkleur</string> - <string name="theme_item_primary_icon_color_detail">Toegepast op: Pictogrammen in de navigatielade.</string> - <string name="theme_item_bottom_app_bar_icon_color">Kleur Onderste Navigatiebalkpictogram</string> - <string name="theme_item_bottom_app_bar_icon_color_detail">Toegepast op: Pictogrammen in de onderste navigatiebalk</string> - <string name="theme_item_post_icon_and_info_color">Postpictogram en informatiekleur</string> - <string name="theme_item_post_icon_and_info_color_detail">Toegepast op: Pictogrammen, score en het aantal reacties in berichten</string> - <string name="theme_item_comment_icon_and_info_color">Reactiepictogram en informatiekleur</string> - <string name="theme_item_comment_icon_and_info_color_detail">Toegepast op: Pictogrammen en score in reacties</string> - <string name="theme_item_fab_icon_color">Zwevende Actieknop Pictogramkleur</string> - <string name="theme_item_fab_icon_color_detail">Toegepast op: Zwevende actieknop pictogram</string> - <string name="theme_item_send_message_icon_color">Verzend Berichtpictogramkleur</string> - <string name="theme_item_send_message_icon_color_detail">Toegepast op: verzend privébericht pictogram</string> - <string name="theme_item_toolbar_primary_text_and_icon_color">Werkbalk Primaire Tekst en Pictogramkleur</string> - <string name="theme_item_toolbar_primary_text_and_icon_color_detail">Toegepast op: Primaire teksten en pictogrammen in werkbalken</string> - <string name="theme_item_toolbar_secondary_text_color">Werkbalk Secundaire Tekstkleur</string> - <string name="theme_item_toolbar_secondary_text_color_detail">Toegepast op: Secundaire teksten in werkbalken</string> - <string name="theme_item_circular_progress_bar_background_color">Circulaire Voortgangsbalk Achtergrondkleur</string> - <string name="theme_item_circular_progress_bar_background_color_detail">Toegepast op: Achtergrond van Circulaire voortgangsbalk</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background">Achtergrondkleur van tabbladindeling in uitgevouwen werkbalk</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background_detail">Toegepast op: Tabblad layoutachtergrond (uitgevouwen werkbalk)</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color">Tekstkleur van tabbladindeling in uitgevouwen werkbalk</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color_detail">Toegepast op: Tekstkleur van tabbladlayout (uitgevouwen werkbalk)</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator">Tabbladindicatorkleur van tabbladindeling in uitgevouwen werkbalk</string> - <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator_detail">Toegepast op: Tabbladindicatorkleur in tabbladindeling (uitgevouwen werkbalk)</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background">Achtergrondkleur van tabbladindeling in samengevouwen werkbalk</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background_detail">Toegepast op: Tabbladlayout achtergrond (samengevouwen werkbalk)</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color">Tekstkleur van tabbladindeling in samengevouwen werkbalk</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color_detail">Toegepast op: Tekstkleur van tabbladlayout (samengevouwen werkbalk)</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator">Tabbladindicatorkleur van tabbladindeling in samengevouwen werkbalk</string> - <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator_detail">Toegepast op: Tabbladindicatorkleur in tabbladindeling (samengevouwen werkbalk)</string> - <string name="theme_item_upvoted_color">Upvote Kleur</string> - <string name="theme_item_upvoted_color_detail">Toegepast op: Stemknoppen en scores (upvoted)</string> - <string name="theme_item_downvoted_color">Downvote Kleur</string> - <string name="theme_item_downvoted_color_detail">Toegepast op: Stemknoppen en scores (downvoted)</string> - <string name="theme_item_post_type_background_color">Posttype Achtergrondkleur</string> - <string name="theme_item_post_type_background_color_detail">Toegepast op: Achtergrond van het Posttype (IMAGE, TEXT, VIDEO, GIF, LINK)</string> - <string name="theme_item_post_type_text_color">Posttype Tekstkleur</string> - <string name="theme_item_post_type_text_color_detail">Toegepast op: Tekstkleur van het Posttype (IMAGE, TEXT, VIDEO, GIF, LINK)</string> - <string name="theme_item_spoiler_background_color">Spoiler Achtergrondkleur</string> - <string name="theme_item_spoiler_background_color_detail">Toegepast op: Achtergrond van de spoilertag</string> - <string name="theme_item_spoiler_text_color">Spoiler Tekstkleur</string> - <string name="theme_item_spoiler_text_color_detail">Toegepast op: Tekstkleur van de spoilertag</string> - <string name="theme_item_nsfw_background_color">NSFW Achtergrondkleur</string> - <string name="theme_item_nsfw_background_color_detail">Toegepast op: Achtergrond van de NSFW tag</string> - <string name="theme_item_nsfw_text_color">NSFW Tekstkleur</string> - <string name="theme_item_nsfw_text_color_detail">Toegepast op: Tekstkleur van de NSFW tag</string> - <string name="theme_item_flair_background_color">Flair Achtergrondkleur</string> - <string name="theme_item_flair_background_color_detail">Toegepast op: Achtergrond van de flair tag</string> - <string name="theme_item_flair_text_color">Flair Tekstkleur</string> - <string name="theme_item_flair_text_color_detail">Toegepast op: Tekstkleur van de flair tag</string> - <string name="theme_item_awards_background_color">Awards achtergrondkleur</string> - <string name="theme_item_awards_background_color_detail">Toegepast op: Achtergrond van de awards tag</string> - <string name="theme_item_awards_text_color">Awards Tekstkleur</string> - <string name="theme_item_awards_text_color_detail">Toegepast op: Tekstkleur van de awards tag</string> - <string name="theme_item_archived_tint">Gearchiveerde Pictogramkleur</string> - <string name="theme_item_archived_tint_detail">Toegepast op: Gearchiveerde pictogramkleur</string> - <string name="theme_item_locked_icon_tint">Vergrendelde Pictogramkleur</string> - <string name="theme_item_locked_icon_tint_detail">Toegepast op: Vergrendelde pictogramkleur</string> - <string name="theme_item_crosspost_icon_tint">Crosspost Pictogramkleur</string> - <string name="theme_item_crosspost_icon_tint_detail">Toegepast op: Crosspost pictogramkleur</string> - <string name="theme_item_stickied_post_icon_tint">Stickied Post Pictogramkleur</string> - <string name="theme_item_stickied_post_icon_tint_detail">Toegepast op: Stickied Postpictorgram</string> - <string name="theme_item_subscribed_color">Geabonneerd</string> - <string name="theme_item_subscribed_color_detail">Toegepast op: Afmeldknop</string> - <string name="theme_item_unsubscribed_color">Afgemeld</string> - <string name="theme_item_unsubscribed_color_detail">Toegepast op: Aboneerknop</string> - <string name="theme_item_username_color">Gebruikersnaamkleur</string> - <string name="theme_item_username_color_detail">Toegepast op: Gebruikersnaam</string> - <string name="theme_item_subreddit_color">Subredditkleur</string> - <string name="theme_item_subreddit_color_detail">Toegepast op: Subredditnaam</string> - <string name="theme_item_author_flair_text_color">Auteur Flairkleur</string> - <string name="theme_item_author_flair_text_color_detail">Toegepast op: Auteurflair in reacties</string> - <string name="theme_item_submitter_color">Indiener</string> - <string name="theme_item_submitter_color_detail">Toegepast op: Submitter in reacties</string> - <string name="theme_item_moderator_color">Moderator</string> - <string name="theme_item_moderator_color_detail">Toegepast op: Moderator in opmerking</string> - <string name="theme_item_single_comment_thread_background_color">Enkele Reactie Draad Achtergrondkleur</string> - <string name="theme_item_single_comment_thread_background_color_detail">Toegepast op: Enkele Reactie</string> - <string name="theme_item_unread_message_background_color">Ongelezen Bericht Achtergrondkleur</string> - <string name="theme_item_unread_message_background_color_detail">Toegepast op: Ongelezen Bericht Achtergrondkleur</string> - <string name="theme_item_divider_color">Kleurverdeler</string> - <string name="theme_item_divider_color_detail">Toegepast op: Reactieverdeler, scheidingslijnen in pagina\'s voor het indienen van berichten, etc.</string> - <string name="theme_item_vote_and_reply_unavailable_button_color">Stem en Antwoord Niet Beschikbaar Knopkleur</string> - <string name="theme_item_vote_and_reply_unavailable_button_color_detail">Toegepast op: Stem- en Antwoordknoppen (Niet Beschikbaar)</string> - <string name="theme_item_comment_vertical_bar_color_1">Reactie Verticale Balk Kleur 1</string> - <string name="theme_item_comment_vertical_bar_color_1_detail">Toegepast op: Reactie Verticale Balk (Level 1)</string> - <string name="theme_item_comment_vertical_bar_color_2">Reactie Verticale Balk Kleur 2</string> - <string name="theme_item_comment_vertical_bar_color_2_detail">Toegepast op: Reactie Verticale Balk (Level 2)</string> - <string name="theme_item_comment_vertical_bar_color_3">Reactie Verticale Balk Kleur 3</string> - <string name="theme_item_comment_vertical_bar_color_3_detail">Toegepast op: Reactie Verticale Balk (Level 3)</string> - <string name="theme_item_comment_vertical_bar_color_4">Reactie Verticale Balk Kleur 4</string> - <string name="theme_item_comment_vertical_bar_color_4_detail">Toegepast op: Reactie Verticale Balk (Level 4)</string> - <string name="theme_item_comment_vertical_bar_color_5">Reactie Verticale Balk Kleur 5</string> - <string name="theme_item_comment_vertical_bar_color_5_detail">Toegepast op: Reactie Verticale Balk (Level 5)</string> - <string name="theme_item_comment_vertical_bar_color_6">Reactie Verticale Balk Kleur 6</string> - <string name="theme_item_comment_vertical_bar_color_6_detail">Toegepast op: Reactie Verticale Balk (Level 6)</string> - <string name="theme_item_comment_vertical_bar_color_7">Reactie Verticale Balk Kleur 7</string> - <string name="theme_item_comment_vertical_bar_color_7_detail">Toegepast op: Reactie Verticale Balk (Level 7)</string> - <string name="theme_item_nav_bar_color">Kleur Navigatiebalk</string> - <string name="theme_item_nav_bar_color_detail">Toegepast op: Navigatiebalk</string> - <string name="theme_item_light_status_bar">Donkere Statusbalkpictogramkleur</string> - <string name="theme_item_light_nav_bar">Donkere Navigatiebalkpictogramkleur</string> - <string name="theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface">Wijzig de pictogramkleur van de statusbalk nadat de werkbalk is samengevouwen in een meeslepende interface</string> - <string name="theme_item_available_on_android_8">Alleen beschikbaar op Android 8.0 en nieuwer</string> - <string name="theme_item_available_on_android_6">Alleen beschikbaar op Android 6.0 en nieuwer</string> - <string name="predefined_themes">Voorgedefinieerde Thema\'s</string> - <string name="user_themes">Jouw Thema\'s</string> - <string name="no_theme_name">Wat is de naam van deze thema?</string> - <string name="theme_name_hint">Themanaam</string> - <string name="theme_name_indigo">Indigo</string> - <string name="theme_name_indigo_dark">Indigo Donker</string> - <string name="theme_name_indigo_amoled">Indigo Amoled</string> - <string name="theme_name_white">Wit</string> - <string name="theme_name_white_dark">Wit Donker</string> - <string name="theme_name_white_amoled">Wit Amoled</string> - <string name="theme_name_red">Rood</string> - <string name="theme_name_red_dark">Donkerrood</string> - <string name="theme_name_red_amoled">Rood Amoled</string> - <string name="theme_name_dracula">Dracula</string> - <string name="theme_name_calm_pastel">Calm Pastel</string> - <string name="create_light_theme">Maak een Lichte Thema\nGebaseerd op een Indigo thema</string> - <string name="create_dark_theme">Maak een Donkere Thema\nGebaseerd op een Indigo Donkere Thema</string> - <string name="create_amoled_theme">Maak een Amoled Thema\nGebaseerd op een Indigo Amoled Thema</string> - <string name="create_theme_info">Als je een thema wilt maken op basis van een ander thema, klik dan op de \"+\" - knop op een thema.</string> - <string name="edit_theme_name">Wijzig Themanaam</string> - <string name="edit_theme">Wijzig Thema</string> - <string name="delete_theme">Verwijder Thema</string> - <string name="delete_theme_dialog_message">Weet je zeker dat u%1$s wilt verwijderen?</string> - <string name="share_theme">Deel Thema</string> - <string name="change_theme_name">Naam wijzigen</string> - <string name="theme_copied">Gekopieerd! Plak het en deel het met andere mensen.</string> - <string name="copy_theme_faied">Kan de themaconfiguratie niet kopiëren</string> - <string name="cannot_find_theme">Kan deze thema niet vinden</string> - <string name="import_theme">Importeer Thema</string> - <string name="no_data_in_clipboard">Kan gegevens niet vinden op klembord</string> - <string name="import_theme_success">Importeer Thema gelukt</string> - <string name="parse_theme_failed">Parse Thema Mislukt</string> - <string name="duplicate_theme_name_dialog_title">Duplicaat Thema Gevonden</string> - <string name="duplicate_theme_name_dialog_message">Een thema in de database wordt ook wel %1$s genoemd. Wil je de naam van dit geïmporteerde thema wijzigen?</string> - <string name="rename">Hernoemen</string> - <string name="override">Overschrijven</string> - <string name="color_picker">Kleurenkiezer</string> - <string name="invalid_color">Ongeldige Kleur</string> - <string name="delete_all_subreddits_success">Verwijder alle subreddits gelukt</string> - <string name="delete_all_users_success">Verwijder alle gebruikers gelukt</string> - <string name="delete_all_sort_types_success">Verwijder alle sorteringstypen gelukt</string> - <string name="delete_all_post_layouts_success">Verwijder alle layouts gelukt</string> - <string name="delete_all_themes_success">Verwijder alle themas gelukt</string> - <string name="delete_all_front_page_scrolled_positions_success">Verwijder alle gescrolde posities op de voorpagina gelukt</string> - <string name="reset_all_settings_success">Reset alle instellingen gelukt</string> - <string name="username_preview">u/Hostilenemy</string> - <string name="subreddit_preview">r/Infinity_For_Reddit</string> - <string name="primary_text_preview">Primaire Tekst</string> - <string name="secondary_text_preview">Secundaire Tekst</string> - <string name="post_title_preview">Dit is een post</string> - <string name="post_content_preview">Deze zwaartekrachtgrap wordt een beetje oud, maar ik trap er elke keer in.</string> - <string name="post_type_preview">Post</string> - <string name="flair_preview">Flair</string> - <string name="awards_preview">4 Awards</string> - <string name="author_flair_preview">Auteur Flair</string> - <string name="comment_content_preview">Ik heb voor mijn vriendin een beterschapskaartje. \nZe is niet ziek of zo, maar ze kan zeker beter worden.</string> - <string name="edit_multi_reddit">Wijzig Multireddit</string> - <string name="delete_multi_reddit">Verwijder Multireddit</string> - <string name="n_awards">%1$d Awards</string> - <string name="one_award">1 Award</string> - <string name="report">Meld</string> - <string name="reporting">Aan het melden</string> - <string name="report_successful">Gemeld</string> - <string name="report_failed">Melden mislukt</string> - <string name="report_reason_not_selected">Je hebt geen reden gekozen</string> - <string name="report_reason_general_spam">Het is spam</string> - <string name="report_reason_general_copyright_issue">Het bevat een auteursrechtkwestie</string> - <string name="report_reason_general_child_pornography">Het bevat kinderpornografie</string> - <string name="report_reason_general_abusive_content">Het bevat beledigende inhoud</string> - <string name="home">Thuis</string> - <string name="popular">Populair</string> - <string name="notifications">Notificaties</string> - <string name="messages">Berichten</string> - <string name="message">Bericht</string> - <string name="fetch_gfycat_video_failed">Ophalen van Gfycat video is mislukt</string> - <string name="fetch_redgifs_video_failed">Ophalen van Redgifs video is mislukt</string> - <string name="fetching_video_info_please_wait">Ophalen van videoinfo. Even geduld aub.</string> - <string name="error_fetching_imgur_media">Kan afbeeldingen niet laden</string> - <string name="downloading_reddit_video">Videotrack downloaden</string> - <string name="downloading_reddit_video_audio_track">Audiotrack downloaden</string> - <string name="downloading_reddit_video_muxing">Muxing Video en Audio</string> - <string name="downloading_reddit_video_save_file_to_public_dir">Video Opslaan</string> - <string name="downloading_reddit_video_finished">Gedownload</string> + <string name="settings_automatically_try_redgifs_title">"Probeer Automatisch Redgifs te Openen als Video's op Gfycat zijn Verwijderd."</string> + <string name="settings_video_player_ignore_nav_bar_title">"Negeer de Navigatiebalk in de Videospeler"</string> + <string name="settings_video_player_ignore_nav_bar_summary">"Voorkom dat de Videocontroller een Extra Marge Heeft"</string> + <string name="settings_confirm_to_exit">"Bevestig om af te sluiten"</string> + <string name="settings_category_comment_title">"Opmerking"</string> + <string name="settings_show_top_level_comments_first_title">"Toon Top-niveau Opmerkingen Eerst"</string> + <string name="settings_show_comment_divider_title">"Toon Commentaarverdeler"</string> + <string name="settings_comment_toolbar_hide_on_click">"Klik om de Werkbalk Opmerkingen te Tonen / Verbergen"</string> + <string name="settings_fully_collapse_comment_title">"Opmerking Volledig Instorten"</string> + <string name="settings_comment_toolbar_hidden">"De Werkbalk Opmerkingen is Standaard Verborgen"</string> + <string name="settings_show_absolute_number_of_votes_title">"Toon Absoluut Aantal Stemmen"</string> + <string name="settings_show_elapsed_time">"Verstreken Tijd Weergeven in Posts en Opmerkingen"</string> + <string name="settings_time_format_title">"Tijd Formaat"</string> + <string name="settings_category_post_title">"Post"</string> + <string name="settings_default_post_layout">"Standaard Post Layout"</string> <!-- Fuzzy --> - <string name="downloading_reddit_video_failed_cannot_get_cache_directory">Download mislukt: geen toegang tot de cachemap</string> - <string name="downloading_reddit_video_failed_cannot_download_video">Download mislukt: kan video niet downloaden</string> - <string name="downloading_reddit_video_failed_cannot_save_video">Download mislukt: kan video niet in cachemap opslaan</string> - <string name="downloading_reddit_video_failed_cannot_save_audio">Download mislukt: kan audio niet opslaan in cachemap</string> - <string name="downloading_reddit_video_failed_cannot_mux">Download mislukt: kan video en audio niet samenvoegen</string> - <string name="downloading_reddit_video_failed_cannot_save_mux_video">Downloaden mislukt: kan de video niet opslaan in de openbare map</string> - <string name="wallpaper_set">Achtergrond set</string> - <string name="error_set_wallpaper">Kan geen achtergrond instellen</string> - <string name="set_to_home_screen">Als startscherm instellen</string> - <string name="set_to_lock_screen">Als vergrendeldscherm instellen</string> - <string name="set_to_both">Als beiden instellen</string> - <string name="default_font_font_preview">Standaard</string> - <string name="load_video_in_redgifs">Probeer de video op Redgifs te laden</string> - <string name="top_score">%1$s pnt</string> - <string name="login_activity_2fa_prompt">Als je 2-factor authenticatie hebt ingeschakeld, typ dan je wachtwoord als volgt in: <wachtwoord>: <2FA code>.\nVoorbeeld: yourpass: 123456</string> - <string name="block_user">Blokkeer gebruiker</string> - <string name="block_user_success">Geblokkeerd</string> - <string name="block_user_failed">Kan gebruiker niet blokkeren</string> - <string name="submit_crosspost_activity_label">Crosspost</string> - <string name="give_award_activity_label">Geef Award</string> - <string name="action_crosspost">Crosspost</string> - <string name="action_select_user_flair">Selecteer Gebruikersflair</string> - <string name="action_give_award">Geef Award</string> - <string name="posts">Posts</string> - <string name="sidebar">Zijbalk</string> - <string name="only_for_logged_in_user">Alleen voor ingelogde gebruikers</string> - <string name="settings_number_of_columns_in_post_feed_title">Het Aantal Kolommen in de Postfeed</string> - <string name="settings_number_of_columns_in_post_feed_portrait_title">Portret</string> - <string name="settings_number_of_columns_in_post_feed_landscape_title">Landschap</string> - <string name="settings_nsfw_and_spoiler_title">NSFW & Spoiler</string> - <string name="settings_delete_all_legacy_settings_title">Verwijder alle legacyinstellingen</string> - <string name="restart_app_see_changes">Start de app opnieuw om de wijzigingen te zien</string> - <string name="settings_tab_count">Aantal Tabbladen</string> - <string name="settings_show_tab_names">Tabbladnamen Weergeven</string> - <string name="settings_more_tabs_summary">Meer Tabbladen</string> - <string name="settings_more_tabs_info_summary">Het inschakelen van de volgende opties zal onbedoeld gedrag veroorzaken: Tabbladen kunnen alle inhoud verliezen nadat ze naar andere zijn overgeschakeld. Dit is hetzelfde als het vernieuwen van de pagina.</string> - <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">Toon Favoriete Geabonneerde Subreddits</string> - <string name="settings_more_tabs_show_subscribed_subreddits_title">Toon Geabonneerde Subreddits</string> - <string name="settings_download_location_title">Download Locatie</string> - <string name="settings_image_download_location_title">Afbeeldingen Downloadlocatie</string> - <string name="settings_gif_download_location_title">GIF Downloadlocatie</string> - <string name="settings_video_download_location_title">Video Downloadlocatie</string> - <string name="settings_separate_folder_for_each_subreddit">Aparte Map Voor Elke Subreddit</string> - <string name="settings_swipe_action_title">Swipe-actie</string> - <string name="settings_disable_swiping_between_tabs_title">Schakel Swipen Tussen Tabbladen Uit</string> - <string name="settings_enable_swipe_action_title">Schakel Swipen In</string> - <string name="settings_swipe_action_threshold">Drempel</string> - <string name="settings_pull_to_refresh_title">Trek om te vernieuwen</string> - <string name="settings_security_title">Beveiliging</string> - <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">Verificatie vereist om naar het accountgedeelte in de navigatielade te gaan</string> + <string name="settings_show_divider_in_compact_layout">"Toon Verdeler in Compact Layout"</string> <!-- Fuzzy --> - <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">Druk lang in om werkbalk in compacte layout te verbergen</string> + <string name="settings_show_thumbnail_on_the_left_in_compact_layout">"Thumbnail aan de Linkerkant Weergeven in Compacte Layout"</string> + <string name="settings_swap_tap_and_long_title">"Wissel Tikken en Lang Indrukken in Opmerkingen"</string> + <string name="settings_swipe_to_go_back_title">"Veeg naar Rechts om Terug te Gaan"</string> + <string name="settings_swipe_to_go_back_summary">"Is Niet van Toepassing op Alle Pagina's"</string> + <string name="settings_lock_jump_to_next_top_level_comment_button_title">"Ga naar de Volgende Top-niveau Opmerking Knop Vergrendelen"</string> + <string name="settings_lock_bottom_app_bar_title">"Vergrendel de Onderste Navigatiebalk"</string> + <string name="settings_swipe_up_to_hide_jump_to_next_top_level_comment_button_title">"Veeg Omhoog om Ga naar de Volgende Top-Niveau Knop te Verbergen"</string> + <string name="settings_lazy_mode_interval_title">"Luie Modus Interval"</string> + <string name="settings_font_title">"Lettertype"</string> + <string name="settings_preview_font_title">"Lettertype Voorbeeld"</string> + <string name="settings_font_summary">"Lettertype"</string> + <string name="settings_title_font_summary">"Titel"</string> + <string name="settings_content_font_summary">"Inhoud"</string> + <string name="settings_font_family_title">"Lettertypefamilie"</string> + <string name="settings_title_font_family_title">"Titel Lettertypefamilie"</string> + <string name="settings_content_font_family_title">"Inhoud Lettertypefamilie"</string> + <string name="settings_font_size_title">"Lettergrootte"</string> + <string name="settings_title_font_size_title">"Titel Lettergrootte"</string> + <string name="settings_content_font_size_title">"Ingoud Lettergrootte"</string> + <string name="settings_enable_nsfw_title">"NSFW Inschakelen"</string> + <string name="settings_blur_nsfw_title">"NSFW-afbeeldingen Vervagen"</string> + <string name="settings_blur_spoiler_title">"Spoiler-afbeeldingen Vervagen"</string> + <string name="settings_about_master_title">"Over"</string> + <string name="settings_acknowledgement_master_title">"Erkenning"</string> + <string name="settings_credits_master_title">"Credits"</string> + <string name="settings_credits_icon_foreground_title">"Pictogram Voorgrond"</string> + <string name="settings_credits_icon_foreground_summary">"Technologie vector gemaakt door freepik - www.freepik.com"</string> + <string name="settings_credits_icon_background_title">"Pictogram Achtergrond"</string> + <string name="settings_credits_icon_background_summary">"Achtergrondvector gemaakt door freepik - www.freepik.com"</string> + <string name="settings_credits_error_image_title">"Error Afbeelding"</string> + <string name="settings_credits_error_image_summary">"Technologie vector gemaakt door freepik - www.freepik.com"</string> + <string name="settings_credits_gilded_icon_title">"Verguld Pictogram"</string> + <string name="settings_credits_gilded_icon_summary">"Pictogram gemaakt door Freepik van www.flaticon.com"</string> + <string name="settings_credits_crosspost_icon_title">"Crosspost Pictogram"</string> + <string name="settings_credits_crosspost_icon_summary">"Pictogram gemaakt door Freepik van www.flaticon.com"</string> + <string name="settings_credits_thumbtack_icon_title">"Thumbtack Pictogram"</string> + <string name="settings_credits_thumbtack_icon_summary">"Pictogram gemaakt door Freepik van www.flaticon.com"</string> + <string name="settings_credits_best_rocket_icon_title">"Raket Picotgram"</string> + <string name="settings_credits_best_rocket_icon_summary">"Pictogram gemaakt door Freepik van www.flaticon.com"</string> + <string name="settings_credits_material_icons_title">"Material Pictogrammen"</string> + <string name="settings_open_source_title">"Open Source"</string> + <string name="settings_open_source_summary">"Geef het een ster op Github als je deze app leuk vindt"</string> + <string name="settings_rate_title">"Beoordeel op Google Play"</string> + <string name="settings_rate_summary">"Geef me een 5-sterrenbeoordeling en ik zal heel blij zijn"</string> + <string name="settings_email_title">"Email"</string> + <string name="settings_email_summary">"docilealligator.app@gmail.com"</string> + <string name="settings_reddit_account_title">"Reddit Account"</string> + <string name="settings_reddit_account_summary">"u/Hostilenemy"</string> + <string name="settings_subreddit_title">"Subreddit"</string> + <string name="settings_subreddit_summary">"r/Infinity_For_Reddit"</string> + <string name="settings_share_title">"Delen"</string> + <string name="settings_share_summary">"Deel deze app met andere mensen als je ervan geniet"</string> + <string name="settings_version_title">"Infinity For Reddit"</string> + <string name="settings_version_summary">"Versie %s"</string> + <string name="settings_category_customization_title">"Aanpassingen"</string> + <string name="settings_customize_light_theme_title">"Licht Thema"</string> + <string name="settings_customize_dark_theme_title">"Donker Thema"</string> + <string name="settings_customize_amoled_theme_title">"Amoled Thema"</string> + <string name="settings_manage_themes_title">"Beheer Thema's"</string> + <string name="settings_custom_theme_cannot_apply_to_settings_page_summary">"Aangepaste thema's kunnen niet worden toegepast op de instellingenpagina (behalve werkbalk, statusbalk en navigatiebalk)."</string> + <string name="settings_advanced_master_title">"Geavanceerd"</string> + <string name="settings_delete_all_subreddits_data_in_database_title">"Verwijder Alle Subreddits in de Database"</string> + <string name="settings_delete_all_users_data_in_database_title">"Verwijder Alle Gebruikers in de Database"</string> + <string name="settings_delete_all_sort_type_data_in_database_title">"Verwijder Alle Sorteringstypen in de Database"</string> + <string name="settings_delete_all_post_layout_data_in_database_title">"Verwijder Alle Post Layouts in de Database"</string> + <string name="settings_delete_all_themes_in_database_title">"Verwijder Alle Thema's in de Database"</string> + <string name="settings_delete_front_page_scrolled_positions_in_database_title">"Verwijder alle voorpagina gescrolde posities in de database"</string> + <string name="settings_reset_all_settings_title">"Reset alle instellingen"</string> + <string name="settings_tab_1_summary">"Tabblad 1"</string> + <string name="settings_tab_2_summary">"Tabblad 2"</string> + <string name="settings_tab_3_summary">"Tabblad 3"</string> + <string name="settings_tab_title">"Titel"</string> + <string name="settings_tab_post_type">"Type"</string> + <string name="settings_tab_subreddit_name">"Subreddit Naam (Zonder r/ prefix)"</string> + <string name="settings_tab_multi_reddit_name">"Multireddit Naam"</string> + <string name="settings_tab_username">"Gebruikersnaam"</string> + <string name="no_developer_easter_egg">"Er zijn hier geen ontwikkelaarsopties"</string> + <string name="no_link_available">"Kan geen link verkrijgen"</string> + <string name="exit_when_submit">"Verlaten?"</string> + <string name="exit_when_submit_post_detail">"Het bericht wordt nog steeds verzonden, zelfs als je hier verlaat"</string> + <string name="exit_when_edit_post_detail">"Het bericht kan nog steeds worden verzonden, zelfs als je hier verlaat"</string> + <string name="exit_when_edit_comment_detail">"De reactie kan nog steeds worden ingediend, zelfs als je hier verlaat"</string> + <string name="discard">"Weggooien?"</string> + <string name="discard_detail">"Het concept wordt NIET opgeslagen"</string> + <string name="yes">"Ja"</string> + <string name="no">"Nee"</string> + <string name="no_data_received">"Geen data ontvangen"</string> + <string name="no_image_path_received">"Geen afbeeldingspad ontvangen"</string> + <string name="no_video_path_received">"Geen video"</string> + <string name="cannot_handle_intent">"Kan het deelverzoek niet verwerken"</string> + <string name="share">"Delen"</string> + <string name="no_email_client">"Geen e-mailservice gevonden"</string> + <string name="no_app">"Geen app beschikbaar"</string> + <string name="comment_saved_success">"Reactie opgeslagen"</string> + <string name="comment_saved_failed">"Niet mogelijk om reactie op te slaan"</string> + <string name="comment_unsaved_success">"Reactie niet opgeslagen"</string> + <string name="comment_unsaved_failed">"Niet mogelijk om reactie niet op te slaan"</string> + <string name="favorites">"Favorieten"</string> + <string name="all">"Alles"</string> + <string name="post_layout_card">"Kaart layout"</string> + <string name="post_layout_compact">"Compacte layout"</string> + <string name="elapsed_time_just_now">"Net Nu"</string> + <string name="elapsed_time_a_minute_ago">"1 Minuut"</string> + <string name="elapsed_time_minutes_ago">"%1$d Minuten"</string> + <string name="elapsed_time_an_hour_ago">"1 Uur"</string> + <string name="elapsed_time_hours_ago">"%1$d Uren"</string> + <string name="elapsed_time_yesterday">"Gisteren"</string> + <string name="elapsed_time_days_ago">"%1$d Dagen"</string> + <string name="elapsed_time_a_month_ago">"1 Maand"</string> + <string name="elapsed_time_months_ago">"%1$d Maanden"</string> + <string name="elapsed_time_a_year_ago">"1 Jaar"</string> + <string name="elapsed_time_years_ago">"%1$d Jaren"</string> + <string name="error_getting_multi_reddit_data">"Fout bij het ophalen van multireddit gegevens"</string> + <string name="error_loading_multi_reddit_list">"Kan multireddits niet synchroniseren"</string> + <string name="error_loading_subscriptions">"Kan abonnementen niet synchroniseren"</string> + <string name="share_this_app">"Bekijk Infinity voor Reddit, een geweldige Reddit client!"</string> + <string name="error_getting_subreddit_name">"Fout bij ophalen van subredditnaam"</string> + <string name="share_post_link">"Deel Post Link"</string> + <string name="share_image_link">"Deel Afbeelding Link"</string> + <string name="share_gif_link">"Deel GIF Link"</string> + <string name="share_video_link">"Deel Video Link"</string> + <string name="share_link">"Deel Link"</string> + <string name="copy_post_link">"Kopieer Post Link"</string> + <string name="copy_image_link">"Kopieer Afbeelding Link"</string> + <string name="copy_gif_link">"Kopieer GIF Link"</string> + <string name="copy_video_link">"Kopieer Video Link"</string> + <string name="copy_link">"Kopieer Link"</string> + <string name="copy_success">"Gekopieerd "</string> + <string name="copy_link_failed">"Kan de link niet kopiëren"</string> + <string name="copy_text">"Kopieer"</string> + <string name="copy_all">"Kopieer Alles"</string> + <string name="copy_markdown">"Kopieer Markdown"</string> + <string name="copy_raw_text">"Kopieer Onbewerkte Tekst"</string> + <string name="copy_all_markdown">"Kopieer Alle Markdown"</string> + <string name="copy_all_raw_text">"Kopieer Alle Onbewerkte Tekst"</string> + <string name="exit_app">"Verlaten?"</string> + <string name="light_theme">"Lichte Thema"</string> + <string name="dark_theme">"Donkere Thema"</string> + <string name="multi_reddit_name_hint">"Naam (Max. 50 Tekens)"</string> + <string name="multi_reddit_description_hint">"Beschrijving"</string> + <string name="private_multi_reddit">"Privé"</string> + <string name="no_multi_reddit_name">"Waar is de naam?"</string> + <string name="create_multi_reddit_failed">"Kan deze multireddit niet maken"</string> + <string name="duplicate_multi_reddit">"Deze multireddit bestaat al"</string> + <string name="edit_multi_reddit_failed">"Kan deze multireddit niet bewerken"</string> + <string name="logged_out">"Je bent uitgelogd"</string> + <string name="delete_multi_reddit_success">"Succesvol verwijderd"</string> + <string name="delete_multi_reddit_failed">"Verwijderen mislukt"</string> + <string name="delete_multi_reddit_dialog_message">"Weet je het zeker?"</string> + <string name="enable_nsfw">"Schakel NSFW in"</string> + <string name="disable_nsfw">"Schakel NSFW uit"</string> + <string name="cannot_save_image">"Kan de afbeelding niet opslaan"</string> + <string name="cannot_save_gif">"Kan de GIF niet opslaan"</string> + <string name="cannot_get_storage">"Geen toegang tot de app opslag"</string> + <string name="save_image_first">"De afbeelding opslaan. Even geduld aub."</string> + <string name="save_gif_first">"De GIF opslaan. Even geduld aub."</string> + <string name="theme_name_description">"Tik om de naam van dit thema te wijzigen."</string> + <string name="theme_item_is_light_theme">"Instellen als lichte thema"</string> + <string name="theme_item_is_dark_theme">"Instellen als donkere thema"</string> + <string name="theme_item_is_amoled_theme">"Instelled als Amoled thema"</string> + <string name="theme_item_color_primary">"Primaire Kleur"</string> + <string name="theme_item_color_primary_detail">"Toegepast op: Werkbalk"</string> + <string name="theme_item_color_primary_dark">"Primaire Kleur Donker"</string> + <string name="theme_item_color_primary_dark_detail">"Toegepast op: Statusbalk"</string> + <string name="theme_item_color_accent">"Kleuraccent"</string> + <string name="theme_item_color_accent_detail">"Toegepast op: Voortgangsbalk"</string> + <string name="theme_item_color_primary_light_theme">"Primaire Kleur Lichte Thema"</string> + <string name="theme_item_color_primary_light_theme_detail">"Toegepast op: achtergrond van zwevende actieknop en knop"</string> + <string name="theme_item_primary_text_color">"Primaire Tekstkleur"</string> + <string name="theme_item_primary_text_color_detail">"Toegepast op: Primaire tekst"</string> + <string name="theme_item_secondary_text_color">"Secundaire Tekstkleur"</string> + <string name="theme_item_secondary_text_color_detail">"Toegepast op: Secundaire Tekstkleur"</string> + <string name="theme_item_post_title_color">"Post Titlekleur"</string> + <string name="theme_item_post_title_color_detail">"Toegepast op: Posttitel"</string> + <string name="theme_item_post_content_color">"Post Content Kleur"</string> + <string name="theme_item_post_content_color_detail">"Toegepast op: Post content"</string> + <string name="theme_item_comment_color">"Reactiekleur"</string> + <string name="theme_item_comment_color_detail">"Toegepast op: Reactie"</string> + <string name="theme_item_button_text_color">"Knop Tekstkleur"</string> + <string name="theme_item_button_text_color_detail">"Toegepast op: Tekst op knop"</string> + <string name="theme_item_chip_text_color">"Chip Tekstkleur"</string> + <string name="theme_item_chip_text_color_detail">"Toegepast op: Abonneerknop"</string> + <string name="theme_item_link_color">"Linkkleur"</string> + <string name="theme_item_link_color_detail">"Toegepast op: URL"</string> + <string name="theme_item_received_message_text_color">"Ontvangen Bericht Tekstkleur"</string> + <string name="theme_item_received_message_text_color_detail">"Toegepast op: Ontvangen Privéberichten"</string> + <string name="theme_item_sent_message_text_color">"Verzonden Bericht Tekstkleur"</string> + <string name="theme_item_sent_message_text_color_detail">"Toegepast op: Verzonden Privéberichten"</string> + <string name="theme_item_background_color">"Achtergrondkleur"</string> + <string name="theme_item_background_color_detail">"Toegepast op: Achtergrond van elke pagina en navigatielade"</string> + <string name="theme_item_card_view_background_color">"Kaartweergave Achtergrondkleur"</string> + <string name="theme_item_card_view_background_color_detail">"Toegepast op: Postachtergrond en Berichtachtergrond"</string> + <string name="theme_item_comment_background_color">"Reactie achtergrondkleur"</string> + <string name="theme_item_comment_background_color_detail">"Toegepast op: Reactie achtergrondkleur"</string> + <string name="theme_item_fully_collapsed_comment_background_color">"Volledig Samengevouwen Reactie Achtergrondkleur"</string> + <string name="theme_item_fully_collapsed_comment_background_color_detail">"Toegepast op: achtergrond van volledig samengevouwen opmerkingen"</string> + <string name="theme_item_awarded_comment_background_color">"Bekroonde Reactie Achtergrondkleur"</string> + <string name="theme_item_awarded_comment_background_color_detail">"Toegepast op: Achtergrond van bekroonde reacties"</string> + <string name="theme_item_received_message_background_color">"Ontvangen Bericht Achtergrondkleur"</string> + <string name="theme_item_received_message_background_color_detail">"Toegepast op: Achtergrond van ontvangen privéberichten"</string> + <string name="theme_item_sent_message_background_color">"Verzonden Bericht Achtergrondkleur"</string> + <string name="theme_item_sent_message_background_color_detail">"Toegepast op: Achtergrond van verzonden privéberichten"</string> + <string name="theme_item_bottom_app_bar_background_color">"Kleur Onderste Navigatiebalk"</string> + <string name="theme_item_bottom_app_bar_background_color_detail">"Toegepast op: Onderste navigatiebalk"</string> + <string name="theme_item_primary_icon_color">"Primaire Icoonkleur"</string> + <string name="theme_item_primary_icon_color_detail">"Toegepast op: Pictogrammen in de navigatielade."</string> + <string name="theme_item_bottom_app_bar_icon_color">"Kleur Onderste Navigatiebalkpictogram"</string> + <string name="theme_item_bottom_app_bar_icon_color_detail">"Toegepast op: Pictogrammen in de onderste navigatiebalk"</string> + <string name="theme_item_post_icon_and_info_color">"Postpictogram en informatiekleur"</string> + <string name="theme_item_post_icon_and_info_color_detail">"Toegepast op: Pictogrammen, score en het aantal reacties in berichten"</string> + <string name="theme_item_comment_icon_and_info_color">"Reactiepictogram en informatiekleur"</string> + <string name="theme_item_comment_icon_and_info_color_detail">"Toegepast op: Pictogrammen en score in reacties"</string> + <string name="theme_item_fab_icon_color">"Zwevende Actieknop Pictogramkleur"</string> + <string name="theme_item_fab_icon_color_detail">"Toegepast op: Zwevende actieknop pictogram"</string> + <string name="theme_item_send_message_icon_color">"Verzend Berichtpictogramkleur"</string> + <string name="theme_item_send_message_icon_color_detail">"Toegepast op: verzend privébericht pictogram"</string> + <string name="theme_item_toolbar_primary_text_and_icon_color">"Werkbalk Primaire Tekst en Pictogramkleur"</string> + <string name="theme_item_toolbar_primary_text_and_icon_color_detail">"Toegepast op: Primaire teksten en pictogrammen in werkbalken"</string> + <string name="theme_item_toolbar_secondary_text_color">"Werkbalk Secundaire Tekstkleur"</string> + <string name="theme_item_toolbar_secondary_text_color_detail">"Toegepast op: Secundaire teksten in werkbalken"</string> + <string name="theme_item_circular_progress_bar_background_color">"Circulaire Voortgangsbalk Achtergrondkleur"</string> + <string name="theme_item_circular_progress_bar_background_color_detail">"Toegepast op: Achtergrond van Circulaire voortgangsbalk"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background">"Achtergrondkleur van tabbladindeling in uitgevouwen werkbalk"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background_detail">"Toegepast op: Tabblad layoutachtergrond (uitgevouwen werkbalk)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color">"Tekstkleur van tabbladindeling in uitgevouwen werkbalk"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color_detail">"Toegepast op: Tekstkleur van tabbladlayout (uitgevouwen werkbalk)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator">"Tabbladindicatorkleur van tabbladindeling in uitgevouwen werkbalk"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator_detail">"Toegepast op: Tabbladindicatorkleur in tabbladindeling (uitgevouwen werkbalk)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background">"Achtergrondkleur van tabbladindeling in samengevouwen werkbalk"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background_detail">"Toegepast op: Tabbladlayout achtergrond (samengevouwen werkbalk)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color">"Tekstkleur van tabbladindeling in samengevouwen werkbalk"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color_detail">"Toegepast op: Tekstkleur van tabbladlayout (samengevouwen werkbalk)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator">"Tabbladindicatorkleur van tabbladindeling in samengevouwen werkbalk"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator_detail">"Toegepast op: Tabbladindicatorkleur in tabbladindeling (samengevouwen werkbalk)"</string> + <string name="theme_item_upvoted_color">"Upvote Kleur"</string> + <string name="theme_item_upvoted_color_detail">"Toegepast op: Stemknoppen en scores (upvoted)"</string> + <string name="theme_item_downvoted_color">"Downvote Kleur"</string> + <string name="theme_item_downvoted_color_detail">"Toegepast op: Stemknoppen en scores (downvoted)"</string> + <string name="theme_item_post_type_background_color">"Posttype Achtergrondkleur"</string> + <string name="theme_item_post_type_background_color_detail">"Toegepast op: Achtergrond van het Posttype (IMAGE, TEXT, VIDEO, GIF, LINK)"</string> + <string name="theme_item_post_type_text_color">"Posttype Tekstkleur"</string> + <string name="theme_item_post_type_text_color_detail">"Toegepast op: Tekstkleur van het Posttype (IMAGE, TEXT, VIDEO, GIF, LINK)"</string> + <string name="theme_item_spoiler_background_color">"Spoiler Achtergrondkleur"</string> + <string name="theme_item_spoiler_background_color_detail">"Toegepast op: Achtergrond van de spoilertag"</string> + <string name="theme_item_spoiler_text_color">"Spoiler Tekstkleur"</string> + <string name="theme_item_spoiler_text_color_detail">"Toegepast op: Tekstkleur van de spoilertag"</string> + <string name="theme_item_nsfw_background_color">"NSFW Achtergrondkleur"</string> + <string name="theme_item_nsfw_background_color_detail">"Toegepast op: Achtergrond van de NSFW tag"</string> + <string name="theme_item_nsfw_text_color">"NSFW Tekstkleur"</string> + <string name="theme_item_nsfw_text_color_detail">"Toegepast op: Tekstkleur van de NSFW tag"</string> + <string name="theme_item_flair_background_color">"Flair Achtergrondkleur"</string> + <string name="theme_item_flair_background_color_detail">"Toegepast op: Achtergrond van de flair tag"</string> + <string name="theme_item_flair_text_color">"Flair Tekstkleur"</string> + <string name="theme_item_flair_text_color_detail">"Toegepast op: Tekstkleur van de flair tag"</string> + <string name="theme_item_awards_background_color">"Awards achtergrondkleur"</string> + <string name="theme_item_awards_background_color_detail">"Toegepast op: Achtergrond van de awards tag"</string> + <string name="theme_item_awards_text_color">"Awards Tekstkleur"</string> + <string name="theme_item_awards_text_color_detail">"Toegepast op: Tekstkleur van de awards tag"</string> + <string name="theme_item_archived_tint">"Gearchiveerde Pictogramkleur"</string> + <string name="theme_item_archived_tint_detail">"Toegepast op: Gearchiveerde pictogramkleur"</string> + <string name="theme_item_locked_icon_tint">"Vergrendelde Pictogramkleur"</string> + <string name="theme_item_locked_icon_tint_detail">"Toegepast op: Vergrendelde pictogramkleur"</string> + <string name="theme_item_crosspost_icon_tint">"Crosspost Pictogramkleur"</string> + <string name="theme_item_crosspost_icon_tint_detail">"Toegepast op: Crosspost pictogramkleur"</string> + <string name="theme_item_stickied_post_icon_tint">"Stickied Post Pictogramkleur"</string> + <string name="theme_item_stickied_post_icon_tint_detail">"Toegepast op: Stickied Postpictorgram"</string> + <string name="theme_item_subscribed_color">"Geabonneerd"</string> + <string name="theme_item_subscribed_color_detail">"Toegepast op: Afmeldknop"</string> + <string name="theme_item_unsubscribed_color">"Afgemeld"</string> + <string name="theme_item_unsubscribed_color_detail">"Toegepast op: Aboneerknop"</string> + <string name="theme_item_username_color">"Gebruikersnaamkleur"</string> + <string name="theme_item_username_color_detail">"Toegepast op: Gebruikersnaam"</string> + <string name="theme_item_subreddit_color">"Subredditkleur"</string> + <string name="theme_item_subreddit_color_detail">"Toegepast op: Subredditnaam"</string> + <string name="theme_item_author_flair_text_color">"Auteur Flairkleur"</string> + <string name="theme_item_author_flair_text_color_detail">"Toegepast op: Auteurflair in reacties"</string> + <string name="theme_item_submitter_color">"Indiener"</string> + <string name="theme_item_submitter_color_detail">"Toegepast op: Submitter in reacties"</string> + <string name="theme_item_moderator_color">"Moderator"</string> + <string name="theme_item_moderator_color_detail">"Toegepast op: Moderator in opmerking"</string> + <string name="theme_item_single_comment_thread_background_color">"Enkele Reactie Draad Achtergrondkleur"</string> + <string name="theme_item_single_comment_thread_background_color_detail">"Toegepast op: Enkele Reactie"</string> + <string name="theme_item_unread_message_background_color">"Ongelezen Bericht Achtergrondkleur"</string> + <string name="theme_item_unread_message_background_color_detail">"Toegepast op: Ongelezen Bericht Achtergrondkleur"</string> + <string name="theme_item_divider_color">"Kleurverdeler"</string> + <string name="theme_item_divider_color_detail">"Toegepast op: Reactieverdeler, scheidingslijnen in pagina's voor het indienen van berichten, etc."</string> + <string name="theme_item_vote_and_reply_unavailable_button_color">"Stem en Antwoord Niet Beschikbaar Knopkleur"</string> + <string name="theme_item_vote_and_reply_unavailable_button_color_detail">"Toegepast op: Stem- en Antwoordknoppen (Niet Beschikbaar)"</string> + <string name="theme_item_comment_vertical_bar_color_1">"Reactie Verticale Balk Kleur 1"</string> + <string name="theme_item_comment_vertical_bar_color_1_detail">"Toegepast op: Reactie Verticale Balk (Level 1)"</string> + <string name="theme_item_comment_vertical_bar_color_2">"Reactie Verticale Balk Kleur 2"</string> + <string name="theme_item_comment_vertical_bar_color_2_detail">"Toegepast op: Reactie Verticale Balk (Level 2)"</string> + <string name="theme_item_comment_vertical_bar_color_3">"Reactie Verticale Balk Kleur 3"</string> + <string name="theme_item_comment_vertical_bar_color_3_detail">"Toegepast op: Reactie Verticale Balk (Level 3)"</string> + <string name="theme_item_comment_vertical_bar_color_4">"Reactie Verticale Balk Kleur 4"</string> + <string name="theme_item_comment_vertical_bar_color_4_detail">"Toegepast op: Reactie Verticale Balk (Level 4)"</string> + <string name="theme_item_comment_vertical_bar_color_5">"Reactie Verticale Balk Kleur 5"</string> + <string name="theme_item_comment_vertical_bar_color_5_detail">"Toegepast op: Reactie Verticale Balk (Level 5)"</string> + <string name="theme_item_comment_vertical_bar_color_6">"Reactie Verticale Balk Kleur 6"</string> + <string name="theme_item_comment_vertical_bar_color_6_detail">"Toegepast op: Reactie Verticale Balk (Level 6)"</string> + <string name="theme_item_comment_vertical_bar_color_7">"Reactie Verticale Balk Kleur 7"</string> + <string name="theme_item_comment_vertical_bar_color_7_detail">"Toegepast op: Reactie Verticale Balk (Level 7)"</string> + <string name="theme_item_nav_bar_color">"Kleur Navigatiebalk"</string> + <string name="theme_item_nav_bar_color_detail">"Toegepast op: Navigatiebalk"</string> + <string name="theme_item_light_status_bar">"Donkere Statusbalkpictogramkleur"</string> + <string name="theme_item_light_nav_bar">"Donkere Navigatiebalkpictogramkleur"</string> + <string name="theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface">"Wijzig de pictogramkleur van de statusbalk nadat de werkbalk is samengevouwen in een meeslepende interface"</string> + <string name="theme_item_available_on_android_8">"Alleen beschikbaar op Android 8.0 en nieuwer"</string> + <string name="theme_item_available_on_android_6">"Alleen beschikbaar op Android 6.0 en nieuwer"</string> + <string name="predefined_themes">"Voorgedefinieerde Thema's"</string> + <string name="user_themes">"Jouw Thema's"</string> + <string name="no_theme_name">"Wat is de naam van deze thema?"</string> + <string name="theme_name_hint">"Themanaam"</string> + <string name="theme_name_indigo">"Indigo"</string> + <string name="theme_name_indigo_dark">"Indigo Donker"</string> + <string name="theme_name_indigo_amoled">"Indigo Amoled"</string> + <string name="theme_name_white">"Wit"</string> + <string name="theme_name_white_dark">"Wit Donker"</string> + <string name="theme_name_white_amoled">"Wit Amoled"</string> + <string name="theme_name_red">"Rood"</string> + <string name="theme_name_red_dark">"Donkerrood"</string> + <string name="theme_name_red_amoled">"Rood Amoled"</string> + <string name="theme_name_dracula">"Dracula"</string> + <string name="theme_name_calm_pastel">"Calm Pastel"</string> + <string name="create_light_theme">"Maak een Lichte Thema +Gebaseerd op een Indigo thema"</string> + <string name="create_dark_theme">"Maak een Donkere Thema +Gebaseerd op een Indigo Donkere Thema"</string> + <string name="create_amoled_theme">"Maak een Amoled Thema +Gebaseerd op een Indigo Amoled Thema"</string> + <string name="create_theme_info">"Als je een thema wilt maken op basis van een ander thema, klik dan op de \"+\" - knop op een thema."</string> + <string name="edit_theme_name">"Wijzig Themanaam"</string> + <string name="edit_theme">"Wijzig Thema"</string> + <string name="delete_theme">"Verwijder Thema"</string> + <string name="delete_theme_dialog_message">"Weet je zeker dat u%1$s wilt verwijderen?"</string> + <string name="share_theme">"Deel Thema"</string> + <string name="change_theme_name">"Naam wijzigen"</string> + <string name="theme_copied">"Gekopieerd! Plak het en deel het met andere mensen."</string> + <string name="copy_theme_faied">"Kan de themaconfiguratie niet kopiëren"</string> + <string name="cannot_find_theme">"Kan deze thema niet vinden"</string> + <string name="import_theme">"Importeer Thema"</string> + <string name="no_data_in_clipboard">"Kan gegevens niet vinden op klembord"</string> + <string name="import_theme_success">"Importeer Thema gelukt"</string> + <string name="parse_theme_failed">"Parse Thema Mislukt"</string> + <string name="duplicate_theme_name_dialog_title">"Duplicaat Thema Gevonden"</string> + <string name="duplicate_theme_name_dialog_message">"Een thema in de database wordt ook wel %1$s genoemd. Wil je de naam van dit geïmporteerde thema wijzigen?"</string> + <string name="rename">"Hernoemen"</string> + <string name="override">"Overschrijven"</string> + <string name="color_picker">"Kleurenkiezer"</string> + <string name="invalid_color">"Ongeldige Kleur"</string> + <string name="delete_all_subreddits_success">"Verwijder alle subreddits gelukt"</string> + <string name="delete_all_users_success">"Verwijder alle gebruikers gelukt"</string> + <string name="delete_all_sort_types_success">"Verwijder alle sorteringstypen gelukt"</string> + <string name="delete_all_post_layouts_success">"Verwijder alle layouts gelukt"</string> + <string name="delete_all_themes_success">"Verwijder alle themas gelukt"</string> + <string name="delete_all_front_page_scrolled_positions_success">"Verwijder alle gescrolde posities op de voorpagina gelukt"</string> + <string name="reset_all_settings_success">"Reset alle instellingen gelukt"</string> + <string name="username_preview">"u/Hostilenemy"</string> + <string name="subreddit_preview">"r/Infinity_For_Reddit"</string> + <string name="primary_text_preview">"Primaire Tekst"</string> + <string name="secondary_text_preview">"Secundaire Tekst"</string> + <string name="post_title_preview">"Dit is een post"</string> + <string name="post_content_preview">"Deze zwaartekrachtgrap wordt een beetje oud, maar ik trap er elke keer in."</string> + <string name="post_type_preview">"Post"</string> + <string name="flair_preview">"Flair"</string> + <string name="awards_preview">"4 Awards"</string> + <string name="author_flair_preview">"Auteur Flair"</string> + <string name="comment_content_preview">"Ik heb voor mijn vriendin een beterschapskaartje. +Ze is niet ziek of zo, maar ze kan zeker beter worden."</string> + <string name="edit_multi_reddit">"Wijzig Multireddit"</string> + <string name="delete_multi_reddit">"Verwijder Multireddit"</string> + <string name="n_awards">"%1$d Awards"</string> + <string name="one_award">"1 Award"</string> + <string name="report">"Meld"</string> + <string name="reporting">"Aan het melden"</string> + <string name="report_successful">"Gemeld"</string> + <string name="report_failed">"Melden mislukt"</string> + <string name="report_reason_not_selected">"Je hebt geen reden gekozen"</string> + <string name="report_reason_general_spam">"Het is spam"</string> + <string name="report_reason_general_copyright_issue">"Het bevat een auteursrechtkwestie"</string> + <string name="report_reason_general_child_pornography">"Het bevat kinderpornografie"</string> + <string name="report_reason_general_abusive_content">"Het bevat beledigende inhoud"</string> + <string name="home">"Thuis"</string> + <string name="popular">"Populair"</string> + <string name="notifications">"Notificaties"</string> + <string name="messages">"Berichten"</string> + <string name="message">"Bericht"</string> + <string name="fetch_gfycat_video_failed">"Ophalen van Gfycat video is mislukt"</string> + <string name="fetch_redgifs_video_failed">"Ophalen van Redgifs video is mislukt"</string> + <string name="fetching_video_info_please_wait">"Ophalen van videoinfo. Even geduld aub."</string> + <string name="error_fetching_imgur_media">"Kan afbeeldingen niet laden"</string> + <string name="downloading_reddit_video">"Videotrack downloaden"</string> + <string name="downloading_reddit_video_audio_track">"Audiotrack downloaden"</string> + <string name="downloading_reddit_video_muxing">"Muxing Video en Audio"</string> + <string name="downloading_reddit_video_save_file_to_public_dir">"Video Opslaan"</string> + <string name="downloading_reddit_video_finished">"Gedownload"</string> <!-- Fuzzy --> - <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">Werkbalk in compacte layout standaard verborgen</string> - <string name="settings_customize_bottom_app_bar_title">Pas de onderste navigatiebalk aan</string> - <string name="settings_main_activity_bottom_app_bar_group_summary">Hoofdpagina</string> - <string name="settings_other_activities_bottom_app_bar_group_summary">Andere Pagina\'s</string> - <string name="settings_bottom_app_bar_option_count">Aantal Opties</string> - <string name="settings_bottom_app_bar_option_1">Optie 1</string> - <string name="settings_bottom_app_bar_option_2">Optie 2</string> - <string name="settings_bottom_app_bar_option_3">Optie 3</string> - <string name="settings_bottom_app_bar_option_4">Optie 4</string> - <string name="settings_bottom_app_bar_fab">Zwevende actieknop</string> - <string name="settings_data_saving_mode">Databesparingsmodus</string> - <string name="settings_data_saving_mode_info_summary">In gegevensbesparingsmodus:\nVoorbeeldafbeeldingen hebben een lagere resolutie.\nReddit-video\'s hebben een lagere resolutie.\nAutomatisch afspelen van video is uitgeschakeld.</string> - <string name="settings_translation_title">Vetaling</string> - <string name="settings_translation_summary">Vertaal deze app op POEditor. Met dank aan alle bijdragers.</string> - <string name="settings_credits_national_flags">Nationale Vlaggen</string> - <string name="settings_credits_national_flags_summary">Icoon gemaakt door Freepik van www.flaticon.com</string> - <string name="copy_failed">Kopiëren mislukt</string> - <string name="delete_all_legacy_settings_success">Verwijder alle oude instellingen gelukt</string> - <string name="downloading_media_finished">Gedownload</string> - <string name="downloading_image_or_gif_failed_cannot_get_destination_directory">Download mislukt: geen toegang tot de bestemmingsmap</string> - <string name="downloading_media_failed_cannot_download_media">Download mislukt</string> - <string name="downloading_media_failed_cannot_save_to_destination_directory">Downloaden mislukt: kan het bestand niet opslaan in de bestemmingsmap</string> - <string name="view_full_comment_markdown">Bekijk volledige markdown</string> - <string name="select_user_flair_success">Gebruikersflair geselecteerd</string> - <string name="select_this_user_flair">Selecteer deze gebruikersflair?</string> - <string name="select_header_size">Selecteer Koptekstgrootte</string> - <string name="large">Groot</string> - <string name="small">Klein</string> - <string name="insert_link">Link Invoegen</string> - <string name="text_hint">Tekst</string> - <string name="link_hint">Link</string> - <string name="unlock_account_section">Ontgrendel het Accountgedeelte</string> - <string name="unlock">Ontgrendel</string> - <string name="submit_post">Post indienen</string> - <string name="refresh">Ververs</string> - <string name="change_sort_type">Wijzig het sorteertype</string> - <string name="change_post_layout">Wijzig het postlayout</string> - <string name="give_award_dialog_title">Geef Award?</string> - <string name="anonymous">Anoniem</string> + <string name="downloading_reddit_video_failed_cannot_get_cache_directory">"Download mislukt: geen toegang tot de cachemap"</string> + <string name="downloading_reddit_video_failed_cannot_download_video">"Download mislukt: kan video niet downloaden"</string> + <string name="downloading_reddit_video_failed_cannot_save_video">"Download mislukt: kan video niet in cachemap opslaan"</string> + <string name="downloading_reddit_video_failed_cannot_save_audio">"Download mislukt: kan audio niet opslaan in cachemap"</string> + <string name="downloading_reddit_video_failed_cannot_mux">"Download mislukt: kan video en audio niet samenvoegen"</string> + <string name="downloading_reddit_video_failed_cannot_save_mux_video">"Downloaden mislukt: kan de video niet opslaan in de openbare map"</string> + <string name="wallpaper_set">"Achtergrond set"</string> + <string name="error_set_wallpaper">"Kan geen achtergrond instellen"</string> + <string name="set_to_home_screen">"Als startscherm instellen"</string> + <string name="set_to_lock_screen">"Als vergrendeldscherm instellen"</string> + <string name="set_to_both">"Als beiden instellen"</string> + <string name="default_font_font_preview">"Standaard"</string> + <string name="load_video_in_redgifs">"Probeer de video op Redgifs te laden"</string> + <string name="top_score">"%1$s pnt"</string> + <string name="login_activity_2fa_prompt">"Als je 2-factor authenticatie hebt ingeschakeld, typ dan je wachtwoord als volgt in: <wachtwoord>: <2FA code>. +Voorbeeld: yourpass: 123456"</string> + <string name="block_user">"Blokkeer gebruiker"</string> + <string name="block_user_success">"Geblokkeerd"</string> + <string name="block_user_failed">"Kan gebruiker niet blokkeren"</string> + <string name="submit_crosspost_activity_label">"Crosspost"</string> + <string name="give_award_activity_label">"Geef Award"</string> + <string name="action_crosspost">"Crosspost"</string> + <string name="action_select_user_flair">"Selecteer Gebruikersflair"</string> + <string name="action_give_award">"Geef Award"</string> + <string name="posts">"Posts"</string> + <string name="sidebar">"Zijbalk"</string> + <string name="only_for_logged_in_user">"Alleen voor ingelogde gebruikers"</string> + <string name="settings_number_of_columns_in_post_feed_title">"Het Aantal Kolommen in de Postfeed"</string> + <string name="settings_number_of_columns_in_post_feed_portrait_title">"Portret"</string> + <string name="settings_number_of_columns_in_post_feed_landscape_title">"Landschap"</string> + <string name="settings_nsfw_and_spoiler_title">"NSFW & Spoiler"</string> + <string name="settings_delete_all_legacy_settings_title">"Verwijder alle legacyinstellingen"</string> + <string name="restart_app_see_changes">"Start de app opnieuw om de wijzigingen te zien"</string> + <string name="settings_tab_count">"Aantal Tabbladen"</string> + <string name="settings_show_tab_names">"Tabbladnamen Weergeven"</string> + <string name="settings_more_tabs_summary">"Meer Tabbladen"</string> + <string name="settings_more_tabs_info_summary">"Het inschakelen van de volgende opties zal onbedoeld gedrag veroorzaken: Tabbladen kunnen alle inhoud verliezen nadat ze naar andere zijn overgeschakeld. Dit is hetzelfde als het vernieuwen van de pagina."</string> + <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">"Toon Favoriete Geabonneerde Subreddits"</string> + <string name="settings_more_tabs_show_subscribed_subreddits_title">"Toon Geabonneerde Subreddits"</string> + <string name="settings_download_location_title">"Download Locatie"</string> + <string name="settings_image_download_location_title">"Afbeeldingen Downloadlocatie"</string> + <string name="settings_gif_download_location_title">"GIF Downloadlocatie"</string> + <string name="settings_video_download_location_title">"Video Downloadlocatie"</string> + <string name="settings_separate_folder_for_each_subreddit">"Aparte Map Voor Elke Subreddit"</string> + <string name="settings_swipe_action_title">"Swipe-actie"</string> + <string name="settings_disable_swiping_between_tabs_title">"Schakel Swipen Tussen Tabbladen Uit"</string> + <string name="settings_enable_swipe_action_title">"Schakel Swipen In"</string> + <string name="settings_swipe_action_threshold">"Drempel"</string> + <string name="settings_pull_to_refresh_title">"Trek om te vernieuwen"</string> + <string name="settings_security_title">"Beveiliging"</string> + <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Verificatie vereist om naar het accountgedeelte in de navigatielade te gaan"</string> <!-- Fuzzy --> - <string name="give_award_error_message">Code: %1$d/\nBericht: %2$s</string> - <string name="give_award_success">Award gegeven</string> - <string name="give_award_failed">Mislukt</string> - <string name="recent_searches">Recente zoekopdrachten</string> - <string name="warning">Waarschuwing</string> - <string name="this_is_a_nsfw_subreddit">Dit is een NSFW subreddit.</string> - <string name="this_user_has_nsfw_content">Deze gebruiker heeft NSFW inhoud</string> - <string name="dismiss">Afwijzgen</string> - <string name="leave">Verlaten</string> + <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Druk lang in om werkbalk in compacte layout te verbergen"</string> <!-- Fuzzy --> - <string name="go_to_subreddit">Ga naar subreddit</string> + <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">"Werkbalk in compacte layout standaard verborgen"</string> + <string name="settings_customize_bottom_app_bar_title">"Pas de onderste navigatiebalk aan"</string> + <string name="settings_main_activity_bottom_app_bar_group_summary">"Hoofdpagina"</string> + <string name="settings_other_activities_bottom_app_bar_group_summary">"Andere Pagina's"</string> + <string name="settings_bottom_app_bar_option_count">"Aantal Opties"</string> + <string name="settings_bottom_app_bar_option_1">"Optie 1"</string> + <string name="settings_bottom_app_bar_option_2">"Optie 2"</string> + <string name="settings_bottom_app_bar_option_3">"Optie 3"</string> + <string name="settings_bottom_app_bar_option_4">"Optie 4"</string> + <string name="settings_bottom_app_bar_fab">"Zwevende actieknop"</string> + <string name="settings_data_saving_mode">"Databesparingsmodus"</string> + <string name="settings_data_saving_mode_info_summary">"In gegevensbesparingsmodus: +Voorbeeldafbeeldingen hebben een lagere resolutie. +Reddit-video's hebben een lagere resolutie. +Automatisch afspelen van video is uitgeschakeld."</string> + <string name="settings_translation_title">"Vetaling"</string> + <string name="settings_translation_summary">"Vertaal deze app op POEditor. Met dank aan alle bijdragers."</string> + <string name="settings_credits_national_flags">"Nationale Vlaggen"</string> + <string name="settings_credits_national_flags_summary">"Icoon gemaakt door Freepik van www.flaticon.com"</string> + <string name="copy_failed">"Kopiëren mislukt"</string> + <string name="delete_all_legacy_settings_success">"Verwijder alle oude instellingen gelukt"</string> + <string name="downloading_media_finished">"Gedownload"</string> + <string name="downloading_image_or_gif_failed_cannot_get_destination_directory">"Download mislukt: geen toegang tot de bestemmingsmap"</string> + <string name="downloading_media_failed_cannot_download_media">"Download mislukt"</string> + <string name="downloading_media_failed_cannot_save_to_destination_directory">"Downloaden mislukt: kan het bestand niet opslaan in de bestemmingsmap"</string> + <string name="view_full_comment_markdown">"Bekijk volledige markdown"</string> + <string name="select_user_flair_success">"Gebruikersflair geselecteerd"</string> + <string name="select_this_user_flair">"Selecteer deze gebruikersflair?"</string> + <string name="select_header_size">"Selecteer Koptekstgrootte"</string> + <string name="large">"Groot"</string> + <string name="small">"Klein"</string> + <string name="insert_link">"Link Invoegen"</string> + <string name="text_hint">"Tekst"</string> + <string name="link_hint">"Link"</string> + <string name="unlock_account_section">"Ontgrendel het Accountgedeelte"</string> + <string name="unlock">"Ontgrendel"</string> + <string name="submit_post">"Post indienen"</string> + <string name="refresh">"Ververs"</string> + <string name="change_sort_type">"Wijzig het sorteertype"</string> + <string name="change_post_layout">"Wijzig het postlayout"</string> + <string name="give_award_dialog_title">"Geef Award?"</string> + <string name="anonymous">"Anoniem"</string> <!-- Fuzzy --> - <string name="go_to_user">Ga naar gebruiker</string> - <string name="go_to_thing_hint">Naam</string> - <string name="random">Willekeurig</string> - <string name="random_subreddit">Willekeurige Subreddit</string> - <string name="random_nsfw_subreddit">Willekeurige NSFW Subreddit</string> - <string name="random_post">Willekeurige Post</string> - <string name="random_nsfw_post">Willekeurige NSFW Post</string> - <string name="fetch_random_thing_failed">Probeer later opnieuw</string> - <string name="downloading">Downloaden</string> - <string name="subreddit_filter_popular_and_all_activity_label">r/all en r/popular</string> - <string name="settings_miscellaneous_title">Diversen</string> - <string name="settings_respect_subreddit_recommended_comment_sort_type_title">Respecteer Subreddit Aanbevolen Sorteertype voor Reacties</string> - <string name="settings_respect_subreddit_recommended_comment_sort_type_summary">Het Sorteertype voor reacties wordt niet opgeslagen</string> - <string name="settings_subreddit_filter_category">Verberg Subreddits</string> - <string name="settings_subreddit_filter_popular_and_all">In r/popular en r/all</string> - <string name="settings_credits_ufo_capturing_animation_title">UFO ontvoering animatie</string> - <string name="select_video_quality">Selecteer Videokwaliteit</string> - <string name="settings_swipe_action_haptic_feedback_title">Haptische Feedback</string> - <string name="settings_hide_subreddit_description_title">Verberg Subreddit Omschrijving</string> - <string name="settings_disable_image_preview_title">Schakel Afbeeldingsvoorbeeld uit in de Gegevensbesparingsmodus</string> - <string name="settings_swipe_action_swipe_left_title">Swipe naar links</string> - <string name="settings_swipe_action_swipe_right_title">Swipe naar rechts</string> - <string name="settings_swipe_action_info_summary">Niet van toepassing op postfeed met meer dan 1 kolom of postdetail.</string> - <string name="theme_item_no_preview_post_type_icon_tint">Geen Voorbeeld Posttype Pictogramkleur</string> - <string name="theme_item_no_preview_post_type_icon_tint_detail">Toegepast op: pictogram dat het type post aangeeft wanneer er geen voorbeeld beschikbaar is</string> - <string name="theme_item_no_preview_post_type_background_color">Geen Voorbeeld Posttype Achtergrondkleur</string> - <string name="theme_item_no_preview_post_type_background_color_detail">Toegepast op: tijdelijke aanduiding die het type post aangeeft wanneer er geen voorbeeld beschikbaar is</string> - <string name="settings_language_title">Taal</string> + <string name="give_award_error_message">"Code: %1$d/ +Bericht: %2$s"</string> + <string name="give_award_success">"Award gegeven"</string> + <string name="give_award_failed">"Mislukt"</string> + <string name="warning">"Waarschuwing"</string> + <string name="this_is_a_nsfw_subreddit">"Dit is een NSFW subreddit."</string> + <string name="this_user_has_nsfw_content">"Deze gebruiker heeft NSFW inhoud"</string> + <string name="dismiss">"Afwijzgen"</string> + <string name="leave">"Verlaten"</string> + + <!-- Fuzzy --> + <string name="go_to_subreddit">"Ga naar subreddit"</string> + + <!-- Fuzzy --> + <string name="go_to_user">"Ga naar gebruiker"</string> + <string name="go_to_thing_hint">"Naam"</string> + <string name="random">"Willekeurig"</string> + <string name="random_subreddit">"Willekeurige Subreddit"</string> + <string name="random_nsfw_subreddit">"Willekeurige NSFW Subreddit"</string> + <string name="random_post">"Willekeurige Post"</string> + <string name="random_nsfw_post">"Willekeurige NSFW Post"</string> + <string name="fetch_random_thing_failed">"Probeer later opnieuw"</string> + <string name="downloading">"Downloaden"</string> + <string name="subreddit_filter_popular_and_all_activity_label">"r/all en r/popular"</string> + <string name="settings_miscellaneous_title">"Diversen"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_title">"Respecteer Subreddit Aanbevolen Sorteertype voor Reacties"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_summary">"Het Sorteertype voor reacties wordt niet opgeslagen"</string> + <string name="settings_subreddit_filter_category">"Verberg Subreddits"</string> + <string name="settings_subreddit_filter_popular_and_all">"In r/popular en r/all"</string> + <string name="settings_credits_ufo_capturing_animation_title">"UFO ontvoering animatie"</string> + <string name="select_video_quality">"Selecteer Videokwaliteit"</string> + <string name="settings_swipe_action_haptic_feedback_title">"Haptische Feedback"</string> + <string name="settings_hide_subreddit_description_title">"Verberg Subreddit Omschrijving"</string> + <string name="settings_disable_image_preview_title">"Schakel Afbeeldingsvoorbeeld uit in de Gegevensbesparingsmodus"</string> + <string name="settings_swipe_action_swipe_left_title">"Swipe naar links"</string> + <string name="settings_swipe_action_swipe_right_title">"Swipe naar rechts"</string> + <string name="settings_swipe_action_info_summary">"Niet van toepassing op postfeed met meer dan 1 kolom of postdetail."</string> + <string name="theme_item_no_preview_post_type_icon_tint">"Geen Voorbeeld Posttype Pictogramkleur"</string> + <string name="theme_item_no_preview_post_type_icon_tint_detail">"Toegepast op: pictogram dat het type post aangeeft wanneer er geen voorbeeld beschikbaar is"</string> + <string name="theme_item_no_preview_post_type_background_color">"Geen Voorbeeld Posttype Achtergrondkleur"</string> + <string name="theme_item_no_preview_post_type_background_color_detail">"Toegepast op: tijdelijke aanduiding die het type post aangeeft wanneer er geen voorbeeld beschikbaar is"</string> + <string name="settings_language_title">"Taal"</string> + <string name="customize_post_filter_activity_label">"Berichtenfilter aanpassen"</string> + <string name="filtered_posts_activity_subtitle">"Gefilterde Posts"</string> + <string name="search_users_result_activity_label">"Gebruikers"</string> + <string name="multireddit_selection_activity_label">"Selecteer een Multireddit"</string> + <string name="action_save_to_database">"Opslaan naar Database"</string> + <string name="action_read_all_messages">"Lees Alle Berichten"</string> + <string name="settings_mark_posts_as_read_on_scroll_title">"Markeer berichten als gelezen bij scroll"</string> + <string name="settings_sort_type_title">"Sorteertype"</string> + <string name="post_filter_usage_multireddit">"Multireddit: %1$s"</string> + <string name="post_filter_usage_multireddit_all">"Multireddit"</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 65024b7c..48a4645a 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -225,6 +225,8 @@ <string name="search">"Szukaj"</string> <string name="posting_video">"Tworzenie postu z wideo"</string> <string name="posting_image">"Tworzenie postu z obrazem"</string> + + <!-- Fuzzy --> <string name="please_wait">"Proszę czekać"</string> <string name="add_account">"Dodaj konto"</string> <string name="anonymous_account">"Anonim"</string> @@ -309,6 +311,8 @@ <string name="settings_volume_keys_navigate_posts_title">"Używaj przycisków głośności, aby nawigować posty"</string> <string name="settings_mute_video_title">"Wycisz filmy"</string> <string name="settings_mute_nsfw_video_title">"Wycisz wideo NSFW"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"Automatycznie próbuj uzyskać filmy z Redgifs, gdy są usunięte z Gfycat"</string> <string name="settings_video_player_ignore_nav_bar_title">"Ignoruj pasek nawigacji w odtwarzaczu wideo"</string> <string name="settings_video_player_ignore_nav_bar_summary">"Zapobiegaj posiadaniu dodatkowego marginesu przez kontroler wideo"</string> @@ -840,7 +844,6 @@ Autoodtwarzanie wideo jest wyłączone."</string> Wiadomość: %2$s"</string> <string name="give_award_success">"Nagroda przyznana"</string> <string name="give_award_failed">"Niepowodzenie"</string> - <string name="recent_searches">"Ostatnie wyszukiwania"</string> <string name="warning">"Ostrzeżenie "</string> <string name="this_is_a_nsfw_subreddit">"To jest subreddit NSFW"</string> <string name="this_user_has_nsfw_content">"Ten użytkownik posiada treści NSFW"</string> @@ -878,6 +881,7 @@ Wiadomość: %2$s"</string> <string name="theme_item_no_preview_post_type_background_color_detail">"Zastosowano dla: Symbol zastępczy wskazujący typ wpisu, gdy podgląd nie jest dostępny"</string> <string name="settings_language_title">"Język"</string> <string name="customize_post_filter_activity_label">"Dostosuj Filtr Posta"</string> + <string name="filtered_posts_activity_subtitle">"Przefiltrowane posty"</string> <string name="post_filter_preference_activity_label">"Filtr postów"</string> <string name="search_users_result_activity_label">"Użytkownicy"</string> <string name="multireddit_selection_activity_label">"Wybierz Multireddit"</string> @@ -896,18 +900,32 @@ Wiadomość: %2$s"</string> <string name="settings_enable_search_history_title">"Włącz historię wyszukiwania"</string> <string name="settings_post_history_title">"Historia postów"</string> <string name="settings_mark_posts_as_read_title">"Oznacz posty jako przeczytane"</string> + <string name="settings_mark_posts_as_read_after_voting_title">"Zaznacz post jako przeczytany po dodaniu vota"</string> <string name="settings_mark_posts_as_read_on_scroll_title">"Oznacz posty jako przeczytane podczas przewijania"</string> <string name="settings_hide_read_posts_automatically_title">"Automatycznie ukrywaj przeczytane posty"</string> <string name="settings_sort_type_title">"Typ Sortu"</string> + <string name="settings_save_sort_type_title">"Zapisz typ sortowania"</string> + <string name="settings_subreddit_default_sort_type_title">"Domyślny typ sortowania subbreditów"</string> + <string name="settings_subreddit_default_sort_time_title">"Domyślny typ sortowania czasu subredditów"</string> + <string name="settings_user_default_sort_type_title">"Domyślny typ sortowania użytkowników"</string> + <string name="settings_user_default_sort_time_title">"Domyślny typ sortowania czasu użytkowników"</string> <string name="open_link">"Otwórz link"</string> <string name="select_subreddits_and_users">"Wybierz subreddity i użytkowników"</string> + <string name="theme_item_read_post_title_color">"Kolor tytułu przeczytanego postu"</string> + <string name="theme_item_read_post_title_color_detail">"Używane do: tytuł przeczytanego postu"</string> + <string name="theme_item_read_post_content_color">"Kolor treści przeczytanego postu"</string> + <string name="theme_item_read_post_content_color_detail">"Używane do: treść przeczytanego postu"</string> + <string name="hide_read_posts">"Ukryj przeczytane posty"</string> + <string name="filter_posts">"Filtruj posty"</string> <string name="only_nsfw">"Tylko NSFW"</string> <string name="only_spoiler">"Tylko spoilery"</string> + <string name="title_excludes_regex_hint">"Tytuł: wyklucza regex"</string> <string name="exclude_subreddits_hint">"Bez subredditów (np. funny,AskReddit)"</string> <string name="exclude_users_hint">"Bez użytkowników"</string> <string name="post_filter_requires_a_name">"Jaka jest nazwa filtru tego posta?"</string> <string name="duplicate_post_filter_dialog_title">"'%1$s' już istnieje"</string> <string name="duplicate_post_filter_dialog_message">"Nadpisać?"</string> + <string name="apply_post_filter_to">"Zastosuj do"</string> <string name="post_filter_usage_home">"Strona główna"</string> <string name="post_filter_usage_subreddit_all">"Subreddit"</string> <string name="post_filter_usage_user">"Użytkownik: %1$s"</string> @@ -915,5 +933,71 @@ Wiadomość: %2$s"</string> <string name="post_filter_usage_multireddit">"MultiReddit: %1$s"</string> <string name="post_filter_usage_multireddit_all">"Multireddit"</string> <string name="post_filter_usage_search">"Szukaj"</string> + <string name="subreddit">"Subreddit"</string> + <string name="user">"Użytkownik"</string> + <string name="edit_post_filter_name_of_usage_info">"Zostaw puste aby zastosować ten filtr postów dla każdego subbredita / +użytkownika / multireddita"</string> + <string name="read_all_messages_time_limit">"Zbyt często to robisz. Spróbuj później. To limit przesyłu API Reddita."</string> + <string name="read_all_messages_success">"Odczytano wszystkie wiadomości pomyślnie"</string> + <string name="read_all_messages_failed">"Nie można odczytać wiadomości"</string> + <string name="add_subreddit_or_user_to_multireddit_success">"%1$s został dodany multireddita %2$s"</string> + <string name="add_subreddit_or_user_to_multireddit_failed">"Nie można dodać %1$s do multireddita %2$s"</string> <string name="choose_a_user">"Wybierz użytkownika"</string> + <string name="settings_hide_post_type">"Ukryj typ posta"</string> + <string name="settings_hide_the_number_of_awards">"Ukryj liczbę nagród"</string> + <string name="settings_hide_subreddit_and_user_prefix">"Ukryj prefix subbredita i użytkownika"</string> + <string name="settings_hide_the_number_of_votes">"Ukryj liczbę głosów"</string> + <string name="settings_hide_the_number_of_comments">"Ukryj liczbę komentarzy"</string> + <string name="post_layout_gallery">"Layout galerii"</string> + <string name="post_layout_card_2">"Layout karty 2"</string> + <string name="have_trouble_login_message">"Chcesz spróbować innej opcji logowania?"</string> + <string name="vote">"Zagłosuj"</string> + <string name="action_share_link">"Zapisz link"</string> + <string name="action_copy_link">"Skopiuj link"</string> + <string name="action_add_to_post_filter">"Dodaj do filtra postów"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"Nie bluruj obrazków NSFW w NSFW subredditach"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Pokazuj awatary z lewej strony"</string> + <string name="settings_backup_settings_title">"Opcje backupu"</string> + <string name="settings_restore_settings_title">"Przywróć ustawienia"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Schowaj sekcję ulubionych subredditów"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Schowaj sekcję subskrybowanych subredditów"</string> + <string name="anonymous_front_page_no_subscriptions">"Zacznij dołączając do subreddita!"</string> + <string name="create_zip_in_destination_directory_failed">"Nie można stworzyć backupu w podanej ścieżce"</string> + <string name="restore_settings_success">"Pomyślnie przywrócono ustawienia. Zrestartuj aplikację zobaczyć zmiany."</string> + <string name="restore_settings_partially_failed">"Niektóre opcje mogły zostać nie wczytane poprawnie. Zrestartuj aplikację aby zobaczyć zmiany."</string> + <string name="restore_settings_failed_file_corrupted">"Nie można wczytać ustawień. Plik może być uszkodzony."</string> + <string name="restore_settings_failed_cannot_get_file">"Brak dostępu do pliku"</string> + <string name="do_not_show_this_again">"Nie pokazuj ponownie"</string> + <string name="continue_suicide_prevention_activity">"Kontynuuj"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"Błąd v.redd.it wideo: Nie można skopiować URL"</string> + <string name="always_on">"Zawsze włączony"</string> + <string name="only_on_wifi">"Tylko przez wi-fi"</string> + <string name="never">"Nigdy"</string> + <string name="extra_large">"Ekstra wielki"</string> + <string name="enormously_large">"Ekstremalnie wielki"</string> + <string name="default_in_array">"Domyślny"</string> + <string name="off">"Wyłącz"</string> + <string name="upvote">"Upvote"</string> + <string name="downvote">"Downvote"</string> + <string name="select">"Wybierz"</string> + <string name="suggest_title">"Zasugeruj tytuł"</string> + <string name="suggest_title_failed">"Nie można zasugerować tytułu"</string> + <string name="settings_crash_reports_title">"Crash reporty"</string> + <string name="settings_disable_nsfw_forever_title">"Wyłącz NSFW na zawszę"</string> + <string name="save_comment">"Zapisz"</string> + <string name="copy_multi_reddit_path">"Skopiuj ścieżkę multireddita"</string> + <string name="copy_multi_reddit_path_failed">"Nie można skopiować ścieżki multireddita"</string> + <string name="crash_reports_deleted">"Reporty crashów zostały usunięte"</string> + <string name="disable_nsfw_forever_message">"Raz włączone, NSFW będzie wyłączone permamentnię, nieważnie czy inne ustawienia NSFW będą włączone czy nie. Jedyną opcją na włącznie NSFW z powrotem jest wyczyszczenie danych aplikacji. + +Nadal chcesz ją włączyć?"</string> + <string name="reply">"Odpowiedz"</string> + <string name="uploaded_images">"Przesłane obrazy"</string> + <string name="select_image">"Wybierz obraz"</string> + <string name="uploading_image">"Przesyłanie"</string> + <string name="upload_image_failed">"Błąd przesyłania obrazu"</string> + <string name="search_comments">"Szukaj w komentarzach"</string> + <string name="please_wait_image_is_uploading">"Obraz jest wciąż przesyłany. Proszę czekać."</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 742664e0..5c3a26ac 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -98,8 +98,10 @@ Toque para tentar novamente."</string> <string name="no_messages">"Vazio"</string> <string name="nsfw">"NSFW"</string> <string name="karma_info">"Karma: %1$d"</string> - <string name="karma_info_user_detail">"Karma: %1$d (%2$d + %3$d)"</string> - <string name="cakeday_info">"Dia do bolo: %1$s"</string> + <string name="karma_info_user_detail">"Karma: +%1$d (%2$d + %3$d)"</string> + <string name="cakeday_info">"Dia do bolo: +%1$s"</string> <string name="since">"Desde:"</string> <string name="profile">"Perfil"</string> @@ -193,7 +195,7 @@ Toque para tentar novamente."</string> <string name="no_flair">"Nenhuma etiqueta"</string> <string name="error_loading_flairs">"Falha ao carregar etiquetas. Toque para tentar novamente."</string> - <string name="no_rule">"Nenhuma regra."</string> + <string name="no_rule">"Nenhuma regra"</string> <string name="error_loading_rules">"Falha ao carregar regras. Toque para tentar novamente."</string> <string name="error_loading_rules_without_retry">"Falha ao Carregar Regras"</string> @@ -235,6 +237,8 @@ Toque para tentar novamente."</string> <string name="search">"Buscar"</string> <string name="posting_video">"Postando Vídeo"</string> <string name="posting_image">"Postando Imagem"</string> + + <!-- Fuzzy --> <string name="please_wait">"Por favor aguarde."</string> <string name="add_account">"Adicionar conta"</string> <string name="anonymous_account">"Anônimo"</string> @@ -245,7 +249,7 @@ Toque para tentar novamente."</string> <string name="post_saved_failed">"Não foi possível salvar o post"</string> <string name="post_unsaved_success">"Removido dos posts salvos"</string> <string name="post_unsaved_failed">"Não foi possível remover dos posts salvos"</string> - <string name="post_hide_success">"Post oculto"</string> + <string name="post_hide_success">"Post ocultado"</string> <string name="post_hide_failed">"Não foi possível ocultar o post"</string> <string name="post_unhide_success">"Post visível"</string> <string name="thing_favorite_failed">"Falha ao adicionar aos favoritos"</string> @@ -287,12 +291,12 @@ Toque para tentar novamente."</string> <string name="label_account">"Conta"</string> <string name="label_post">"Post"</string> <string name="label_preferences">"Preferências"</string> - <string name="account_switched">"Conta alterada, por isso todas as páginas sumiram."</string> + <string name="account_switched">"Conta alterada. Por isso todas as páginas sumiram."</string> <string name="settings_notification_master_title">"Notificação"</string> <string name="settings_notification_enable_notification_title">"Ativar Notificações"</string> <string name="settings_notification_interval_title">"Intervalo de Verificação de Notificações"</string> <string name="settings_theme_title">"Tema"</string> - <string name="settings_amoled_dark_title">"Tema Escuro (Amoled)"</string> + <string name="settings_amoled_dark_title">"Tema Amoled"</string> <string name="settings_interface_title">"Interface"</string> <string name="settings_gestures_and_buttons_title">"Gestos e Botões"</string> <string name="settings_save_front_page_scrolled_position_title">"Posição de rolagem salva na tela inicial"</string> @@ -319,6 +323,8 @@ Toque para tentar novamente."</string> <string name="settings_volume_keys_navigate_posts_title">"Usar as Teclas de Volume para Navegar Entre Posts"</string> <string name="settings_mute_video_title">"Silenciar Vídeos"</string> <string name="settings_mute_nsfw_video_title">"Silenciar Vídeos NSFW"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"Tentar Acessar Automaticamente o Redgifs se os Vídeos do Gfycat Forem Removidos."</string> <string name="settings_video_player_ignore_nav_bar_title">"Ignorar Barra de Navegação no Reprodutor de Vídeos"</string> <string name="settings_video_player_ignore_nav_bar_summary">"Evitar que o Controle de Vídeo Tenha Margens Largas"</string> @@ -326,7 +332,7 @@ Toque para tentar novamente."</string> <string name="settings_category_comment_title">"Comentar"</string> <string name="settings_show_top_level_comments_first_title">"Exibir Comentários Mais Votados Primeiro"</string> <string name="settings_show_comment_divider_title">"Exibir Divisão de Comentários"</string> - <string name="settings_comment_toolbar_hide_on_click">"Clicar para Exibir/Ocultar Barra de Comentários"</string> + <string name="settings_comment_toolbar_hide_on_click">"Clicar para Exibir/Ocultar a Barra de Comentários"</string> <string name="settings_fully_collapse_comment_title">"Retrair Completamente os Comentários"</string> <string name="settings_comment_toolbar_hidden">"Barra de Comentários Oculta por Padrão"</string> <string name="settings_show_absolute_number_of_votes_title">"Exibir Número Absoluto de Votos"</string> @@ -345,7 +351,7 @@ Toque para tentar novamente."</string> <string name="settings_swipe_to_go_back_summary">"Não se Aplica a Todas as Páginas"</string> <string name="settings_lock_jump_to_next_top_level_comment_button_title">"Bloquear Botão de Avanço para Próximo Comentário Mais Votado"</string> <string name="settings_lock_bottom_app_bar_title">"Bloquear Barra de Navegação Inferior"</string> - <string name="settings_swipe_up_to_hide_jump_to_next_top_level_comment_button_title">"Deslizar para Cima para Ocultar Botão de Avanço para Próximo Comentário Mais Votado"</string> + <string name="settings_swipe_up_to_hide_jump_to_next_top_level_comment_button_title">"Deslizar para Cima para Ocultar o Botão de Avanço para Próximo Comentário Mais Votado"</string> <string name="settings_lazy_mode_interval_title">"Intervalo do Modo Preguiçoso"</string> <string name="settings_font_title">"Fonte"</string> <string name="settings_preview_font_title">"Pré-visualizar Fonte"</string> @@ -412,9 +418,9 @@ Toque para tentar novamente."</string> <string name="settings_tab_3_summary">"Aba 3"</string> <string name="settings_tab_title">"Título"</string> <string name="settings_tab_post_type">"Tipo"</string> - <string name="settings_tab_subreddit_name">"Nome do Subreddit (Sem o Prefixo \"r/\")"</string> + <string name="settings_tab_subreddit_name">"Nome do Subreddit (Sem o Prefixo ''r/'')"</string> <string name="settings_tab_multi_reddit_name">"Nome do Multireddit (/usuário/nomedoseuusuário/m/nomedoseumultireddit)"</string> - <string name="settings_tab_username">"Usuário (Sem o Prefixo \"u/\")"</string> + <string name="settings_tab_username">"Usuário (Sem o Prefixo ''u/'')"</string> <string name="no_developer_easter_egg">"Não existem opções de desenvolvedor aqui"</string> <string name="no_link_available">"Link não disponível"</string> <string name="exit_when_submit">"Sair?"</string> @@ -545,7 +551,7 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="theme_item_bottom_app_bar_background_color">"Cor da Barra de Navegação Inferior"</string> <string name="theme_item_bottom_app_bar_background_color_detail">"Aplicado a: Barra de navegação inferior"</string> <string name="theme_item_primary_icon_color">"Cor do Ícone Primário"</string> - <string name="theme_item_primary_icon_color_detail">"Aplicado a: Ícones no menu de navegação"</string> + <string name="theme_item_primary_icon_color_detail">"Aplicado a: Ícones no menu de navegação."</string> <string name="theme_item_bottom_app_bar_icon_color">"Cor do Ícone da Barra de Navegação Inferior"</string> <string name="theme_item_bottom_app_bar_icon_color_detail">"Aplicado a: Ícones na barra de navegação inferior"</string> <string name="theme_item_post_icon_and_info_color">"Cor do Ícone de Post e Informações"</string> @@ -670,7 +676,7 @@ Baseado no tema Índigo"</string> Baseado no tema Índigo Escuro"</string> <string name="create_amoled_theme">"Criar um Tema Amoled Baseado no tema Índigo Amoled"</string> - <string name="create_theme_info">"Se você deseja criar um tema baseado em outro tema, clique no botão \"+\" localizado no tema"</string> + <string name="create_theme_info">"Se você deseja criar um tema baseado em outro tema, clique no botão \"+\" localizado no tema."</string> <string name="edit_theme_name">"Editar nome do tema"</string> <string name="edit_theme">"Editar tema"</string> <string name="delete_theme">"Excluir tema"</string> @@ -702,12 +708,13 @@ Baseado no tema Índigo Amoled"</string> <string name="primary_text_preview">"Texto primário"</string> <string name="secondary_text_preview">"Texto secundário"</string> <string name="post_title_preview">"Este é um post"</string> - <string name="post_content_preview">"Prévia de conteúdo a ser publicado"</string> + <string name="post_content_preview">"Essa piada da gravidade está ficando velha, mas eu sempre caio nessa."</string> <string name="post_type_preview">"POST"</string> <string name="flair_preview">"Etiqueta"</string> <string name="awards_preview">"4 Prêmios"</string> <string name="author_flair_preview">"Etiqueta de autor"</string> - <string name="comment_content_preview">"Prévia do comentário"</string> + <string name="comment_content_preview">"Eu dei para minha namorada um cartão “Melhore logo”. +Ela não está doente nem nada, mas definitivamente poderia melhorar."</string> <string name="edit_multi_reddit">"Editar multireddit"</string> <string name="delete_multi_reddit">"Excluir Multireddit"</string> <string name="n_awards">"%1$d Prêmios"</string> @@ -751,7 +758,7 @@ Baseado no tema Índigo Amoled"</string> <string name="default_font_font_preview">"Padrão"</string> <string name="load_video_in_redgifs">"Tente carregar o vídeo no Redgifs"</string> <string name="top_score">"%1$s pontos"</string> - <string name="login_activity_2fa_prompt">"Se você tem a Autenticação em 2 Etapas ativada, digite a senha da seguinte forma: <senha>:<códigodeautenticação>. + <string name="login_activity_2fa_prompt">"Se você tem a Autenticação em 2 Etapas ativada, digite a senha da seguinte forma: <senha>:<código de autenticação>. Exemplo: suasenha:123456"</string> <string name="block_user">"Bloquear usuário"</string> <string name="block_user_success">"Bloqueado"</string> @@ -775,8 +782,8 @@ Exemplo: suasenha:123456"</string> <string name="settings_more_tabs_summary">"Mais abas"</string> <string name="settings_more_tabs_info_summary">"Ativar as seguintes opções causará um comportamento indesejado: As abas podem perder todo o conteúdo após alternar para outras. Isso é o mesmo que atualizar a página."</string> - <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">"Mostrar subreddits favoritos que estou inscrito"</string> - <string name="settings_more_tabs_show_subscribed_subreddits_title">"Mostrar subreddits que estou inscrito"</string> + <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">"Mostrar Subreddits Favoritos Que Estou Inscrito"</string> + <string name="settings_more_tabs_show_subscribed_subreddits_title">"Mostrar Subreddits Que Estou Inscrito"</string> <string name="settings_download_location_title">"Local de download"</string> <string name="settings_image_download_location_title">"Local de download de imagem"</string> <string name="settings_gif_download_location_title">"Local de download de gif"</string> @@ -791,10 +798,10 @@ As abas podem perder todo o conteúdo após alternar para outras. Isso é o mesm <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Requer autenticação para ir a sessão de conta no menu de navegação"</string> <!-- Fuzzy --> - <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Aperte e segure para esconder a barra de ferramentas no modo compacto"</string> + <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Aperte e Segure Para Esconder a Barra de Ferramentas no Modo Compacto"</string> <!-- Fuzzy --> - <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">"Barra de ferramentas no modo compacto oculta por padrão"</string> + <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">"Barra de Ferramentas Oculta por Padrão no Modo Compacto"</string> <string name="settings_customize_bottom_app_bar_title">"Personalizar barra de navegação inferior"</string> <string name="settings_main_activity_bottom_app_bar_group_summary">"Página inicial"</string> <string name="settings_other_activities_bottom_app_bar_group_summary">"Outras páginas"</string> @@ -807,7 +814,8 @@ As abas podem perder todo o conteúdo após alternar para outras. Isso é o mesm <string name="settings_data_saving_mode">"Modo economia de dados"</string> <string name="settings_data_saving_mode_info_summary">"No modo de economia de dados: A pré-visualização de imagens fica em menor resolução. -Os vídeos do Reddit ficam em menor resolução."</string> +Os vídeos do Reddit ficam em menor resolução. + A reprodução automática de vídeos fica desativada."</string> <string name="settings_translation_title">"Tradução"</string> <string name="settings_translation_summary">"Traduza o app em POEditor. Obrigado a todos os contribuíntes."</string> <string name="settings_credits_national_flags">"Bandeiras nacionais"</string> @@ -841,10 +849,9 @@ Os vídeos do Reddit ficam em menor resolução."</string> Mensagem: %2$s"</string> <string name="give_award_success">"Prêmio concedido"</string> <string name="give_award_failed">"Falhou"</string> - <string name="recent_searches">"Buscas recentes"</string> <string name="warning">"Aviso"</string> <string name="this_is_a_nsfw_subreddit">"Este é um subreddit NSFW."</string> - <string name="this_user_has_nsfw_content">"Este usuário tem conteúdo NSFW."</string> + <string name="this_user_has_nsfw_content">"Este usuário tem conteúdo NSFW"</string> <string name="dismiss">"Dispensar"</string> <string name="leave">"Sair"</string> @@ -865,12 +872,12 @@ Mensagem: %2$s"</string> <string name="settings_miscellaneous_title">"Miscelânea"</string> <string name="settings_respect_subreddit_recommended_comment_sort_type_title">"Respeitar modo de classificação de comentário recomendado pelo subreddit"</string> <string name="settings_respect_subreddit_recommended_comment_sort_type_summary">"Modo de classificação de comentário não será salvo"</string> - <string name="settings_subreddit_filter_category">"Ocultar subreddits"</string> + <string name="settings_subreddit_filter_category">"Ocultar Subreddits"</string> <string name="settings_subreddit_filter_popular_and_all">"Em r/popular e r/all"</string> <string name="settings_credits_ufo_capturing_animation_title">"Animação de captura de OVNIs"</string> <string name="select_video_quality">"Selecionar qualidade do vídeo"</string> <string name="settings_swipe_action_haptic_feedback_title">"Resposta tátil"</string> - <string name="settings_hide_subreddit_description_title">"Ocultar descrição do subreddit"</string> + <string name="settings_hide_subreddit_description_title">"Ocultar Descrição do Subreddit"</string> <string name="settings_disable_image_preview_title">"Desativar pré-visualização de imagem no modo de economia de dados"</string> <string name="settings_swipe_action_swipe_left_title">"Deslizar para a esquerda"</string> <string name="settings_swipe_action_swipe_right_title">"Deslizar para a direita"</string> @@ -902,7 +909,7 @@ Mensagem: %2$s"</string> <string name="settings_mark_posts_as_read_title">"Marque Posts como Lido"</string> <string name="settings_mark_posts_as_read_after_voting_title">"Marque Posts como Lido depois de votar"</string> <string name="settings_mark_posts_as_read_on_scroll_title">"Marcar post como lido ao rolar página"</string> - <string name="settings_hide_read_posts_automatically_title">"Esconder posts lidos automaticamente"</string> + <string name="settings_hide_read_posts_automatically_title">"Ocultar Posts Lidos Automaticamente"</string> <string name="settings_sort_type_title">"Tipo de Classificação"</string> <string name="settings_save_sort_type_title">"Lembrar Classificação"</string> <string name="settings_subreddit_default_sort_type_title">"Classificação Padrão em Subreddits"</string> @@ -912,13 +919,13 @@ Mensagem: %2$s"</string> <string name="open_link">"Abrir Link"</string> <string name="select_subreddits_and_users">"Selecionar subreddits e usuários"</string> <string name="theme_item_read_post_title_color">"Cor do Título de Post Lido"</string> - <string name="theme_item_read_post_title_color_detail">"Título de Post Lido"</string> + <string name="theme_item_read_post_title_color_detail">"Aplicado a: Título de Post Lido"</string> <string name="theme_item_read_post_content_color">"Cor do Conteúdo de Post Lido"</string> - <string name="theme_item_read_post_content_color_detail">"Conteúdo de Post Lido"</string> + <string name="theme_item_read_post_content_color_detail">"Aplicado a: Conteúdo de Post Lido"</string> <string name="theme_item_read_post_card_view_background_color">"Cor de Fundo da Visualização de Posts em Cartão"</string> <string name="theme_item_read_post_card_view_background_color_detail">"Aplicado a: Fundo de Post Lido"</string> <string name="delete_all_read_posts_success">"Sucesso ao deletar todos os posts já lidos"</string> - <string name="hide_read_posts">"Esconder Posts Lidos"</string> + <string name="hide_read_posts">"Ocultar Posts Lidos"</string> <string name="filter_posts">"Filtrar Posts"</string> <string name="only_nsfw">"Apenas NSFW"</string> <string name="only_spoiler">"Apenas Spoiler"</string> @@ -956,4 +963,97 @@ Mensagem: %2$s"</string> <string name="add_subreddit_or_user_to_multireddit_success">"%1$s está adicionado a multireddit %2$s"</string> <string name="add_subreddit_or_user_to_multireddit_failed">"Não foi possível adicionar %1$s para o multireddit %2$s"</string> <string name="choose_a_user">"Escolha um usuário"</string> + <string name="settings_click_to_show_media_in_gallery_layout">"Clicar para Exibir Mídia no Modo Galeria"</string> + <string name="settings_hide_post_type">"Ocultar Tipo de Post"</string> + <string name="settings_hide_the_number_of_awards">"Ocultar o Número de Prêmios"</string> + <string name="settings_hide_subreddit_and_user_prefix">"Ocultar Prefixos do Subreddit e do Usuário"</string> + + <!-- Fuzzy --> + <string name="settings_hide_the_number_of_votes">"Ocultar o Número de Votos"</string> + <string name="settings_hide_the_number_of_comments">"Ocultar o Número de Comentários"</string> + <string name="post_layout_gallery">"Modo Galeria"</string> + <string name="post_layout_card_2">"Modo Cartão 2"</string> + <string name="have_trouble_login_title">"Tendo Problemas para Logar"</string> + <string name="have_trouble_login_message">"Você quer tentar outra forma de logar?"</string> + <string name="vote">"Votar"</string> + <string name="action_share_link">"Compartilhar Link"</string> + <string name="action_copy_link">"Copiar Link"</string> + <string name="action_add_to_post_filter">"Adicionar ao Filtro de Publicação"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"Não borrar imagens NSFW em Subreddits NSFW"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Mostrar Avatar na Esquerda"</string> + <string name="settings_backup_settings_title">"Configurações de Backup"</string> + <string name="settings_restore_settings_title">"Restaurar Configurações"</string> + <string name="settings_credits_love_animation_title">"Animações de Amor"</string> + <string name="settings_swipe_between_posts_title">"Deslizar Entre Posts"</string> + <string name="settings_navigation_drawer_title">"Menu de Navegação"</string> + <string name="settings_collapse_account_section_title">"Fechar Seção de Conta"</string> + <string name="settings_collapse_post_section_title">"Retrair Seção de Post"</string> + <string name="settings_collapse_preferences_section_title">"Retrair Seção de Preferências"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"Retrair Seção de Subreddits Favoritos"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"Retrair Seção de Subreddits Que Estou Inscrito"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Ocultar Seção de Subreddits Favoritos"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Ocultar Seção de Subreddits Que Estou Inscrito"</string> + <string name="settings_default_search_result_tab">"Guia Padrão dos Resultados da Pesquisa"</string> + <string name="device_default">"Dispositivo Padrão"</string> + <string name="set_by_battery_saver">"Definido Pela Economia de Bateria"</string> + <string name="theme_item_upvote_ratio_icon_tint">"Cor do Ícone de Razão de Upvote"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"Aplicado a: Ícone de Razão de Upvote"</string> + <string name="theme_item_current_user_color">"Usuário Atual"</string> + <string name="theme_item_current_user_color_detail">"Aplicado a: Usuário atual nos comentários"</string> + <string name="exclude_domains_hint">"Excluir domínios"</string> + <string name="anonymous_front_page_no_subscriptions">"Começe se juntando em um subreddit!"</string> + <string name="backup_settings_success">"Configurações exportadas com sucesso para o diretório de destino. A senha do arquivo zip gerado é 123321. Por favor não altere este arquivo zip."</string> + <string name="create_zip_in_destination_directory_failed">"Não foi possível criar o backup zip no diretório de destino"</string> + <string name="backup_some_settings_failed">"Não foi possível realizar o backup de algumas configurações, mas outras foram exportadas com sucesso para o diretório de destino"</string> + <string name="restore_settings_success">"Configurações restauradas com sucesso. Reinicie o app para aplicar as mudanças."</string> + <string name="restore_settings_partially_failed">"Algumas configurações não foram restauradas. Reinicie o app para aplicar as mudanças."</string> + <string name="restore_settings_failed_file_corrupted">"Não foi possível restaurar as configurações. O arquivo pode estar corrompido."</string> + <string name="restore_settings_failed_cannot_get_file">"Não foi possível acessar o arquivo"</string> + <string name="suicide_prevention_quote">"Se você está procurando um sinal para não se matar é isto. \u2764"</string> + <string name="do_not_show_this_again">"Não exibir novamente"</string> + <string name="continue_suicide_prevention_activity">"Continuar"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"Erro ao buscar vídeo v.redd.it: Não foi possível obter o url de redirecionamento"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"Erro ao buscar vídeo em v.redd.it: Não foi possível obter a postagem"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"Erro ao buscar vídeo em v.redd.it: Não foi possível obter o id da postagem"</string> + <string name="always_on">"Sempre Ativo"</string> + <string name="only_on_wifi">"Somente no Wifi"</string> + <string name="never">"Nunca"</string> + <string name="normal">"Normal"</string> + <string name="extra_large">"Muito Grande"</string> + <string name="enormously_large">"Extremamente Grande"</string> + <string name="default_in_array">"Padrão"</string> + <string name="off">"Desligado"</string> + <string name="only_on_cellular_data">"Somente nos Dados Móveis"</string> + <string name="upvote">"Upvote"</string> + <string name="downvote">"Downvote"</string> + <string name="select">"Selecionar"</string> + <string name="exclude_subreddit">"Excluir este subreddit"</string> + <string name="exclude_user">"Excluir este usuário"</string> + <string name="exclude_flair">"Excluir esta etiqueta"</string> + <string name="contain_flair">"Conter esta estiqueta"</string> + <string name="exclude_domain">"Excluir Domínio"</string> + <string name="suggest_title">"Sugerir Título"</string> + <string name="suggest_title_failed">"Falha ao sugerir título"</string> + <string name="action_delete_logs">"Apagar Registros"</string> + <string name="inbox_with_count">"Inbox (%1$d)"</string> + <string name="comment_continue_thread">"Continuar thread"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"Deslize Verticalmente Para Voltar da Mídia"</string> + <string name="settings_hide_post_flair">"Ocultar Etiqueta do Post"</string> + <string name="settings_crash_reports_title">"Relatório de Erros"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"Cuidado"</string> + <string name="settings_disable_nsfw_forever_title">"Desativar NSFW Permanentemente"</string> + <string name="settings_show_only_one_comment_level_indicator">"Exibir Somente Um Nível de Comentário"</string> + <string name="save_comment">"Salvar"</string> + <string name="unsave_comment">"Não salvar"</string> + <string name="copy_multi_reddit_path">"Copiar Caminho do Multireddit"</string> + <string name="copy_multi_reddit_path_failed">"Não foi possível copiar o caminho do multireddit"</string> + <string name="crash_reports_deleted">"Relatório de erros apagado"</string> + <string name="disable_nsfw_forever_message">"Uma vez ativado, o NSFW será desativado permanentemente, independentemente da configuração do NSFW estar ativada ou não. E essa opção é irreversível, a única maneira de reativar o NSFW é limpar os dados do aplicativo. + +Ainda deseja ativá-lo?"</string> + <string name="reply">"Responder"</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml new file mode 100644 index 00000000..a2e8aa71 --- /dev/null +++ b/app/src/main/res/values-pt/strings.xml @@ -0,0 +1,1072 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="login_activity_label">"Entrar"</string> + <string name="comment_activity_label">"Enviar Comentário"</string> + <string name="comment_activity_label_is_replying">"Responder"</string> + <string name="post_text_activity_label">"Publicação de texto"</string> + <string name="subreddit_selection_activity_label">"Selecione uma Comunidade"</string> + <string name="post_link_activity_label">"Publicação de Ligação"</string> + <string name="post_image_activity_label">"Publicação de Imagem"</string> + <string name="post_video_activity_label">"Publicação de vídeo"</string> + <string name="rules_activity_label">"Regras"</string> + <string name="search_subreddits_activity_label">"Comunidades"</string> + <string name="edit_post_activity_label">"Editar publicação"</string> + <string name="edit_comment_activity_label">"Editar Comentário"</string> + <string name="view_message_activity_label">"Caixa de Entrada"</string> + <string name="settings_activity_label">"Definições"</string> + <string name="account_saved_thing_activity_label">"Guardado"</string> + <string name="create_multi_reddit_activity_label">"Criar Multireddit"</string> + <string name="subreddit_multiselection_activity_label">"Selecionar Comunidades"</string> + <string name="custom_theme_listing_activity_label">"Temas Personalizados"</string> + <string name="customize_theme_activity_label">"Personalizar Tema"</string> + <string name="customize_theme_activity_create_theme_label">"Criar Tema"</string> + <string name="theme_preview_activity_label">"Pré-visualizar Tema"</string> + <string name="edit_multi_reddit_activity_label">"Editar Multireddit"</string> + <string name="selected_subeddits_activity_label">"Comunidades selecionadas"</string> + <string name="report_activity_label">"Denunciar"</string> + <string name="view_imgur_media_activity_image_label">"Imagem %1$d/%2$d"</string> + <string name="view_imgur_media_activity_video_label">"Vídeo %1$d/%2$d"</string> + <string name="send_private_message_activity_label">"Enviar MP"</string> + <string name="view_reddit_gallery_activity_image_label">"Imagem %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_gif_label">"Gif %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_video_label">"Vídeo %1$d/%2$d"</string> + <string name="navigation_drawer_open">"Abrir gaveta de navegação"</string> + <string name="navigation_drawer_close">"Fechar gaveta de navegação"</string> + <string name="action_download">"Transferir"</string> + <string name="action_refresh">"Atualizar"</string> + <string name="action_add_comment">"Adicionar um comentário"</string> + <string name="action_save_post">"Guardar publicação"</string> + <string name="action_view_crosspost_parent">"Ver crosspost parent"</string> + <string name="action_search">"Pesquisar"</string> + <string name="action_start_lazy_mode">"Iniciar Modo Preguiça"</string> + <string name="action_stop_lazy_mode">"Parar Modo Preguiça"</string> + <string name="action_send">"Enviar"</string> + <string name="action_sort">"Ordenar"</string> + <string name="action_hide_post">"Esconder publicação"</string> + <string name="action_unhide_post">"Revelar publicação"</string> + <string name="action_edit_post">"Editar publicação"</string> + <string name="action_delete_post">"Eliminar publicação"</string> + <string name="action_mark_nsfw">"Marcar como 18+"</string> + <string name="action_unmark_nsfw">"Desmarcar 18+"</string> + <string name="action_mark_spoiler">"Marcar como Spoiler"</string> + <string name="action_unmark_spoiler">"Desmarcar como Spoiler"</string> + <string name="action_edit_flair">"Editar Flair"</string> + <string name="action_change_post_layout">"Alterar Visualização de Publicações"</string> + <string name="action_save">"Guardar"</string> + <string name="action_edit_multi_reddit">"Editar MultiReddit"</string> + <string name="action_delete_multi_reddit">"Eliminar MultiReddit"</string> + <string name="action_share">"Partilhar"</string> + <string name="action_preview">"Pré-visualizar"</string> + <string name="action_report">"Denunciar"</string> + <string name="action_see_removed">"Ver Removido"</string> + <string name="action_set_wallpaper">"Definir como Imagem de Fundo"</string> + <string name="action_send_private_message">"Enviar Mensagem Privada"</string> + <string name="action_block_user">"Bloquear Utilizador"</string> + <string name="parse_json_response_error">"Ocorreu um erro ao analisar a resposta do JSON"</string> + <string name="retrieve_token_error">"Erro ao Recuperar token"</string> + <string name="something_went_wrong">"Algo correu mal. Tente novamente mais tarde."</string> + <string name="access_denied">"Acesso negado"</string> + <string name="parse_user_info_error">"Ocorreu um erro ao analisar as informações do utilizador"</string> + <string name="no_system_webview_error">"Ocorreu um erro ao abrir 'WebView' do Sistema"</string> + <string name="error_loading_image_tap_to_retry">"Ocorreu um erro ao carregar a imagem. Toque para tentar novamente."</string> + <string name="load_posts_error">"Erro ao carregar publicações. +Toque para tentar novamente."</string> + <string name="load_more_posts_error">"Erro ao carregar publicações."</string> + <string name="load_post_error">"Erro ao carregar publicação. +Toque para tentar novamente."</string> + <string name="search_subreddits_error">"Ocorreu um erro ao pesquisar por comunidades. +Toque para tentar novamente."</string> + <string name="search_users_error">"Ocorreu um erro ao pesquisar por utilizadores. +Toque para tentar novamente."</string> + <string name="no_posts">"Sem publicações encontradas"</string> + <string name="no_comments">"Sem comentários encontrados"</string> + <string name="no_subreddits">"Nenhuma comunidade encontrada"</string> + <string name="no_users">"Nenhum utilizador encontrado"</string> + <string name="no_multi_reddits">"Nenhum Multireddit encontrado"</string> + <string name="no_storage_permission">"Sem permissão de armazenamento para guardar este ficheiro"</string> + <string name="load_comments_failed">"Erro ao carregar comentários. +Toque para tentar novamente."</string> + <string name="retry">"Tentar novamente"</string> + <string name="comments">"Comentários"</string> + <string name="no_comments_yet">"Ainda sem comentários. Escrever um comentário?"</string> + <string name="vote_failed">"Falha ao votar"</string> + <string name="refresh_post_failed">"Erro ao recarregar publicação"</string> + <string name="load_messages_failed">"Erro ao carregar mensagens. +Toque para tentar novamente."</string> + <string name="no_messages">"Vazio"</string> + <string name="nsfw">"18+"</string> + <string name="karma_info">"Karma: %1$d"</string> + <string name="karma_info_user_detail">"Karma: +%1$d (%2$d + %3$d)"</string> + <string name="cakeday_info">"Dia de bolo: +%1$s"</string> + <string name="since">"Desde:"</string> + <string name="profile">"Perfil"</string> + <string name="subscriptions">"Subscrições"</string> + <string name="multi_reddit">"Multi-reddit"</string> + <string name="inbox">"Caixa de Entrada"</string> + <string name="upvoted">"Voto Positivo"</string> + <string name="downvoted">"Voto Negativo"</string> + <string name="hidden">"Escondido"</string> + <string name="saved">"Guardado"</string> + <string name="gilded">"Dourado"</string> + <string name="settings">"Definições"</string> + <string name="subscribers_number_detail">"Membros: %1$d"</string> + <string name="online_subscribers_number_detail">"Online: %1$d"</string> + <string name="cannot_fetch_subreddit_info">"Não é possível obter informações da comunidade"</string> + <string name="cannot_fetch_user_info">"Não é possível obter informações do utilizador"</string> + <string name="cannot_fetch_sidebar">"Não é possível obter informações da barra lateral"</string> + <string name="cannot_fetch_multireddit">"Não é possível obter informações do multireddit"</string> + <string name="subscribe">"Subscrever"</string> + <string name="unsubscribe">"Cancelar subscrição"</string> + <string name="subscribed">"Subscrito"</string> + <string name="subscribe_failed">"Adesão Falhou"</string> + <string name="unsubscribed">"Subscrição cancelada"</string> + <string name="unsubscribe_failed">"Falha ao Cancelar Subscrição"</string> + <string name="follow">"Seguir"</string> + <string name="unfollow">"Deixar de Seguir"</string> + <string name="followed">"Seguido"</string> + <string name="follow_failed">"Falhou ao Seguir"</string> + <string name="unfollowed">"Deixado de Seguir"</string> + <string name="unfollow_failed">"Falhou ao Deixar de Seguir"</string> + <string name="content_description_banner_imageview">"Imagem Estandarte da Comunidade"</string> + <string name="app_label">"Infinity"</string> + <string name="search_hint">"Pesquisar por qualquer coisa"</string> + <string name="no_posts_no_lazy_mode">"Sem publicações disponíveis"</string> + <string name="lazy_mode_start">"Modo Preguiça inicia em %1$.1fs"</string> + <string name="lazy_mode_stop">"O Modo Perguiça parou"</string> + <string name="write_comment_hint">"Os seus pensamentos interessantes aqui"</string> + <string name="comment_content_required">"Onde está o seu pensamento interessante?"</string> + <string name="sending_comment">"A enviar"</string> + <string name="send_comment_success">"Comentário enviado"</string> + <string name="send_comment_failed">"Não foi possível enviar este comentário"</string> + <string name="send_message_username_hint">"Utilizador"</string> + <string name="send_message_subject_hint">"Assunto (100 caracteres no máximo)"</string> + <string name="send_message_content_hint">"Mensagem"</string> + <string name="reply_message_failed">"Não foi possível responder a esta mensagem"</string> + <string name="error_getting_message">"Erro ao receber esta mensagem"</string> + <string name="message_username_required">"A quem deseja enviar esta mensagem?"</string> + <string name="message_subject_required">"A sua mensagem deve ter um assunto"</string> + <string name="message_content_required">"Tem de dizer algo ao destinatário"</string> + <string name="sending_message">"A enviar"</string> + <string name="send_message_success">"Mensagem enviada"</string> + <string name="send_message_failed">"Não foi possível enviar esta mensagem"</string> + <string name="select_a_subreddit">"Por favor escolha uma comunidade primeiro"</string> + <string name="title_required">"A publicação precisa de um bom título"</string> + <string name="link_required">"Onde está o endereço?"</string> + <string name="select_an_image">"Por favor selecione primeiro uma imagem"</string> + <string name="posting">"A publicar"</string> + <string name="post_failed">"Não foi possível publicar"</string> + <string name="error_processing_image">"Erro ao processar imagem"</string> + <string name="error_processing_video">"Erro ao processar vídeo"</string> + <string name="download_started">"Transferência Iniciada. Consultar a notificação para ver o progresso."</string> + <string name="comment_load_more_comments">"Carregar mais comentários"</string> + <string name="comment_load_more_comments_failed">"Erro ao carregar. Toque para tentar novamente"</string> + <string name="loading">"A carregar"</string> + <string name="post_title_hint">"Título"</string> + <string name="post_text_content_hint">"Conteúdo"</string> + <string name="choose_a_subreddit">"Escolha uma comunidade"</string> + <string name="rules">"Regras"</string> + <string name="post_link_hint">"URL"</string> + <string name="subreddits">"Comunidades"</string> + <string name="users">"Utilizadores"</string> + <string name="multi_reddits">"MultiReddits"</string> + <string name="bottom_sheet_post_text">"Texto"</string> + <string name="bottom_sheet_post_link">"Ligação"</string> + <string name="bottom_sheet_post_image">"Imagem"</string> + <string name="bottom_sheet_post_video">"Vídeo"</string> + <string name="select_from_gallery">"Enviar uma imagem"</string> + <string name="select_again">"Selecione novamente"</string> + <string name="error_getting_image">"Erro ao enviar a imagem"</string> + <string name="error_getting_video">"Erro ao enviar o vídeo"</string> + <string name="no_camera_available">"Nenhuma aplicação de câmara disponível"</string> + <string name="error_creating_temp_file">"Erro ao criar ficheiro temporário"</string> + <string name="video_is_processing">"Vídeo a ser processado. Por favor aguarde."</string> + <string name="image_is_processing">"Imagem a ser processada. Por favor aguarde."</string> + <string name="gif_is_processing">"Gif a ser processado. Por favor aguarde."</string> + <string name="flair">"Flair"</string> + <string name="spoiler">"Spoiler"</string> + <string name="no_flair">"Sem flair"</string> + <string name="error_loading_flairs">"Erro ao carregar flairs. +Toque para tentar novamente."</string> + <string name="no_rule">"Sem regra"</string> + <string name="error_loading_rules">"Erro ao carregar regras. +Toque para tentar novamente."</string> + <string name="error_loading_rules_without_retry">"Erro ao Carregar Regras"</string> + <string name="search_in">"Pesquisar em"</string> + <string name="all_subreddits">"Todas as comunidades"</string> + <string name="sort_best">"Melhor"</string> + <string name="sort_hot">"Em Destaque"</string> + <string name="sort_new">"Novos"</string> + <string name="sort_random">"Aleatório"</string> + <string name="sort_rising">"Em Ascensão"</string> + <string name="sort_top">"Top"</string> + <string name="sort_controversial">"Polémicos"</string> + <string name="sort_relevance">"Relevância"</string> + <string name="sort_comments">"Comentários"</string> + <string name="sort_activity">"Atividade"</string> + <string name="sort_confidence">"Confiança"</string> + <string name="sort_old">"Mais antigo"</string> + + <!-- Fuzzy --> + <string name="sort_qa">"PR"</string> + <string name="sort_live">"Em direto"</string> + <string name="sort_time_hour">"Hora"</string> + <string name="sort_time_day">"Dia"</string> + <string name="sort_time_week">"Semana"</string> + <string name="sort_time_month">"Mês"</string> + <string name="sort_time_year">"Ano"</string> + <string name="sort_time_all_time">"Desde sempre"</string> + <string name="no_activity_found_for_share">"Não há nenhuma aplicação que possa lidar com a ação de partilha"</string> + <string name="archived_post_vote_unavailable">"Publicação arquivada. Votos indisponíveis."</string> + <string name="archived_post_comment_unavailable">"Publicação arquivada. Comentários indisponíveis."</string> + <string name="archived_post_reply_unavailable">"Publicação arquivada. Respostas indisponíveis."</string> + <string name="locked_post_comment_unavailable">"Publicação bloqueada. Comentários indisponíveis."</string> + <string name="locked_post_reply_unavailable">"Publicação bloqueada. Respostas indisponíveis."</string> + <string name="text">"TEXTO"</string> + <string name="link">"ENDEREÇO"</string> + <string name="image">"IMAGEM"</string> + <string name="video">"VÍDEO"</string> + <string name="gif">"GIF"</string> + <string name="gallery">"GALERIA"</string> + <string name="best">"Os Melhores"</string> + <string name="search">"Pesquisar"</string> + <string name="posting_video">"A Publicar Vídeo"</string> + <string name="posting_image">"A Publicar Imagem"</string> + + <!-- Fuzzy --> + <string name="please_wait">"Por favor aguarde."</string> + <string name="add_account">"Adicionar conta"</string> + <string name="anonymous_account">"Anónimo"</string> + <string name="log_out">"Terminar sessão"</string> + <string name="press_here_to_login">"Pressione aqui para iniciar sessão"</string> + <string name="login_first">"Inicie sessão primeiro"</string> + <string name="post_saved_success">"Publicação guardada"</string> + <string name="post_saved_failed">"Incapaz de guardar publicação"</string> + <string name="post_unsaved_success">"Publicação não guardada"</string> + <string name="post_unsaved_failed">"Não foi possível esquecer publicação"</string> + <string name="post_hide_success">"Publicação escondida"</string> + <string name="post_hide_failed">"Não foi possível esconder publicação"</string> + <string name="post_unhide_success">"Publicação revelada"</string> + <string name="thing_favorite_failed">"Falha ao adicionar aos favoritos"</string> + <string name="thing_unfavorite_failed">"Falha ao remover dos favoritos"</string> + <string name="post_unhide_failed">"Não foi possível revelar publicação"</string> + <string name="delete_this_post">"Eliminar esta Publicação"</string> + <string name="delete_this_comment">"Eliminar este Comentário"</string> + <string name="are_you_sure">"Tem a certeza?"</string> + <string name="edit">"Editar"</string> + <string name="delete">"Eliminar"</string> + <string name="see_removed_comment">"Ver Comentário Removido"</string> + <string name="fetching_removed_comment">"A obter comentário removido"</string> + <string name="show_removed_comment_failed">"Comentário removido não encontrado"</string> + <string name="fetching_removed_post">"A obter publicação removido"</string> + <string name="show_removed_post_failed">"Publicação removida não encontrada"</string> + <string name="cancel">"Cancelar"</string> + <string name="ok">"OK"</string> + + <!-- Fuzzy --> + <string name="edit_success">"Editado com sucesso"</string> + <string name="delete_post_success">"Eliminada com sucesso"</string> + <string name="delete_post_failed">"Falha ao eliminar"</string> + <string name="mark_nsfw_success">"Marcado como 18+ com sucesso"</string> + <string name="mark_nsfw_failed">"Falhou ao marcar como 18+"</string> + <string name="unmark_nsfw_success">"Desmarcado como 18+ com sucesso"</string> + <string name="unmark_nsfw_failed">"Falhou ao desmarcar como 18+"</string> + <string name="mark_spoiler_success">"Marcado como spoiler com sucesso"</string> + <string name="mark_spoiler_failed">"Marcação como spoiler falhou"</string> + <string name="unmark_spoiler_success">"Desmarcado como Spoiler com sucesso"</string> + <string name="unmark_spoiler_failed">"Desmarcação de spoiler falhou"</string> + <string name="update_flair_success">"Flair atualizado com sucesso"</string> + <string name="update_flair_failed">"Falha ao atualizar flair"</string> + <string name="edit_flair">"Editar Flair"</string> + <string name="only_allow_64_chars">"Permitir apenas menos de 64 caracteres"</string> + <string name="view_all_comments">"Clique aqui para explorar todos os comentários"</string> + <string name="notification_summary_account">"Conta"</string> + <string name="notification_summary_message">"Nova Mensagem"</string> + <string name="notification_summary_subreddit">"Comunidade"</string> + <string name="notification_summary_award">"Prémio"</string> + <string name="notification_new_messages">"%1$d Mensagens Novas"</string> + <string name="label_account">"Conta"</string> + <string name="label_post">"Publicação"</string> + <string name="label_preferences">"Preferências"</string> + <string name="account_switched">"Conta trocada. Portanto todas as outras páginas desapareceram."</string> + <string name="settings_notification_master_title">"Notificação"</string> + <string name="settings_notification_enable_notification_title">"Ativar Notificações"</string> + <string name="settings_notification_interval_title">"Intervalo de Verificação de Notificações"</string> + <string name="settings_theme_title">"Tema"</string> + <string name="settings_amoled_dark_title">"Escuro Amoled"</string> + <string name="settings_interface_title">"Interface"</string> + <string name="settings_gestures_and_buttons_title">"Gestos e Botões"</string> + <string name="settings_save_front_page_scrolled_position_title">"Guardar Posição de Deslizamento em INÍCIO"</string> + <string name="settings_save_front_page_scrolled_position_summary">"Explorar novas publicações após recarregar INÍCIO (Página Principal, ordenado por: Melhor)"</string> + <string name="settings_open_link_in_app_title">"Abrir Ligação na Aplicação"</string> + <string name="settigns_video_title">"Vídeo"</string> + <string name="settings_video_autoplay_title">"Reprodução Automática de Vídeos"</string> + <string name="settings_mute_autoplaying_videos_title">"Vídeos em auto-reprodução Sem Som"</string> + <string name="settings_autoplay_nsfw_videos_title">"Reprodução Automática de Vídeos 18+"</string> + <string name="settings_start_autoplay_visible_area_offset_portrait_title">"Área Visível de Vídeos para Desencadear Reprodução (Retrato)"</string> + <string name="settings_start_autoplay_visible_area_offset_portrait_summary">"Inicia reprodução automática de vídeos quando estão %1$d%% visíveis"</string> + <string name="settings_start_autoplay_visible_area_offset_landscape_title">"Área Visível de Vídeos para Desencadear Reprodução (Paisagem)"</string> + <string name="settings_start_autoplay_visible_area_offset_landscape_summary">"Inicia reprodução automática de vídeos quando estão %1$d%% visíveis"</string> + <string name="settings_immersive_interface_title">"Interface Imersiva"</string> + <string name="settings_immersive_interface_summary">"Não é Aplicada a Todas as Páginas"</string> + <string name="settings_immersive_interface_ignore_nav_bar_title">"Ignorar Barra de Navegação na Interface Imersiva"</string> + <string name="settings_immersive_interface_ignore_nav_bar_summary">"Impede que Barra de Navegação Inferior tenha Preenchimento Extra"</string> + <string name="settings_customize_tabs_in_main_page_title">"Personalizar Separadores da Página Principal"</string> + <string name="settings_enable_bottom_app_bar_title">"Ativar Barra Navegação Inferior"</string> + <string name="settings_enable_bottom_app_bar_summary">"Não aplicável no Modo Anónimo"</string> + <string name="settings_category_post_and_comment_title">"Publicação e Comentário"</string> + <string name="settings_vote_buttons_on_the_right_title">"Botões de Voto à Direita"</string> + <string name="settings_volume_keys_navigate_comments_title">"Usar Teclas de Volume para Navegar pelos Comentários"</string> + <string name="settings_volume_keys_navigate_posts_title">"Usar Teclas de Volume para Navegar pelas Publicações"</string> + <string name="settings_mute_video_title">"Vídeos Sem Som"</string> + <string name="settings_mute_nsfw_video_title">"Vídeos 18+ Sem Som"</string> + + <!-- Fuzzy --> + <string name="settings_automatically_try_redgifs_title">"Tentar aceder ao Redgifs automaticamente caso os vídeos no Gfycat tenham sido removidos."</string> + <string name="settings_video_player_ignore_nav_bar_title">"Ignorar Barra de Navegação no Reprodutor de Vídeo"</string> + <string name="settings_video_player_ignore_nav_bar_summary">"Impedir que o Controlador de Vídeo Tenha Margem Extra"</string> + <string name="settings_confirm_to_exit">"Confirmar para Sair"</string> + <string name="settings_category_comment_title">"Comentário"</string> + <string name="settings_show_top_level_comments_first_title">"Mostrar Comentários de Topo Primeiro"</string> + <string name="settings_show_comment_divider_title">"Mostrar Separador de Comentários"</string> + <string name="settings_comment_toolbar_hide_on_click">"Clicar para Mostrar/Esconder a Barra de Ferramentas dos Comentários"</string> + <string name="settings_fully_collapse_comment_title">"Colapsar Comentário por Completo"</string> + <string name="settings_comment_toolbar_hidden">"Barra de Ferramentas dos Comentários Escondida por Defeito"</string> + <string name="settings_show_absolute_number_of_votes_title">"Mostrar Número de Votos Absolutos"</string> + <string name="settings_show_elapsed_time">"Mostrar tempo decorrido nas Publicações e Comentários"</string> + <string name="settings_time_format_title">"Formato da Hora"</string> + <string name="settings_category_post_title">"Publicação"</string> + <string name="settings_default_post_layout">"Visualização de Publicações Padrão"</string> + <string name="settings_show_divider_in_compact_layout">"Mostrar Separador"</string> + <string name="settings_show_thumbnail_on_the_left_in_compact_layout">"Mostrar Miniatura à Esquerda"</string> + <string name="settings_swipe_to_go_back_title">"Deslizar para a Direita para Voltar Atrás"</string> + <string name="settings_swipe_to_go_back_summary">"Não é Aplicado a Todas as Páginas"</string> + <string name="settings_lock_jump_to_next_top_level_comment_button_title">"Prender botão Saltar para Próximo Comentário de Topo"</string> + <string name="settings_lock_bottom_app_bar_title">"Prender Barra de Navegação na Parte Inferior"</string> + <string name="settings_swipe_up_to_hide_jump_to_next_top_level_comment_button_title">"Deslizar para Cima para Esconder o Botão de Saltar para Próximo Comentário de Topo"</string> + <string name="settings_lazy_mode_interval_title">"Intervalo do Modo Preguiça"</string> + <string name="settings_font_title">"Tipo de Letra"</string> + <string name="settings_preview_font_title">"Pré-visualizar Tipo de Letra"</string> + <string name="settings_font_summary">"Tipo de Letra"</string> + <string name="settings_title_font_summary">"Titulo"</string> + <string name="settings_content_font_summary">"Conteúdo"</string> + <string name="settings_font_family_title">"Família Tipográfica"</string> + <string name="settings_title_font_family_title">"Família Tipográfica do Título"</string> + <string name="settings_content_font_family_title">"Família Tipográfica do Conteúdo"</string> + <string name="settings_font_size_title">"Tamanho do Tipo de Letra"</string> + <string name="settings_title_font_size_title">"Tamanho de Letra do Título"</string> + <string name="settings_content_font_size_title">"Tamanho de Letra do Conteúdo"</string> + <string name="settings_enable_nsfw_title">"Ativar 18+"</string> + <string name="settings_blur_nsfw_title">"Desfocar Imagens 18+"</string> + <string name="settings_blur_spoiler_title">"Desfocar Imagens Spoiler"</string> + <string name="settings_about_master_title">"Sobre"</string> + <string name="settings_acknowledgement_master_title">"Reconhecimento"</string> + <string name="settings_credits_master_title">"Créditos"</string> + <string name="settings_credits_icon_foreground_title">"Ícone Primeiro Plano"</string> + <string name="settings_credits_icon_foreground_summary">"Vetor tecnológico criado por freepik - www.freepik.com"</string> + <string name="settings_credits_icon_background_title">"Fundo do Ícone"</string> + <string name="settings_credits_icon_background_summary">"Vetor tecnológico criado por freepik - www.freepik.com"</string> + <string name="settings_credits_error_image_title">"Imagem de Erro"</string> + <string name="settings_credits_error_image_summary">"Vetor tecnológico criado por freepik - www.freepik.com"</string> + <string name="settings_credits_gilded_icon_title">"Ícone Dourado"</string> + <string name="settings_credits_gilded_icon_summary">"Ícone criado por Freepik da www.flaticon.com"</string> + <string name="settings_credits_crosspost_icon_title">"Ícone de Republicação"</string> + <string name="settings_credits_crosspost_icon_summary">"Ícone criado por Freepik da www.flaticon.com"</string> + <string name="settings_credits_thumbtack_icon_title">"Ícone Thumbtack"</string> + <string name="settings_credits_thumbtack_icon_summary">"Ícone criado por Freepik da www.flaticon.com"</string> + <string name="settings_credits_best_rocket_icon_title">"Ícone Rocket"</string> + <string name="settings_credits_best_rocket_icon_summary">"Ícone criado por Freepik da www.flaticon.com"</string> + <string name="settings_credits_material_icons_title">"Ícones Material"</string> + <string name="settings_open_source_title">"Código-fonte"</string> + <string name="settings_open_source_summary">"Avalie no Github caso goste desta aplicação"</string> + <string name="settings_rate_title">"Avaliar no Google Play"</string> + <string name="settings_rate_summary">"Dê-me 5 estrelas que ficarei muito contente"</string> + <string name="settings_email_title">"Email"</string> + <string name="settings_email_summary">"docilealligator.app@gmail.com"</string> + <string name="settings_reddit_account_title">"Conta do Reddit"</string> + <string name="settings_reddit_account_summary">"u/Hostilenemy"</string> + <string name="settings_subreddit_title">"Comunidade"</string> + <string name="settings_subreddit_summary">"r/Infinity_For_Reddit"</string> + <string name="settings_share_title">"Partilhar"</string> + <string name="settings_share_summary">"Se aprecia esta aplicação, partilhe-a com outros"</string> + <string name="settings_version_title">"Infinity For Reddit"</string> + <string name="settings_version_summary">"Versão %s"</string> + <string name="settings_category_customization_title">"Personalização"</string> + <string name="settings_customize_light_theme_title">"Tema Claro"</string> + <string name="settings_customize_dark_theme_title">"Tema Escuro"</string> + <string name="settings_customize_amoled_theme_title">"Tema Amoled"</string> + <string name="settings_manage_themes_title">"Gerir Temas"</string> + <string name="settings_custom_theme_cannot_apply_to_settings_page_summary">"Temas personalizados não podem ser aplicados à página de definições (exceto à barra de ferramentas, barra de estado e barra de navegação)."</string> + <string name="settings_advanced_master_title">"Avançado"</string> + <string name="settings_delete_all_subreddits_data_in_database_title">"Eliminar Todas as Comunidades da BD"</string> + <string name="settings_delete_all_users_data_in_database_title">"Eliminar Todos os Utilizadores da BD"</string> + <string name="settings_delete_all_sort_type_data_in_database_title">"Eliminar Todos os Tipos de Ordenação da BD"</string> + <string name="settings_delete_all_post_layout_data_in_database_title">"Eliminar Todas as Visualizações de Publicações da BD"</string> + <string name="settings_delete_all_themes_in_database_title">"Eliminar Todos os Temas da BD"</string> + <string name="settings_delete_front_page_scrolled_positions_in_database_title">"Eliminar Todas as Posições de Deslizamento da BD"</string> + <string name="settings_reset_all_settings_title">"Repor Todas as Definições"</string> + <string name="settings_tab_1_summary">"Separador 1"</string> + <string name="settings_tab_2_summary">"Separador 2"</string> + <string name="settings_tab_3_summary">"Separador 3"</string> + <string name="settings_tab_title">"Título"</string> + <string name="settings_tab_post_type">"Tipo"</string> + <string name="settings_tab_subreddit_name">"Nome da Comunidade (sem prefixo r/)"</string> + <string name="settings_tab_multi_reddit_name">"Nome MultiReddit (/utilizador/oseunomedeutilizador/m/oseunomemultireddit)"</string> + <string name="settings_tab_username">"Nome de Utilizador (sem prefixo u/)"</string> + <string name="no_developer_easter_egg">"Aqui não existem opções de programador"</string> + <string name="no_link_available">"Não foi possível obter a ligação"</string> + <string name="exit_when_submit">"Sair?"</string> + <string name="exit_when_submit_post_detail">"A publicação será submetida mesmo que saía daqui."</string> + <string name="exit_when_edit_post_detail">"A publicação poderá ser submetida mesmo que saía daqui."</string> + <string name="exit_when_edit_comment_detail">"O comentário poderá ser enviado mesmo que saía daqui."</string> + <string name="discard">"Descartar?"</string> + <string name="discard_detail">"O rascunho NÃO será guardado."</string> + <string name="yes">"Sim"</string> + <string name="no">"Não"</string> + <string name="no_data_received">"Não foram recebidos dados"</string> + <string name="no_image_path_received">"Caminho da imagem não recebido"</string> + <string name="no_video_path_received">"Caminho do vídeo não recebido"</string> + <string name="cannot_handle_intent">"Não foi possível lidar com o pedido de partilha"</string> + <string name="share">"Partilhar"</string> + <string name="no_email_client">"Não foi encontrado nenhum cliente de email"</string> + <string name="no_app">"Nenhuma aplicação disponível"</string> + <string name="comment_saved_success">"Comentário guardado"</string> + <string name="comment_saved_failed">"Não foi possível guardar o comentário"</string> + <string name="comment_unsaved_success">"Comentário esquecido"</string> + <string name="comment_unsaved_failed">"Não foi possível esquecer o comentário"</string> + <string name="favorites">"Favoritos"</string> + <string name="all">"Todos"</string> + <string name="post_layout_card">"Cartão"</string> + <string name="post_layout_compact">"Compacta"</string> + <string name="elapsed_time_just_now">"Agora mesmo"</string> + <string name="elapsed_time_a_minute_ago">"1 Minuto"</string> + <string name="elapsed_time_minutes_ago">"%1$d Minutos"</string> + <string name="elapsed_time_an_hour_ago">"1 Hora"</string> + <string name="elapsed_time_hours_ago">"%1$d Horas"</string> + <string name="elapsed_time_yesterday">"Ontem"</string> + <string name="elapsed_time_days_ago">"%1$d Dias"</string> + <string name="elapsed_time_a_month_ago">"1 Mês"</string> + <string name="elapsed_time_months_ago">"%1$d Meses"</string> + <string name="elapsed_time_a_year_ago">"1 Ano"</string> + <string name="elapsed_time_years_ago">"%1$d Anos"</string> + <string name="error_getting_multi_reddit_data">"Erro ao obter dados do multireddit"</string> + <string name="error_loading_multi_reddit_list">"Não foi possível sincronizar multireddits"</string> + <string name="error_loading_subscriptions">"Não foi possível sincronizar as subscrições"</string> + <string name="share_this_app">"Check out Infinity for Reddit, an awesome Reddit client! +https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit"</string> + <string name="error_getting_subreddit_name">"Erro ao obter o nome da comunidade"</string> + <string name="share_post_link">"Partilhar Endereço da Publicação"</string> + <string name="share_image_link">"Partilhar Endereço da Imagem"</string> + <string name="share_gif_link">"Partilhar Endereço do Gif"</string> + <string name="share_video_link">"Partilhar Endereço do Vídeo"</string> + <string name="share_link">"Partilhar Endereço"</string> + <string name="copy_post_link">"Copiar Endereço da Publicação"</string> + <string name="copy_image_link">"Copiar Endereço da Imagem"</string> + <string name="copy_gif_link">"Copiar Endereço do Gif"</string> + <string name="copy_video_link">"Copiar Endereço do Vídeo"</string> + <string name="copy_link">"Copiar Endereço"</string> + <string name="copy_success">"Copiado"</string> + <string name="copy_link_failed">"Não foi possível copiar a ligação"</string> + <string name="copy_text">"Copiar"</string> + <string name="copy_all">"Copiar Tudo"</string> + <string name="copy_markdown">"Copiar Markdown"</string> + <string name="copy_raw_text">"Copiar Texto Simples"</string> + <string name="copy_all_markdown">"Copiar todo o Markdown"</string> + <string name="copy_all_raw_text">"Copiar Todo o Texto Simples"</string> + <string name="exit_app">"Sair?"</string> + <string name="light_theme">"Tema Claro"</string> + <string name="dark_theme">"Tema Escuro"</string> + <string name="multi_reddit_name_hint">"Nome (50 caracteres máx)"</string> + <string name="multi_reddit_description_hint">"Descrição"</string> + <string name="private_multi_reddit">"Privado"</string> + <string name="no_multi_reddit_name">"Onde está o nome?"</string> + <string name="create_multi_reddit_failed">"Não é possível criar este multireddit"</string> + <string name="duplicate_multi_reddit">"Este multireddit já existe"</string> + <string name="edit_multi_reddit_failed">"Não é possível editar este multireddit"</string> + <string name="logged_out">"Não tem sessão iniciada"</string> + <string name="delete_multi_reddit_success">"Eliminado com sucesso"</string> + <string name="delete_multi_reddit_failed">"Falha ao eliminar"</string> + <string name="delete_multi_reddit_dialog_message">"Tem a certeza?"</string> + <string name="enable_nsfw">"Ativar 18+"</string> + <string name="disable_nsfw">"Desativar 18+"</string> + <string name="cannot_save_image">"Não é possível guardar a imagem"</string> + <string name="cannot_save_gif">"Não é possível guardar o gif"</string> + <string name="cannot_get_storage">"Não é possível aceder ao armazenamento da aplicação"</string> + <string name="save_image_first">"A guardar imagem. Aguarde."</string> + <string name="save_gif_first">"A guardar GIF. Aguarde."</string> + <string name="theme_name_description">"Toque para alterar o nome deste tema."</string> + <string name="theme_item_is_light_theme">"Definir como Tema Claro"</string> + <string name="theme_item_is_dark_theme">"Definir como Tema Escuro"</string> + <string name="theme_item_is_amoled_theme">"Definir como Tema Amoled"</string> + <string name="theme_item_color_primary">"Cor Primária"</string> + <string name="theme_item_color_primary_detail">"Aplica-se a: Barra de ferramentas"</string> + <string name="theme_item_color_primary_dark">"Cor Primária Escura"</string> + <string name="theme_item_color_primary_dark_detail">"Aplicado a: Barra de Estado"</string> + <string name="theme_item_color_accent">"Cor Principal"</string> + <string name="theme_item_color_accent_detail">"Aplicado a: Barra de Progresso, etc"</string> + <string name="theme_item_color_primary_light_theme">"Cor Primária do Tema Claro"</string> + <string name="theme_item_color_primary_light_theme_detail">"Aplicado a: Fundo do Botão de Ação Flutuante e Botão"</string> + <string name="theme_item_primary_text_color">"Cor Texto Primário"</string> + <string name="theme_item_primary_text_color_detail">"Aplicado a: Texto Primário"</string> + <string name="theme_item_secondary_text_color">"Cor Texto Secundário"</string> + <string name="theme_item_secondary_text_color_detail">"Aplicado a: Texto Secundário"</string> + <string name="theme_item_post_title_color">"Cor Título de Publicação"</string> + <string name="theme_item_post_title_color_detail">"Aplicado a: Título de Publicação"</string> + <string name="theme_item_post_content_color">"Cor Conteúdo da Publicação"</string> + <string name="theme_item_post_content_color_detail">"Aplicado a: Conteúdo da Publicação"</string> + <string name="theme_item_comment_color">"Cor de Comentário"</string> + <string name="theme_item_comment_color_detail">"Aplicado a: Comentário"</string> + <string name="theme_item_button_text_color">"Cor Texto do Botão"</string> + <string name="theme_item_button_text_color_detail">"Aplicado a: Texto do Botão"</string> + <string name="theme_item_chip_text_color">"Cor do Texto Chip"</string> + <string name="theme_item_chip_text_color_detail">"Aplicado a: Botão Aderir"</string> + <string name="theme_item_link_color">"Cor da Ligação"</string> + <string name="theme_item_link_color_detail">"Aplicado ao: URL"</string> + <string name="theme_item_received_message_text_color">"Cor do Texto de Mensagem Recebida"</string> + <string name="theme_item_received_message_text_color_detail">"Aplicado a: Mensagens Privadas Recebidas"</string> + <string name="theme_item_sent_message_text_color">"Cor do Texto Mensagem Enviada"</string> + <string name="theme_item_sent_message_text_color_detail">"Aplicado a: Mensagens Privadas Enviadas"</string> + <string name="theme_item_background_color">"Cor de Fundo"</string> + <string name="theme_item_background_color_detail">"Aplicado a: Fundo de todas as páginas e gaveta de navegação"</string> + <string name="theme_item_card_view_background_color">"Cor de Fundo da Visualização em Cartão"</string> + <string name="theme_item_card_view_background_color_detail">"Aplicado a: Fundo de publicação e messagem"</string> + <string name="theme_item_comment_background_color">"Cor de Fundo de Comentário"</string> + <string name="theme_item_comment_background_color_detail">"Aplicado a: Fundo de Comentário"</string> + <string name="theme_item_fully_collapsed_comment_background_color">"Cor de Fundo de Comentário Totalmente Colapsado"</string> + <string name="theme_item_fully_collapsed_comment_background_color_detail">"Aplicado a: Fundo de comentários totalmente colapsados"</string> + <string name="theme_item_awarded_comment_background_color">"Cor de Fundo de Comentário Premiado"</string> + <string name="theme_item_awarded_comment_background_color_detail">"Aplicado a: Fundo de comentários premiados"</string> + <string name="theme_item_received_message_background_color">"Cor de Fundo de Mensagem Recebida"</string> + <string name="theme_item_received_message_background_color_detail">"Aplicado a: Fundo de mensagens privadas recebidas"</string> + <string name="theme_item_sent_message_background_color">"Cor de Fundo Mensagem Enviada"</string> + <string name="theme_item_sent_message_background_color_detail">"Aplicado a: Fundo das mensagens privadas enviadas"</string> + <string name="theme_item_bottom_app_bar_background_color">"Cor da Barra de Navegação Inferior"</string> + <string name="theme_item_bottom_app_bar_background_color_detail">"Aplicado a: Barra de navegação inferior"</string> + <string name="theme_item_primary_icon_color">"Cor do Ícone Principal"</string> + <string name="theme_item_primary_icon_color_detail">"Aplicado a: Ícones da gaveta de navegação."</string> + <string name="theme_item_bottom_app_bar_icon_color">"Cor dos Ícones da Barra de Navegação Inferior"</string> + <string name="theme_item_bottom_app_bar_icon_color_detail">"Aplicado a: Ícones da barra de navegação inferior"</string> + <string name="theme_item_post_icon_and_info_color">"Cor do Ícone de Publicação e das Informações"</string> + <string name="theme_item_post_icon_and_info_color_detail">"Aplicado a: Ícones, pontuação e número de comentários de publicação"</string> + <string name="theme_item_comment_icon_and_info_color">"Cor do Ícone de Comentário e das Informações"</string> + <string name="theme_item_comment_icon_and_info_color_detail">"Aplicado a: Ícones e pontuações no comentários"</string> + <string name="theme_item_fab_icon_color">"Cor do Ícone do Botão de Ação Flutuante"</string> + <string name="theme_item_fab_icon_color_detail">"Aplicado a: Botão de ação flutuante"</string> + <string name="theme_item_send_message_icon_color">"Cor do Ícone Enviar Mensagem"</string> + <string name="theme_item_send_message_icon_color_detail">"Aplicado a: Ícone enviar mensagem privada"</string> + <string name="theme_item_toolbar_primary_text_and_icon_color">"Cor do Texto e Ícone Principais da Barra de ferramentas"</string> + <string name="theme_item_toolbar_primary_text_and_icon_color_detail">"Aplicado a: Textos e Ícones principais da barra de ferramentas"</string> + <string name="theme_item_toolbar_secondary_text_color">"Cor do Texto Secundário da Barra de Tarefas"</string> + <string name="theme_item_toolbar_secondary_text_color_detail">"Aplicado a: Texto secundário na barra de ferramentas"</string> + <string name="theme_item_circular_progress_bar_background_color">"Cor de Fundo da Barra de Progresso Circular"</string> + <string name="theme_item_circular_progress_bar_background_color_detail">"Aplicado a: Fundo da barra de progresso circular"</string> + <string name="theme_item_upvoted_color">"Cor de Voto Positivo"</string> + <string name="theme_item_upvoted_color_detail">"Aplicado a: Botões de Voto e Pontuações (Voto Positivo)"</string> + <string name="theme_item_downvoted_color">"Cor do Voto Negativo"</string> + <string name="theme_item_downvoted_color_detail">"Aplicado a: Botões de Voto e Pontuações (Voto Negativo)"</string> + <string name="theme_item_post_type_background_color">"Cor de Fundo do Tipo de Publicação"</string> + <string name="theme_item_post_type_background_color_detail">"Aplicado a: Cor de fundo do tipo de publicação (IMAGEM, TEXTO, VIDEO, GIF, LIGAÇÃO)"</string> + <string name="theme_item_post_type_text_color">"Cor do Texto do Tipo de Publicação"</string> + <string name="theme_item_post_type_text_color_detail">"Aplicado a: Cor do texto do tipo de publicação (IMAGEM, TEXTO, VIDEO, GIF, LIGAÇÃO)"</string> + <string name="theme_item_spoiler_background_color">"Cor de Fundo Spoiler"</string> + <string name="theme_item_spoiler_background_color_detail">"Aplicado a: Fundo da etiqueta spoiler"</string> + <string name="theme_item_spoiler_text_color">"Cor do Texto Spoiler"</string> + <string name="theme_item_spoiler_text_color_detail">"Aplicado a: Cor do texto na etiqueta spoiler"</string> + <string name="theme_item_nsfw_background_color">"Cor de Fundo de 18+"</string> + <string name="theme_item_nsfw_background_color_detail">"Aplicado a: Cor de fundo da etiqueta 18+"</string> + <string name="theme_item_nsfw_text_color">"Cor do Texto 18+"</string> + <string name="theme_item_nsfw_text_color_detail">"Aplicado a: Cor do texto da etiqueta 18+"</string> + <string name="theme_item_flair_background_color">"Cor de Fundo Flair"</string> + <string name="theme_item_flair_background_color_detail">"Aplicado a: Fundo da etiqueta flair"</string> + <string name="theme_item_flair_text_color">"Cor do Texto Flair"</string> + <string name="theme_item_flair_text_color_detail">"Aplicado a: Cor do texto da etiqueta flair"</string> + <string name="theme_item_awards_background_color">"Cor de Fundo de Prémios"</string> + <string name="theme_item_awards_background_color_detail">"Aplicado a: Fundo da etiqueta de prémios"</string> + <string name="theme_item_awards_text_color">"Cor do Texto Prémios"</string> + <string name="theme_item_awards_text_color_detail">"Aplicado a: Cor do texto da etiqueta prémios"</string> + <string name="theme_item_archived_tint">"Cor do Ícone de Arquivo"</string> + <string name="theme_item_archived_tint_detail">"Aplicado a: Ícone de Arquivo"</string> + <string name="theme_item_locked_icon_tint">"Cor do Ícone de Bloqueio"</string> + <string name="theme_item_locked_icon_tint_detail">"Aplicado a: Ícone de Bloqueio"</string> + <string name="theme_item_crosspost_icon_tint">"Cor do Ícone de Republicação"</string> + <string name="theme_item_crosspost_icon_tint_detail">"Aplicado a: Ícone de republicação"</string> + <string name="theme_item_stickied_post_icon_tint">"Cor do Ícone de Publicação Afixada"</string> + <string name="theme_item_stickied_post_icon_tint_detail">"Aplicado a: Ícone de Publicação Afixada"</string> + <string name="theme_item_subscribed_color">"Membro"</string> + <string name="theme_item_subscribed_color_detail">"Aplicado a: Botão cancelar adesão"</string> + <string name="theme_item_unsubscribed_color">"Cancelar Adesão"</string> + <string name="theme_item_unsubscribed_color_detail">"Aplicado a: Botão aderir"</string> + <string name="theme_item_username_color">"Cor do Nome de Utilizador"</string> + <string name="theme_item_username_color_detail">"Aplicado a: Nome de Utilizador"</string> + <string name="theme_item_subreddit_color">"Cor das Comunidades"</string> + <string name="theme_item_subreddit_color_detail">"Aplicado a: Nome da Comunidade"</string> + <string name="theme_item_author_flair_text_color">"Cor de Flair de Autor"</string> + <string name="theme_item_author_flair_text_color_detail">"Aplicado a: Flair de Autor nos Comentários"</string> + <string name="theme_item_submitter_color">"Autor"</string> + <string name="theme_item_submitter_color_detail">"Autor nos comentários"</string> + <string name="theme_item_moderator_color">"Moderador"</string> + <string name="theme_item_moderator_color_detail">"Aplicado a: Moderador nos comentários"</string> + <string name="theme_item_single_comment_thread_background_color">"Cor de Fundo de Comentário Único"</string> + <string name="theme_item_single_comment_thread_background_color_detail">"Aplicado a: Comentário Único"</string> + <string name="theme_item_unread_message_background_color">"Cor de Fundo de Mensagem Não Lida"</string> + <string name="theme_item_unread_message_background_color_detail">"Aplicado a: Cor de Fundo de Mensagem Não Lida"</string> + <string name="theme_item_divider_color">"Cor do Separador"</string> + <string name="theme_item_divider_color_detail">"Aplicado a: Separador de comentários, separadores nas páginas de publicações submetidas, etc."</string> + <string name="theme_item_vote_and_reply_unavailable_button_color">"Cor dos Botões de Voto e Resposta Indisponíveis"</string> + <string name="theme_item_vote_and_reply_unavailable_button_color_detail">"Aplicado a: Botões de Voto e Resposta (Indisponível)"</string> + <string name="theme_item_comment_vertical_bar_color_1">"Cor Da Barra Vertical de Comentário 1"</string> + <string name="theme_item_comment_vertical_bar_color_1_detail">"Aplica a: Cor Da Barra Vertical de Comentário (Nível 1)"</string> + <string name="theme_item_comment_vertical_bar_color_2">"Cor Da Barra Vertical de Comentário 2"</string> + <string name="theme_item_comment_vertical_bar_color_2_detail">"Aplica a: Cor Da Barra Vertical de Comentário (Nível 2)"</string> + <string name="theme_item_comment_vertical_bar_color_3">"Cor Da Barra Vertical de Comentário 3"</string> + <string name="theme_item_comment_vertical_bar_color_3_detail">"Aplica a: Cor Da Barra Vertical de Comentário (Nível 3)"</string> + <string name="theme_item_comment_vertical_bar_color_4">"Cor Da Barra Vertical de Comentário 4"</string> + <string name="theme_item_comment_vertical_bar_color_4_detail">"Aplica a: Cor Da Barra Vertical de Comentário (Nível 6)"</string> + <string name="theme_item_comment_vertical_bar_color_5">"Cor Da Barra Vertical de Comentário 5"</string> + <string name="theme_item_comment_vertical_bar_color_5_detail">"Aplica a: Cor Da Barra Vertical de Comentário (Nível 5)"</string> + <string name="theme_item_comment_vertical_bar_color_6">"Cor Da Barra Vertical de Comentário 6"</string> + <string name="theme_item_comment_vertical_bar_color_6_detail">"Aplica a: Cor Da Barra Vertical de Comentário (Nível 6)"</string> + <string name="theme_item_comment_vertical_bar_color_7">"Cor Da Barra Vertical de Comentário 7"</string> + <string name="theme_item_comment_vertical_bar_color_7_detail">"Aplica a: Cor Da Barra Vertical de Comentário (Nível 7)"</string> + <string name="theme_item_nav_bar_color">"Cor da Barra de Ñavegação"</string> + <string name="theme_item_nav_bar_color_detail">"Aplicado a: Barra de navegação"</string> + <string name="theme_item_light_status_bar">"Cor do Ícone da Barra de Estado Escura"</string> + <string name="theme_item_light_nav_bar">"Cor do Ícone da Barra de Navegação Escura"</string> + <string name="theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface">"Alterar a Cor do Ícone da Barra de Estado após colapso da Barra de Ferramentas na Interface Imersiva"</string> + <string name="theme_item_available_on_android_8">"Disponível apenas para Android 8.0 ou posterior."</string> + <string name="theme_item_available_on_android_6">"Disponível apenas para Android 6.0 ou posterior."</string> + <string name="predefined_themes">"Temas Pré-definidos"</string> + <string name="user_themes">"Os Seus Temas"</string> + <string name="no_theme_name">"Qual é o nome deste tema?"</string> + <string name="theme_name_hint">"Nome do Tema"</string> + <string name="theme_name_indigo">"Indigo"</string> + <string name="theme_name_indigo_dark">"Indigo Escuro"</string> + <string name="theme_name_indigo_amoled">"Indigo Amoled"</string> + <string name="theme_name_white">"Branco"</string> + <string name="theme_name_white_dark">"Branco Escuro"</string> + <string name="theme_name_white_amoled">"Branco Amoled"</string> + <string name="theme_name_red">"Vermelho"</string> + <string name="theme_name_red_dark">"Vermelho Escuro"</string> + <string name="theme_name_red_amoled">"Vermelho Amoled"</string> + <string name="theme_name_dracula">"Drácula"</string> + <string name="theme_name_calm_pastel">"Pastel Calmo"</string> + <string name="create_light_theme">"Criar Tema Claro +com base no Tema Indigo"</string> + <string name="create_dark_theme">"Criar Tema Claro +com base no Tema Indigo Escuro"</string> + <string name="create_amoled_theme">"Criar Tema Amoled +com base no Tema Indigo Amoled"</string> + <string name="create_theme_info">"Caso deseje criar um tema baseado noutro tema, clique no botão \"+\" do tema."</string> + <string name="edit_theme_name">"Editar Nome do Tema"</string> + <string name="edit_theme">"Editar Tema"</string> + <string name="delete_theme">"Eliminar Tema"</string> + <string name="delete_theme_dialog_message">"Tem a certeza que deseja eliminar %1$s?"</string> + <string name="share_theme">"Partilhar Tema"</string> + <string name="change_theme_name">"Alterar Nome"</string> + <string name="theme_copied">"Copiado! Cole e partilhe-o com outras pessoas."</string> + <string name="copy_theme_faied">"Não foi possível copiar as configurações do tema"</string> + <string name="cannot_find_theme">"Tema não encontrado"</string> + <string name="import_theme">"Importar Tema"</string> + <string name="no_data_in_clipboard">"Não foram encontrados dados na área de transferência"</string> + <string name="import_theme_success">"Tema importado com sucesso"</string> + <string name="parse_theme_failed">"Análise ao Tema Falhou"</string> + <string name="duplicate_theme_name_dialog_title">"Encontrado Tema Duplicado"</string> + <string name="duplicate_theme_name_dialog_message">"Já existe um tema na base de dados com o nome %1$s. Deseja alterar o nome do tema importado?"</string> + <string name="rename">"Renomear"</string> + <string name="override">"Substituir"</string> + <string name="color_picker">"Seletor de Cores"</string> + <string name="invalid_color">"Cor Inválida"</string> + + <!-- Fuzzy --> + <string name="delete_all_subreddits_success">"Todas as comunidades foram eliminados com sucesso"</string> + <string name="delete_all_users_success">"Todos os utilizadores eliminados com sucesso"</string> + <string name="delete_all_sort_types_success">"Todos os tipos de ordenação eliminados com sucesso"</string> + <string name="delete_all_post_layouts_success">"Todas as visualizações eliminadas com sucesso"</string> + <string name="delete_all_themes_success">"Todos os temas eliminados com sucesso"</string> + <string name="delete_all_front_page_scrolled_positions_success">"Eliminação das posições de deslizamento com sucesso"</string> + <string name="reset_all_settings_success">"Todas as definições repostas com sucesso"</string> + <string name="username_preview">"u/Hostilenemy"</string> + <string name="subreddit_preview">"r/Infinity_For_Reddit"</string> + <string name="primary_text_preview">"Texto Principal"</string> + <string name="secondary_text_preview">"Texto Secundário"</string> + <string name="post_title_preview">"Isto é uma publicação"</string> + <string name="post_content_preview">"Esta piada da Lei da Gravida é velha, mas apanha-me sempre."</string> + <string name="post_type_preview">"PUBLICAÇÃO"</string> + <string name="flair_preview">"Flair"</string> + <string name="awards_preview">"4 Prémios"</string> + <string name="author_flair_preview">"Flair do Autor"</string> + <string name="comment_content_preview">"Arranjei um cartão a desejar as \"Melhoras\" à minha namorada. +Ela não está doente nem nada, mas certamente poderá melhorar."</string> + <string name="edit_multi_reddit">"Editar Multireddit"</string> + <string name="delete_multi_reddit">"Eliminar Multireddit"</string> + <string name="n_awards">"%1$d Prémios"</string> + <string name="one_award">"1 Prémio"</string> + <string name="report">"Denunciar"</string> + <string name="reporting">"A denunciar"</string> + <string name="report_successful">"Denunciado"</string> + <string name="report_failed">"Falhou ao denunciar"</string> + <string name="report_reason_not_selected">"Não selecionou uma razão"</string> + <string name="report_reason_general_spam">"Isto é 'Spam'"</string> + <string name="report_reason_general_copyright_issue">"Contém Problemas de Direitos de Autor"</string> + <string name="report_reason_general_child_pornography">"Contém Pornografia Infantil"</string> + <string name="report_reason_general_abusive_content">"Contém Conteúdo Abusivo"</string> + <string name="home">"Início"</string> + <string name="popular">"Popular"</string> + <string name="notifications">"Notificações"</string> + <string name="messages">"Mensagens"</string> + <string name="message">"Mensagem"</string> + <string name="fetch_gfycat_video_failed">"Falha ao obter vídeo do Gfycat"</string> + <string name="fetch_redgifs_video_failed">"Falha ao obter vídeo do Redgifs"</string> + <string name="fetching_video_info_please_wait">"A obter informações do vídeo. Aguarde."</string> + <string name="error_fetching_imgur_media">"Impossível carregar imagens"</string> + <string name="downloading_reddit_video">"A transferir faixa de vídeo"</string> + <string name="downloading_reddit_video_audio_track">"A transferir faixa de aúdio"</string> + <string name="downloading_reddit_video_muxing">"A multiplexar Vídeo e Aúdio"</string> + <string name="downloading_reddit_video_save_file_to_public_dir">"A guardar vídeo"</string> + <string name="downloading_reddit_video_finished">"Transferido"</string> + <string name="downloading_reddit_video_failed_cannot_get_cache_directory">"A transferência falhou: não é possível aceder à diretoria cache"</string> + <string name="downloading_reddit_video_failed_cannot_download_video">"A transferência falhou: não é possível transferir o vídeo"</string> + <string name="downloading_reddit_video_failed_cannot_save_video">"A transferência falhou: não é possível guardar o vídeo na diretoria cache"</string> + <string name="downloading_reddit_video_failed_cannot_save_audio">"A transferência falhou: não é possível guardar o aúdio na diretoria cache"</string> + <string name="downloading_reddit_video_failed_cannot_mux">"A transferência falhou: não foi possível multiplexar o vídeo e o áudio"</string> + <string name="downloading_reddit_video_failed_cannot_save_mux_video">"A transferência falhou: não foi possível guardar o vídeo na diretoria pública"</string> + <string name="wallpaper_set">"Definir como imagem de fundo"</string> + <string name="error_set_wallpaper">"Não foi possível definir a imagem de fundo"</string> + <string name="set_to_home_screen">"Ecrã Principal"</string> + <string name="set_to_lock_screen">"Ecrã de Bloqueio"</string> + <string name="set_to_both">"Ambos"</string> + <string name="default_font_font_preview">"Padrão"</string> + <string name="load_video_in_redgifs">"Tente carregar o vídeo no Redgifs"</string> + <string name="top_score">"%1$s pontos"</string> + <string name="login_activity_2fa_prompt">"Caso tenha autenticação de 2 fatores ativada, por favor introduza a palavra-passe da seguinte forma: <palavra-passe>:<código 2FA>. +Exemplo: asuapasse:123456"</string> + <string name="block_user">"Bloquear Utilizador"</string> + <string name="block_user_success">"Bloqueado"</string> + <string name="block_user_failed">"Falha a bloquear utilizador"</string> + <string name="submit_crosspost_activity_label">"Republicar"</string> + <string name="give_award_activity_label">"Premiar"</string> + <string name="action_crosspost">"Republicar"</string> + <string name="action_select_user_flair">"Selecionar Flair de Utilizador"</string> + <string name="action_give_award">"Premiar"</string> + <string name="posts">"Publicações"</string> + <string name="sidebar">"Barra Lateral"</string> + <string name="only_for_logged_in_user">"Apenas para Utilizadores com Sessão Iniciada"</string> + <string name="settings_number_of_columns_in_post_feed_title">"Número de Colunas no Feed de Publicações"</string> + <string name="settings_number_of_columns_in_post_feed_portrait_title">"Retrato"</string> + <string name="settings_number_of_columns_in_post_feed_landscape_title">"Paisagem"</string> + <string name="settings_nsfw_and_spoiler_title">"18+ & Spoiler"</string> + <string name="settings_delete_all_legacy_settings_title">"Eliminar Todas as Definições Datadas"</string> + <string name="restart_app_see_changes">"Reinicie a aplicação para ver as alterações"</string> + <string name="settings_tab_count">"Número de Separadores"</string> + <string name="settings_show_tab_names">"Mostrar o Nome dos Separadores"</string> + <string name="settings_more_tabs_summary">"Mais Separadores"</string> + <string name="settings_more_tabs_info_summary">"Ativar as seguintes opções poderá causar um comportamento inesperado: +Os separadores poderão perder todo o conteúdo após alternar entre outros. É o mesmo que recarregar a página."</string> + <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">"Mostrar Comunidades Subscritas Favoritas"</string> + <string name="settings_more_tabs_show_subscribed_subreddits_title">"Mostrar Comunidades Subscritas"</string> + <string name="settings_download_location_title">"Localização para Transferências"</string> + <string name="settings_image_download_location_title">"Localização de Transferência de Imagens"</string> + <string name="settings_gif_download_location_title">"Localização para Transferência de GIFs"</string> + <string name="settings_video_download_location_title">"Localização para Transferência de Vídeos"</string> + <string name="settings_separate_folder_for_each_subreddit">"Separar por Pasta de Cada Comunidade"</string> + <string name="settings_swipe_action_title">"Ação de Deslizamento"</string> + <string name="settings_disable_swiping_between_tabs_title">"Desativar Deslizar entre Separadores"</string> + <string name="settings_enable_swipe_action_title">"Ativar Ação Deslizar"</string> + <string name="settings_swipe_action_threshold">"Valor limite"</string> + <string name="settings_pull_to_refresh_title">"Puxe para Atualizar"</string> + <string name="settings_security_title">"Segurança"</string> + <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Requer Autenticação para Ir à Secção de Conta na Gaveta de Navegação"</string> + <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Pressionar longo para Esconder Barra de Ferramentas"</string> + <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">"Esconder Barra de Ferramentas por Defeito"</string> + <string name="settings_customize_bottom_app_bar_title">"Personalizar Barra de Navegação Inferior"</string> + <string name="settings_main_activity_bottom_app_bar_group_summary">"Página Principal"</string> + <string name="settings_other_activities_bottom_app_bar_group_summary">"Outras Páginas"</string> + <string name="settings_bottom_app_bar_option_count">"Número de Opções"</string> + <string name="settings_bottom_app_bar_option_1">"Opção 1"</string> + <string name="settings_bottom_app_bar_option_2">"Opção 2"</string> + <string name="settings_bottom_app_bar_option_3">"Opção 3"</string> + <string name="settings_bottom_app_bar_option_4">"Opção 4"</string> + <string name="settings_bottom_app_bar_fab">"Botão de Ação Flutuante"</string> + <string name="settings_data_saving_mode">"Modo de Poupança de Dados"</string> + <string name="settings_data_saving_mode_info_summary">"No modo de poupança de dados: +Pré-visualização de imagens em baixa resolução. +Vídeos do Reddit em baixa resolução. +Reprodução automática de vídeos desativada."</string> + <string name="settings_translation_title">"Tradução"</string> + <string name="settings_translation_summary">"Traduzir esta aplicação no POEditor. Obrigado a todos os colaboradores."</string> + <string name="settings_credits_national_flags">"Bandeiras Nacionais"</string> + <string name="settings_credits_national_flags_summary">"Ícone criado por Freepik da www.flaticon.com"</string> + <string name="copy_failed">"A cópia falhou"</string> + <string name="delete_all_legacy_settings_success">"A eliminação das definições antigas foi bem sucedida"</string> + <string name="downloading_media_finished">"Transferido"</string> + <string name="downloading_image_or_gif_failed_cannot_get_destination_directory">"A transferência falhou: não é possível aceder ao diretório de destino"</string> + <string name="downloading_media_failed_cannot_download_media">"A transferência falhou"</string> + <string name="downloading_media_failed_cannot_save_to_destination_directory">"A transferência falhou: não é possível guardar o ficheiro no diretório de destino"</string> + <string name="view_full_comment_markdown">"Ver Markdown Completo"</string> + <string name="select_user_flair_success">"Flair de Utilizador Selecionado"</string> + <string name="select_this_user_flair">"Selecionar este flair de utilizador?"</string> + <string name="select_header_size">"Selecionar Tamanho do Cabeçalho"</string> + <string name="large">"Grande"</string> + <string name="small">"Pequeno"</string> + <string name="insert_link">"Inserir Ligação"</string> + <string name="text_hint">"Texto"</string> + <string name="link_hint">"Ligação"</string> + <string name="unlock_account_section">"Desbloquear Secção de Conta"</string> + <string name="unlock">"Desbloquear"</string> + <string name="submit_post">"Submeter Publicação"</string> + <string name="refresh">"Atualizar"</string> + <string name="change_sort_type">"Alterar Tipo de Ordenação"</string> + <string name="change_post_layout">"Alterar Visualização de Publicações"</string> + <string name="give_award_dialog_title">"Premiar?"</string> + <string name="anonymous">"Anónimo"</string> + <string name="give_award_error_message">"Código: %1$d/ +Mensagem: %2$s"</string> + <string name="give_award_success">"Prémio oferecido"</string> + <string name="give_award_failed">"Falhou"</string> + <string name="warning">"Aviso"</string> + <string name="this_is_a_nsfw_subreddit">"Esta é uma comunidade 18+."</string> + <string name="this_user_has_nsfw_content">"Este utilizador tem conteúdo 18+"</string> + <string name="dismiss">"Descartar"</string> + <string name="leave">"Sair"</string> + <string name="go_to_subreddit">"Ir para a Comunidade"</string> + <string name="go_to_user">"Ir para o Utilizador"</string> + <string name="go_to_thing_hint">"Nome"</string> + <string name="random">"Aleatório"</string> + <string name="random_subreddit">"Comunidade Aleatória"</string> + <string name="random_nsfw_subreddit">"Comunidade 18+ Aleatória"</string> + <string name="random_post">"Publicação Aleatória"</string> + <string name="random_nsfw_post">"Publicação 18+ Aleatória"</string> + <string name="fetch_random_thing_failed">"Tente novamente mais tarde"</string> + <string name="downloading">"A transferir"</string> + <string name="subreddit_filter_popular_and_all_activity_label">"r/all e r/popular"</string> + <string name="settings_miscellaneous_title">"Diversos"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_title">"Respeitar Tipo de Ordenação de Comentários Recomendada pela Comunidade"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_summary">"Tipo de ordenação de comentários não será guardada"</string> + <string name="settings_subreddit_filter_category">"Esconder Comunidades"</string> + <string name="settings_subreddit_filter_popular_and_all">"Em r/popular e r/all"</string> + <string name="settings_credits_ufo_capturing_animation_title">"Animação UFO Capturing"</string> + <string name="select_video_quality">"Escolher Qualidade de Vídeo"</string> + <string name="settings_swipe_action_haptic_feedback_title">"Feedback táctil"</string> + <string name="settings_hide_subreddit_description_title">"Esconder Descrição da Comunidade"</string> + <string name="settings_disable_image_preview_title">"Desativar Pré-visualização de Imagens no Modo de Poupança de Dados"</string> + <string name="settings_swipe_action_swipe_left_title">"Deslizar para a Esquerda"</string> + <string name="settings_swipe_action_swipe_right_title">"Deslizar para a Direita"</string> + <string name="settings_swipe_action_info_summary">"Não aplicável ao feed de publicações com mais que uma coluna ou detalhes de publicação."</string> + <string name="theme_item_no_preview_post_type_icon_tint">"Cor do Ícone do Tipo de Publicação sem Pré-visualização"</string> + <string name="theme_item_no_preview_post_type_background_color">"Cor de fundo do post de tipo sem-preview"</string> + <string name="settings_language_title">"Idioma"</string> + <string name="customize_post_filter_activity_label">"Personalizar Filtro de Publicações"</string> + <string name="filtered_posts_activity_subtitle">"Publicações Filtradas"</string> + <string name="post_filter_preference_activity_label">"Filtro de Publicações"</string> + <string name="search_users_result_activity_label">"Utilizadores"</string> + <string name="multireddit_selection_activity_label">"Escolher um Multireddit"</string> + <string name="action_save_to_database">"Guardar na Base de Dados"</string> + <string name="action_read_all_messages">"Ler Todas as Mensagens"</string> + <string name="action_add_to_multireddit">"Adicionar ao Multireddit"</string> + <string name="search_only_subreddits_hint">"Pesquisar comunidades"</string> + <string name="search_only_users_hint">"Pesquisar utilizadores"</string> + <string name="post_type_gif">"Gif"</string> + <string name="post_type_gallery">"Galeria"</string> + <string name="settings_disable_immersive_interface_in_landscape_mode">"Desativar Interface Imersiva no Modo Paisagem"</string> + <string name="settings_privacy_policy_title">"Política de Privacidade"</string> + <string name="settings_delete_read_posts_in_database_title">"Eliminar Todas as publicações lidas da BD"</string> + <string name="settings_post_filter_title">"Filtros de Publicações"</string> + <string name="settings_only_disable_preview_in_video_and_gif_posts_title">"Desativar Pré-visualização apenas a Publicações Vídeo e GIF"</string> + <string name="settings_enable_search_history_title">"Ativar Histórico de Pesquisa"</string> + <string name="settings_post_history_title">"Histórico de Pesquisa"</string> + <string name="settings_mark_posts_as_read_title">"Marcar Publicação como Lida"</string> + <string name="settings_mark_posts_as_read_after_voting_title">"Marcar Publicação como Lida após Votar"</string> + <string name="settings_mark_posts_as_read_on_scroll_title">"Marcar Publicações como Lidas ao Deslizar"</string> + <string name="settings_hide_read_posts_automatically_title">"Esconder Publicações Lidas Automaticamente"</string> + <string name="settings_sort_type_title">"Tipo de Ordenação"</string> + <string name="settings_save_sort_type_title">"Guardar Tipo de Ordenação"</string> + <string name="settings_subreddit_default_sort_type_title">"Ordenação Padrão das Comunidades"</string> + <string name="settings_subreddit_default_sort_time_title">"Ordenação Temporal Padrão das Comunidades"</string> + <string name="settings_user_default_sort_type_title">"Ordenação Padrão de Utilizador"</string> + <string name="settings_user_default_sort_time_title">"Ordenação Temporal Padrão do Utilizador"</string> + <string name="open_link">"Abrir Ligação"</string> + <string name="select_subreddits_and_users">"Selecione Comunidades e Utilizadores"</string> + <string name="theme_item_read_post_title_color">"Cor do Título de Publicação Lida"</string> + <string name="theme_item_read_post_title_color_detail">"Aplicado a: Título de publicação lida"</string> + <string name="theme_item_read_post_content_color">"Cor de Conteúdo de Publicação Lida"</string> + <string name="theme_item_read_post_content_color_detail">"Aplicado a: Conteúdo de publicação lida"</string> + <string name="theme_item_read_post_card_view_background_color">"Cor de Fundo de Publicação Lida em Cartão"</string> + <string name="theme_item_read_post_card_view_background_color_detail">"Aplicado a: Fundo de publicação lida"</string> + <string name="delete_all_read_posts_success">"Todas publicações lidas eliminadas com sucesso"</string> + <string name="hide_read_posts">"Esconder Publicações Lidas"</string> + <string name="filter_posts">"Filtrar Publicações"</string> + <string name="only_nsfw">"Apenas 18+"</string> + <string name="only_spoiler">"Apenas Spoiler"</string> + <string name="title_excludes_strings_hint">"Título: excluir palavras-chave (palavra1,palavra2)"</string> + <string name="title_excludes_regex_hint">"Título: excluir expressões regulares"</string> + <string name="exclude_subreddits_hint">"Excluir comunidades (ex.: funny,AskReddit)"</string> + <string name="exclude_users_hint">"Excluir utilizadores (ex.: Hostilenemy,random)"</string> + <string name="exclude_flairs_hint">"Excluir flairs (ex.: flair1, flair2)"</string> + <string name="contain_flairs_hint">"Contém flairs (ex.: flair1, flair2)"</string> + <string name="min_vote_hint">"Mínimo de votos (-1: sem restrição)"</string> + <string name="max_vote_hint">"Máximo de votos (-1: sem restrição)"</string> + <string name="min_comments_hint">"Mínimo de comentários (-1: sem restrição)"</string> + <string name="max_comments_hint">"Máximo de comentários (-1: sem restrição)"</string> + <string name="min_awards_hint">"Mínimo de prémios (-1: sem restrição)"</string> + <string name="max_awards_hint">"Máximo de prémios (-1: sem restrição)"</string> + <string name="post_filter_name_hint">"Nome do Filtro de Publicação"</string> + <string name="post_filter_requires_a_name">"Qual é o nome deste Filtro de Publicações?"</string> + <string name="duplicate_post_filter_dialog_title">"'%1$s' já existe"</string> + <string name="duplicate_post_filter_dialog_message">"Substituir?"</string> + <string name="apply_post_filter_to">"Aplicar a"</string> + <string name="post_filter_usage_home">"Início"</string> + <string name="post_filter_usage_subreddit">"Comunidade: %1$s"</string> + <string name="post_filter_usage_subreddit_all">"Comunidade"</string> + <string name="post_filter_usage_user">"Utilizador: %1$s"</string> + <string name="post_filter_usage_user_all">"Utilizador"</string> + <string name="post_filter_usage_multireddit">"MultiReddit: %1$s"</string> + <string name="post_filter_usage_multireddit_all">"MultiReddit"</string> + <string name="post_filter_usage_search">"Pesquisar"</string> + <string name="subreddit">"Comunidade"</string> + <string name="user">"Utilizador"</string> + <string name="edit_post_filter_name_of_usage_info">"Deixar em branco para aplicar este filtro de publicação a todos os utilizadores / comunidades / multireddit"</string> + <string name="read_all_messages_time_limit">"Está a repetir esta ação com demasiada frequência. Tente novamente mais tarde. Este é o valor limite da API do Reddit."</string> + <string name="read_all_messages_success">"Todas as mensagens lidas com sucesso"</string> + <string name="read_all_messages_failed">"Não é possível ler todas as mensagens"</string> + <string name="add_subreddit_or_user_to_multireddit_success">"%1$s foi adicionado ao multireddit %2$s"</string> + <string name="add_subreddit_or_user_to_multireddit_failed">"Não é possível adicionar %1$s ao multireddit %2$s"</string> + <string name="choose_a_user">"Escolher um utilizador"</string> + <string name="settings_click_to_show_media_in_gallery_layout">"Clicar para Mostrar Média na Visualização Galeria"</string> + <string name="settings_hide_post_type">"Esconder Tipo de Publicação"</string> + <string name="settings_hide_the_number_of_awards">"Esconder Número de Prémios"</string> + <string name="settings_hide_subreddit_and_user_prefix">"Esconder Prefixos de Comunidades e Utilizador"</string> + <string name="settings_hide_the_number_of_votes">"Esconder Número de Votos"</string> + <string name="settings_hide_the_number_of_comments">"Esconder Número de Comentários"</string> + <string name="post_layout_gallery">"Galeria"</string> + <string name="post_layout_card_2">"Cartão 2"</string> + <string name="have_trouble_login_title">"Dificuldades ao Iniciar Sessão"</string> + <string name="have_trouble_login_message">"Quer tentar iniciar sessão de outra forma?"</string> + <string name="vote">"Votar"</string> + <string name="action_share_link">"Partilhar Ligação"</string> + <string name="action_copy_link">"Copiar Ligação"</string> + <string name="action_add_to_post_filter">"Adicionar ao Filtro de Publicações"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"Não desfocar Imagens 18+ em Comunidades 18+"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Mostrar Avatar à Esquerda"</string> + <string name="settings_backup_settings_title">"Cópia de Segurança das Definições"</string> + <string name="settings_restore_settings_title">"Restaurar Definições"</string> + <string name="settings_credits_love_animation_title">"Animação Love"</string> + <string name="settings_swipe_between_posts_title">"Deslizar entre Publicações"</string> + <string name="settings_navigation_drawer_title">"Gaveta de Navegação"</string> + <string name="settings_collapse_account_section_title">"Colapsar Secção de Conta"</string> + <string name="settings_collapse_post_section_title">"Colapsar Secção de Publicações"</string> + <string name="settings_collapse_preferences_section_title">"Colapsar Secção de Preferências"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"Colapsar Secção de Comunidades Favoritas"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"Colapsar Secção de Comunidades Subscritas"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Esconder Secção de Comunidades Favoritas"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Esconder Secção de Comunidades Subscritas"</string> + <string name="settings_default_search_result_tab">"Separador do Resultado de Pesquisas Padrão"</string> + <string name="device_default">"Padrão do dispositivo"</string> + <string name="set_by_battery_saver">"Definido por Poupança de Bateria"</string> + <string name="theme_item_upvote_ratio_icon_tint">"Cor do Ícone do Rácio de Votos Positivos"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"Aplicado ao: Ícone do rácio de votos positivos"</string> + <string name="theme_item_current_user_color">"Utilizador Atual"</string> + <string name="theme_item_current_user_color_detail">"Aplicado a: Utilizador atual nos comentários"</string> + <string name="exclude_domains_hint">"Excluir Domínios"</string> + <string name="anonymous_front_page_no_subscriptions">"Comece por se juntar a uma comunidade!"</string> + <string name="backup_settings_success">"As definições foram exportadas para o diretório de destino com sucesso. A palavra-chave do ficheiro zip gerado é 123321. Por favor não modifique o ficheiro zip."</string> + <string name="create_zip_in_destination_directory_failed">"Não foi possível criar a cópia de segurança zip no diretório de destino"</string> + <string name="backup_some_settings_failed">"Não foi possível copiar algumas definições mas outras foram exportadas com sucesso para o diretório de destino"</string> + <string name="restore_settings_success">"Definições restauradas com sucesso. Reinicie a aplicação para ver as alterações."</string> + <string name="restore_settings_partially_failed">"Algumas definições poderão não ter sido restauradas com sucesso. Reinicie a aplicação para ver as alterações."</string> + <string name="restore_settings_failed_file_corrupted">"Não é possível restaurar as definições. O ficheiro poderá estar corrompido. "</string> + <string name="restore_settings_failed_cannot_get_file">"Não é possível aceder ao ficheiro"</string> + <string name="suicide_prevention_quote">"Se está a procura de um sinal para não se suicidar, isto é o sinal.\u2764"</string> + <string name="do_not_show_this_again">"Não mostrar novamente"</string> + <string name="continue_suicide_prevention_activity">"Continuar"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"Erro ao obter vídeo v.redd.it: Não é possível obter o url de redirecionamento"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"Erro ao obter vídeo v.redd.it: Não é possível obter a publicação"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"Erro ao obter vídeo v.redd.it: Não é possível obter o id da publicação"</string> + <string name="always_on">"Sempre ligado"</string> + <string name="only_on_wifi">"Apenas em WiFi"</string> + <string name="never">"Nunca"</string> + <string name="normal">"Normal"</string> + <string name="extra_large">"Grande"</string> + <string name="enormously_large">"Enorme"</string> + <string name="default_in_array">"Padrão"</string> + <string name="off">"Desligado"</string> + <string name="only_on_cellular_data">"Apenas em dados móveis"</string> + <string name="upvote">"Voto Positivo"</string> + <string name="downvote">"Voto Negativo"</string> + <string name="select">"Selecionar"</string> + <string name="exclude_subreddit">"Excluir esta comunidade"</string> + <string name="exclude_user">"Excluir este utilizador"</string> + <string name="exclude_flair">"Excluir esta flair"</string> + <string name="contain_flair">"Contém esta flair"</string> + <string name="exclude_domain">"Excluir Domínio"</string> + <string name="suggest_title">"Sugerir Título"</string> + <string name="suggest_title_failed">"Falha ao sugerir título"</string> + <string name="action_delete_logs">"Eliminar Logs"</string> + <string name="inbox_with_count">"Caixa de Entrada (%1$d)"</string> + <string name="comment_continue_thread">"Continuar"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"Deslize Verticalmente para Sair dos Média"</string> + <string name="settings_hide_post_flair">"Esconder Flair da Publicação"</string> + <string name="settings_crash_reports_title">"Relatório de Falhas"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"Perigoso"</string> + <string name="settings_disable_nsfw_forever_title">"Desativar 18+ para Sempre"</string> + <string name="settings_show_only_one_comment_level_indicator">"Mostrar Apenas Um Indicador do Nível de Comentário"</string> + <string name="save_comment">"Guardar"</string> + <string name="unsave_comment">"Esquecer"</string> + <string name="copy_multi_reddit_path">"Copiar Caminho do Multireddit"</string> + <string name="copy_multi_reddit_path_failed">"Não é possível copiar o caminho do multireddit"</string> + <string name="crash_reports_deleted">"Os relatórios de erros eliminados"</string> + <string name="disable_nsfw_forever_message">"Uma vez ativo, todo o conteúdo impróprio será desativado permanentemente, quer a definição de conteúdo 18+ esteja ativa ou não. Esta configuração é irreversível e a única maneira de reativar conteúdo 18+ é limpando os dados da aplicação. + +Ainda deseja ativar esta opção?"</string> + <string name="reply">"Responder"</string> + <string name="rpan_activity_label">"RPAN"</string> + <string name="post_gallery_activity_label">"Publicação de Galeria"</string> + <string name="trending_activity_label">"Tendências"</string> + <string name="action_share_rpan_link">"Partilhar Endereço RPAN"</string> + <string name="action_share_post_link">"Partilhar Endereço da Publicação"</string> + <string name="rpan">"RPAN"</string> + <string name="trending">"Tendências"</string> + <string name="receive_post_reply_notifications">"Receber notificações de respostas de publicações"</string> + <string name="bottom_sheet_post_gallery">"Galeria"</string> + <string name="posting_gallery">"A Publicar Galeria"</string> + <string name="label_reddit">"Reddit"</string> + <string name="settings_default_link_post_layout">"Disposição predefinida de Publicações de Ligação"</string> + <string name="settings_category_material_you_title">"Material You"</string> + <string name="settings_enable_material_you_warning_summary">"Assegure-se de que não tem temas com nome +\"Material You\", +\"Material You Dark\" ou +\"Material You Amoled\" +Caso contrário, altere o nome antes de ativar Material You"</string> + <string name="settings_enable_material_you_title">"Ativar Material You"</string> + <string name="settings_enable_material_you_summary">"Personalizar Infinity baseado na imagem de fundo"</string> + <string name="settings_apply_material_you_title">"Aplicar Material You"</string> + <string name="settings_apply_material_you_summary">"Em caso do Infinity não alterar o tema"</string> + <string name="settings_more_tabs_show_favorite_multireddits_title">"Mostrar MultiReddit Favorito"</string> + <string name="settings_more_tabs_show_multireddits_title">"Mostrar MultiReddit"</string> + <string name="settings_collapse_reddit_section_title">"Recolher Secção do Reddit"</string> + <string name="settings_video_player_automatic_landscape_orientation">"Alterar para Orientação Paisagem automaticamente no Reprodutor de Vídeo"</string> + <string name="settings_remember_muting_option_in_post_feed">"Lembrar opção sem som no Feed de Publicações"</string> + <string name="link_post_layout_auto">"Auto"</string> + <string name="uploaded_images">"Imagens Enviadas"</string> + <string name="select_image">"Selecionar Imagem"</string> + <string name="capture">"Capturar"</string> + <string name="uploading_image">"A Enviar"</string> + <string name="upload_image_success">"Imagem enviada com sucesso. Clicar no botão da imagem para ver as imagens enviadas."</string> + <string name="get_image_bitmap_failed">"Incapaz de obter o bitmap da imagem"</string> + <string name="upload_image_failed">"Incapaz de enviar a imagem"</string> + <string name="load_rpan_broadcasts_failed">"Não é possível carregar as emissões RPAN"</string> + <string name="parse_rpan_broadcasts_failed">"Não é possível analisar as emissões de RPAN"</string> + <string name="parse_rpan_broadcast_failed">"Não é possível analisar a emissão de RPAN"</string> + <string name="search_comments">"Pesquisar Comentários"</string> + <string name="please_wait_image_is_uploading">"Uma imagem ainda a ser enviada. Por favor aguarde."</string> + <string name="error_fetch_trending_search">"A obtenção de tendências falharam. +Toque para tentar novamente."</string> + <string name="error_parse_trending_search">"Falhou ao analisar a pesquisa de tendências. +Toque para tentar novamente."</string> + <string name="no_trending_search">"Sem tendências encontradas. +Toque para tentar novamente."</string> +</resources>
\ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml new file mode 100644 index 00000000..f27f6014 --- /dev/null +++ b/app/src/main/res/values-ru/strings.xml @@ -0,0 +1,1087 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="login_activity_label">"Войти"</string> + <string name="comment_activity_label">"Отправить комментарий"</string> + <string name="comment_activity_label_is_replying">"Ответить"</string> + <string name="post_text_activity_label">"Текстовый пост"</string> + <string name="subreddit_selection_activity_label">"Выберите сабреддит"</string> + <string name="post_link_activity_label">"Пост со ссылкой"</string> + <string name="post_image_activity_label">"Пост с изображением"</string> + <string name="post_video_activity_label">"Пост с видео"</string> + <string name="rules_activity_label">"Правила"</string> + <string name="search_subreddits_activity_label">"Сабреддиты"</string> + <string name="edit_post_activity_label">"Изменить пост"</string> + <string name="edit_comment_activity_label">"Изменить комментарий"</string> + <string name="view_message_activity_label">"Входящие"</string> + <string name="settings_activity_label">"Настройки"</string> + <string name="account_saved_thing_activity_label">"Сохранено"</string> + <string name="create_multi_reddit_activity_label">"Создать мультиреддит"</string> + <string name="subreddit_multiselection_activity_label">"Выберите сабреддиты"</string> + <string name="custom_theme_listing_activity_label">"Пользовательские темы"</string> + <string name="customize_theme_activity_label">"Изменить тему"</string> + <string name="customize_theme_activity_create_theme_label">"Создать тему"</string> + <string name="theme_preview_activity_label">"Предпросмотр темы"</string> + <string name="edit_multi_reddit_activity_label">"Изменить мультиреддит"</string> + + <!-- This is a duplicate, and I forgot to add another "д" --> + <string name="selected_subeddits_activity_label">"Выбранные сабреддиты"</string> + <string name="report_activity_label">"Пожаловаться"</string> + + <!-- Idk what this is supposed to be in english --> + <string name="view_imgur_media_activity_image_label">"Изображение %1$d/%2$d"</string> + + <!-- Idk what this is supposed to mean. --> + <string name="view_imgur_media_activity_video_label">"Видео %1$d/%2$d"</string> + <string name="send_private_message_activity_label">"Отправить личное сообщение"</string> + <string name="view_reddit_gallery_activity_image_label">"Изображение %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_gif_label">"GIF %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_video_label">"Видео %1$d/%2$d"</string> + <string name="navigation_drawer_open">"Открыть панель навигации"</string> + <string name="navigation_drawer_close">"Закрыть панель навигации"</string> + <string name="action_download">"Загрузить"</string> + <string name="action_refresh">"Обновить"</string> + <string name="action_add_comment">"Добавить комментарий"</string> + <string name="action_save_post">"Сохранить пост"</string> + <string name="action_view_crosspost_parent">"Посмотреть родительский кросспост"</string> + <string name="action_search">"Поиск"</string> + <string name="action_start_lazy_mode">"Включить ленивый режим"</string> + <string name="action_stop_lazy_mode">"Остановить ленивый режим"</string> + <string name="action_send">"Отправить"</string> + <string name="action_sort">"Сортировать"</string> + <string name="action_hide_post">"Скрыть пост"</string> + <string name="action_unhide_post">"Показать пост"</string> + <string name="action_edit_post">"Изменить пост"</string> + <string name="action_delete_post">"Удалить пост"</string> + <string name="action_mark_nsfw">"Отметить как NSFW"</string> + <string name="action_unmark_nsfw">"Убрать отметку NSFW"</string> + <string name="action_mark_spoiler">"Отметить как спойлер"</string> + <string name="action_unmark_spoiler">"Убрать отметку спойлер"</string> + <string name="action_edit_flair">"Изменить флайр"</string> + <string name="action_change_post_layout">"Выбрать вид поста"</string> + <string name="action_save">"Сохранить"</string> + <string name="action_edit_multi_reddit">"Изменить мультиреддит"</string> + <string name="action_delete_multi_reddit">"Удалить мультиреддит"</string> + <string name="action_share">"Поделиться"</string> + <string name="action_preview">"Предпросмотр"</string> + <string name="action_report">"Пожаловаться"</string> + <string name="action_see_removed">"Увидеть удалённое"</string> + <string name="action_set_wallpaper">"Установить как обои"</string> + <string name="action_send_private_message">"Отправить личное сообщение"</string> + <string name="action_block_user">"Заблокировать пользователя"</string> + <string name="parse_json_response_error">"Произошла ошибка при анализе JSON-отчёта"</string> + <string name="retrieve_token_error">"Ошибка получения токена"</string> + <string name="something_went_wrong">"Что-то пошло не так. Попробуйте позже."</string> + <string name="access_denied">"В доступе отказано"</string> + <string name="parse_user_info_error">"Произошла ошибка во время обработки информации о пользователе"</string> + <string name="no_system_webview_error">"Ошибка открытия системного WebView"</string> + <string name="error_loading_image_tap_to_retry">"Произошла ошибка при загрузке изображения. Нажмите, чтобы повторить попытку."</string> + <string name="load_posts_error">"Произошла ошибка при загрузке постов. Нажмите, чтобы повторить попытку."</string> + <string name="load_more_posts_error">"Произошла ошибка при загрузке постов."</string> + <string name="load_post_error">"Произошла ошибка при загрузке поста. +Нажмите, чтобы повторить попытку."</string> + <string name="search_subreddits_error">"Произошла ошибка при поиске сабреддитов. +Нажмите, чтобы повторить попытку."</string> + <string name="search_users_error">"Произошла ошибка при поиске пользователей. +Нажмите, чтобы повторить попытку."</string> + <string name="no_posts">"Посты не найдены"</string> + <string name="no_comments">"Комментарии не найдены"</string> + <string name="no_subreddits">"Сабреддиты не найдены"</string> + <string name="no_users">"Пользователи не найдены"</string> + <string name="no_multi_reddits">"Мультиреддиты не найдены"</string> + <string name="no_storage_permission">"Отсутствует доступ к хранилищу для сохранения этого файла"</string> + <string name="load_comments_failed">"Произошла ошибка при загрузке комментариев. +Нажмите, чтобы повторить попытку."</string> + <string name="retry">"Повторить"</string> + <string name="comments">"Комментарии"</string> + <string name="no_comments_yet">"Комментариев ещё нет. Написать комментарий?"</string> + <string name="vote_failed">"Не удалось проголосовать"</string> + <string name="refresh_post_failed">"Произошла ошибка при обновлении поста."</string> + <string name="load_messages_failed">"Ошибка загрузки сообщений. Нажмите для повтора."</string> + <string name="no_messages">"Пусто"</string> + <string name="nsfw">"NSFW"</string> + <string name="karma_info">"Карма: %1$d"</string> + <string name="karma_info_user_detail">"Карма: +%1$d (%2$d + %3$d)"</string> + <string name="cakeday_info">"День торта: +%1$s"</string> + <string name="since">"Создан:"</string> + <string name="profile">"Профиль"</string> + <string name="subscriptions">"Подписки"</string> + <string name="multi_reddit">"Мультиреддит"</string> + <string name="inbox">"Входящие"</string> + <string name="upvoted">"Голос+"</string> + <string name="downvoted">"Голос-"</string> + <string name="hidden">"Скрытые"</string> + <string name="saved">"Сохранённые"</string> + <string name="gilded">"Позолоченные"</string> + <string name="settings">"Настройки"</string> + <string name="subscribers_number_detail">"Подписчики: %1$d"</string> + <string name="online_subscribers_number_detail">"Онлайн: %1$d"</string> + <string name="cannot_fetch_subreddit_info">"Не удалось получить информацию о сабреддите"</string> + <string name="cannot_fetch_user_info">"Не удалось получить информацию о пользователе"</string> + <string name="cannot_fetch_sidebar">"Не удалось получить боковую панель"</string> + <string name="cannot_fetch_multireddit">"Не удалось получить информацию о мультиреддите"</string> + <string name="subscribe">"Подписаться"</string> + <string name="unsubscribe">"Отписаться"</string> + <string name="subscribed">"Вы подписаны"</string> + <string name="subscribe_failed">"Не удалось подписаться"</string> + <string name="unsubscribed">"Вы отписались"</string> + <string name="unsubscribe_failed">"Ну удалось отписаться"</string> + <string name="follow">"Следить"</string> + <string name="unfollow">"Не следить"</string> + <string name="followed">"Вы следите"</string> + <string name="follow_failed">"Не удалось начать следить"</string> + <string name="unfollowed">"Вы не следите"</string> + <string name="unfollow_failed">"Не удалось перестать следить"</string> + <string name="content_description_banner_imageview">"Изображение банера сабреддита"</string> + <string name="app_label">"Infinity"</string> + <string name="search_hint">"Ищите что угодно"</string> + <string name="no_posts_no_lazy_mode">"Нет доступных постов"</string> + <string name="lazy_mode_start">"Ленивый режим начнётся через %1$.1fs"</string> + <string name="lazy_mode_stop">"Ленивый режим остановлен"</string> + <string name="write_comment_hint">"Ваши интересные мысли здесь"</string> + <string name="comment_content_required">"А где ваши интересные размышления?"</string> + <string name="sending_comment">"Отправка"</string> + <string name="send_comment_success">"Комментарий отправлен"</string> + <string name="send_comment_failed">"Не удалось отправить данный комментарий"</string> + <string name="send_message_username_hint">"Пользователь"</string> + <string name="send_message_subject_hint">"Тема (до 100 знаков)"</string> + <string name="send_message_content_hint">"Сообщение"</string> + <string name="reply_message_failed">"Не удалось ответить на это сообщение"</string> + <string name="error_getting_message">"Не удалось получить сообщение"</string> + <string name="message_username_required">"А кому вы хотите отправить это сообщение?"</string> + <string name="message_subject_required">"Сообщение должно содержать тему"</string> + <string name="message_content_required">"А написать содержимое?"</string> + <string name="sending_message">"Отправляем"</string> + <string name="send_message_success">"Сообщение отправлено"</string> + <string name="send_message_failed">"Не удалось отправить это сообщение"</string> + <string name="select_a_subreddit">"Пожалуйста, сначала выберите сабреддит"</string> + <string name="title_required">"Посту требуется заголовок"</string> + <string name="link_required">"А ссылка где?"</string> + <string name="select_an_image">"Пожалуйста, сначала выберите изображение"</string> + <string name="posting">"Публикация"</string> + <string name="post_failed">"Не удалось опубликовать пост"</string> + <string name="error_processing_image">"Ошибка при обработке изображения"</string> + <string name="error_processing_video">"Ошибка при обработке видео"</string> + <string name="download_started">"Загрузка началась. Проверьте уведомления для отслеживания прогресса."</string> + <string name="comment_load_more_comments">"Загрузить больше комментариев"</string> + <string name="comment_load_more_comments_failed">"Загрузка не выполнена. Нажмите для повторной загрузки."</string> + <string name="loading">"Загрузка"</string> + <string name="post_title_hint">"Заголовок"</string> + <string name="post_text_content_hint">"Контент"</string> + <string name="choose_a_subreddit">"Выбрать сабреддит"</string> + <string name="rules">"Правила"</string> + <string name="post_link_hint">"Ссылка"</string> + <string name="subreddits">"Сабреддиты"</string> + <string name="users">"Пользователи"</string> + <string name="multi_reddits">"Мультиреддиты"</string> + <string name="bottom_sheet_post_text">"Текст"</string> + <string name="bottom_sheet_post_link">"Ссылка"</string> + <string name="bottom_sheet_post_image">"Изображение"</string> + <string name="bottom_sheet_post_video">"Видео"</string> + <string name="select_from_gallery">"Выберите изображение"</string> + <string name="select_again">"Выбрать снова"</string> + <string name="error_getting_image">"Не удалось получить изображение"</string> + <string name="error_getting_video">"Не удалось получить видео"</string> + <string name="no_camera_available">"Нет доступных приложений камеры"</string> + <string name="error_creating_temp_file">"Не удалось создать временный файл"</string> + <string name="video_is_processing">"Видео обрабатывается. Пожалуйста, подождите."</string> + <string name="image_is_processing">"Изображение обрабатывается. Пожалуйста, подождите."</string> + <string name="gif_is_processing">"GIF обрабатывается. Пожалуйста, подождите."</string> + <string name="flair">"Стиль"</string> + <string name="spoiler">"Спойлер"</string> + <string name="no_flair">"Нет стиля"</string> + <string name="error_loading_flairs">"Ошибка загрузки стилей. +Нажмите, чтобы перезагрузить."</string> + <string name="no_rule">"Правил нет"</string> + <string name="error_loading_rules">"Ошибка загрузки правил. +Нажмите, чтобы перезагрузить."</string> + <string name="error_loading_rules_without_retry">"Ошибка загрузки правил"</string> + <string name="search_in">"Искать в"</string> + <string name="all_subreddits">"Все сабреддиты"</string> + <string name="sort_best">"Лучшее"</string> + <string name="sort_hot">"Горячее"</string> + <string name="sort_new">"Новое"</string> + <string name="sort_random">"Случайный"</string> + <string name="sort_rising">"Набирающее популярность"</string> + <string name="sort_top">"Топовое"</string> + <string name="sort_controversial">"Обсуждаемое"</string> + <string name="sort_relevance">"Релевантное"</string> + <string name="sort_comments">"Комментарии"</string> + <string name="sort_activity">"Активность"</string> + <string name="sort_confidence">"Доверенное"</string> + <string name="sort_old">"Старый"</string> + <string name="sort_qa">"ЧаВО"</string> + <string name="sort_live">"Live"</string> + <string name="sort_time_hour">"Час"</string> + <string name="sort_time_day">"День"</string> + <string name="sort_time_week">"Неделя"</string> + <string name="sort_time_month">"Месяц"</string> + <string name="sort_time_year">"Год"</string> + <string name="sort_time_all_time">"За всё время"</string> + <string name="no_activity_found_for_share">"Нечем обработать действие «Поделиться»."</string> + <string name="archived_post_vote_unavailable">"Архивный пост. Голосование недоступно."</string> + <string name="archived_post_comment_unavailable">"Архивный пост. Комментирование недоступно."</string> + <string name="archived_post_reply_unavailable">"Архивный пост."</string> + <string name="locked_post_comment_unavailable">"Заблокированный пост. Коммент недоступен."</string> + <string name="locked_post_reply_unavailable">"Заблокированный пост. Ответ недоступен."</string> + <string name="text">"ТЕКСТ"</string> + <string name="link">"ССЫЛКА"</string> + <string name="image">"ИЗОБРАЖЕНИЕ"</string> + <string name="video">"ВИДЕО"</string> + <string name="gif">"GIF"</string> + <string name="gallery">"ГАЛЕРЕЯ"</string> + <string name="best">"Лучшее"</string> + <string name="search">"Поиск"</string> + <string name="posting_video">"Видео публикуется"</string> + <string name="posting_image">"Изображение публикуется"</string> + + <!-- Fuzzy --> + <string name="please_wait">"Пожалуйста, подождите."</string> + <string name="add_account">"Добавить аккаунт"</string> + <string name="anonymous_account">"Аноним"</string> + <string name="log_out">"Выйти"</string> + <string name="press_here_to_login">"Нажмите, чтобы войти"</string> + <string name="login_first">"Сначала нужно войти"</string> + <string name="post_saved_success">"Пост сохранён"</string> + <string name="post_saved_failed">"Невозможно сохранить пост"</string> + <string name="post_unsaved_success">"Пост удалён из сохранённых"</string> + <string name="post_unsaved_failed">"Не удалось удалить пост из сохранённых"</string> + <string name="post_hide_success">"Пост скрыт"</string> + <string name="post_hide_failed">"Не удалось скрыть пост"</string> + <string name="post_unhide_success">"Пост раскрыт"</string> + <string name="thing_favorite_failed">"Не удалось добавить в избранное"</string> + <string name="thing_unfavorite_failed">"Не удалось удалить из избранного"</string> + <string name="post_unhide_failed">"Не удалось показать пост"</string> + <string name="delete_this_post">"Удалить этот пост"</string> + <string name="delete_this_comment">"Удалить этот комментарий"</string> + <string name="are_you_sure">"Вы уверены?"</string> + <string name="edit">"Изменить"</string> + <string name="delete">"Удалить"</string> + <string name="see_removed_comment">"Посмотреть удалённый комментарий"</string> + <string name="fetching_removed_comment">"Получение удалённого комментария"</string> + <string name="show_removed_comment_failed">"Не удалось найти удалённый комментарий"</string> + <string name="fetching_removed_post">"Получение удалённого сообщения"</string> + <string name="show_removed_post_failed">"Не удалось найти удалённую запись"</string> + <string name="cancel">"Отменить"</string> + <string name="ok">"ОК"</string> + <string name="edit_success">"Редактирование успешно"</string> + <string name="delete_post_success">"Удалено успешно"</string> + <string name="delete_post_failed">"Не удалось удалить"</string> + <string name="mark_nsfw_success">"Успешно помечено как NSFW"</string> + <string name="mark_nsfw_failed">"Отметить как NSFW не удалось"</string> + <string name="unmark_nsfw_success">"Снятие отметки NSFW успешно"</string> + <string name="unmark_nsfw_failed">"Снять отметку NSFW не удалось"</string> + <string name="mark_spoiler_success">"Помечено как спойлер успешно"</string> + <string name="mark_spoiler_failed">"Отметить как спойлер не удалось"</string> + <string name="unmark_spoiler_success">"Отметка спойлера снята успешно"</string> + <string name="unmark_spoiler_failed">"Не удалось снять отметку спойлера"</string> + <string name="update_flair_success">"Флейр успешно обновлён"</string> + <string name="update_flair_failed">"Ошибка обновления флейра"</string> + <string name="edit_flair">"Изменить флейр"</string> + <string name="only_allow_64_chars">"Допускается не более 64 символов"</string> + <string name="view_all_comments">"Нажмите здесь, чтобы посмотреть все комментарии"</string> + <string name="notification_summary_account">"Аккаунт"</string> + <string name="notification_summary_message">"Новое сообщение"</string> + <string name="notification_summary_subreddit">"Сабреддит"</string> + <string name="notification_summary_award">"Награда"</string> + <string name="notification_new_messages">"%1$d новых сообщений"</string> + <string name="label_account">"Аккаунт"</string> + <string name="label_post">"Пост"</string> + <string name="label_preferences">"Настройки"</string> + <string name="account_switched">"Аккаунт переключён, поэтому все страницы исчезли."</string> + <string name="settings_notification_master_title">"Уведомление"</string> + <string name="settings_notification_enable_notification_title">"Включить уведомления"</string> + <string name="settings_notification_interval_title">"Интервал проверки уведомлений"</string> + <string name="settings_theme_title">"Тема"</string> + <string name="settings_amoled_dark_title">"Чёрная AMOLED"</string> + <string name="settings_interface_title">"Интерфейс"</string> + <string name="settings_gestures_and_buttons_title">"Жесты и кнопки"</string> + <string name="settings_save_front_page_scrolled_position_title">"Сохранять прокрученную позицию на «Главной»"</string> + <string name="settings_save_front_page_scrolled_position_summary">"Просмотр новых постов после обновления на «Главной» (Заглавная страница, сортировка: лучшее)"</string> + <string name="settings_open_link_in_app_title">"Открыть ссылку в приложении"</string> + <string name="settigns_video_title">"Видео"</string> + <string name="settings_video_autoplay_title">"Автовоспроизведение видео"</string> + <string name="settings_mute_autoplaying_videos_title">"Отключать звук у автовоспроизводящихся видео"</string> + <string name="settings_autoplay_nsfw_videos_title">"Автовоспроизведение NSFW-видео"</string> + <string name="settings_start_autoplay_visible_area_offset_portrait_title">"Автоматическое воспроизведение видео (портрет)"</string> + <string name="settings_start_autoplay_visible_area_offset_portrait_summary">"Начать автовоспроизведение, когда станет доступно %1$d%% видео"</string> + <string name="settings_start_autoplay_visible_area_offset_landscape_title">"Автоматическое воспроизведение видео (пейзаж)"</string> + <string name="settings_start_autoplay_visible_area_offset_landscape_summary">"Начать автовоспроизведение, когда станет доступно %1$d%% видео"</string> + <string name="settings_immersive_interface_title">"Режим погружения"</string> + <string name="settings_immersive_interface_summary">"Применимо не ко всем страницам"</string> + <string name="settings_immersive_interface_ignore_nav_bar_title">"Не использовать панель навигации в режиме погружения"</string> + <string name="settings_immersive_interface_ignore_nav_bar_summary">"Предотвратить лишнее заполнения нижней панели навигации"</string> + <string name="settings_customize_tabs_in_main_page_title">"Настройка вкладок на главном экране"</string> + <string name="settings_enable_bottom_app_bar_title">"Включить нижнюю навигацию"</string> + <string name="settings_enable_bottom_app_bar_summary">"Не работает в анонимном режиме"</string> + <string name="settings_category_post_and_comment_title">"Посты и комментарии"</string> + <string name="settings_vote_buttons_on_the_right_title">"Кнопка голосования справа"</string> + <string name="settings_volume_keys_navigate_comments_title">"Навигация кнопками громкости между комментариями в постах"</string> + <string name="settings_volume_keys_navigate_posts_title">"Навигация кнопками громкости в постах"</string> + <string name="settings_mute_video_title">"Видео без звука"</string> + <string name="settings_mute_nsfw_video_title">"NSFW-видео без звука"</string> + + <!-- Fuzzy --> + <string name="settings_automatically_try_redgifs_title">"Автопопытка доступа к Redgifs, если видео на Gfycat удалены"</string> + <string name="settings_video_player_ignore_nav_bar_title">"Не использовать панель навигации в видеоплеере"</string> + <string name="settings_video_player_ignore_nav_bar_summary">"Предотвратить случайные нажатия"</string> + <string name="settings_confirm_to_exit">"Подтверждать выход"</string> + <string name="settings_category_comment_title">"Комментарий"</string> + <string name="settings_show_top_level_comments_first_title">"Сначала показывать комментарии верхнего уровня"</string> + <string name="settings_show_comment_divider_title">"Показывать разделитель комментариев"</string> + <string name="settings_comment_toolbar_hide_on_click">"Нажмите, чтобы отобразить/скрыть панель инструментов комментариев"</string> + <string name="settings_fully_collapse_comment_title">"Полностью свернуть комментарий"</string> + <string name="settings_comment_toolbar_hidden">"Скрыть панель инструментов комментариев по умолчанию"</string> + <string name="settings_show_absolute_number_of_votes_title">"Показывать абсолютное количество голосов"</string> + <string name="settings_show_elapsed_time">"Показывать прошедшее время в постах и комментариях"</string> + <string name="settings_time_format_title">"Формат времени"</string> + <string name="settings_category_post_title">"Пост"</string> + <string name="settings_default_post_layout">"Вид поста по умолчанию"</string> + <string name="settings_show_divider_in_compact_layout">"Показывать разделитель"</string> + <string name="settings_show_thumbnail_on_the_left_in_compact_layout">"Показывать миниатюры слева"</string> + <string name="settings_swap_tap_and_long_title">"Поменять местами касание и долгое нажатие в комментариях"</string> + <string name="settings_swipe_to_go_back_title">"Правый жест для возврата"</string> + <string name="settings_swipe_to_go_back_summary">"Не применяется ко всем страницам"</string> + <string name="settings_lock_jump_to_next_top_level_comment_button_title">"Блокировать переход к следующей кнопке комментариев верхнего уровня"</string> + <string name="settings_lock_bottom_app_bar_title">"Заблокировать нижнюю панель навигации"</string> + <string name="settings_swipe_up_to_hide_jump_to_next_top_level_comment_button_title">"Жест вверх, чтобы скрыть кнопку перехода к следующему верхнему уровню комментария"</string> + <string name="settings_lazy_mode_interval_title">"Интервал ленивого режима"</string> + <string name="settings_font_title">"Шрифт"</string> + <string name="settings_preview_font_title">"Предпросмотр шрифтов"</string> + <string name="settings_font_summary">"Шрифт"</string> + <string name="settings_title_font_summary">"Заглавие"</string> + <string name="settings_content_font_summary">"Содержимое"</string> + <string name="settings_font_family_title">"Семейство шрифтов"</string> + <string name="settings_title_font_family_title">"Семейство шрифтов заголовка"</string> + <string name="settings_content_font_family_title">"Семейство шрифтов содержания"</string> + <string name="settings_font_size_title">"Размер шрифта"</string> + <string name="settings_title_font_size_title">"Размер шрифта заголовка"</string> + <string name="settings_content_font_size_title">"Размер шрифта содержания"</string> + <string name="settings_enable_nsfw_title">"Включить NSFW"</string> + <string name="settings_blur_nsfw_title">"Размытие изображений NSFW"</string> + <string name="settings_blur_spoiler_title">"Размывать изображения под спойлером"</string> + <string name="settings_about_master_title">"Обо всём"</string> + <string name="settings_acknowledgement_master_title">"Признательность"</string> + <string name="settings_credits_master_title">"Благодарности"</string> + <string name="settings_credits_icon_foreground_title">"Значок переднего плана"</string> + <string name="settings_credits_icon_foreground_summary">"Технологический вектор, созданный freepik – www.freepik.com"</string> + <string name="settings_credits_icon_background_title">"Фон значка"</string> + <string name="settings_credits_icon_background_summary">"Фоновый вектор, созданный freepik – www.freepik.com"</string> + <string name="settings_credits_error_image_title">"Ошибка изображения"</string> + <string name="settings_credits_error_image_summary">"Технологический вектор, созданный freepik – www.freepik.com"</string> + <string name="settings_credits_gilded_icon_title">"Значок золота"</string> + <string name="settings_credits_gilded_icon_summary">"Значок создан Freepik из from www.flaticon.com"</string> + <string name="settings_credits_crosspost_icon_title">"Значок кросспоста"</string> + <string name="settings_credits_crosspost_icon_summary">"Значок создан Freepik из www.flaticon.com"</string> + <string name="settings_credits_thumbtack_icon_title">"Значок канцелярской кнопки"</string> + <string name="settings_credits_thumbtack_icon_summary">"Значок создан Freepik из from www.flaticon.com"</string> + <string name="settings_credits_best_rocket_icon_title">"Значок ракеты"</string> + <string name="settings_credits_best_rocket_icon_summary">"Значок создан Freepik из from www.flaticon.com"</string> + <string name="settings_credits_material_icons_title">"Значки Material"</string> + <string name="settings_open_source_title">"Открытый источник"</string> + <string name="settings_open_source_summary">"Посетите его на Github, если вам нравится это приложение"</string> + <string name="settings_rate_title">"Оцените на Google Play"</string> + <string name="settings_rate_summary">"Поставьте мне оценку 5 звёзд, и я буду очень счастлив"</string> + <string name="settings_email_title">"Эл. почта"</string> + <string name="settings_email_summary">"docilealligator.app@gmail.com"</string> + <string name="settings_reddit_account_title">"Аккаунт Reddit"</string> + <string name="settings_reddit_account_summary">"u/Hostilenemy"</string> + <string name="settings_subreddit_title">"Сабреддит"</string> + <string name="settings_subreddit_summary">"r/Infinity_For_Reddit"</string> + <string name="settings_share_title">"Поделиться"</string> + <string name="settings_share_summary">"Поделитесь этим приложением с другими людьми, если оно вам нравится"</string> + <string name="settings_version_title">"Infinity для Reddit"</string> + <string name="settings_version_summary">"Версия %s"</string> + <string name="settings_category_customization_title">"Персонализация"</string> + <string name="settings_customize_light_theme_title">"Светлая тема"</string> + <string name="settings_customize_dark_theme_title">"Тёмная тема"</string> + <string name="settings_customize_amoled_theme_title">"Тема AMOLED"</string> + <string name="settings_manage_themes_title">"Менеджер тем"</string> + <string name="settings_custom_theme_cannot_apply_to_settings_page_summary">"Пользовательские темы не применяются к странице настроек (кроме панели инструментов, строки состояния и панели навигации)."</string> + <string name="settings_advanced_master_title">"Дополнительные"</string> + <string name="settings_delete_all_subreddits_data_in_database_title">"Удалить все сабреддиты из базы данных"</string> + <string name="settings_delete_all_users_data_in_database_title">"Удалить всех пользователей из базы данных"</string> + <string name="settings_delete_all_sort_type_data_in_database_title">"Удалить все типы сортировки из базы данных"</string> + <string name="settings_delete_all_post_layout_data_in_database_title">"Удалить все макеты постов в базе данных"</string> + <string name="settings_delete_all_themes_in_database_title">"Удалить все темы из базы данных"</string> + <string name="settings_delete_front_page_scrolled_positions_in_database_title">"Удалить все позиции прокрутки главной страницы в базе данных"</string> + <string name="settings_reset_all_settings_title">"Сбросить настройки"</string> + <string name="settings_tab_1_summary">"Вкладка 1"</string> + <string name="settings_tab_2_summary">"Вкладка 2"</string> + <string name="settings_tab_3_summary">"Вкладка 3"</string> + <string name="settings_tab_title">"Название"</string> + <string name="settings_tab_post_type">"Тип"</string> + <string name="settings_tab_subreddit_name">"Название сабреддита (без префикса r/)"</string> + <string name="settings_tab_multi_reddit_name">"Название мультиреддита (/user/yourusername/m/yourmultiredditname)"</string> + <string name="settings_tab_username">"Имя пользователя (без префикса u/)"</string> + <string name="no_developer_easter_egg">"Здесь нет вариантов разработчика"</string> + <string name="no_link_available">"Не могу получить ссылку"</string> + <string name="exit_when_submit">"Выйти?"</string> + <string name="exit_when_submit_post_detail">"Пост всё равно будет отправлен, даже если вы уйдёте отсюда."</string> + <string name="exit_when_edit_post_detail">"Пост может быть отправлено, даже если вы уйдёте отсюда."</string> + <string name="exit_when_edit_comment_detail">"Комментарий всё ещё может быть отправлен, даже если вы уйдёте отсюда."</string> + <string name="discard">"Отменить?"</string> + <string name="discard_detail">"Все черновики НЕ будут сохранены."</string> + <string name="yes">"Да"</string> + <string name="no">"Нет"</string> + <string name="no_data_received">"Данные не получены"</string> + <string name="no_image_path_received">"Путь к изображению не получен"</string> + <string name="no_video_path_received">"Путь к видео не получен"</string> + <string name="cannot_handle_intent">"Не удалось обработать запрос «Поделиться»"</string> + <string name="share">"Поделиться"</string> + <string name="no_email_client">"Клиент эл. почты не найден"</string> + <string name="no_app">"Приложение недоступно"</string> + <string name="comment_saved_success">"Комментарий сохранён"</string> + <string name="comment_saved_failed">"Не удалось сохранить комментарий"</string> + <string name="comment_unsaved_success">"Комментарий не сохранён"</string> + <string name="comment_unsaved_failed">"Невозможно удалить комментарий"</string> + <string name="favorites">"Избранное"</string> + <string name="all">"Все"</string> + <string name="post_layout_card">"Карточный стиль"</string> + <string name="post_layout_compact">"Компактный стиль"</string> + <string name="elapsed_time_just_now">"Только что"</string> + <string name="elapsed_time_a_minute_ago">"1 минута"</string> + <string name="elapsed_time_minutes_ago">"%1$d мин."</string> + <string name="elapsed_time_an_hour_ago">"1 час"</string> + <string name="elapsed_time_hours_ago">"%1$d час."</string> + <string name="elapsed_time_yesterday">"Вчера"</string> + + <!-- I am not sure how to unify this one. Plural form differs depending on numerals. --> + <string name="elapsed_time_days_ago">"%1$d дн."</string> + <string name="elapsed_time_a_month_ago">"1 месяц"</string> + <string name="elapsed_time_months_ago">"%1$d мес."</string> + <string name="elapsed_time_a_year_ago">"1 год"</string> + <string name="elapsed_time_years_ago">"%1$d лет"</string> + <string name="error_getting_multi_reddit_data">"Ошибка при получении данных о мультиреддите"</string> + <string name="error_loading_multi_reddit_list">"Не удалось синхронизировать мультиреддиты"</string> + <string name="error_loading_subscriptions">"Не удалось синхронизировать подписки"</string> + <string name="share_this_app">"Попробуйте Infinity для Reddit, отличный клиент для Реддита! +https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit"</string> + <string name="error_getting_subreddit_name">"Ошибка при получении названия сабреддита"</string> + <string name="share_post_link">"Поделиться ссылкой на пост"</string> + <string name="share_image_link">"Поделиться ссылкой на изображение"</string> + <string name="share_gif_link">"Поделиться ссылкой на GIF"</string> + <string name="share_video_link">"Поделиться ссылкой на видео"</string> + <string name="share_link">"Поделиться ссылкой"</string> + <string name="copy_post_link">"Скопировать ссылку на пост"</string> + <string name="copy_image_link">"Скопировать ссылку изображения"</string> + <string name="copy_gif_link">"Скопировать ссылку на GIF"</string> + <string name="copy_video_link">"Скопировать ссылку на видео"</string> + <string name="copy_link">"Скопировать ссылку"</string> + <string name="copy_success">"Скопировано"</string> + <string name="copy_link_failed">"Не удалось скопировать ссылку"</string> + <string name="copy_text">"Скопировать"</string> + <string name="copy_all">"Скопировать всё"</string> + <string name="copy_markdown">"Скопировать Markdown"</string> + <string name="copy_raw_text">"Скопировать только текст"</string> + <string name="copy_all_markdown">"Копировать весь Markdown"</string> + <string name="copy_all_raw_text">"Копировать весь исходный текст"</string> + <string name="exit_app">"Выйти?"</string> + <string name="light_theme">"Светлая тема"</string> + <string name="dark_theme">"Тёмная тема"</string> + <string name="multi_reddit_name_hint">"Название (максимум 50 символов)"</string> + <string name="multi_reddit_description_hint">"Описание"</string> + <string name="private_multi_reddit">"Приватный"</string> + <string name="no_multi_reddit_name">"Где название?"</string> + <string name="create_multi_reddit_failed">"Невозможно создать мультиреддит"</string> + <string name="duplicate_multi_reddit">"Мультиреддит уже существует"</string> + <string name="edit_multi_reddit_failed">"Не удалось изменить мультиреддит"</string> + <string name="logged_out">"Вы вышли из системы"</string> + <string name="delete_multi_reddit_success">"Успешно удалено"</string> + <string name="delete_multi_reddit_failed">"Ошибка удаления"</string> + <string name="delete_multi_reddit_dialog_message">"Вы уверены?"</string> + <string name="enable_nsfw">"Включить NSFW"</string> + <string name="disable_nsfw">"Отключить NSFW"</string> + <string name="cannot_save_image">"Не удалось сохранить изображение"</string> + <string name="cannot_save_gif">"Не удалось сохранить GIF"</string> + <string name="cannot_get_storage">"Нет доступа к хранилищу"</string> + <string name="save_image_first">"Изображение сохраняется. Пожалуйста, подождите."</string> + <string name="save_gif_first">"GIF сохраняется. Пожалуйста, подождите."</string> + <string name="theme_name_description">"Нажмите, чтобы поменять название темы"</string> + <string name="theme_item_is_light_theme">"Установить как светлую тему"</string> + <string name="theme_item_is_dark_theme">"Установить как тёмную тему"</string> + <string name="theme_item_is_amoled_theme">"Установить как тему AMOLED"</string> + <string name="theme_item_color_primary">"Основной цвет"</string> + <string name="theme_item_color_primary_detail">"Применяется к: панель инструментов"</string> + <string name="theme_item_color_primary_dark">"Основной тёмный цвет"</string> + <string name="theme_item_color_primary_dark_detail">"Применяется к: панель статуса"</string> + <string name="theme_item_color_accent">"Акцент цвета"</string> + <string name="theme_item_color_accent_detail">"Применяется к: панель выполнения и т.д."</string> + <string name="theme_item_color_primary_light_theme">"Основной цвет светлой темы"</string> + <string name="theme_item_color_primary_light_theme_detail">"Применяется к: фон плавающей кнопки действия"</string> + <string name="theme_item_primary_text_color">"Цвет основного текста"</string> + <string name="theme_item_primary_text_color_detail">"Применяется к: основной текст"</string> + <string name="theme_item_secondary_text_color">"Цвет дополнительного текста"</string> + <string name="theme_item_secondary_text_color_detail">"Применяется к: дополнительный текст"</string> + <string name="theme_item_post_title_color">"Цвет заголовка поста"</string> + <string name="theme_item_post_title_color_detail">"Применяется к: заголовок поста"</string> + <string name="theme_item_post_content_color">"Применяется к: заголовок поста"</string> + <string name="theme_item_post_content_color_detail">"Применяется к: содержимое поста"</string> + <string name="theme_item_comment_color">"Цвет комментария"</string> + <string name="theme_item_comment_color_detail">"Применяется к: комментарий"</string> + <string name="theme_item_button_text_color">"Цвет текста кнопки"</string> + <string name="theme_item_button_text_color_detail">"Применяется к: текст на кнопке"</string> + <string name="theme_item_chip_text_color">"Цвет чип текста"</string> + <string name="theme_item_chip_text_color_detail">"Применяется к: кнопка «Подписаться»"</string> + <string name="theme_item_link_color">"Цвет ссылки"</string> + <string name="theme_item_link_color_detail">"Применяется к: URL"</string> + <string name="theme_item_received_message_text_color">"Цвет текста полученного сообщения"</string> + <string name="theme_item_received_message_text_color_detail">"Применяется к: полученные личные сообщения"</string> + <string name="theme_item_sent_message_text_color">"Цвет текста отправленного сообщения"</string> + <string name="theme_item_sent_message_text_color_detail">"Применяется к: отправленное личное сообщение"</string> + <string name="theme_item_background_color">"Цвет фона"</string> + <string name="theme_item_background_color_detail">"Применяется к: фон каждой страницы и панели навигации"</string> + <string name="theme_item_card_view_background_color">"Цвет фона карточки"</string> + <string name="theme_item_card_view_background_color_detail">"Применяется к: фон поста и фон сообщения"</string> + <string name="theme_item_comment_background_color">"Цвет фона комментария"</string> + <string name="theme_item_comment_background_color_detail">"Применяется к: фон комментария"</string> + <string name="theme_item_fully_collapsed_comment_background_color">"Цвет фона полностью свёрнутого комментария"</string> + <string name="theme_item_fully_collapsed_comment_background_color_detail">"Применяется к: фон свёрнутых комментариев"</string> + <string name="theme_item_awarded_comment_background_color">"Цвет фона награждённого комментария"</string> + <string name="theme_item_awarded_comment_background_color_detail">"Применяется к: фон награждённых комментариев"</string> + <string name="theme_item_received_message_background_color">"Цвет фона полученного сообщения"</string> + <string name="theme_item_received_message_background_color_detail">"Применяется к: фон полученного личного сообщения"</string> + <string name="theme_item_sent_message_background_color">"Цвет фона отправленного сообщения"</string> + <string name="theme_item_sent_message_background_color_detail">"Применяется к: фон отправленного личного сообщения"</string> + <string name="theme_item_bottom_app_bar_background_color">"Цвет нижней панели навигации"</string> + <string name="theme_item_bottom_app_bar_background_color_detail">"Применяется к: кнопки панели навигации"</string> + <string name="theme_item_primary_icon_color">"Цвет основного значка"</string> + <string name="theme_item_primary_icon_color_detail">"Применяется к: значки в панели навигации"</string> + <string name="theme_item_bottom_app_bar_icon_color">"Цвет значка нижней панели"</string> + <string name="theme_item_bottom_app_bar_icon_color_detail">"Применяется к: значки на нижней панели навигации"</string> + <string name="theme_item_post_icon_and_info_color">"Значок поста и цвет информации"</string> + <string name="theme_item_post_icon_and_info_color_detail">"Применяется к: значки, оценка и количество комментариев в постах"</string> + <string name="theme_item_comment_icon_and_info_color">"Значок комментария и цвет информации"</string> + <string name="theme_item_comment_icon_and_info_color_detail">"Применяется к: значки и оценка в комментариях"</string> + <string name="theme_item_fab_icon_color">"Цвет плавающей кнопки действий"</string> + <string name="theme_item_fab_icon_color_detail">"Применяется к: значок плавающей кнопки действий"</string> + <string name="theme_item_send_message_icon_color">"Цвет значка отправленного сообщения"</string> + <string name="theme_item_send_message_icon_color_detail">"Применяется к: значок отправленного личного сообщения"</string> + <string name="theme_item_toolbar_primary_text_and_icon_color">"Основные тексты и значки на панели инструментов"</string> + <string name="theme_item_toolbar_primary_text_and_icon_color_detail">"Применяется к: основные тексты и значки на панелях инструментов"</string> + <string name="theme_item_toolbar_secondary_text_color">"Цвет дополнительного текста на панели инструментов"</string> + <string name="theme_item_toolbar_secondary_text_color_detail">"Применяется к: дополнительные тексты на панелях инструментов"</string> + <string name="theme_item_circular_progress_bar_background_color">"Цвет фона кругового индикатора выполнения"</string> + <string name="theme_item_circular_progress_bar_background_color_detail">"Применяется к: фон кругового индикатора выполнения"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background">"Цвет фона макета вкладки свёрнутой панели инструментов"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background_detail">"Применяется к: фон макета вкладки (свёрнутая панель инструментов)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color">"Цвет текста макета вкладки свёрнутой панели инструментов"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color_detail">"Применяется к: цвет текста макета вкладки (свёрнутая панель инструментов)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator">"Цвет индикатора вкладки в макете вкладки свёрнутой панели инструментов"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator_detail">"Применяется к: цвет индикатора вкладки в макете вкладки (свёрнутая панель инструментов)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background">"Цвет фона вкладки макета свёрнутой панели инструментов"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background_detail">"Применяется к: фон макета вкладки (свёрнутая панель инструментов)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color">"Цвет текста макета вкладки свёрнутой панели инструментов"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color_detail">"Применяется к: цвет текста макета вкладки (свёрнутая панель инструментов)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator">"Цвет индикатора вкладки в макете вкладки свёрнутой панели инструментов"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator_detail">"Применяется к: цвет индикатора вкладки в макете вкладки (свёрнутая панель инструментов)"</string> + <string name="theme_item_upvoted_color">"Цвет голоса+"</string> + <string name="theme_item_upvoted_color_detail">"Применяется к: кнопки голосования и баллы (голос+)"</string> + <string name="theme_item_downvoted_color">"Цвет голоса-"</string> + <string name="theme_item_downvoted_color_detail">"Применяется к: кнопки голосования и баллы (голос-)"</string> + <string name="theme_item_post_type_background_color">"Цвет фона типа поста"</string> + <string name="theme_item_post_type_background_color_detail">"Применяется к: фон типа сообщения (ИЗОБРАЖЕНИЕ, ТЕКСТ, ВИДЕО, GIF, ССЫЛКА)"</string> + <string name="theme_item_post_type_text_color">"Цвет текста типа поста"</string> + <string name="theme_item_post_type_text_color_detail">"Применяется к: цвет текста типа поста (ИЗОБРАЖЕНИЕ, ТЕКСТ, ВИДЕО, GIF, ССЫЛКА)"</string> + <string name="theme_item_spoiler_background_color">"Цвет фона спойлера"</string> + <string name="theme_item_spoiler_background_color_detail">"Применяется к: фон отметки спойлера"</string> + <string name="theme_item_spoiler_text_color">"Цвет текста спойлера"</string> + <string name="theme_item_spoiler_text_color_detail">"Применяется к: цвет текста отметки спойлера"</string> + <string name="theme_item_nsfw_background_color">"Цвет фона NSFW"</string> + <string name="theme_item_nsfw_background_color_detail">"Применяется к: цвет фона отметки NSFW"</string> + <string name="theme_item_nsfw_text_color">"Цвет текста NSFW"</string> + <string name="theme_item_nsfw_text_color_detail">"Применяется к: цвет текста отметки NSFW"</string> + <string name="theme_item_flair_background_color">"Цвет фона флейра"</string> + <string name="theme_item_flair_background_color_detail">"Применяется к: фон флейра"</string> + <string name="theme_item_flair_text_color">"Цвет флейра"</string> + <string name="theme_item_flair_text_color_detail">"Применяется к: цвет текста флейра"</string> + <string name="theme_item_awards_background_color">"Цвет фона наград"</string> + <string name="theme_item_awards_background_color_detail">"Применяется к: фон награды"</string> + <string name="theme_item_awards_text_color">"Цвет текста награды"</string> + <string name="theme_item_awards_text_color_detail">"Применяется к: цвет текста награды"</string> + <string name="theme_item_archived_tint">"Цвет значка архивного поста"</string> + <string name="theme_item_archived_tint_detail">"Применяется к: значок архивного поста"</string> + <string name="theme_item_locked_icon_tint">"Цвет значка блокировки"</string> + <string name="theme_item_locked_icon_tint_detail">"Применяется к: значок блокировки"</string> + <string name="theme_item_crosspost_icon_tint">"Цвет значка кросспоста"</string> + <string name="theme_item_crosspost_icon_tint_detail">"Применяется к: значок кросспоста"</string> + <string name="theme_item_stickied_post_icon_tint">"Цвет значка прикреплённого сообщения"</string> + <string name="theme_item_stickied_post_icon_tint_detail">"Применяется к: значок прикреплённого сообщения"</string> + <string name="theme_item_subscribed_color">"Подписаться"</string> + <string name="theme_item_subscribed_color_detail">"Применяется к: кнопка «Отписаться»"</string> + <string name="theme_item_unsubscribed_color">"Отписаться"</string> + <string name="theme_item_unsubscribed_color_detail">"Применяется к: кнопка «Подписаться»"</string> + <string name="theme_item_username_color">"Цвет имени пользователя"</string> + <string name="theme_item_username_color_detail">"Применяется к: имя пользователя"</string> + <string name="theme_item_subreddit_color">"Цвет сабреддита"</string> + <string name="theme_item_subreddit_color_detail">"Применяется к: название сабреддита"</string> + <string name="theme_item_author_flair_text_color">"Цвет автора флейра"</string> + <string name="theme_item_author_flair_text_color_detail">"Применяется к: автор флейра в комментариях"</string> + <string name="theme_item_submitter_color">"Отправитель"</string> + <string name="theme_item_submitter_color_detail">"Применяется к: отправитель в комментариях"</string> + <string name="theme_item_moderator_color">"Модератор"</string> + <string name="theme_item_moderator_color_detail">"Применяется к: модератор в комментариях"</string> + <string name="theme_item_single_comment_thread_background_color">"Цвет фона цепочки отдельного комментария"</string> + <string name="theme_item_single_comment_thread_background_color_detail">"Применяется к: отдельный комментарий"</string> + <string name="theme_item_unread_message_background_color">"Цвет фона непрочитанного сообщения"</string> + <string name="theme_item_unread_message_background_color_detail">"Применяется к: цвет фона непрочитанного сообщения"</string> + <string name="theme_item_divider_color">"Цвет разделителя"</string> + <string name="theme_item_divider_color_detail">"Применяется к: разделитель комментариев, разделители на страницах для отправки постов и т.д."</string> + <string name="theme_item_vote_and_reply_unavailable_button_color">"Цвет недоступной кнопки голосования и ответа"</string> + <string name="theme_item_vote_and_reply_unavailable_button_color_detail">"Применяется к: кнопки голосования и ответа (недоступные)"</string> + <string name="theme_item_comment_vertical_bar_color_1">"Цвет вертикальной полосы комментария 1"</string> + <string name="theme_item_comment_vertical_bar_color_1_detail">"Применяется к: вертикальная полоса комментариев (уровень 1)"</string> + <string name="theme_item_comment_vertical_bar_color_2">"Цвет вертикальной полосы комментария 2"</string> + <string name="theme_item_comment_vertical_bar_color_2_detail">"Применяется к: вертикальная полоса комментариев (уровень 2)"</string> + <string name="theme_item_comment_vertical_bar_color_3">"Цвет вертикальной полосы комментария 3"</string> + <string name="theme_item_comment_vertical_bar_color_3_detail">"Применяется к: вертикальная полоса комментариев (уровень 3)"</string> + <string name="theme_item_comment_vertical_bar_color_4">"Цвет вертикальной полосы комментария 4"</string> + <string name="theme_item_comment_vertical_bar_color_4_detail">"Применяется к: вертикальная полоса комментариев (уровень 4)"</string> + <string name="theme_item_comment_vertical_bar_color_5">"Цвет вертикальной полосы комментария 5"</string> + <string name="theme_item_comment_vertical_bar_color_5_detail">"Применяется к: вертикальная полоса комментариев (уровень 5)"</string> + <string name="theme_item_comment_vertical_bar_color_6">"Цвет вертикальной полосы комментария 6"</string> + <string name="theme_item_comment_vertical_bar_color_6_detail">"Применяется к: вертикальная полоса комментариев (уровень 6)"</string> + <string name="theme_item_comment_vertical_bar_color_7">"Цвет вертикальной полосы комментария 7"</string> + <string name="theme_item_comment_vertical_bar_color_7_detail">"Применяется к: вертикальная полоса комментариев (уровень 7)"</string> + <string name="theme_item_nav_bar_color">"Цвет панели навигации"</string> + <string name="theme_item_nav_bar_color_detail">"Применяется к: панель навигации"</string> + <string name="theme_item_light_status_bar">"Цвет значка тёмной строки состояния"</string> + <string name="theme_item_light_nav_bar">"Цвет значка тёмной панели навигации"</string> + <string name="theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface">"Изменить цвет значка строки состояния после свёртывания панели инструментов в режиме погружения"</string> + <string name="theme_item_available_on_android_8">"Доступно только для Android 8.0 или более поздних версий."</string> + <string name="theme_item_available_on_android_6">"Доступно только для Android 6.0 или более поздних версий."</string> + <string name="predefined_themes">"Предопределённые темы"</string> + <string name="user_themes">"Ваши темы"</string> + <string name="no_theme_name">"Как называется эта тема?"</string> + <string name="theme_name_hint">"Название темы"</string> + <string name="theme_name_indigo">"Индиго"</string> + <string name="theme_name_indigo_dark">"Тёмный индиго"</string> + <string name="theme_name_indigo_amoled">"Индиго AMOLED"</string> + <string name="theme_name_white">"Белая"</string> + <string name="theme_name_white_dark">"Тёмно-белая"</string> + <string name="theme_name_white_amoled">"Белая AMOLED"</string> + <string name="theme_name_red">"Красная"</string> + <string name="theme_name_red_dark">"Тёмный красный"</string> + <string name="theme_name_red_amoled">"Красная AMOLED"</string> + <string name="theme_name_dracula">"Дракула"</string> + <string name="theme_name_calm_pastel">"Спокойная пастель"</string> + <string name="create_light_theme">"Создать светлую тему +На основе темы «Индиго»"</string> + <string name="create_dark_theme">"Создать тёмную тему +На основе темы «Тёмный индиго»"</string> + <string name="create_amoled_theme">"Создать тему AMOLED +На основе темы «Индиго AMOLED»"</string> + <string name="create_theme_info">"Если вы хотите создать тему на основе другой темы, нажмите на той теме «+»."</string> + <string name="edit_theme_name">"Изменить название темы"</string> + <string name="edit_theme">"Изменить тему"</string> + <string name="delete_theme">"Удалить тему"</string> + <string name="delete_theme_dialog_message">"Удалить тему %1$s?"</string> + <string name="share_theme">"Поделиться темой"</string> + <string name="change_theme_name">"Сменить название"</string> + <string name="theme_copied">"Скопировано! Вставьте и поделитесь с другими людьми."</string> + <string name="copy_theme_faied">"Невозможно скопировать конфигурацию темы"</string> + <string name="cannot_find_theme">"Не могу найти эту тему"</string> + <string name="import_theme">"Импортировать тему"</string> + <string name="no_data_in_clipboard">"Не удалось найти данные в буфере обмена"</string> + <string name="import_theme_success">"Тема успешно импортирована"</string> + <string name="parse_theme_failed">"Ошибка синтаксического анализа темы"</string> + <string name="duplicate_theme_name_dialog_title">"Обнаружен дубликат темы"</string> + <string name="duplicate_theme_name_dialog_message">"Тема в базе данных также называется %1$s. Изменить название этой импортированной темы?"</string> + <string name="rename">"Переименовать"</string> + <string name="override">"Переопределить"</string> + <string name="color_picker">"Палитра цветов"</string> + <string name="invalid_color">"Неверный цвет"</string> + <string name="delete_all_subreddits_success">"Все сабреддиты успешно удалены"</string> + <string name="delete_all_users_success">"Все пользователи успешно удалены"</string> + <string name="delete_all_sort_types_success">"Все типы сортировки успешно удалены"</string> + <string name="delete_all_post_layouts_success">"Все макеты постов успешно удалены"</string> + <string name="delete_all_themes_success">"Все темы успешно удалены"</string> + <string name="delete_all_front_page_scrolled_positions_success">"Все позиции прокрутки главной страницы в базе данных успешно удалены"</string> + <string name="reset_all_settings_success">"Все настройки успешно сброшены"</string> + <string name="username_preview">"u/Hostilenemy"</string> + <string name="subreddit_preview">"r/Infinity_For_Reddit"</string> + <string name="primary_text_preview">"Основной текст"</string> + <string name="secondary_text_preview">"Дополнительный текст"</string> + <string name="post_title_preview">"Это пост"</string> + <string name="post_content_preview">"Эта шутка о гравитации уже устарела, но я каждый раз попадаюсь на неё."</string> + <string name="post_type_preview">"ПОСТ"</string> + <string name="flair_preview">"Флейр"</string> + <string name="awards_preview">"4 награды"</string> + <string name="author_flair_preview">"Флейр автора"</string> + <string name="comment_content_preview">"Я подарил своей девушке карточку «Поправляйся скорее». +Она не больна или что-то вроде того, но определённо может поправиться."</string> + <string name="edit_multi_reddit">"Изменить мультиреддит"</string> + <string name="delete_multi_reddit">"Удалить мультиреддит"</string> + <string name="n_awards">"%1$d наград"</string> + <string name="one_award">"1 награда"</string> + <string name="report">"Отчёт"</string> + <string name="reporting">"Отчёт отправляется"</string> + <string name="report_successful">"Отчёт отправлен"</string> + <string name="report_failed">"Ошибка отправки отчёта"</string> + <string name="report_reason_not_selected">"Вы не выбрали причину"</string> + <string name="report_reason_general_spam">"Спам"</string> + <string name="report_reason_general_copyright_issue">"Содержит замечание об авторских правах"</string> + <string name="report_reason_general_child_pornography">"Содержит детскую порнографию"</string> + <string name="report_reason_general_abusive_content">"Содержит оскорбительный контент"</string> + <string name="home">"Главная"</string> + <string name="popular">"Популярное"</string> + <string name="notifications">"Уведомления"</string> + <string name="messages">"Сообщения"</string> + <string name="message">"Сообщение"</string> + <string name="fetch_gfycat_video_failed">"Не удалось получить видео Gfycat"</string> + <string name="fetch_redgifs_video_failed">"Не удалось получить видео Redgifs"</string> + <string name="fetching_video_info_please_wait">"Получение информации о видео. Пожалуйста, подождите."</string> + <string name="error_fetching_imgur_media">"Невозможно загрузить изображения"</string> + <string name="downloading_reddit_video">"Загрузка видео"</string> + <string name="downloading_reddit_video_audio_track">"Загрузка аудио"</string> + <string name="downloading_reddit_video_muxing">"Микширование видео и аудио"</string> + <string name="downloading_reddit_video_save_file_to_public_dir">"Сохранение видео"</string> + <string name="downloading_reddit_video_finished">"Загружено"</string> + <string name="downloading_reddit_video_failed_cannot_get_cache_directory">"Ошибка загрузки: не удалось получить доступ к папке кэша"</string> + <string name="downloading_reddit_video_failed_cannot_download_video">"Ошибка загрузки: не удалось загрузить видео"</string> + <string name="downloading_reddit_video_failed_cannot_save_video">"Ошибка загрузки: не удалось сохранить видео в папку кэша"</string> + <string name="downloading_reddit_video_failed_cannot_save_audio">"Ошибка загрузки: не удалось сохранить аудио в папку кэша"</string> + <string name="downloading_reddit_video_failed_cannot_mux">"Ошибка загрузки: не удалось смикшировать видео и аудио"</string> + <string name="downloading_reddit_video_failed_cannot_save_mux_video">"Ошибка загрузки: не удалось сохранить видео в общую папку"</string> + <string name="wallpaper_set">"Установить обои"</string> + <string name="error_set_wallpaper">"Установить как обои"</string> + <string name="set_to_home_screen">"Закрепить на домашнем экране"</string> + <string name="set_to_lock_screen">"Установить на экран блокировки"</string> + <string name="set_to_both">"Установить на оба экрана"</string> + <string name="default_font_font_preview">"По умолчанию"</string> + <string name="load_video_in_redgifs">"Попробуйте загрузить видео на Redgifs"</string> + <string name="top_score">"%1$s пойнтов"</string> + <string name="login_activity_2fa_prompt">"Если у вас включена двухфакторная аутентификация, введите пароль, как показано ниже: &lt;password&gt;:&lt;2FA code&gt;. +Пример: yourpass:123456"</string> + <string name="block_user">"Заблокировать пользователя"</string> + <string name="block_user_success">"Заблокирован"</string> + <string name="block_user_failed">"Ошибка блокировки пользователя"</string> + <string name="submit_crosspost_activity_label">"Кросспост"</string> + <string name="give_award_activity_label">"Наградить"</string> + <string name="action_crosspost">"Кросспост"</string> + <string name="action_select_user_flair">"Установить флaйр пользователя"</string> + <string name="action_give_award">"Выдать награду"</string> + <string name="posts">"Посты"</string> + <string name="sidebar">"Боковая панель"</string> + <string name="only_for_logged_in_user">"Для авторизовавшихся пользователей"</string> + <string name="settings_number_of_columns_in_post_feed_title">"Количество столбцов в ленте постов"</string> + <string name="settings_number_of_columns_in_post_feed_portrait_title">"Портрет"</string> + <string name="settings_number_of_columns_in_post_feed_landscape_title">"Ландшафт"</string> + <string name="settings_nsfw_and_spoiler_title">"NSFW и спойлеры"</string> + <string name="settings_delete_all_legacy_settings_title">"Удалить все устаревшие настройки"</string> + <string name="restart_app_see_changes">"Перезапустите приложение, чтобы увидеть изменения."</string> + <string name="settings_tab_count">"Количество вкладок"</string> + <string name="settings_show_tab_names">"Показать заголовок вкладок"</string> + <string name="settings_more_tabs_summary">"Больше вкладок"</string> + <string name="settings_more_tabs_info_summary">"Включение следующих параметров вызовет непредвиденное поведение: +Вкладки могут потерять все содержимое после переключения на другие. Это то же, что и обновление страницы."</string> + <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">"Показать избранные сабреддиты из подписок"</string> + <string name="settings_more_tabs_show_subscribed_subreddits_title">"Показывать сабреддиты из подписок"</string> + <string name="settings_download_location_title">"Папка для загрузок"</string> + <string name="settings_image_download_location_title">"Папка для изображений"</string> + <string name="settings_gif_download_location_title">"Папка для GIF"</string> + <string name="settings_video_download_location_title">"Папка для видео"</string> + <string name="settings_separate_folder_for_each_subreddit">"Отдельная папка для каждого сабреддита"</string> + <string name="settings_swipe_action_title">"Жест"</string> + <string name="settings_disable_swiping_between_tabs_title">"Отключить перелистывание вкладок"</string> + <string name="settings_enable_swipe_action_title">"Включить жест"</string> + <string name="settings_swipe_action_threshold">"Предел"</string> + <string name="settings_pull_to_refresh_title">"Потяните, чтобы обновить"</string> + <string name="settings_security_title">"Безопасность"</string> + <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Запрашивать аутентификацию для перехода в раздел «Аккаунт» в панели навигации"</string> + <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Удерживать – скрытие панели инструментов в компакте"</string> + <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">"Панель инструментов в компактом макете скрыта по умолчанию"</string> + <string name="settings_customize_bottom_app_bar_title">"Настроить нижнюю панель навигации"</string> + <string name="settings_main_activity_bottom_app_bar_group_summary">"Главная страница"</string> + <string name="settings_other_activities_bottom_app_bar_group_summary">"Другие страницы"</string> + <string name="settings_bottom_app_bar_option_count">"Количество вариантов"</string> + <string name="settings_bottom_app_bar_option_1">"Действие 1"</string> + <string name="settings_bottom_app_bar_option_2">"Действие 2"</string> + <string name="settings_bottom_app_bar_option_3">"Действие 3"</string> + <string name="settings_bottom_app_bar_option_4">"Действие 4"</string> + <string name="settings_bottom_app_bar_fab">"Плавающая кнопка действий"</string> + <string name="settings_data_saving_mode">"Режим экономии трафика"</string> + <string name="settings_data_saving_mode_info_summary">"В режиме экономии трафика: +Просмотр изображений – уменьшенное разрешение. +Видео Reddit – уменьшенное разрешение. +Автовоспроизведение видео отключено."</string> + <string name="settings_translation_title">"Перевод"</string> + <string name="settings_translation_summary">"Переводите это приложение на POEditor. Благодарю всех за ваш вклад."</string> + <string name="settings_credits_national_flags">"Национальные флаги"</string> + <string name="settings_credits_national_flags_summary">"Значок создан Freepik из www.flaticon.com"</string> + <string name="copy_failed">"Не удалось скопировать"</string> + <string name="delete_all_legacy_settings_success">"Все старые настройки успешно удалены"</string> + <string name="downloading_media_finished">"Скачано"</string> + <string name="downloading_image_or_gif_failed_cannot_get_destination_directory">"Ошибка при скачивании: не удалось получить доступ к папке"</string> + <string name="downloading_media_failed_cannot_download_media">"Ошибка при скачивании"</string> + <string name="downloading_media_failed_cannot_save_to_destination_directory">"Ошибка при скачивании: не удалось сохранить файл в целевую папку"</string> + <string name="view_full_comment_markdown">"Посмотреть полный Markdown"</string> + <string name="select_user_flair_success">"Флейр пользователя выбран"</string> + <string name="select_this_user_flair">"Выбрать флейр пользователя?"</string> + <string name="select_header_size">"Выбрать размер заголовка"</string> + <string name="large">"Крупный"</string> + <string name="small">"Мелкий"</string> + <string name="insert_link">"Вставить ссылку"</string> + <string name="text_hint">"Текст"</string> + <string name="link_hint">"Ссылка"</string> + <string name="unlock_account_section">"Выбранный аккаунт разблокирован"</string> + <string name="unlock">"Разблокировать"</string> + <string name="submit_post">"Отправить пост"</string> + <string name="refresh">"Обновить"</string> + <string name="change_sort_type">"Изменить тип сортировки"</string> + <string name="change_post_layout">"Изменить макет поста"</string> + <string name="give_award_dialog_title">"Выдать награду?"</string> + <string name="anonymous">"Аноним"</string> + <string name="give_award_error_message">"Код: %1$d/ +Сообщение: %2$s"</string> + <string name="give_award_success">"Награда выдана"</string> + <string name="give_award_failed">"Ошибка"</string> + <string name="warning">"Предупреждение"</string> + <string name="this_is_a_nsfw_subreddit">"Это NSFW-сабреддит"</string> + <string name="this_user_has_nsfw_content">"У пользователь есть NSFW-контент"</string> + <string name="dismiss">"Отклонить"</string> + <string name="leave">"Покинуть"</string> + <string name="go_to_subreddit">"Перейти к сабреддиту"</string> + <string name="go_to_user">"Перейти к пользователю"</string> + <string name="go_to_thing_hint">"Имя"</string> + <string name="random">"Случайно"</string> + <string name="random_subreddit">"Случайный сабреддит"</string> + <string name="random_nsfw_subreddit">"Случайный NSFW-сабреддит"</string> + <string name="random_post">"Случайный пост"</string> + <string name="random_nsfw_post">"Случайный NSFW-пост"</string> + <string name="fetch_random_thing_failed">"Попробуйте позже"</string> + <string name="downloading">"Скачивание"</string> + <string name="subreddit_filter_popular_and_all_activity_label">"r/all и r/popular"</string> + <string name="settings_miscellaneous_title">"Прочее"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_title">"Учитывать рекомендуемый тип сортировки сабреддита"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_summary">"Тип сортировки комментариев не будет сохранен"</string> + <string name="settings_subreddit_filter_category">"Спрятать сабреддиты"</string> + <string name="settings_subreddit_filter_popular_and_all">"В r/popular и r/all"</string> + <string name="settings_credits_ufo_capturing_animation_title">"Анимация захвата НЛО"</string> + <string name="select_video_quality">"Выбрать качество видео"</string> + <string name="settings_swipe_action_haptic_feedback_title">"Тактильная отдача"</string> + <string name="settings_hide_subreddit_description_title">"Скрыть описание сабреддитов"</string> + <string name="settings_disable_image_preview_title">"Отключить предпросмотр изображения в режиме экономии трафика"</string> + <string name="settings_swipe_action_swipe_left_title">"Жест влево"</string> + <string name="settings_swipe_action_swipe_right_title">"Жест вправо"</string> + <string name="settings_swipe_action_info_summary">"Не для ленты новостей > 1 столбца или деталей поста."</string> + <string name="theme_item_no_preview_post_type_icon_tint">"Цвет значка типа поста без предпросмотра"</string> + <string name="theme_item_no_preview_post_type_icon_tint_detail">"Применяется к: значок, показывающий тип поста без доступного предпросмотра"</string> + <string name="theme_item_no_preview_post_type_background_color">"Цвет заднего фона поста без предпросмотра"</string> + <string name="theme_item_no_preview_post_type_background_color_detail">"Применяется к: заплатка, показывающая тип поста без доступного предпросмотра"</string> + <string name="settings_language_title">"Язык"</string> + <string name="customize_post_filter_activity_label">"Настроить фильтр постов"</string> + <string name="filtered_posts_activity_subtitle">"Фильтрованные посты"</string> + <string name="post_filter_preference_activity_label">"Фильтр постов"</string> + <string name="search_users_result_activity_label">"Пользователи"</string> + <string name="multireddit_selection_activity_label">"Выберите мультиреддит"</string> + <string name="action_save_to_database">"Сохранить в базе данных"</string> + <string name="action_read_all_messages">"Читать все сообщения"</string> + <string name="action_add_to_multireddit">"Добавить в мультиреддит"</string> + <string name="search_only_subreddits_hint">"Искать сабреддиты"</string> + <string name="search_only_users_hint">"Искать пользователя"</string> + <string name="post_type_gif">"GIF"</string> + <string name="post_type_gallery">"Галерея"</string> + <string name="settings_disable_immersive_interface_in_landscape_mode">"Отключить режим погружения в ландшафтном режиме"</string> + <string name="settings_privacy_policy_title">"Политика конфиденциальности"</string> + <string name="settings_delete_read_posts_in_database_title">"Удалить все прочтённые посты из базы данных"</string> + <string name="settings_post_filter_title">"Фильтр постов"</string> + <string name="settings_only_disable_preview_in_video_and_gif_posts_title">"Отключить предпросмотр только в постах с видео и GIF"</string> + <string name="settings_enable_search_history_title">"Включить историю поиска"</string> + <string name="settings_post_history_title">"История поста"</string> + <string name="settings_mark_posts_as_read_title">"Отметить посты как прочтённые"</string> + <string name="settings_mark_posts_as_read_after_voting_title">"Отмечать посты прочтёнными после голосования"</string> + <string name="settings_mark_posts_as_read_on_scroll_title">"Отмечать посты прочтёнными при прокрутке"</string> + <string name="settings_hide_read_posts_automatically_title">"Автоматически скрывать прочтённые посты"</string> + <string name="settings_sort_type_title">"Тип сортировки"</string> + <string name="settings_save_sort_type_title">"Сохранить тип сортировки"</string> + <string name="settings_subreddit_default_sort_type_title">"Тип сортировки в сабреддите"</string> + <string name="settings_subreddit_default_sort_time_title">"Время сортировки в сабреддите"</string> + <string name="settings_user_default_sort_type_title">"Тип сортировки пользователя"</string> + <string name="settings_user_default_sort_time_title">"Время сортировки пользователя"</string> + <string name="open_link">"Открыть ссылку"</string> + <string name="select_subreddits_and_users">"Выбрать сабреддиты и пользователей"</string> + <string name="theme_item_read_post_title_color">"Цвет заголовка прочтённого поста"</string> + <string name="theme_item_read_post_title_color_detail">"Применяется к: заголовок прочтённого поста"</string> + <string name="theme_item_read_post_content_color">"Цвет содержимого прочтённого поста"</string> + <string name="theme_item_read_post_content_color_detail">"Применяется к: содержимое прочтённого поста"</string> + <string name="theme_item_read_post_card_view_background_color">"Цвет фона карточки прочтённого поста"</string> + <string name="theme_item_read_post_card_view_background_color_detail">"Применяется к: фон прочтённого поста"</string> + <string name="delete_all_read_posts_success">"Все прочтённые посты успешно удалены"</string> + <string name="hide_read_posts">"Скрыть прочтённые посты"</string> + <string name="filter_posts">"Фильтр постов"</string> + <string name="only_nsfw">"Только NSFW"</string> + <string name="only_spoiler">"Только спойлер"</string> + <string name="title_excludes_strings_hint">"Заголовок: исключая ключевые слова (key1,key2)"</string> + <string name="title_excludes_regex_hint">"Заголовок: исключая регулярное выражение"</string> + <string name="exclude_subreddits_hint">"Исключить сабреддиты (например: funny,AskReddit)"</string> + <string name="exclude_users_hint">"Исключить пользователей (например: Hostilenemy,random)"</string> + <string name="exclude_flairs_hint">"Исключить флейры (например: flair1,flair2)"</string> + <string name="contain_flairs_hint">"Содержит флейры (например: flair1,flair2)"</string> + <string name="min_vote_hint">"Минимум голосов (-1: без ограничений)"</string> + <string name="max_vote_hint">"Максимум голосов (-1: без ограничений)"</string> + <string name="min_comments_hint">"Минимум комментариев (-1: без ограничений)"</string> + <string name="max_comments_hint">"Максимум комментариев (-1: без ограничений)"</string> + <string name="min_awards_hint">"Минимум наград (-1: без ограничений)"</string> + <string name="max_awards_hint">"Максимум наград (-1: без ограничений)"</string> + <string name="post_filter_name_hint">"Название фильтра постов"</string> + <string name="post_filter_requires_a_name">"Как называется этот фильтр постов?"</string> + <string name="duplicate_post_filter_dialog_title">"«%1$s» уже существует"</string> + <string name="duplicate_post_filter_dialog_message">"Переопределить это?"</string> + <string name="apply_post_filter_to">"Применить к"</string> + <string name="post_filter_usage_home">"Домашняя"</string> + <string name="post_filter_usage_subreddit">"Сабреддит: %1$s"</string> + <string name="post_filter_usage_subreddit_all">"Сабреддит"</string> + <string name="post_filter_usage_user">"Пользователь: %1$s"</string> + <string name="post_filter_usage_user_all">"Пользователь"</string> + <string name="post_filter_usage_multireddit">"Мультиреддит: %1$s"</string> + <string name="post_filter_usage_multireddit_all">"Мультиреддит"</string> + <string name="post_filter_usage_search">"Поиск"</string> + <string name="subreddit">"Сабреддит"</string> + <string name="user">"Пользователь"</string> + <string name="edit_post_filter_name_of_usage_info">"Оставьте пустым, чтобы применить этот фильтр постов ко всем сабреддитам / пользователям / мультиреддитам"</string> + <string name="read_all_messages_time_limit">"Вы делаете это слишком часто. Попробуйте позже. Это ограничение скорости Reddit API."</string> + <string name="read_all_messages_success">"Все сообщения успешно прочтены"</string> + <string name="read_all_messages_failed">"Невозможно прочитать все сообщения"</string> + <string name="add_subreddit_or_user_to_multireddit_success">"%1$s добавлен в мультиреддит %2$s"</string> + <string name="add_subreddit_or_user_to_multireddit_failed">"Невозможно добавить %1$s в мультиреддит %2$s"</string> + <string name="choose_a_user">"Выберите пользователя"</string> + <string name="settings_click_to_show_media_in_gallery_layout">"Открывать мультимедиа нажатием в режиме галереи"</string> + <string name="settings_hide_post_type">"Скрыть тип поста"</string> + <string name="settings_hide_the_number_of_awards">"Скрыть количество наград"</string> + <string name="settings_hide_subreddit_and_user_prefix">"Скрыть префикс сабреддита и пользователя"</string> + <string name="settings_hide_the_number_of_votes">"Скрыть количество голосов"</string> + <string name="settings_hide_the_number_of_comments">"Скрыть количество комментариев"</string> + <string name="post_layout_gallery">"Галерея"</string> + <string name="post_layout_card_2">"Карточный стиль 2"</string> + <string name="have_trouble_login_title">"Проблемы со входом"</string> + <string name="have_trouble_login_message">"Хотите попробовать другой способ авторизации?"</string> + <string name="vote">"Голос"</string> + <string name="action_share_link">"Поделиться ссылкой"</string> + <string name="action_copy_link">"Копировать ссылку"</string> + <string name="action_add_to_post_filter">"Добавить пост в фильтр"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"NSFW-посты в NSFW-сабреддитах без размытия"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Показывать аватар слева"</string> + <string name="settings_backup_settings_title">"Резервное копирование настроек"</string> + <string name="settings_restore_settings_title">"Восстановить настройки"</string> + <string name="settings_credits_love_animation_title">"Анимация любви"</string> + <string name="settings_swipe_between_posts_title">"Жест между постами"</string> + <string name="settings_navigation_drawer_title">"Боковая панель"</string> + <string name="settings_collapse_account_section_title">"Свернуть раздел аккаунта"</string> + <string name="settings_collapse_post_section_title">"Свернуть раздел поста"</string> + <string name="settings_collapse_preferences_section_title">"Свернуть раздел настроек"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"Свернуть раздел избранных сабреддитов"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"Свернуть раздел сабреддитов в подписках"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Скрыть раздел избранных сабреддитов"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Скрыть раздел сабреддитов с подпиской"</string> + <string name="settings_default_search_result_tab">"Вкладка результатов поиска"</string> + <string name="device_default">"По умолчанию устройства"</string> + <string name="set_by_battery_saver">"Устанавливается функцией экономии заряда батареи"</string> + <string name="theme_item_upvote_ratio_icon_tint">"Цвет значка соотношения голосов"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"Применяется к: значок соотношения голосов"</string> + <string name="theme_item_current_user_color">"Текущий пользователь"</string> + <string name="theme_item_current_user_color_detail">"Применяется к: текущий пользователь в комментариях"</string> + <string name="exclude_domains_hint">"Исключить домены"</string> + <string name="anonymous_front_page_no_subscriptions">"Начните с присоединения к сабреддиту!"</string> + <string name="backup_settings_success">"Настройки успешно экспортированы в выбранную папку. Пароль созданного zip-файла – 123321. Пожалуйста, не изменяйте zip-файл."</string> + <string name="create_zip_in_destination_directory_failed">"Не удалось создать zip-архив с резервной копией настроек в выбранной папке."</string> + <string name="backup_some_settings_failed">"Не удалось создать резервную копию некоторых настроек, но другие были успешно экспортированы в выбранную папку."</string> + <string name="restore_settings_success">"Настройки успешно восстановлены. Перезапустите приложение, чтобы увидеть изменения."</string> + <string name="restore_settings_partially_failed">"Некоторые настройки не могут быть восстановлены. Перезапустите приложение, чтобы увидеть изменения."</string> + <string name="restore_settings_failed_file_corrupted">"Невозможно восстановить настройки. Возможно, файл повреждён."</string> + <string name="restore_settings_failed_cannot_get_file">"Нет доступа к файлу"</string> + <string name="suicide_prevention_quote">"Если вы ищете знак, чтобы не убивать себя, то вот он: ❤"</string> + <string name="do_not_show_this_again">"Больше не показывать"</string> + <string name="continue_suicide_prevention_activity">"Продолжить"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"Ошибка при получении видео v.redd.it: не удалось получить URL-адрес перенаправления"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"Ошибка при загрузке видео v.redd.it: не удалось получить пост"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"Ошибка при загрузке видео v.redd.it: не удалось получить идентификатор поста"</string> + <string name="always_on">"Всегда включено"</string> + <string name="only_on_wifi">"Только через Wi-Fi"</string> + <string name="never">"Никогда"</string> + <string name="normal">"Нормальный"</string> + <string name="extra_large">"Очень большой"</string> + <string name="enormously_large">"Невероятно большой"</string> + <string name="default_in_array">"По умолчанию"</string> + <string name="off">"Выкл."</string> + <string name="only_on_cellular_data">"Только через мобильные данные"</string> + <string name="upvote">"Голос+"</string> + <string name="downvote">"Голос-"</string> + <string name="select">"Выбрать"</string> + <string name="exclude_subreddit">"Исключить этот сабреддит"</string> + <string name="exclude_user">"Исключить этого пользователя"</string> + <string name="exclude_flair">"Исключить этот флейр"</string> + <string name="contain_flair">"Содержит флейр"</string> + <string name="exclude_domain">"Исключить домен"</string> + <string name="suggest_title">"Предложить название"</string> + <string name="suggest_title_failed">"Не удалось предложить название"</string> + <string name="action_delete_logs">"Удалить журнал"</string> + <string name="inbox_with_count">"Входящие (%1$d)"</string> + <string name="comment_continue_thread">"Продолжить обсуждение"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"Вертикальный жест для закрытия мультимедиа"</string> + <string name="settings_hide_post_flair">"Скрыть флейр поста"</string> + <string name="settings_crash_reports_title">"Отчёты о сбоях"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"Опасные"</string> + <string name="settings_disable_nsfw_forever_title">"Отключить NSFW навсегда"</string> + <string name="settings_show_only_one_comment_level_indicator">"Показывать только один индикатор уровня комментария"</string> + <string name="save_comment">"Сохранить"</string> + <string name="unsave_comment">"Удалить"</string> + <string name="copy_multi_reddit_path">"Копировать путь мультиреддита"</string> + <string name="copy_multi_reddit_path_failed">"Невозможно скопировать путь мультиреддита"</string> + <string name="crash_reports_deleted">"Отчёты о сбоях удаляются"</string> + <string name="disable_nsfw_forever_message">"После включения NSFW будет навсегда отключено, независимо от того, включён параметр NSFW или нет. И эта функция необратима, единственный способ снова включить NSFW – это очистить данные приложения. + +Всё ещё хотите включить его?"</string> + <string name="reply">"Ответ"</string> + <string name="rpan_activity_label">"RPAN"</string> + <string name="post_gallery_activity_label">"Пост в галерее"</string> + <string name="trending_activity_label">"Популярное"</string> + <string name="action_share_rpan_link">"Поделиться ссылкой RPAN"</string> + <string name="action_share_post_link">"Поделиться ссылкой на пост"</string> + <string name="rpan">"RPAN"</string> + <string name="trending">"Популярное"</string> + <string name="receive_post_reply_notifications">"Получать уведомления об ответах на пост"</string> + <string name="bottom_sheet_post_gallery">"Галерея"</string> + <string name="posting_gallery">"Галерея постов"</string> + <string name="label_reddit">"Reddit"</string> + <string name="settings_default_link_post_layout">"Вид поста со ссылками по умолчанию"</string> + <string name="settings_category_material_you_title">"Material You"</string> + <string name="settings_enable_material_you_warning_summary">"Убедитесь, что у вас нет тем с именами +«Material You», +«Material You Dark» или +«Material You Amoled». +В противном случае переименуйте их перед включением «Material You»."</string> + <string name="settings_enable_material_you_title">"Включить «Material You»"</string> + <string name="settings_enable_material_you_summary">"Персонализация Infinity на основе фонового изображения рабочего экрана"</string> + <string name="settings_apply_material_you_title">"Применить «Material You»"</string> + <string name="settings_apply_material_you_summary">"В случае, если приложение Infinity не изменило тему"</string> + <string name="settings_more_tabs_show_favorite_multireddits_title">"Показывать избранные мультиреддиты"</string> + <string name="settings_more_tabs_show_multireddits_title">"Показывать мультиреддиты"</string> + <string name="settings_collapse_reddit_section_title">"Свернуть раздел Reddit"</string> + <string name="settings_video_player_automatic_landscape_orientation">"Автоматически переключаться на альбомную ориентацию в видеопроигрывателе"</string> + <string name="settings_remember_muting_option_in_post_feed">"Запоминать отключение звука в ленте постов"</string> + <string name="link_post_layout_auto">"Автовыбор"</string> + <string name="uploaded_images">"Загруженные изображения"</string> + <string name="select_image">"Выберите изображение"</string> + <string name="capture">"Захват"</string> + <string name="uploading_image">"Загрузка"</string> + <string name="upload_image_success">"Изображение успешно загружено. Нажмите кнопку «Изображение» ещё раз, чтобы просмотреть загруженные изображения."</string> + <string name="get_image_bitmap_failed">"Невозможно получить растровое изображение"</string> + <string name="upload_image_failed">"Невозможно загрузить изображение"</string> + <string name="load_rpan_broadcasts_failed">"Невозможно загрузить широковещательные сообщения RPAN"</string> + <string name="parse_rpan_broadcasts_failed">"Невозможно разобрать широковещательные сообщения RPAN"</string> + <string name="parse_rpan_broadcast_failed">"Невозможно разобрать широковещательную передачу RPAN"</string> + <string name="search_comments">"Поиск комментариев"</string> + <string name="please_wait_image_is_uploading">"Изображение загружается, подождите."</string> + <string name="error_fetch_trending_search">"Не удалось получить популярные поисковые запросы. +Нажмите, чтобы повторить попытку."</string> + <string name="error_parse_trending_search">"Не удалось разобрать популярные поисковые запросы. +Нажмите, чтобы повторить попытку."</string> + <string name="no_trending_search">"Не удалось найти популярные поисковые запросы. +Нажмите, чтобы повторить попытку."</string> +</resources>
\ No newline at end of file diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml new file mode 100644 index 00000000..eadb8ed1 --- /dev/null +++ b/app/src/main/res/values-so/strings.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="login_activity_label">"Gal"</string> + <string name="comment_activity_label">"Dir Faallada"</string> + <string name="comment_activity_label_is_replying">"Ujawaab"</string> + <string name="post_text_activity_label">"Bandhig Qoraal"</string> + <string name="subreddit_selection_activity_label">"Dooro Bulsho"</string> + <string name="post_link_activity_label">"Bandhig Tixraac"</string> + <string name="post_image_activity_label">"Bandhig Sawir"</string> + <string name="post_video_activity_label">"Bandhig Muuqaal"</string> + <string name="rules_activity_label">"Sharciyada"</string> + <string name="search_subreddits_activity_label">"Bulshooyin"</string> + <string name="edit_post_activity_label">"Tifatir Bandhiga"</string> + <string name="edit_comment_activity_label">"Tifatir Faallada"</string> + <string name="view_message_activity_label">"Fariimaha"</string> + <string name="settings_activity_label">"Fadhiga"</string> + <string name="account_saved_thing_activity_label">"Lakaydiyay"</string> + <string name="create_multi_reddit_activity_label">"Samee Reddit-badane"</string> + <string name="subreddit_multiselection_activity_label">"Dooro Qaybaha"</string> + <string name="custom_theme_listing_activity_label">"Nashqado Gaar ah"</string> + <string name="customize_theme_activity_label">"Nashqadee"</string> + <string name="customize_theme_activity_create_theme_label">"Samee Nashqad"</string> + <string name="edit_multi_reddit_activity_label">"Tifatir Reddit-badane"</string> + <string name="selected_subeddits_activity_label">"Qaybaha Ladoortay"</string> + <string name="report_activity_label">"Wari"</string> + <string name="view_imgur_media_activity_image_label">"Sawirka %1$d/%2$d"</string> + <string name="view_imgur_media_activity_video_label">"Muuqaalka %1$d/%2$d"</string> + <string name="send_private_message_activity_label">"Dir farriin gaar ah"</string> + <string name="view_reddit_gallery_activity_image_label">"Sawirka %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_gif_label">"Gif %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_video_label">"Muuqaalka %1$d/%2$d"</string> + <string name="navigation_drawer_open">"Fur khaanada dhexsocodka"</string> + <string name="navigation_drawer_close">"Xidh khaanada dhexsocodka"</string> + <string name="action_download">"Daji"</string> + <string name="action_refresh">"Cusboonaysii"</string> + <string name="action_add_comment">"Ku dar faallo"</string> +</resources>
\ No newline at end of file diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 4a6a136e..2656381c 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -236,6 +236,8 @@ Tekrar denemek için tıklayın."</string> <string name="search">"Arama"</string> <string name="posting_video">"Video Paylaşılıyor"</string> <string name="posting_image">"Fotoğraf Paylaşılıyor"</string> + + <!-- Fuzzy --> <string name="please_wait">"Lütfen bekleyin."</string> <string name="add_account">"Hesap ekle"</string> <string name="anonymous_account">"Anonim"</string> @@ -316,18 +318,20 @@ Tekrar denemek için tıklayın."</string> <string name="settings_enable_bottom_app_bar_summary">"Anonim Modda Etkisi Yok"</string> <string name="settings_category_post_and_comment_title">"Gönderi ve Yorum"</string> <string name="settings_vote_buttons_on_the_right_title">"Oy Düğmeleri Sağda"</string> - <string name="settings_volume_keys_navigate_comments_title">"Gönderilerdeki Yorumlarda Gezinmek İçin Ses Tuşlarını Kullanın"</string> - <string name="settings_volume_keys_navigate_posts_title">"Gönderilerde Gezinmek İçin Ses Tuşlarını Kullanın"</string> + <string name="settings_volume_keys_navigate_comments_title">"Gönderilerdeki Yorumlarda Gezinmek İçin Ses Tuşlarını Kullan"</string> + <string name="settings_volume_keys_navigate_posts_title">"Gönderilerde Gezinmek İçin Ses Tuşlarını Kullan"</string> <string name="settings_mute_video_title">"Videoları Sessize Al"</string> <string name="settings_mute_nsfw_video_title">"NSFW Videolarını Sessize Al"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"Gfycat'taki Videolar Kaldırılırsa Redgif'lere Erişmeyi Otomatik Olarak Dene"</string> <string name="settings_video_player_ignore_nav_bar_title">"Video Oynatıcısındaki Navigasyon Çubuğunu Yoksay"</string> - <string name="settings_video_player_ignore_nav_bar_summary">"Video Denetleyicisinde Fazladan Kenar Olmasını Önleyin"</string> + <string name="settings_video_player_ignore_nav_bar_summary">"Video Denetleyicisinde Fazladan Kenar Olmasını Önle"</string> <string name="settings_confirm_to_exit">"Çıkışı Doğrula"</string> <string name="settings_category_comment_title">"Yorum"</string> <string name="settings_show_top_level_comments_first_title">"Önce En İyi Yorumları Göster"</string> <string name="settings_show_comment_divider_title">"Yorum Bölücüsünü Göster"</string> - <string name="settings_comment_toolbar_hide_on_click">"Yorum Araç Çubuğunu Göstermek / Gizlemek İçin Tıklayın"</string> + <string name="settings_comment_toolbar_hide_on_click">"Yorum Araç Çubuğunu Göstermek / Gizlemek İçin Tıkla"</string> <string name="settings_fully_collapse_comment_title">"Yorumu Tamamen Daralt"</string> <string name="settings_comment_toolbar_hidden">"Varsayılan Gizli Yorum Araç Çubuğu"</string> <string name="settings_show_absolute_number_of_votes_title">"Kesin Oy Sayısını Göster"</string> @@ -342,7 +346,7 @@ Tekrar denemek için tıklayın."</string> <!-- Fuzzy --> <string name="settings_show_thumbnail_on_the_left_in_compact_layout">"Kompakt Düzende Soldaki Küçük Resmi Göster"</string> <string name="settings_swap_tap_and_long_title">"Yorumlarda Dokunmayı ve Uzun Dokunmayı Değiştirme"</string> - <string name="settings_swipe_to_go_back_title">"Geri Dönmek İçin Sağa Kaydırın"</string> + <string name="settings_swipe_to_go_back_title">"Geri Dönmek İçin Sağa Kaydır"</string> <string name="settings_swipe_to_go_back_summary">"Tüm Sayfalara Uygulanamaz"</string> <string name="settings_lock_jump_to_next_top_level_comment_button_title">"Bir Sonraki En İyi Yorumlar Düğmesine Geçmeyi Kilitle"</string> <string name="settings_lock_bottom_app_bar_title">"Alt Navigasyon Çubuğunu Kilitle"</string> @@ -670,11 +674,11 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="theme_name_dracula">"Drakula"</string> <string name="theme_name_calm_pastel">"Pastel Rengi"</string> <string name="create_light_theme">"Çivit Mavisi Renginde -Açık Tema Tabanı Oluştur"</string> +Açık Tema Şablonu Oluştur"</string> <string name="create_dark_theme">"Çivit Mavisi Renginde -Koyu Tema Tabanı Oluştur"</string> +Koyu Tema Şablonu Oluştur"</string> <string name="create_amoled_theme">"Çivit Mavisi Renginde -Amoled Tema Tabanı Oluştur"</string> +Amoled Tema Şablonu Oluştur"</string> <string name="create_theme_info">"Başka bir temaya dayalı tema oluşturmak istiyorsanız, bunun yerine bir temadaki \"+\" düğmesine tıklayın."</string> <string name="edit_theme_name">"Tema Adını Düzenle"</string> <string name="edit_theme">"Temayı Düzenle"</string> @@ -769,7 +773,7 @@ Amoled Tema Tabanı Oluştur"</string> <string name="posts">"Gönderiler"</string> <string name="sidebar">"Hakkında"</string> <string name="only_for_logged_in_user">"Sadece Oturum Açmış Kullanıcılar için"</string> - <string name="settings_number_of_columns_in_post_feed_title">"Yayın Feed'inindeki Sütun Sayısı"</string> + <string name="settings_number_of_columns_in_post_feed_title">"Gönderi Akışındaki Sütun Sayısı"</string> <string name="settings_number_of_columns_in_post_feed_portrait_title">"Portre"</string> <string name="settings_number_of_columns_in_post_feed_landscape_title">"Manzara"</string> <string name="settings_nsfw_and_spoiler_title">"NSFW ve Spoiler"</string> @@ -847,7 +851,6 @@ Sekmeler, diğerlerine geçtikten sonra tüm içeriği kaybedebilir. Bu, sayfay Mesaj: %2$s"</string> <string name="give_award_success">"Ödül verildi"</string> <string name="give_award_failed">"İşlem Başarısız Oldu"</string> - <string name="recent_searches">"Son aramalar"</string> <string name="warning">"Uyarı"</string> <string name="this_is_a_nsfw_subreddit">"Bu bir NSFW subredditidir."</string> <string name="this_user_has_nsfw_content">"Bu kullanıcının NSFW içeriği var"</string> @@ -864,7 +867,7 @@ Sekmeler, diğerlerine geçtikten sonra tüm içeriği kaybedebilir. Bu, sayfay <string name="random_subreddit">"Rastgele Subreddit"</string> <string name="random_nsfw_subreddit">"Rastgele NSFW Subreddit'i"</string> <string name="random_post">"Rastgele Gönderi"</string> - <string name="random_nsfw_post">"Rastgele NSFW gönderisi"</string> + <string name="random_nsfw_post">"Rastgele NSFW Gönderisi"</string> <string name="fetch_random_thing_failed">"Daha sonra tekrar deneyin"</string> <string name="downloading">"İndiriliyor"</string> <string name="subreddit_filter_popular_and_all_activity_label">"r/all ve r/popular"</string> @@ -880,7 +883,7 @@ Sekmeler, diğerlerine geçtikten sonra tüm içeriği kaybedebilir. Bu, sayfay <string name="settings_disable_image_preview_title">"Veri Tasarrufu Modunda Görüntüleri Önizlemeyi Devre Dışı Bırak"</string> <string name="settings_swipe_action_swipe_left_title">"Sola Kaydır"</string> <string name="settings_swipe_action_swipe_right_title">"Sağa Kaydır"</string> - <string name="settings_swipe_action_info_summary">"Birden fazla sütun veya gönderi ayrıntısı içeren yayın feed'i için geçerli değildir."</string> + <string name="settings_swipe_action_info_summary">"Birden fazla sütun veya gönderi ayrıntısı içeren gönderi akışı için geçerli değildir."</string> <string name="theme_item_no_preview_post_type_icon_tint">"Önizlemesiz Gönderi Türü Simge Rengi"</string> <string name="theme_item_no_preview_post_type_icon_tint_detail">"Uygulandığı yer: Önizleme olmadığında gönderinin türünü belirten simge"</string> <string name="theme_item_no_preview_post_type_background_color">"Önizlemesiz Gönderi Türü Arka Plan Rengi"</string> @@ -977,4 +980,134 @@ Sekmeler, diğerlerine geçtikten sonra tüm içeriği kaybedebilir. Bu, sayfay <string name="have_trouble_login_title">"Giriş Yapmakta Sorun Yaşanıyor"</string> <string name="have_trouble_login_message">"Giriş yapmanın başka bir yolunu denemek ister misiniz?"</string> <string name="vote">"Oy"</string> + <string name="action_share_link">"Bağlantıyı Paylaş"</string> + <string name="action_copy_link">"Bağlantıyı Kopyala"</string> + <string name="action_add_to_post_filter">"Gönderi Filtresine Ekle"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"NSFW Subredditlerindeki NSFW Görüntülerini bulanıklaştırma"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Avatarı Solda Göster"</string> + <string name="settings_backup_settings_title">"Yedekleme Ayarları"</string> + <string name="settings_restore_settings_title">"Ayarları Eski Haline Getir"</string> + <string name="settings_credits_love_animation_title">"Aşk Animasyonu"</string> + <string name="settings_swipe_between_posts_title">"Gönderiler Arasında Kaydır"</string> + <string name="settings_navigation_drawer_title">"Gezinme Çekmecesi"</string> + <string name="settings_collapse_account_section_title">"Hesap Bölümünü Daralt"</string> + <string name="settings_collapse_post_section_title">"Gönderi Bölümünü Daralt"</string> + <string name="settings_collapse_preferences_section_title">"Tercihler Bölümünü Daralt"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"Favori Subredditler Bölümünü Daralt"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"Abone Olunan Subredditler Bölümünü Daralt"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Favori Subredditler Bölümünü Gizle"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Abone Olunan Subredditler Bölümünü Gizle"</string> + <string name="settings_default_search_result_tab">"Varsayılan Arama Sonucu Sekmesi"</string> + <string name="device_default">"Cihaz Varsayılanı"</string> + <string name="set_by_battery_saver">"Pil Tasarruflu Olarak Ayarla"</string> + <string name="theme_item_upvote_ratio_icon_tint">"Olumlu Oy Oranı Simgesi Rengi"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"Uygulandığı yer: Ek oy oranı simgesi"</string> + <string name="theme_item_current_user_color">"Geçerli Kullanıcı"</string> + <string name="theme_item_current_user_color_detail">"Uygulandığı yer: Yorumlardaki geçerli kullanıcı"</string> + <string name="exclude_domains_hint">"Alan adlarını hariç tut"</string> + <string name="anonymous_front_page_no_subscriptions">"Bir subreddit'e katılarak başla!"</string> + + <!-- Fuzzy --> + <string name="backup_settings_success">"Ayarlar hedef dizine başarıyla aktarıldı"</string> + <string name="create_zip_in_destination_directory_failed">"Hedef dizinde yedek zip oluşturulamadı"</string> + <string name="backup_some_settings_failed">"Bazı ayarlar yedeklenemedi, ancak diğerleri başarıyla hedef dizine aktarıldı"</string> + <string name="restore_settings_success">"Ayarlar başarıyla geri yüklendi. Değişiklikleri görmek için uygulamayı yeniden başlatın."</string> + <string name="restore_settings_partially_failed">"Bazı ayarlar başarıyla geri yüklenemeyebilir. Değişiklikleri görmek için uygulamayı yeniden başlatın."</string> + <string name="restore_settings_failed_file_corrupted">"Ayarlar geri yüklenemedi. Dosya bozulmuş olabilir."</string> + <string name="restore_settings_failed_cannot_get_file">"Dosyaya erişilemiyor"</string> + <string name="suicide_prevention_quote">"Kendinizi öldürmemek için bir işaret arıyorsanız, işte bu. \u2764"</string> + <string name="do_not_show_this_again">"Bunu bir daha gösterme"</string> + <string name="continue_suicide_prevention_activity">"Devam et"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"V.redd.it videosu getirilirken hata oluştu: Yönlendirme bağlantısı alınamıyor"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"V.redd.it videosu getirilirken hata oluştu: Gönderi alınamıyor"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"V.redd.it videosu getirilirken hata oluştu: Gönderi ID'si alınamıyor"</string> + <string name="always_on">"Her Zaman"</string> + <string name="only_on_wifi">"Sadece WiFi'da"</string> + <string name="never">"Asla"</string> + <string name="normal">"Normal"</string> + <string name="extra_large">"Daha Büyük"</string> + <string name="enormously_large">"Çok Büyük"</string> + <string name="default_in_array">"Varsayılan"</string> + <string name="off">"Kapalı"</string> + <string name="only_on_cellular_data">"Sadece Hücresel Veride"</string> + <string name="upvote">"Olumlu oy"</string> + <string name="downvote">"Olumsuz oy"</string> + <string name="select">"Seç"</string> + <string name="exclude_subreddit">"Bu subreddit'i hariç tut"</string> + <string name="exclude_user">"Bu kullanıcıyı hariç tut"</string> + <string name="exclude_flair">"Bu etiketi hariç tut"</string> + <string name="contain_flair">"Bu etiketi içer"</string> + <string name="exclude_domain">"Alan Adını Hariç Tut"</string> + <string name="suggest_title">"Başlık Öner"</string> + <string name="suggest_title_failed">"Bir başlık önerilemedi"</string> + <string name="action_delete_logs">"Seyir Defterini Sil"</string> + <string name="inbox_with_count">"Gelen Kutusu (%1$d)"</string> + <string name="comment_continue_thread">"Konuya devam et"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"Medyadan Geri Dönmek İçin Dikey Kaydır"</string> + <string name="settings_hide_post_flair">"Gönderi Etiketini Gizle"</string> + <string name="settings_crash_reports_title">"Kilitlenme Raporları"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"Sakıncalı"</string> + <string name="settings_disable_nsfw_forever_title">"NSFW'yi Her Zaman Devre Dışı Bırak"</string> + <string name="settings_show_only_one_comment_level_indicator">"Sadece Bir Yorum Seviyesi Belirtecini Göster"</string> + <string name="save_comment">"Kaydet"</string> + <string name="unsave_comment">"Kaydetme"</string> + <string name="copy_multi_reddit_path">"Multireddit'in Yolunu Kopyala"</string> + <string name="copy_multi_reddit_path_failed">"Multireddit'in yolu kopyalanamadı"</string> + <string name="crash_reports_deleted">"Kilitlenme raporları silindi"</string> + <string name="disable_nsfw_forever_message">"Etkinleştirildikten sonra, NSFW ayarının etkin olup olmadığına bakılmaksızın NSFW kalıcı olarak devre dışı bırakılacaktır. Ve bu seçenek geri alınamaz, NSFW'yi yeniden etkinleştirmenin tek yolu uygulama verilerini temizlemektir. + +Yine de etkinleştirmek istiyor musunuz?"</string> + <string name="reply">"Yanıtla"</string> + + <!-- What is RPAN? --> + <string name="rpan_activity_label">"Canlı Yayın"</string> + <string name="post_gallery_activity_label">"Galeri Gönderisi"</string> + <string name="trending_activity_label">"Trendler"</string> + <string name="action_share_rpan_link">"Canlı Yayın Bağlantısını Paylaş"</string> + <string name="action_share_post_link">"Gönderi Bağlantısını Paylaş"</string> + <string name="rpan">"Canlı Yayın"</string> + <string name="trending">"Trendler"</string> + <string name="receive_post_reply_notifications">"Gönderi yanıtlanınca bildirimlerini al"</string> + <string name="bottom_sheet_post_gallery">"Galeri"</string> + <string name="posting_gallery">"Galeri Paylaşma"</string> + <string name="label_reddit">"Reddit"</string> + <string name="settings_default_link_post_layout">"Varsayılan Bağlantı Gönderisi Düzeni"</string> + <string name="settings_category_material_you_title">"Material You"</string> + <string name="settings_enable_material_you_warning_summary">"Şu adda temalarınız olmadığından emin olun; +\"Material You\", +\"Material You Dark\" veya +\"Material You Amoled\". +Yoksa, Material You'u etkinleştirmeden önce bunları yeniden adlandırın."</string> + <string name="settings_enable_material_you_title">"Material You'u Etkinleştir"</string> + <string name="settings_enable_material_you_summary">"Infinity'yi Duvar Kağıdına Göre Kişiselleştir"</string> + <string name="settings_apply_material_you_title">"Material You'u Uygula"</string> + <string name="settings_apply_material_you_summary">"Infinity'nin temayı değiştirmemesi durumunda"</string> + <string name="settings_more_tabs_show_favorite_multireddits_title">"Favori Multiredditleri Göster"</string> + <string name="settings_more_tabs_show_multireddits_title">"Multiredditleri Göster"</string> + <string name="settings_collapse_reddit_section_title">"Reddit Bölümünü Daralt"</string> + <string name="settings_video_player_automatic_landscape_orientation">"Video Oynatırken Otomatik Olarak Yatay Ekrana Geç"</string> + <string name="settings_remember_muting_option_in_post_feed">"Gönderi Akışında Sessize Alma Seçeneğini Hatırla"</string> + <string name="link_post_layout_auto">"Otomatik"</string> + <string name="uploaded_images">"Foroğraf Yüklemesi"</string> + <string name="select_image">"Bir Fotoğraf Seç"</string> + <string name="capture">"Bir Fotoğraf Çek"</string> + <string name="uploading_image">"Yükleniyor"</string> + <string name="upload_image_success">"Fotoğraf başarıyla yüklendi. Yüklenen fotoğrafları görmek için fotoğraf düğmesine tekrar tıklayın."</string> + <string name="get_image_bitmap_failed">"Fotoğrafın bitmap'i alınamıyor"</string> + <string name="upload_image_failed">"Fotoğraf yüklenemiyor"</string> + <string name="load_rpan_broadcasts_failed">"Canlı Yayınlar yüklenemiyor"</string> + <string name="parse_rpan_broadcasts_failed">"Canlı Yayınlar ayrıştırılamıyor"</string> + <string name="parse_rpan_broadcast_failed">"Canlı Yayın ayrıştırılamıyor"</string> + <string name="search_comments">"Yorumları Ara"</string> + <string name="please_wait_image_is_uploading">"Hâlâ bir fotoğraf yükleniyor. Lütfen bekleyin."</string> + <string name="error_fetch_trending_search">"Trend aramalar getirilemedi. +Tekrar denemek için tıklayın."</string> + <string name="error_parse_trending_search">"Trend aramalar ayrıştırılamadı. +Tekrar denemek için tıklayın."</string> + <string name="no_trending_search">"Trend aramalar bulunamadı. +Tekrar denemek için tıklayın."</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml new file mode 100644 index 00000000..6931c715 --- /dev/null +++ b/app/src/main/res/values-vi/strings.xml @@ -0,0 +1,1040 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="login_activity_label">"Đăng nhập"</string> + <string name="comment_activity_label">"Gửi bình luận"</string> + <string name="comment_activity_label_is_replying">"Trả lời"</string> + <string name="post_text_activity_label">"Bài đăng chữ"</string> + <string name="subreddit_selection_activity_label">"Chọn một Subreddit"</string> + <string name="post_link_activity_label">"Bài đăng chứa Liên kết"</string> + <string name="post_image_activity_label">"Bài đăng hình ảnh"</string> + <string name="post_video_activity_label">"Bài đăng video"</string> + <string name="rules_activity_label">"Qui định"</string> + <string name="search_subreddits_activity_label">"Các Subreddit"</string> + <string name="edit_post_activity_label">"Sửa bài đăng"</string> + <string name="edit_comment_activity_label">"Sửa bình luận"</string> + <string name="view_message_activity_label">"Hộp thư"</string> + <string name="settings_activity_label">"Cài đặt"</string> + <string name="account_saved_thing_activity_label">"Lưu"</string> + <string name="create_multi_reddit_activity_label">"Tạo Multireddit"</string> + <string name="subreddit_multiselection_activity_label">"Chọn các Subreddit"</string> + <string name="custom_theme_listing_activity_label">"Chủ đề tùy chỉnh"</string> + <string name="customize_theme_activity_label">"Tùy chỉnh chủ đề"</string> + <string name="customize_theme_activity_create_theme_label">"Tạo chủ đề"</string> + <string name="theme_preview_activity_label">"Xem trước chủ đề"</string> + <string name="edit_multi_reddit_activity_label">"Sửa Multireddit"</string> + <string name="selected_subeddits_activity_label">"Các Subreddit đã chọn"</string> + <string name="report_activity_label">"Báo cáo"</string> + <string name="view_imgur_media_activity_image_label">"Hình ảnh %1$d/%2$d"</string> + <string name="view_imgur_media_activity_video_label">"Video %1$d/%2$d"</string> + <string name="send_private_message_activity_label">"Gửi PM"</string> + <string name="view_reddit_gallery_activity_image_label">"Hình ảnh %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_gif_label">"Gif %1$d/%2$d"</string> + <string name="view_reddit_gallery_activity_video_label">"Video %1$d/%2$d"</string> + <string name="navigation_drawer_open">"Mở thanh điều hướng"</string> + <string name="navigation_drawer_close">"Đóng thanh điều hướng"</string> + <string name="action_download">"Tải xuống"</string> + <string name="action_refresh">"Làm mới"</string> + <string name="action_add_comment">"Thêm một bình luận"</string> + <string name="action_save_post">"Lưu bài đăng"</string> + <string name="action_view_crosspost_parent">"Xem mục mẹ của bài đăng chéo"</string> + <string name="action_search">"Tìm kiếm"</string> + <string name="action_start_lazy_mode">"Bật chế độ lười biếng"</string> + <string name="action_stop_lazy_mode">"Tắt chế độ lười biếng"</string> + <string name="action_send">"Gửi"</string> + <string name="action_sort">"Sắp xếp"</string> + <string name="action_hide_post">"Ẩn bài đăng"</string> + <string name="action_unhide_post">"Hiện bài đăng"</string> + <string name="action_edit_post">"Sửa bài đăng"</string> + <string name="action_delete_post">"Xóa bài đăng"</string> + <string name="action_mark_nsfw">"Đánh dấu NSFW"</string> + <string name="action_unmark_nsfw">"Bỏ đánh dấu NSFW"</string> + <string name="action_mark_spoiler">"Đánh dấu Spoiler"</string> + <string name="action_unmark_spoiler">"Bỏ đánh dấu Spoiler"</string> + <string name="action_edit_flair">"Sửa tư cách"</string> + <string name="action_change_post_layout">"Thay đổi bố cục bài đăng"</string> + <string name="action_save">"Lưu"</string> + <string name="action_edit_multi_reddit">"Sửa MultiReddit"</string> + <string name="action_delete_multi_reddit">"Xóa MultiReddit"</string> + <string name="action_share">"Chia sẻ"</string> + <string name="action_preview">"Xem trước"</string> + <string name="action_report">"Báo cáo"</string> + <string name="action_see_removed">"Xem bài đăng đã xóa"</string> + <string name="action_set_wallpaper">"Đặt làm hình nền"</string> + <string name="action_send_private_message">"Gửi tin nhắn riêng tư"</string> + <string name="action_block_user">"Chặn người dùng"</string> + <string name="parse_json_response_error">"Lỗi khi phân tích phản hồi JSON"</string> + <string name="retrieve_token_error">"Lỗi khi truy xuất mã thông báo"</string> + <string name="something_went_wrong">"Đã xảy ra lỗi. Thử lại sau"</string> + <string name="access_denied">"Truy cập bị từ chối"</string> + <string name="parse_user_info_error">"Lỗi khi phân tích thông tin người dùng"</string> + <string name="no_system_webview_error">"Lỗi khi mở WebView của hệ thống"</string> + <string name="error_loading_image_tap_to_retry">"Lỗi khi tải hình ảnh. Chạm để thử lại."</string> + <string name="load_posts_error">"Lỗi khi tải các bài đăng. Chạm để thử lại."</string> + <string name="load_more_posts_error">"Lỗi khi tải các bài đăng."</string> + <string name="load_post_error">"Lỗi khi tải bài đăng này. Chạm để thử lại."</string> + <string name="search_subreddits_error">"Lỗi khi tìm kiếm các subreddit. Chạm để thử lại."</string> + <string name="search_users_error">"Lỗi khi tìm kiếm các người dùng. Chạm để thử lại."</string> + <string name="no_posts">"Không tìm thấy bài đăng"</string> + <string name="no_comments">"Không tìm thấy bình luận"</string> + <string name="no_subreddits">"Không tìm thấy subreddits"</string> + <string name="no_users">"Không tìm thấy người dùng"</string> + <string name="no_multi_reddits">"Không tìm thấy Multireddits"</string> + <string name="no_storage_permission">"Không có quyền bộ nhớ để lưu tệp này"</string> + <string name="load_comments_failed">"Lỗi khi tải bình luận. Chạm để thử lại."</string> + <string name="retry">"Thử lại"</string> + <string name="comments">"Bình luận"</string> + <string name="no_comments_yet">"Chưa có bình luận nào cả. Viết một bình luận không?"</string> + <string name="vote_failed">"Vote thất bại"</string> + <string name="refresh_post_failed">"Lỗi khi làm mới bài đăng"</string> + <string name="load_messages_failed">"Lỗi khi tải tin nhắn. Chạm để thử lại"</string> + <string name="no_messages">"Không có tin nhắn"</string> + <string name="nsfw">"NSFW"</string> + <string name="karma_info">"Nghiệp quả: %1$d"</string> + <string name="karma_info_user_detail">"Nghiệp quả: +%1$d (%2$d + %3$d)"</string> + <string name="cakeday_info">"Ngày bánh ga tô: +%1$s"</string> + <string name="since">"Từ khi"</string> + <string name="profile">"Trang cá nhân"</string> + <string name="subscriptions">"Mục đã đăng kí"</string> + <string name="multi_reddit">"Multireddit"</string> + <string name="inbox">"Hộp thư"</string> + <string name="upvoted">"Thich"</string> + <string name="downvoted">"Không thích"</string> + <string name="hidden">"Ẩn"</string> + <string name="saved">"Lưu"</string> + <string name="gilded">"Mạ vàng"</string> + <string name="settings">"Cài đặt"</string> + <string name="subscribers_number_detail">"Người đăng ký: %1$d"</string> + <string name="online_subscribers_number_detail">"Trực tuyến: %1$d"</string> + <string name="cannot_fetch_subreddit_info">"Không thể lấy thông tin subreddit"</string> + <string name="cannot_fetch_user_info">"Không thể lấy thông tin người dùng"</string> + <string name="cannot_fetch_sidebar">"Không thể lấy thanh bên"</string> + <string name="cannot_fetch_multireddit">"Không thể lấy thông tin multireddit"</string> + <string name="subscribe">"Đăng ký"</string> + <string name="unsubscribe">"Hủy đăng ký"</string> + <string name="subscribed">"Đã đăng ký"</string> + <string name="subscribe_failed">"Đăng ký thất bại"</string> + + <!-- what the different between Unsubscribe and Unsubscribed --> + <string name="unsubscribed">"Đã hủy đăng kí"</string> + <string name="unsubscribe_failed">"Hủy đăng kí thất bại"</string> + <string name="follow">"Theo dõi"</string> + <string name="unfollow">"Hủy theo dõi"</string> + <string name="followed">"Đã theo dõi"</string> + <string name="follow_failed">"Theo dõi thất bại"</string> + <string name="unfollowed">"Đã ngừng theo dõi"</string> + <string name="unfollow_failed">"Ngừng theo dõi thất bại"</string> + <string name="content_description_banner_imageview">"Ảnh bìa của Subreddit"</string> + <string name="app_label">"Infinity"</string> + <string name="search_hint">"Tìm bất cứ thứ gì"</string> + <string name="no_posts_no_lazy_mode">"Không bài đăng nào có sẵn"</string> + <string name="lazy_mode_start">"Chế độ lười biếng bắt đầu trong %1$.1fs"</string> + <string name="lazy_mode_stop">"Chế độ lười biếng đã dừng"</string> + <string name="write_comment_hint">"Viết những ý nghĩ thú vị của bạn ở đây"</string> + <string name="comment_content_required">"Những ý nghĩ thú vị của bạn đâu rồi?"</string> + <string name="sending_comment">"Đang gửi"</string> + <string name="send_comment_success">"Bình luận đã gửi"</string> + <string name="send_comment_failed">"Không thể gửi bình luận này"</string> + <string name="send_message_username_hint">"Người dùng"</string> + <string name="send_message_subject_hint">"Chủ đề (100 kí tự tối đa)"</string> + <string name="send_message_content_hint">"Tin nhắn"</string> + <string name="reply_message_failed">"Không thể trả lời tin nhắn này"</string> + <string name="error_getting_message">"Lỗi khi nhận tin nhắn này"</string> + <string name="message_username_required">"Này, bạn muốn gửi tin nhắn này cho ai?"</string> + <string name="message_subject_required">"Tin nhắn của bạn nên có một chủ đề"</string> + <string name="message_content_required">"Bạn cần phải nói với người nhận điều gì đó"</string> + <string name="sending_message">"Đang gửi"</string> + <string name="send_message_success">"Tin nhắn đã gửi"</string> + <string name="send_message_failed">"Không thể gửi tin nhắn này"</string> + <string name="select_a_subreddit">"Hãy chọn một subreddit trước"</string> + <string name="title_required">"Bài đăng cần một tiêu đề hay"</string> + <string name="link_required">"Này, Liên kết đâu rồi?"</string> + <string name="select_an_image">"Hãy chọn một bức ảnh trước"</string> + <string name="posting">"Đang đăng bài"</string> + <string name="post_failed">"Không thể đăng bài được"</string> + <string name="error_processing_image">"Lỗi khi xử lí ảnh"</string> + <string name="error_processing_video">"Lỗi khi xử lí video"</string> + <string name="download_started">"Đã bắt đầu tải về. Hãy kiểm tra thông báo để xem tiến độ."</string> + <string name="comment_load_more_comments">"Tải thêm bình luận"</string> + <string name="comment_load_more_comments_failed">"Tải thất bại. Chạm để thử lại."</string> + <string name="loading">"Đang tải"</string> + <string name="post_title_hint">"Tiêu đề"</string> + <string name="post_text_content_hint">"Nội dung"</string> + <string name="choose_a_subreddit">"Chọn một subreddit"</string> + <string name="rules">"Luật lệ"</string> + <string name="post_link_hint">"URL"</string> + <string name="subreddits">"Các subreddit"</string> + <string name="users">"Những người dùng"</string> + <string name="multi_reddits">"Các MultiReddit"</string> + <string name="bottom_sheet_post_text">"Văn bản"</string> + <string name="bottom_sheet_post_link">"Liên kết"</string> + <string name="bottom_sheet_post_image">"Hình ảnh"</string> + <string name="bottom_sheet_post_video">"Video"</string> + <string name="select_from_gallery">"Chọn một bức ảnh"</string> + <string name="select_again">"Hãy chọn lại"</string> + <string name="error_getting_image">"Lỗi khi nhận hình ảnh"</string> + <string name="error_getting_video">"Lỗi khi nhận video"</string> + <string name="no_camera_available">"Không ứng dụng camera nào có sẵn"</string> + <string name="error_creating_temp_file">"Lỗi khi tạo tệp tạm thời"</string> + <string name="video_is_processing">"Video đang xử lý. Vui lòng đợi."</string> + <string name="image_is_processing">"Hình ảnh đang xử lý. Vui lòng đợi."</string> + <string name="gif_is_processing">"Tệp Gif đang xử lý. Vui lòng đợi."</string> + <string name="flair">"Tư cách"</string> + <string name="spoiler">"Spoiler"</string> + <string name="no_flair">"Không có tư cách"</string> + <string name="error_loading_flairs">"Lỗi khi tải tư cách. +Nhấn để thử lại."</string> + <string name="no_rule">"Không có luật lệ"</string> + <string name="error_loading_rules">"Lỗi khi tải qui định. Chạm để thử lại."</string> + <string name="error_loading_rules_without_retry">"Lỗi khi tải qui định"</string> + <string name="search_in">"Tìm kiếm trong"</string> + <string name="all_subreddits">"Tất cả các subreddit"</string> + <string name="sort_best">"Hay nhất"</string> + <string name="sort_hot">"Nóng"</string> + <string name="sort_new">"Mới"</string> + <string name="sort_random">"Ngẫu nhiên"</string> + <string name="sort_rising">"Đang nổi"</string> + <string name="sort_top">"Hàng đầu"</string> + <string name="sort_controversial">"Gây tranh cãi"</string> + <string name="sort_relevance">"Liên quan"</string> + <string name="sort_comments">"Bình luận"</string> + <string name="sort_activity">"Sự hoạt động"</string> + <string name="sort_confidence">"Sự tự tin"</string> + <string name="sort_old">"Cũ nhất"</string> + <string name="sort_qa">"QA"</string> + <string name="sort_live">"Trực tiếp"</string> + <string name="sort_time_hour">"Giờ"</string> + <string name="sort_time_day">"Ngày"</string> + <string name="sort_time_week">"Tuần"</string> + <string name="sort_time_month">"Tháng"</string> + <string name="sort_time_year">"Năm"</string> + <string name="sort_time_all_time">"Mọi thời gian"</string> + <string name="no_activity_found_for_share">"Không có ứng dụng nào có thể xử lý hành động chia sẻ"</string> + <string name="archived_post_vote_unavailable">"Bài đăng đang được lưu trữ. Không thể vote."</string> + <string name="archived_post_comment_unavailable">"Bài đăng đang được lưu trữ. Không thể bình luận."</string> + <string name="archived_post_reply_unavailable">"Bài đăng đang được lưu trữ. Không thể trả lời."</string> + <string name="locked_post_comment_unavailable">"Bài đăng đang bị khóa. Không thể bình luận."</string> + <string name="locked_post_reply_unavailable">"Bài đăng đang bị khóa. Không thể trả lời."</string> + <string name="text">"VĂN BẢN"</string> + <string name="link">"LIÊN KẾT"</string> + <string name="image">"HÌNH ẢNH"</string> + <string name="video">"VIDEO"</string> + <string name="gif">"GIF"</string> + <string name="gallery">"BỘ SƯU TẬP"</string> + <string name="best">"Hay nhất"</string> + <string name="search">"Tìm kiếm"</string> + <string name="posting_video">"Đang đăng video"</string> + <string name="posting_image">"Đang đăng hình ảnh"</string> + + <!-- Fuzzy --> + <string name="please_wait">"Vui lòng đợi."</string> + <string name="add_account">"Thêm tài khoản"</string> + <string name="anonymous_account">"Vô danh"</string> + <string name="log_out">"Đăng xuất"</string> + <string name="press_here_to_login">"Nhấn vào đây để đăng nhập"</string> + <string name="login_first">"Đăng nhập trước đã"</string> + <string name="post_saved_success">"Bài đăng đã được lưu"</string> + <string name="post_saved_failed">"Không thể lưu bài đăng"</string> + <string name="post_unsaved_success">"Bài đăng đã được huỷ lưu"</string> + <string name="post_unsaved_failed">"Không thể huỷ lưu bài đăng"</string> + <string name="post_hide_success">"Bài đăng đã được ẩn"</string> + <string name="post_hide_failed">"Không thể ẩn bài đăng"</string> + <string name="post_unhide_success">"Bài đăng đã được hiện"</string> + <string name="thing_favorite_failed">"Yêu thích thất bại"</string> + <string name="thing_unfavorite_failed">"Xóa yêu thích thất bại"</string> + <string name="post_unhide_failed">"Không thể không ẩn bài đăng"</string> + <string name="delete_this_post">"Xóa bài đăng này"</string> + <string name="delete_this_comment">"Xóa bình luận này"</string> + <string name="are_you_sure">"Bạn có chắc không?"</string> + <string name="edit">"Sửa"</string> + <string name="delete">"Xóa"</string> + <string name="see_removed_comment">"Xem bình luận bị xóa"</string> + <string name="fetching_removed_comment">"Đang tìm bình luận bị xóa"</string> + <string name="show_removed_comment_failed">"Không thể tìm được bình luận bị xóa"</string> + <string name="fetching_removed_post">"Đang tìm bài đăng bị xóa"</string> + <string name="show_removed_post_failed">"Không thể tìm được bài đăng bị xóa"</string> + <string name="cancel">"Hủy"</string> + <string name="ok">"OK"</string> + + <!-- Fuzzy --> + <string name="edit_success">"Sửa thành công"</string> + <string name="delete_post_success">"Xóa thành công"</string> + <string name="delete_post_failed">"Xóa thất bại"</string> + + <!-- Fuzzy --> + <string name="mark_nsfw_success">"Đánh dấu NSFW thành công"</string> + <string name="mark_nsfw_failed">"Đánh dấu NSFW thất bại"</string> + + <!-- Fuzzy --> + <string name="unmark_nsfw_success">"Bỏ đánh dấu NSFW thành công"</string> + <string name="unmark_nsfw_failed">"Bỏ đánh dấu NSFW thất bại"</string> + + <!-- Fuzzy --> + <string name="mark_spoiler_success">"Đánh dấu spoiler thành công"</string> + <string name="mark_spoiler_failed">"Đánh dấu spoiler thất bại"</string> + + <!-- Fuzzy --> + <string name="unmark_spoiler_success">"Bỏ đánh dấu spoiler thành công"</string> + <string name="unmark_spoiler_failed">"Bỏ đánh dấu spoiler thất bại"</string> + <string name="update_flair_success">"Cập nhật tư cách thành công"</string> + <string name="update_flair_failed">"Cập nhật tư cách thất bại"</string> + <string name="edit_flair">"Sửa tư cách"</string> + <string name="only_allow_64_chars">"Chỉ cho phép ít hơn 64 ký tự"</string> + <string name="view_all_comments">"Nhấn vào đây để xem tất cả các bình luận"</string> + <string name="notification_summary_account">"Tài khoản"</string> + <string name="notification_summary_message">"Tin nhắn mới"</string> + <string name="notification_summary_subreddit">"Subreddit"</string> + <string name="notification_summary_award">"Giải thưởng"</string> + <string name="notification_new_messages">"%1$d Tin nhắn mới"</string> + <string name="label_account">"Tài khoản"</string> + <string name="label_post">"Bài đăng"</string> + <string name="label_preferences">"Cài đặt"</string> + <string name="account_switched">"Tài khoản đã được chuyển đổi. Các trang khác sẽ bị biến mất"</string> + <string name="settings_notification_master_title">"Thông báo"</string> + <string name="settings_notification_enable_notification_title">"Bật thông báo"</string> + <string name="settings_notification_interval_title">"Khoảng thời gian để kiểm tra thông báo"</string> + <string name="settings_theme_title">"Chủ đề"</string> + <string name="settings_amoled_dark_title">"Tối kiểu Amoled"</string> + <string name="settings_interface_title">"Giao diện"</string> + <string name="settings_gestures_and_buttons_title">"Cử chỉ & Nút"</string> + <string name="settings_save_front_page_scrolled_position_title">"Giữ vị trí cuộn trong Trang chủ"</string> + <string name="settings_save_front_page_scrolled_position_summary">"Duyệt các bài viết mới sau khi làm mới trong TRANG CHỦ (Trang chính, loại sắp xếp: Hay nhất)"</string> + <string name="settings_open_link_in_app_title">"Mở liên kết trong ứng dụng"</string> + <string name="settigns_video_title">"VIDEO"</string> + <string name="settings_video_autoplay_title">"Tự động phát Video"</string> + <string name="settings_mute_autoplaying_videos_title">"Tắt tiếng những Video tự động phát"</string> + <string name="settings_autoplay_nsfw_videos_title">"Tự động phát những video NSFW"</string> + <string name="settings_start_autoplay_visible_area_offset_portrait_title">"Tự phát Video theo diện tích có thể nhìn được (Dọc)"</string> + <string name="settings_start_autoplay_visible_area_offset_portrait_summary">"Tự động phát các video khi %1$d%% trong số chúng có thể nhìn thấy được"</string> + <string name="settings_start_autoplay_visible_area_offset_landscape_title">"Tự phát Video theo diện tích có thể nhìn được (Ngang)"</string> + <string name="settings_start_autoplay_visible_area_offset_landscape_summary">"Tự động phát các video khi %1$d%% trong số chúng có thể nhìn thấy được"</string> + <string name="settings_immersive_interface_title">"Giao diện đắm mình"</string> + <string name="settings_immersive_interface_summary">"Không áp dụng cho tất cả trang"</string> + <string name="settings_immersive_interface_ignore_nav_bar_title">"Bỏ qua thanh điều hướng trong giao diện đắm mình"</string> + <string name="settings_immersive_interface_ignore_nav_bar_summary">"Ngăn cho thanh điều hướng có thêm đệm dưới cùng"</string> + <string name="settings_customize_tabs_in_main_page_title">"Tùy chỉnh các Tab trong trang chính"</string> + <string name="settings_enable_bottom_app_bar_title">"Bật điều hướng ở dưới cùng"</string> + <string name="settings_enable_bottom_app_bar_summary">"Không có tác dụng trong chế độ vô danh"</string> + <string name="settings_category_post_and_comment_title">"Bài đăng và bình luận"</string> + <string name="settings_vote_buttons_on_the_right_title">"Nút Vote ở bên phải"</string> + <string name="settings_volume_keys_navigate_comments_title">"Dùng nút âm lượng để di chuyển bình luận trong bài đăng"</string> + <string name="settings_volume_keys_navigate_posts_title">"Dùng nút âm lượng để di chuyển bài đăng"</string> + <string name="settings_mute_video_title">"Tắt tiếng Video"</string> + <string name="settings_mute_nsfw_video_title">"Tắt tiếng video NSFW"</string> + + <!-- Fuzzy --> + <string name="settings_automatically_try_redgifs_title">"Tự động thử truy cập Redgifs nếu Video trên Gfycat bị xóa."</string> + <string name="settings_video_player_ignore_nav_bar_title">"Bỏ qua thanh điều hướng trong trình phát video"</string> + <string name="settings_video_player_ignore_nav_bar_summary">"Ngăn trình điều khiển video có thêm lề"</string> + <string name="settings_confirm_to_exit">"Xác nhận để thoát"</string> + <string name="settings_category_comment_title">"Bình luận"</string> + <string name="settings_show_top_level_comments_first_title">"Hiện bình luận cấp trên cùng trước"</string> + <string name="settings_show_comment_divider_title">"Hiện chia tách bình luận"</string> + <string name="settings_comment_toolbar_hide_on_click">"Nhấn để hiện/ẩn thanh công cụ bình luận"</string> + <string name="settings_fully_collapse_comment_title">"Thu gọn bình luận hoàn toàn"</string> + <string name="settings_comment_toolbar_hidden">"Thanh công cụ bình luận bị ẩn theo mặc định"</string> + <string name="settings_show_absolute_number_of_votes_title">"Hiện số lượng vote tuyệt đối"</string> + <string name="settings_show_elapsed_time">"Hiện thời gian đã trôi qua trong các bình luận và bài đăng"</string> + <string name="settings_time_format_title">"Định dạng thời gian"</string> + <string name="settings_category_post_title">"Bài đăng"</string> + <string name="settings_default_post_layout">"Bố cục bài đăng mặc định"</string> + <string name="settings_show_divider_in_compact_layout">"Hiện chia tách"</string> + <string name="settings_show_thumbnail_on_the_left_in_compact_layout">"Hiện ảnh thu nhỏ ở bên trái"</string> + <string name="settings_swap_tap_and_long_title">"Đổi chỗ Nhấn và Nhấn giữ trong các bình luận"</string> + <string name="settings_swipe_to_go_back_title">"Vuối phải để quay lại"</string> + <string name="settings_swipe_to_go_back_summary">"Không áp dụng cho tất cả trang"</string> + <string name="settings_lock_jump_to_next_top_level_comment_button_title">"Khoá nút Nhảy đến bình luận cấp trên cùng tiếp theo"</string> + <string name="settings_lock_bottom_app_bar_title">"Khoá thanh điều hướng ở dưới cùng"</string> + <string name="settings_swipe_up_to_hide_jump_to_next_top_level_comment_button_title">"Vuốt lên để ẩn nút Nhảy đến bình luận cấp trên cùng tiếp theo"</string> + <string name="settings_lazy_mode_interval_title">"Khoảng thời gian Chế độ lười biếng"</string> + <string name="settings_font_title">"Phông chữ"</string> + <string name="settings_preview_font_title">"Xem trước phông chữ"</string> + <string name="settings_font_summary">"Phông chữ"</string> + <string name="settings_title_font_summary">"Tiêu đề"</string> + <string name="settings_content_font_summary">"Nội dung"</string> + <string name="settings_font_family_title">"Nhóm phông chữ"</string> + <string name="settings_title_font_family_title">"Nhóm phông chữ tiêu đề"</string> + <string name="settings_content_font_family_title">"Nhóm phông chữ nội dung"</string> + <string name="settings_font_size_title">"Cỡ chữ"</string> + <string name="settings_title_font_size_title">"Cỡ chữ tiêu đề"</string> + <string name="settings_content_font_size_title">"Cỡ chữ nội dung"</string> + <string name="settings_enable_nsfw_title">"Bật NSFW"</string> + <string name="settings_blur_nsfw_title">"Làm mờ hình ảnh NSFW"</string> + <string name="settings_blur_spoiler_title">"Làm mờ hình ảnh Spoiler"</string> + <string name="settings_about_master_title">"Giới thiệu"</string> + <string name="settings_acknowledgement_master_title">"Sự công nhận"</string> + <string name="settings_credits_master_title">"Ghi nhận"</string> + <string name="settings_credits_icon_foreground_title">"Nền trước của biểu tượng"</string> + <string name="settings_credits_icon_foreground_summary">"Véc tơ công nghệ được tạo bởi freepik - www.freepik.com"</string> + <string name="settings_credits_icon_background_title">"Nền của biểu tượng"</string> + <string name="settings_credits_icon_background_summary">"Véc tơ nền được tạo bởi freepik - www.freepik.com"</string> + <string name="settings_credits_error_image_title">"Hình ảnh lỗi"</string> + <string name="settings_credits_error_image_summary">"Véc tơ công nghệ được tạo bởi freepik - www.freepik.com"</string> + <string name="settings_credits_gilded_icon_title">"Biểu tượng mạ vàng"</string> + <string name="settings_credits_gilded_icon_summary">"Biểu tượng được tạo bởi Freepik từ www.flaticon.com"</string> + <string name="settings_credits_crosspost_icon_title">"Biểu tượng bài đăng chéo"</string> + <string name="settings_credits_crosspost_icon_summary">"Biểu tượng được tạo bởi Freepik từ www.flaticon.com"</string> + <string name="settings_credits_thumbtack_icon_title">"Biểu tượng đinh ghim"</string> + <string name="settings_credits_thumbtack_icon_summary">"Biểu tượng được làm bởi Freepik từ www.flaticon.com"</string> + <string name="settings_credits_best_rocket_icon_title">"Biểu tượng Rocket"</string> + <string name="settings_credits_best_rocket_icon_summary">"Biểu tượng được làm bởi Freepik từ www.flaticon.com"</string> + <string name="settings_credits_material_icons_title">"Biểu tượng Material"</string> + <string name="settings_open_source_title">"Mã nguồn mở"</string> + <string name="settings_open_source_summary">"Gắn sao trên Github nếu bạn thích ứng dụng này"</string> + <string name="settings_rate_title">"Đánh giá trên Google Play"</string> + <string name="settings_rate_summary">"Đánh giá 5 sao cho mình thì mình sẽ vui lắm :)"</string> + <string name="settings_email_title">"Email"</string> + <string name="settings_email_summary">"docilealligator.app@gmail.com"</string> + <string name="settings_reddit_account_title">"Tài khoản Reddit"</string> + <string name="settings_reddit_account_summary">"u/Hostilenemy"</string> + <string name="settings_subreddit_title">"Subreddit"</string> + <string name="settings_subreddit_summary">"r/Infinity_For_Reddit"</string> + <string name="settings_share_title">"Chia sẻ"</string> + <string name="settings_share_summary">"Hãy chia sẻ ứng dụng này với người khác nếu bạn thích nó"</string> + <string name="settings_version_title">"Infinity cho Reddit"</string> + <string name="settings_version_summary">"Phiên bản %s"</string> + <string name="settings_category_customization_title">"Tuỳ biến"</string> + <string name="settings_customize_light_theme_title">"Chủ đề sáng"</string> + <string name="settings_customize_dark_theme_title">"Chủ đề tối"</string> + <string name="settings_customize_amoled_theme_title">"Chủ đề Amoled"</string> + <string name="settings_manage_themes_title">"Quản lý chủ đề"</string> + <string name="settings_custom_theme_cannot_apply_to_settings_page_summary">"Các chủ đề tuỳ chỉnh không thể được áp dụng cho trang cài đặt (trừ thanh công cụ, thanh trạng thái và thanh điều hướng)."</string> + <string name="settings_advanced_master_title">"Nâng cao"</string> + <string name="settings_delete_all_subreddits_data_in_database_title">"Xoá tất cả subreddit trong cơ sở dữ liệu"</string> + <string name="settings_delete_all_users_data_in_database_title">"Xoá tất cả người dùng trong cơ sở dữ liệu"</string> + <string name="settings_delete_all_sort_type_data_in_database_title">"Xoá tất cả loại sắp xếp trong cơ sở dữ liệu"</string> + <string name="settings_delete_all_post_layout_data_in_database_title">"Xoá tất cả bố cục bài đăng trong cơ sở dữ liệu"</string> + <string name="settings_delete_all_themes_in_database_title">"Xoá tất cả chủ đề trong cơ sở dữ liệu"</string> + <string name="settings_delete_front_page_scrolled_positions_in_database_title">"Xoá tất cả vị trí đã cuộn trong trang chính trong cơ sở dữ liệu"</string> + <string name="settings_reset_all_settings_title">"Đặt lại tất cả cài đặt"</string> + <string name="settings_tab_1_summary">"Tab 1"</string> + <string name="settings_tab_2_summary">"Tab 2"</string> + <string name="settings_tab_3_summary">"Tab 3"</string> + <string name="settings_tab_title">"Tiêu đề"</string> + <string name="settings_tab_post_type">"Loại"</string> + <string name="settings_tab_subreddit_name">"Tên subreddit (Không có tiền tố r/)"</string> + <string name="settings_tab_multi_reddit_name">"Tên MultiReddit (/user/yourusername/m/yourmultiredditname)"</string> + <string name="settings_tab_username">"Tên người dùng (Không có tiền tố u/)"</string> + <string name="no_developer_easter_egg">"Không có tuỳ chọn cho nhà phát triển nào ở đây"</string> + <string name="no_link_available">"Không thể lấy liên kết"</string> + <string name="exit_when_submit">"Rời khỏi?"</string> + <string name="exit_when_submit_post_detail">"Bài đăng vẫn sẽ được gửi đi kể cả nếu bạn rời khỏi đây."</string> + <string name="exit_when_edit_post_detail">"Bài đăng vẫn có thể được gửi đi kể cả nếu bạn rời khỏi đây."</string> + <string name="exit_when_edit_comment_detail">"Bình luận vẫn có thể được gửi đi kể cả nếu bạn rời khỏi đây."</string> + <string name="discard">"Bỏ đi?"</string> + <string name="discard_detail">"Tất cả bản nháp sẽ KHÔNG được lưu."</string> + <string name="yes">"Có"</string> + <string name="no">"Không"</string> + <string name="no_data_received">"Không có dữ liệu nào được nhận"</string> + <string name="no_image_path_received">"Không có đường dẫn hình ảnh nào được nhận"</string> + <string name="no_video_path_received">"Không có đường dẫn video nào được nhận"</string> + <string name="cannot_handle_intent">"Không thể xử lý yêu cầu chia sẻ"</string> + <string name="share">"Chia sẻ"</string> + <string name="no_email_client">"Không tìm thấy ứng dụng email nào"</string> + <string name="no_app">"Không có ứng dụng nào"</string> + <string name="comment_saved_success">"Bình luận đã được lưu"</string> + <string name="comment_saved_failed">"Không thể lưu bình luận"</string> + <string name="comment_unsaved_success">"Bình luận đã được huỷ lưu"</string> + <string name="comment_unsaved_failed">"Không thể huỷ lưu bình luận"</string> + <string name="favorites">"Yêu thích"</string> + <string name="all">"Tất cả"</string> + <string name="post_layout_card">"Bố cục thẻ"</string> + <string name="post_layout_compact">"Bố cục nhỏ gọn"</string> + <string name="elapsed_time_just_now">"Vừa ngay lúc này"</string> + <string name="elapsed_time_a_minute_ago">"1 phút"</string> + <string name="elapsed_time_minutes_ago">"%1$d phút"</string> + <string name="elapsed_time_an_hour_ago">"1 tiếng"</string> + <string name="elapsed_time_hours_ago">"%1$d tiếng"</string> + <string name="elapsed_time_yesterday">"Hôm qua"</string> + <string name="elapsed_time_days_ago">"%1$d ngày"</string> + <string name="elapsed_time_a_month_ago">"1 tháng"</string> + <string name="elapsed_time_months_ago">"%1$d tháng"</string> + <string name="elapsed_time_a_year_ago">"1 năm"</string> + <string name="elapsed_time_years_ago">"%1$d năm"</string> + <string name="error_getting_multi_reddit_data">"Lỗi khi lấy dữ liệu multireddit"</string> + <string name="error_loading_multi_reddit_list">"Không thể đồng bộ các multireddit"</string> + <string name="error_loading_subscriptions">"Không thể đồng bộ mục đăng ký"</string> + <string name="share_this_app">"Hãy thử Infinity cho Reddit, một ứng dụng tuyệt vời cho Reddit! +https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit"</string> + <string name="error_getting_subreddit_name">"Lỗi khi lấy tên subreddit"</string> + <string name="share_post_link">"Chia sẻ liên kết bài đăng"</string> + <string name="share_image_link">"Chia sẻ liên kết hình ảnh"</string> + <string name="share_gif_link">"Chia sẻ liên kết Gif"</string> + <string name="share_video_link">"Chia sẻ liên kết video"</string> + <string name="share_link">"Chia sẻ liên kết"</string> + <string name="copy_post_link">"Sao chép liên kết bài đăng"</string> + <string name="copy_image_link">"Sao chép liên kết hình ảnh"</string> + <string name="copy_gif_link">"Sao chép liên kết Gif"</string> + <string name="copy_video_link">"Sao chép liên kết video"</string> + <string name="copy_link">"Sao chép liên kết"</string> + <string name="copy_success">"Đã sao chép"</string> + <string name="copy_link_failed">"Không thể sao chép liên kết"</string> + <string name="copy_text">"Sao chép"</string> + <string name="copy_all">"Sao chép tất cả"</string> + <string name="copy_markdown">"Sao chép Markdown"</string> + <string name="copy_raw_text">"Sao chép văn bản thô"</string> + <string name="copy_all_markdown">"Sao chép tất cả Markdown"</string> + <string name="copy_all_raw_text">"Sao chép tất cả văn bản thô"</string> + <string name="exit_app">"Thoát?"</string> + <string name="light_theme">"Chủ đề sáng"</string> + <string name="dark_theme">"Chủ đề tối"</string> + <string name="multi_reddit_name_hint">"Tên (Tối đa 50 kí tự)"</string> + <string name="multi_reddit_description_hint">"Mô tả"</string> + <string name="private_multi_reddit">"Riêng tư"</string> + <string name="no_multi_reddit_name">"Tên ở đâu rồi?"</string> + <string name="create_multi_reddit_failed">"Không thể tạo multireddit này"</string> + <string name="duplicate_multi_reddit">"Multireddit này đã tồn tại"</string> + <string name="edit_multi_reddit_failed">"Không thể chỉnh sửa multireddit này"</string> + <string name="logged_out">"Bạn đã đăng xuất"</string> + <string name="delete_multi_reddit_success">"Xoá thành công"</string> + <string name="delete_multi_reddit_failed">"Xoá thất bại"</string> + <string name="delete_multi_reddit_dialog_message">"Bạn có chắc không?"</string> + <string name="enable_nsfw">"Bật NSFW"</string> + <string name="disable_nsfw">"Tắt NSFW"</string> + <string name="cannot_save_image">"Không thể lưu hình ảnh"</string> + <string name="cannot_save_gif">"Không thể lưu gif"</string> + <string name="cannot_get_storage">"Không thể truy cập bộ nhớ ứng dụng"</string> + <string name="save_image_first">"Đang lưu hình ảnh. Vui lòng đợi."</string> + <string name="save_gif_first">"Đang lưu gif. Vui lòng đợi."</string> + <string name="theme_name_description">"Nhấn để đổi tên chủ đề này."</string> + <string name="theme_item_is_light_theme">"Đặt làm chủ đề sáng"</string> + <string name="theme_item_is_dark_theme">"Đặt làm chủ đề tối"</string> + <string name="theme_item_is_amoled_theme">"Đặt làm chủ đề Amoled"</string> + <string name="theme_item_color_primary">"Màu chính"</string> + <string name="theme_item_color_primary_detail">"Áp dụng cho: Thanh công cụ"</string> + <string name="theme_item_color_primary_dark">"Màu chính Tối"</string> + <string name="theme_item_color_primary_dark_detail">"Áp dụng cho: Thanh trạng thái"</string> + <string name="theme_item_color_accent">"Màu nổi bật"</string> + <string name="theme_item_color_accent_detail">"Áp dụng cho: Thanh tiến trình, v.v."</string> + <string name="theme_item_color_primary_light_theme">"Màu chính Chủ đề sáng"</string> + <string name="theme_item_color_primary_light_theme_detail">"Áp dụng cho: Nền của nút hành động nổi và nút"</string> + <string name="theme_item_primary_text_color">"Màu chính cho văn bản"</string> + <string name="theme_item_primary_text_color_detail">"Áp dụng cho: Văn bản chính"</string> + <string name="theme_item_secondary_text_color">"Màu văn bản phụ"</string> + <string name="theme_item_secondary_text_color_detail">"Áp dụng cho: Văn bản phụ"</string> + <string name="theme_item_post_title_color">"Màu tiêu đề bài đăng"</string> + <string name="theme_item_post_title_color_detail">"Áp dụng cho: Tiêu đề bài đăng"</string> + <string name="theme_item_post_content_color">"Màu nội dung bài đăng"</string> + <string name="theme_item_post_content_color_detail">"Áp dụng cho: Nội dung bài đăng"</string> + <string name="theme_item_comment_color">"Màu bình luận"</string> + <string name="theme_item_comment_color_detail">"Áp dụng cho: Bình luận"</string> + <string name="theme_item_button_text_color">"Màu văn bản trên nút"</string> + <string name="theme_item_button_text_color_detail">"Áp dụng cho: Văn bản trên nút"</string> + <string name="theme_item_chip_text_color">"Màu văn bản trên thẻ"</string> + <string name="theme_item_chip_text_color_detail">"Áp dụng cho: Nút đăng ký"</string> + <string name="theme_item_link_color">"Màu liên kết"</string> + <string name="theme_item_link_color_detail">"Áp dụng cho: URL"</string> + <string name="theme_item_received_message_text_color">"Màu văn bản tin nhắn đã nhận"</string> + <string name="theme_item_received_message_text_color_detail">"Áp dụng cho: Tin nhắn riêng tư đã nhận"</string> + <string name="theme_item_sent_message_text_color">"Màu văn bản tin nhắn đã gửi"</string> + <string name="theme_item_sent_message_text_color_detail">"Áp dụng cho: Tin nhắn riêng tư đã gửi"</string> + <string name="theme_item_background_color">"Màu nền"</string> + <string name="theme_item_background_color_detail">"Áp dụng cho: Nền của mọi trang và ngăn điều hướng"</string> + <string name="theme_item_card_view_background_color">"Màu nền hiển thị dạng thẻ"</string> + <string name="theme_item_card_view_background_color_detail">"Áp dụng cho: Nền bài đăng và nền tin nhắn"</string> + <string name="theme_item_comment_background_color">"Màu nền bình luận"</string> + <string name="theme_item_comment_background_color_detail">"Áp dụng cho: Nền bình luận"</string> + <string name="theme_item_fully_collapsed_comment_background_color">"Màu nền bình luận được thu gọn hoàn toàn"</string> + <string name="theme_item_fully_collapsed_comment_background_color_detail">"Áp dụng cho: Nền của bình luận được thu gọn hoàn toàn"</string> + <string name="theme_item_awarded_comment_background_color">"Màu nền bình luận được trao giải thưởng"</string> + <string name="theme_item_awarded_comment_background_color_detail">"Áp dụng cho: Nền của bình luận được trao giải thưởng"</string> + <string name="theme_item_received_message_background_color">"Màu nền tin nhắn được nhận"</string> + <string name="theme_item_received_message_background_color_detail">"Áp dụng cho: Nền của tin nhắn riêng tư được nhận"</string> + <string name="theme_item_sent_message_background_color">"Màu nền tin nhắn đã gửi"</string> + <string name="theme_item_sent_message_background_color_detail">"Áp dụng cho: Nền của tin nhắn riêng tư đã gửi"</string> + <string name="theme_item_bottom_app_bar_background_color">"Màu thanh điều hướng ở dưới cùng"</string> + <string name="theme_item_bottom_app_bar_background_color_detail">"Áp dụng cho: Thanh điều hướng ở dưới cùng"</string> + <string name="theme_item_primary_icon_color">"Màu chính của biểu tượng"</string> + <string name="theme_item_primary_icon_color_detail">"Áp dụng cho: Biểu tượng trong ngăn điều hướng."</string> + <string name="theme_item_bottom_app_bar_icon_color">"Màu biểu tượng của ngăn điều hướng ở dưới cùng"</string> + <string name="theme_item_bottom_app_bar_icon_color_detail">"Áp dụng cho: Biểu tượng trong ngăn điều hướng ở dưới cùng"</string> + <string name="theme_item_post_icon_and_info_color">"Màu biểu tượng và thông tin bài đăng"</string> + <string name="theme_item_post_icon_and_info_color_detail">"Áp dụng cho: Biểu tượng, số điểm và số lượng bình luận trong bài đăng"</string> + <string name="theme_item_comment_icon_and_info_color">"Màu biểu tượng và thông tin bình luận"</string> + <string name="theme_item_comment_icon_and_info_color_detail">"Áp dụng cho: Biểu tượng và số điểm trong bình luận"</string> + <string name="theme_item_fab_icon_color">"Màu biểu tượng nút hành động nổi"</string> + <string name="theme_item_fab_icon_color_detail">"Áp dụng cho: Biểu tượng nút hành động nổi"</string> + <string name="theme_item_send_message_icon_color">"Màu biểu tượng gửi tin nhắn"</string> + <string name="theme_item_send_message_icon_color_detail">"Áp dụng cho: Biểu tượng gửi tin nhắn riêng tư"</string> + <string name="theme_item_toolbar_primary_text_and_icon_color">"Màu văn bản chính và biểu tượng của thanh công cụ"</string> + <string name="theme_item_toolbar_primary_text_and_icon_color_detail">"Áp dụng cho: Văn bản chính và biểu tượng trong thanh công cụ"</string> + <string name="theme_item_toolbar_secondary_text_color">"Màu văn bản phụ của thanh công cụ"</string> + <string name="theme_item_toolbar_secondary_text_color_detail">"Áp dụng cho: Văn bản phụ trong thanh công cụ"</string> + <string name="theme_item_circular_progress_bar_background_color">"Màu nền thanh tiến trình hình tròn"</string> + <string name="theme_item_circular_progress_bar_background_color_detail">"Áp dụng cho: Nền của thanh tiến trình hình tròn"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background">"Màu nền của bố cục tab trong thanh công cụ được mở rộng"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background_detail">"Áp dụng cho: Nền bố cục tab (thanh công cụ được mở rộng)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color">"Màu văn bản của bố cục tab trong thanh công cụ được mở rộng"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color_detail">"Áp dụng cho: Màu văn bản bố cục tab (thanh công cụ được mở rộng)"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator">"Màu dấu chỉ thị tab của bố cục tab trong thanh công cụ được mở rộng"</string> + <string name="theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator_detail">"Áp dụng cho: Màu dấu chỉ thị tab trong bố cục tab (thanh công cụ được mở rộng)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background">"Màu nền của bố cục tab trong thanh công cụ được thu gọn"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background_detail">"Áp dụng cho: Nền bố cục tab (thanh công cụ được thu gọn)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color">"Màu văn bản của bố cục tab trong thanh công cụ được thu gọn"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color_detail">"Áp dụng cho: Màu văn bản bố cục tab (thanh công cụ được thu gọn)"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator">"Màu dấu chỉ thị tab của bố cục tab trong thanh công cụ được thu gọn"</string> + <string name="theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator_detail">"Áp dụng cho: Màu dấu chỉ thị tab trong bố cục tab (thanh công cụ được thu gọn)"</string> + <string name="theme_item_upvoted_color">"Màu đã upvote"</string> + <string name="theme_item_upvoted_color_detail">"Áp dụng cho: Nút và số điểm vote (đã upvote)"</string> + <string name="theme_item_downvoted_color">"Màu đã downvote"</string> + <string name="theme_item_downvoted_color_detail">"Áp dụng cho: Nút và số điểm vote (đã downvote)"</string> + <string name="theme_item_post_type_background_color">"Màu nền loại bài đăng"</string> + <string name="theme_item_post_type_background_color_detail">"Áp dụng cho: Nền của loại bài đăng (HÌNH ẢNH, VĂN BẢN, VIDEO, GIF, LIÊN KẾT)"</string> + <string name="theme_item_post_type_text_color">"Màu văn bản loại bài đăng"</string> + <string name="theme_item_post_type_text_color_detail">"Áp dụng cho: Màu văn bản của loại bài đăng (HÌNH ẢNH, VĂN BẢN, VIDEO, GIF, LIÊN KẾT)"</string> + <string name="theme_item_spoiler_background_color">"Màu nền spoiler"</string> + <string name="theme_item_spoiler_background_color_detail">"Áp dụng cho: Nền của thẻ spoiler"</string> + <string name="theme_item_spoiler_text_color">"Màu văn bản spoiler"</string> + <string name="theme_item_spoiler_text_color_detail">"Áp dụng cho: Màu văn bản trong thẻ spoiler"</string> + <string name="theme_item_nsfw_background_color">"Màu nền NSFW"</string> + <string name="theme_item_nsfw_background_color_detail">"Áp dụng cho: Nền của thẻ NSFW"</string> + <string name="theme_item_nsfw_text_color">"Màu văn bản NSFW"</string> + <string name="theme_item_nsfw_text_color_detail">"Áp dụng cho: Màu văn bản của thẻ NSFW"</string> + <string name="theme_item_flair_background_color">"Màu nền tư cách"</string> + <string name="theme_item_flair_background_color_detail">"Áp dụng cho: Nền của thẻ tư cách"</string> + <string name="theme_item_flair_text_color">"Màu văn bản tư cách"</string> + <string name="theme_item_flair_text_color_detail">"Áp dụng cho: Màu văn bản của thẻ tư cách"</string> + <string name="theme_item_awards_background_color">"Màu nền giải thưởng"</string> + <string name="theme_item_awards_background_color_detail">"Áp dụng cho: Nền của thẻ giải thưởng"</string> + <string name="theme_item_awards_text_color">"Màu văn bản giải thưởng"</string> + <string name="theme_item_awards_text_color_detail">"Áp dụng cho: Màu văn bản của thẻ giải thưởng"</string> + <string name="theme_item_archived_tint">"Màu biểu tượng đã lưu trữ"</string> + <string name="theme_item_archived_tint_detail">"Áp dụng cho: Biểu tượng đã lưu trữ"</string> + <string name="theme_item_locked_icon_tint">"Màu biểu tượng đã khoá"</string> + <string name="theme_item_locked_icon_tint_detail">"Áp dụng cho: Biểu tượng đã khoá"</string> + <string name="theme_item_crosspost_icon_tint">"Màu biểu tượng đăng chéo"</string> + <string name="theme_item_crosspost_icon_tint_detail">"Áp dụng cho: Biểu tượng đăng chéo"</string> + <string name="theme_item_stickied_post_icon_tint">"Màu biểu tượng bài đăng được ghim"</string> + <string name="theme_item_stickied_post_icon_tint_detail">"Áp dụng cho: Biểu tượng bài đăng được ghim"</string> + <string name="theme_item_subscribed_color">"Đã đăng ký"</string> + <string name="theme_item_subscribed_color_detail">"Áp dụng cho: Nút huỷ đăng ký"</string> + <string name="theme_item_unsubscribed_color">"Chưa đăng ký"</string> + <string name="theme_item_unsubscribed_color_detail">"Áp dụng cho: Nút đăng ký"</string> + <string name="theme_item_username_color">"Màu tên người dùng"</string> + <string name="theme_item_username_color_detail">"Áp dụng cho: Tên người dùng"</string> + <string name="theme_item_subreddit_color">"Màu subreddit"</string> + <string name="theme_item_subreddit_color_detail">"Áp dụng cho: Tên subreddit"</string> + <string name="theme_item_author_flair_text_color">"Màu tư cách tác giả"</string> + <string name="theme_item_author_flair_text_color_detail">"Áp dụng cho: Tư cách tác giả trong mục bình luận"</string> + <string name="theme_item_submitter_color">"Người gửi"</string> + <string name="theme_item_submitter_color_detail">"Áp dụng cho: Người gửi trong mục bình luận"</string> + <string name="theme_item_moderator_color">"Người điều hành"</string> + <string name="theme_item_moderator_color_detail">"Áp dụng cho: Người điều hành trong mục bình luận"</string> + <string name="theme_item_single_comment_thread_background_color">"Màu nền thread bình luận đơn"</string> + <string name="theme_item_single_comment_thread_background_color_detail">"Áp dụng cho: Bình luận đơn"</string> + <string name="theme_item_unread_message_background_color">"Màu nền tin nhắn chưa đọc"</string> + <string name="theme_item_unread_message_background_color_detail">"Áp dụng cho: Màu nền tin nhắn chưa đọc"</string> + <string name="theme_item_divider_color">"Màu chia tách"</string> + <string name="theme_item_divider_color_detail">"Áp dụng cho: Chia tách bình luận, chia tách trong các trang để gửi bài đăng, v.v."</string> + <string name="theme_item_vote_and_reply_unavailable_button_color">"Màu nút Vote và Trả lời không có sẵn"</string> + <string name="theme_item_vote_and_reply_unavailable_button_color_detail">"Áp dụng cho: Các nút vote và trả lời (không có sẵn)"</string> + <string name="theme_item_comment_vertical_bar_color_1">"Màu thanh bình luận dọc 1"</string> + <string name="theme_item_comment_vertical_bar_color_1_detail">"Áp dụng cho: Thanh bình luận dọc (Cấp 1)"</string> + <string name="theme_item_comment_vertical_bar_color_2">"Màu thanh bình luận dọc 2"</string> + <string name="theme_item_comment_vertical_bar_color_2_detail">"Áp dụng cho: Thanh bình luận dọc (Cấp 2)"</string> + <string name="theme_item_comment_vertical_bar_color_3">"Màu thanh bình luận dọc 3"</string> + <string name="theme_item_comment_vertical_bar_color_3_detail">"Áp dụng cho: Thanh bình luận dọc (Cấp 3)"</string> + <string name="theme_item_comment_vertical_bar_color_4">"Màu thanh bình luận dọc 4"</string> + <string name="theme_item_comment_vertical_bar_color_4_detail">"Áp dụng cho: Thanh bình luận dọc (Cấp 4)"</string> + <string name="theme_item_comment_vertical_bar_color_5">"Màu thanh bình luận dọc 5"</string> + <string name="theme_item_comment_vertical_bar_color_5_detail">"Áp dụng cho: Thanh bình luận dọc (Cấp 5)"</string> + <string name="theme_item_comment_vertical_bar_color_6">"Màu thanh bình luận dọc 6"</string> + <string name="theme_item_comment_vertical_bar_color_6_detail">"Áp dụng cho: Thanh bình luận dọc (Cấp 6)"</string> + <string name="theme_item_comment_vertical_bar_color_7">"Màu thanh bình luận dọc 7"</string> + <string name="theme_item_comment_vertical_bar_color_7_detail">"Áp dụng cho: Thanh bình luận dọc (Cấp 7)"</string> + <string name="theme_item_nav_bar_color">"Màu thanh điều hướng"</string> + <string name="theme_item_nav_bar_color_detail">"Áp dụng cho: Thanh điều hướng"</string> + <string name="theme_item_light_status_bar">"Màu biểu tượng thanh trạng thái tối"</string> + <string name="theme_item_light_nav_bar">"Màu biểu tượng thanh điều hướng tối"</string> + <string name="theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface">"Thay đổi màu biểu tượng thanh trạng thái sau khi thu gọn thanh công cụ trong chế độ giao diện đắm mình"</string> + <string name="theme_item_available_on_android_8">"Chỉ có sẵn cho Android 8.0 hoặc cao hơn."</string> + <string name="theme_item_available_on_android_6">"Chỉ có sẵn cho Android 6.0 hoặc cao hơn."</string> + <string name="predefined_themes">"Chủ đề có sẵn từ trước"</string> + <string name="user_themes">"Chủ đề của bạn"</string> + <string name="no_theme_name">"Tên chủ đề này là gì?"</string> + <string name="theme_name_hint">"Tên chủ đề"</string> + <string name="theme_name_indigo">"Chàm"</string> + <string name="theme_name_indigo_dark">"Chàm Tối"</string> + <string name="theme_name_indigo_amoled">"Chàm Amoled"</string> + <string name="theme_name_white">"Trắng"</string> + <string name="theme_name_white_dark">"Trắng Tối"</string> + <string name="theme_name_white_amoled">"Trắng Amoled"</string> + <string name="theme_name_red">"Đỏ"</string> + <string name="theme_name_red_dark">"Đỏ Tối"</string> + <string name="theme_name_red_amoled">"Đỏ Amoled"</string> + <string name="theme_name_dracula">"Dracula"</string> + <string name="theme_name_calm_pastel">"Màu phấn tĩnh lặng"</string> + <string name="create_light_theme">"Tạo một chủ đề sáng +Dựa trên chủ đề Chàm"</string> + <string name="create_dark_theme">"Tạo một chủ đề tối +Dựa trên chủ đề Chàm Tối"</string> + <string name="create_amoled_theme">"Tạo một chủ đề Amoled +Dựa trên chủ đề Chàm Amoled"</string> + <string name="create_theme_info">"Nếu bạn muốn tạo một chủ đề dựa trên một chủ đề khác, hãy nhấn nút \"+\" trên một chủ đề."</string> + <string name="edit_theme_name">"Sửa tên chủ đề"</string> + <string name="edit_theme">"Sửa chủ đề"</string> + <string name="delete_theme">"Xoá chủ đề"</string> + <string name="delete_theme_dialog_message">"Bạn có chắc muốn xoá %1$s không?"</string> + <string name="share_theme">"Chia sẻ chủ đề"</string> + <string name="change_theme_name">"Đổi tên"</string> + <string name="theme_copied">"Đã sao chép! Hãy dán và chia sẻ nó với những người khác."</string> + <string name="copy_theme_faied">"Không thể sao chép thiết lập chủ đề"</string> + <string name="cannot_find_theme">"Không thể tìm thấy chủ đề này"</string> + <string name="import_theme">"Nhập chủ đề"</string> + <string name="no_data_in_clipboard">"Không thể tìm thấy dữ liệu trong bộ nhớ tạm"</string> + <string name="import_theme_success">"Nhập chủ đề thành công"</string> + <string name="parse_theme_failed">"Phân tích chủ đề thất bại"</string> + <string name="duplicate_theme_name_dialog_title">"Đã tìm thấy chủ đề bản sao"</string> + <string name="duplicate_theme_name_dialog_message">"Một chủ đề trong cơ sở dữ liệu cũng được gọi là %1$s. Bạn có muốn đổi tên của chủ đề được nhập không?"</string> + <string name="rename">"Đổi tên"</string> + <string name="override">"Ghi đè"</string> + <string name="color_picker">"Trình chọn màu"</string> + <string name="invalid_color">"Màu không hợp lệ"</string> + <string name="delete_all_subreddits_success">"Xoá tất cả subreddit thành công"</string> + <string name="delete_all_users_success">"Xoá tất cả người dùng thành công"</string> + <string name="delete_all_sort_types_success">"Xoá tất cả loại sắp xếp thành công"</string> + <string name="delete_all_post_layouts_success">"Xoá tất cả bố cục bài đăng thành công"</string> + <string name="delete_all_themes_success">"Xoá tất cả chủ đề thành công"</string> + <string name="delete_all_front_page_scrolled_positions_success">"Xoá tất cả vị trí đã cuộn trong trang chính thành công"</string> + <string name="reset_all_settings_success">"Đặt lại tất cả cài đặt thành công"</string> + <string name="username_preview">"u/Hostilenemy"</string> + <string name="subreddit_preview">"r/Infinity_For_Reddit"</string> + <string name="primary_text_preview">"Văn bản chính"</string> + <string name="secondary_text_preview">"Văn bản phụ"</string> + <string name="post_title_preview">"Đây là một bài đăng"</string> + <string name="post_content_preview">"Chuyện cười về trọng lực này đang trở nên hơi cũ rồi, nhưng mọi lần tôi đều thấy buồn cười."</string> + <string name="post_type_preview">"BÀI ĐĂNG"</string> + <string name="flair_preview">"Tư cách"</string> + <string name="awards_preview">"4 giải thưởng"</string> + <string name="author_flair_preview">"Tư cách tác giả"</string> + <string name="comment_content_preview">"Tôi đã mua cho bạn gái một tấm thẻ \"Hãy sớm khá hơn\". +Cô ta không ốm hay gì cả, nhưng cô ấy chắc chắn có thể khá hơn."</string> + <string name="edit_multi_reddit">"Sửa Multireddit"</string> + <string name="delete_multi_reddit">"Xoá Multireddit"</string> + <string name="n_awards">"%1$d giải thưởng"</string> + <string name="one_award">"1 giải thưởng"</string> + <string name="report">"Báo cáo"</string> + <string name="reporting">"Đang báo cáo"</string> + <string name="report_successful">"Đã báo cáo"</string> + <string name="report_failed">"Báo cáo thất bại"</string> + <string name="report_reason_not_selected">"Bạn chưa chọn lý do"</string> + <string name="report_reason_general_spam">"Nó là spam"</string> + <string name="report_reason_general_copyright_issue">"Nó chứa vấn đề bản quyền"</string> + <string name="report_reason_general_child_pornography">"Nó chứa porn trẻ em"</string> + <string name="report_reason_general_abusive_content">"Nó chứa nội dung lạm dụng"</string> + <string name="home">"Trang chủ"</string> + <string name="popular">"Phổ biến"</string> + <string name="notifications">"Thông báo"</string> + <string name="messages">"Tin nhắn"</string> + <string name="message">"Tin nhắn"</string> + <string name="fetch_gfycat_video_failed">"Lấy video Gfycat thất bại"</string> + <string name="fetch_redgifs_video_failed">"Lấy video Redgifs thất bại"</string> + <string name="fetching_video_info_please_wait">"Đang lấy thông tin video. Vui lòng đợi."</string> + <string name="error_fetching_imgur_media">"Không thể tải hình ảnh"</string> + <string name="downloading_reddit_video">"Đang tải xuống bài video"</string> + <string name="downloading_reddit_video_audio_track">"Đang tải xuống bài âm thanh"</string> + <string name="downloading_reddit_video_muxing">"Đang pha trộn video và âm thanh"</string> + <string name="downloading_reddit_video_save_file_to_public_dir">"Đang lưu video"</string> + <string name="downloading_reddit_video_finished">"Đã tải xuống"</string> + <string name="downloading_reddit_video_failed_cannot_get_cache_directory">"Tải xuống thất bại: không thể truy cập thư mục bộ nhớ đệm"</string> + <string name="downloading_reddit_video_failed_cannot_download_video">"Tải xuống thất bại: không thể tải xuống video"</string> + <string name="downloading_reddit_video_failed_cannot_save_video">"Tải xuống thất bại: không thể lưu video vào thư mục bộ nhớ đệm"</string> + <string name="downloading_reddit_video_failed_cannot_save_audio">"Tải xuống thất bại: không thể lưu âm thanh vào thư mục bộ nhớ đệm"</string> + <string name="downloading_reddit_video_failed_cannot_mux">"Tải xuống thất bại: không thể pha trộn video và âm thanh"</string> + <string name="downloading_reddit_video_failed_cannot_save_mux_video">"Tải xuống thất bại: không thể lưu video vào thư mục công khai"</string> + <string name="wallpaper_set">"Hình nền đã được đặt"</string> + <string name="error_set_wallpaper">"Không thể đặt hình nền"</string> + <string name="set_to_home_screen">"Đặt làm màn hình chính"</string> + <string name="set_to_lock_screen">"Đặt làm màn hình khoá"</string> + <string name="set_to_both">"Đặt làm cả hai"</string> + <string name="default_font_font_preview">"Mặc định"</string> + <string name="load_video_in_redgifs">"Thử tải video trên Redgifs"</string> + <string name="top_score">"%1$s điểm"</string> + <string name="login_activity_2fa_prompt">"Nếu bạn đã bật xác thực 2 yếu tố, hãy vui lòng nhập mật khẩu như sau: <mật khẩu>:<mã 2FA>. +Ví dụ: yourpass:123456"</string> + <string name="block_user">"Chặn người dùng"</string> + <string name="block_user_success">"Đã chặn"</string> + <string name="block_user_failed">"Chặn người dùng thất bại"</string> + <string name="submit_crosspost_activity_label">"Đăng chéo"</string> + <string name="give_award_activity_label">"Cho giải thưởng"</string> + <string name="action_crosspost">"Đăng chéo"</string> + <string name="action_select_user_flair">"Chọn tư cách người dùng"</string> + <string name="action_give_award">"Cho giải thưởng"</string> + <string name="posts">"Bài đăng"</string> + <string name="sidebar">"Thanh bên"</string> + <string name="only_for_logged_in_user">"Chỉ cho người dùng đã đăng nhập"</string> + <string name="settings_number_of_columns_in_post_feed_title">"Số lượng cột trong nguồn dữ liệu bài đăng"</string> + <string name="settings_number_of_columns_in_post_feed_portrait_title">"Dọc"</string> + <string name="settings_number_of_columns_in_post_feed_landscape_title">"Ngang"</string> + <string name="settings_nsfw_and_spoiler_title">"NSFW & Spoiler"</string> + <string name="settings_delete_all_legacy_settings_title">"Xoá tất cả cài đặt cũ"</string> + <string name="restart_app_see_changes">"Khởi động lại ứng dụng để thấy các thay đổi"</string> + <string name="settings_tab_count">"Số tab"</string> + <string name="settings_show_tab_names">"Hiện tên tab"</string> + <string name="settings_more_tabs_summary">"Nhiều tab hơn"</string> + <string name="settings_more_tabs_info_summary">"Việc bật các tuỳ chọn sau sẽ gây ra một hành vi ngoài ý muốn: +Các tab có thể sẽ mất tất cả nội dung sau khi chuyển sang các tab khác. Điều này cũng giống như tải lại trang."</string> + <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">"Hiện subreddit yêu thích đã đăng ký"</string> + <string name="settings_more_tabs_show_subscribed_subreddits_title">"Hiện subreddit đã đăng ký"</string> + <string name="settings_download_location_title">"Vị trí tải xuống"</string> + <string name="settings_image_download_location_title">"Vị trí tải xuống hình ảnh"</string> + <string name="settings_gif_download_location_title">"Vị trí tải xuống Gif"</string> + <string name="settings_video_download_location_title">"Vị trí tải xuống video"</string> + <string name="settings_separate_folder_for_each_subreddit">"Thư mục riêng cho mỗi subreddit"</string> + <string name="settings_swipe_action_title">"Hành động vuốt"</string> + <string name="settings_disable_swiping_between_tabs_title">"Tắt vuốt giữa các tab"</string> + <string name="settings_enable_swipe_action_title">"Bật hành động vuốt"</string> + <string name="settings_swipe_action_threshold">"Ngưỡng"</string> + <string name="settings_pull_to_refresh_title">"Kéo để làm mới"</string> + <string name="settings_security_title">"Bảo mật"</string> + <string name="settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title">"Yêu cầu xác thực để đi đến khu vực Tài khoản trong ngăn điều hướng"</string> + <string name="settings_long_press_to_hide_toolbar_in_compact_layout_title">"Nhấn giữ để ẩn thanh công cụ"</string> + <string name="settings_post_compact_layout_toolbar_hidden_by_default_title">"Ẩn thanh công cụ theo mặc định"</string> + <string name="settings_customize_bottom_app_bar_title">"Tuỳ biến thanh điều hướng ở dưới cùng"</string> + <string name="settings_main_activity_bottom_app_bar_group_summary">"Trang chính"</string> + <string name="settings_other_activities_bottom_app_bar_group_summary">"Các trang khác"</string> + <string name="settings_bottom_app_bar_option_count">"Số tuỳ chọn"</string> + <string name="settings_bottom_app_bar_option_1">"Tuỳ chọn 1"</string> + <string name="settings_bottom_app_bar_option_2">"Tuỳ chọn 2"</string> + <string name="settings_bottom_app_bar_option_3">"Tuỳ chọn 3"</string> + <string name="settings_bottom_app_bar_option_4">"Tuỳ chọn 4"</string> + <string name="settings_bottom_app_bar_fab">"Nút hành động nổi"</string> + <string name="settings_data_saving_mode">"Chế độ tiết kiệm dữ liệu"</string> + <string name="settings_data_saving_mode_info_summary">"Trong chế độ tiết kiệm dữ liệu: +Các hình ảnh xem trước có độ phân giải thấp hơn. +Các video của Reddit có độ phân giải thấp hơn. +Tự động phát video bị tắt."</string> + <string name="settings_translation_title">"Phiên dịch"</string> + <string name="settings_translation_summary">"Phiên dịch ứng dụng này trên POEditor. Cảm ơn tất cả người đóng góp."</string> + <string name="settings_credits_national_flags">"Cờ quốc gia"</string> + <string name="settings_credits_national_flags_summary">"Biểu tượng được tạo bởi Freepik từ www.flaticon.com"</string> + <string name="copy_failed">"Sao chép thất bại"</string> + <string name="delete_all_legacy_settings_success">"Xoá tất cả cài đặt cũ thành công"</string> + <string name="downloading_media_finished">"Đã tải xuống"</string> + <string name="downloading_image_or_gif_failed_cannot_get_destination_directory">"Tải xuống thất bại: không thể truy cập thư mục đích"</string> + <string name="downloading_media_failed_cannot_download_media">"Tải xuống thất bại"</string> + <string name="downloading_media_failed_cannot_save_to_destination_directory">"Tải xuống thất bại: không thể lưu tệp vào thư mục đích"</string> + <string name="view_full_comment_markdown">"Xem Markdown đầy đủ"</string> + <string name="select_user_flair_success">"Tư cách người dùng đã được chọn"</string> + <string name="select_this_user_flair">"Chọn tư cách người dùng này?"</string> + <string name="select_header_size">"Chọn kích thước tiêu đề"</string> + <string name="large">"Lớn"</string> + <string name="small">"Nhỏ"</string> + <string name="insert_link">"Chèn liên kết"</string> + <string name="text_hint">"Văn bản"</string> + <string name="link_hint">"Liên kết"</string> + <string name="unlock_account_section">"Mở khoá khu vực Tài khoản"</string> + <string name="unlock">"Mở khoá"</string> + <string name="submit_post">"Gửi bài đăng"</string> + <string name="refresh">"Làm mới"</string> + <string name="change_sort_type">"Thay đổi loại sắp xếp"</string> + <string name="change_post_layout">"Thay đổi bố cục bài đăng"</string> + <string name="give_award_dialog_title">"Cho giải thưởng?"</string> + <string name="anonymous">"Vô danh"</string> + <string name="give_award_error_message">"Mã: %1$d/ +Thông báo: %2$s"</string> + <string name="give_award_success">"Giải thưởng đã được cho"</string> + <string name="give_award_failed">"Thất bại"</string> + <string name="warning">"Cảnh báo"</string> + <string name="this_is_a_nsfw_subreddit">"Đây là một subreddit NSFW."</string> + <string name="this_user_has_nsfw_content">"Người dùng này có nội dung NSFW"</string> + <string name="dismiss">"Bỏ qua"</string> + <string name="leave">"Rời khỏi"</string> + <string name="go_to_subreddit">"Đi đến subreddit"</string> + <string name="go_to_user">"Đi đến người dùng"</string> + <string name="go_to_thing_hint">"Tên"</string> + <string name="random">"Ngẫu nhiên"</string> + <string name="random_subreddit">"Subreddit ngẫu nhiên"</string> + <string name="random_nsfw_subreddit">"Subreddit NSFW ngẫu nhiên"</string> + <string name="random_post">"Bài đăng ngẫu nhiên"</string> + <string name="random_nsfw_post">"Bài đăng NSFW ngẫu nhiên"</string> + <string name="fetch_random_thing_failed">"Hãy thử lại sau"</string> + <string name="downloading">"Đang tải xuống"</string> + <string name="subreddit_filter_popular_and_all_activity_label">"r/all và r/popular"</string> + <string name="settings_miscellaneous_title">"Khác"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_title">"Tôn trọng loại sắp xếp bình luận được subreddit khuyên dùng"</string> + <string name="settings_respect_subreddit_recommended_comment_sort_type_summary">"Loại sắp xếp bình luận sẽ không được lưu"</string> + <string name="settings_subreddit_filter_category">"Ẩn subreddit"</string> + <string name="settings_subreddit_filter_popular_and_all">"Trong r/popular và r/all"</string> + <string name="settings_credits_ufo_capturing_animation_title">"Hoạt ảnh UFO đang bắt lấy"</string> + <string name="select_video_quality">"Chọn chất lượng video"</string> + <string name="settings_swipe_action_haptic_feedback_title">"Phản hồi xúc giác"</string> + <string name="settings_hide_subreddit_description_title">"Ẩn mô tả subreddit"</string> + <string name="settings_disable_image_preview_title">"Tắt xem trước hình ảnh trong chế độ tiết kiệm dữ liệu"</string> + <string name="settings_swipe_action_swipe_left_title">"Vuốt trái"</string> + <string name="settings_swipe_action_swipe_right_title">"Vuốt phải"</string> + <string name="settings_swipe_action_info_summary">"Không áp dụng cho nguồn dữ liệu bài đăng có nhiều hơn 1 cột hoặc chi tiết bài đăng."</string> + <string name="theme_item_no_preview_post_type_icon_tint">"Màu biểu tượng loại bài đăng không có xem trước"</string> + <string name="theme_item_no_preview_post_type_icon_tint_detail">"Áp dụng cho: Biểu tượng chỉ ra loại bài đăng khi không có xem trước"</string> + <string name="theme_item_no_preview_post_type_background_color">"Màu nền loại bài đăng không có xem trước"</string> + <string name="theme_item_no_preview_post_type_background_color_detail">"Áp dụng cho: Chỗ giữ chỗ chỉ ra loại bài đăng khi không có xem trước"</string> + <string name="settings_language_title">"Ngôn ngữ"</string> + <string name="customize_post_filter_activity_label">"Tuỳ chỉnh bộ lọc bài đăng"</string> + <string name="filtered_posts_activity_subtitle">"Bài đăng được lọc"</string> + <string name="post_filter_preference_activity_label">"Bộ lọc bài đăng"</string> + <string name="search_users_result_activity_label">"Người dùng"</string> + <string name="multireddit_selection_activity_label">"Chọn một multireddit"</string> + <string name="action_save_to_database">"Lưu vào cơ sở dữ liệu"</string> + <string name="action_read_all_messages">"Đọc tất cả tin nhắn"</string> + <string name="action_add_to_multireddit">"Thêm vào multireddit"</string> + <string name="search_only_subreddits_hint">"Tìm kiếm subreddit"</string> + <string name="search_only_users_hint">"Tìm kiếm người dùng"</string> + <string name="post_type_gif">"Gif"</string> + <string name="post_type_gallery">"Thư viện"</string> + <string name="settings_disable_immersive_interface_in_landscape_mode">"Tắt giao diện đắm mình trong chế độ xoay ngang"</string> + <string name="settings_privacy_policy_title">"Chính sách riêng tư"</string> + <string name="settings_delete_read_posts_in_database_title">"Xoá tất cả bài đăng đã đọc trong cơ sở dữ liệu"</string> + <string name="settings_post_filter_title">"Bộ lọc bài đăng"</string> + <string name="settings_only_disable_preview_in_video_and_gif_posts_title">"Chỉ tắt xem trước trong các bài đăng video và gif"</string> + <string name="settings_enable_search_history_title">"Bật lịch sử tìm kiếm"</string> + <string name="settings_post_history_title">"Lịch sử bài đăng"</string> + <string name="settings_mark_posts_as_read_title">"Đánh dấu các bài đăng là đã đọc"</string> + <string name="settings_mark_posts_as_read_after_voting_title">"Đánh dấu các bài đăng là đã đọc sau khi vote"</string> + <string name="settings_mark_posts_as_read_on_scroll_title">"Đánh dấu các bài đăng là đã đọc khi cuộn"</string> + <string name="settings_hide_read_posts_automatically_title">"Tự động ẩn các bài đăng đã đọc"</string> + <string name="settings_sort_type_title">"Loại sắp xếp"</string> + <string name="settings_save_sort_type_title">"Lưu loại sắp xếp"</string> + <string name="settings_subreddit_default_sort_type_title">"Loại sắp xếp subreddit mặc định"</string> + <string name="settings_subreddit_default_sort_time_title">"Thời gian sắp xếp subreddit mặc định"</string> + <string name="settings_user_default_sort_type_title">"Loại sắp xếp người dùng mặc định"</string> + <string name="settings_user_default_sort_time_title">"Thời gian sắp xếp người dùng mặc định"</string> + <string name="open_link">"Mở liên kết"</string> + <string name="select_subreddits_and_users">"Chọn các subreddit và người dùng"</string> + <string name="theme_item_read_post_title_color">"Màu tiêu đề bài đăng đã đọc"</string> + <string name="theme_item_read_post_title_color_detail">"Áp dụng cho: Tiêu đề bài đăng đã đọc"</string> + <string name="theme_item_read_post_content_color">"Màu nội dung bài đăng đã đọc"</string> + <string name="theme_item_read_post_content_color_detail">"Áp dụng cho: Nội dung bài đăng đã đọc"</string> + <string name="theme_item_read_post_card_view_background_color">"Màu nền hiển thị dạng thẻ cho bài đăng đã đọc"</string> + <string name="theme_item_read_post_card_view_background_color_detail">"Áp dụng cho: Nền bài đăng đã đọc"</string> + <string name="delete_all_read_posts_success">"Xoá tất cả bài đăng đã đọc thành công"</string> + <string name="hide_read_posts">"Ẩn bài đăng đã đọc"</string> + <string name="filter_posts">"Lọc bài đăng"</string> + <string name="only_nsfw">"Chỉ NSFW"</string> + <string name="only_spoiler">"Chỉ Spoiler"</string> + <string name="title_excludes_strings_hint">"Tiêu đề: loại trừ từ khoá (key1,key2)"</string> + <string name="title_excludes_regex_hint">"Tiêu đề: loại trừ biểu thức tìm kiếm"</string> + <string name="exclude_subreddits_hint">"Loại trừ subreddit (vd: funny,AskReddit)"</string> + <string name="exclude_users_hint">"Loại trừ người dùng (vd: Hostilenemy,random)"</string> + <string name="exclude_flairs_hint">"Loại trừ tư cách (vd: flair1,flair2)"</string> + <string name="contain_flairs_hint">"Chứa tư cách (vd: flair1,flair2)"</string> + <string name="min_vote_hint">"Vote tối thiểu (-1: không hạn chế)"</string> + <string name="max_vote_hint">"Vote tối đa (-1: không hạn chế)"</string> + <string name="min_comments_hint">"Bình luận tối thiểu (-1: không hạn chế)"</string> + <string name="max_comments_hint">"Bình luận tối đa (-1: không hạn chế)"</string> + <string name="min_awards_hint">"Giải thưởng tối thiểu (-1: không hạn chế)"</string> + <string name="max_awards_hint">"Giải thưởng tối đa (-1: không hạn chế)"</string> + <string name="post_filter_name_hint">"Tên bộ lọc bài đăng"</string> + <string name="post_filter_requires_a_name">"Bộ lọc bài đăng này tên là gì?"</string> + <string name="duplicate_post_filter_dialog_title">"'%1$s' đã tồn tại"</string> + <string name="duplicate_post_filter_dialog_message">"Ghi đè nó?"</string> + <string name="apply_post_filter_to">"Áp dụng vào"</string> + <string name="post_filter_usage_home">"Trang chủ"</string> + <string name="post_filter_usage_subreddit">"Subreddit: %1$s"</string> + <string name="post_filter_usage_subreddit_all">"Subreddit"</string> + <string name="post_filter_usage_user">"Người dùng: %1$s"</string> + <string name="post_filter_usage_user_all">"Người dùng"</string> + <string name="post_filter_usage_multireddit">"Multireddit: %1$s"</string> + <string name="post_filter_usage_multireddit_all">"Multireddit"</string> + <string name="post_filter_usage_search">"Tìm kiếm"</string> + <string name="subreddit">"Subreddit"</string> + <string name="user">"Người dùng"</string> + <string name="edit_post_filter_name_of_usage_info">"Để trống để áp dụng bộ lọc bài đăng này vào tất cả subreddit / người dùng / multireddit"</string> + <string name="read_all_messages_time_limit">"Bạn đang làm việc này quá thường xuyên. Hãy thử lại sau. Đây là giới hạn tốc độ của Reddit."</string> + <string name="read_all_messages_success">"Đã đọc tất cả tin nhắn thành công"</string> + <string name="read_all_messages_failed">"Không thể đọc tất cả tin nhắn"</string> + <string name="add_subreddit_or_user_to_multireddit_success">"%1$s được thêm vào multireddit %2$s"</string> + <string name="add_subreddit_or_user_to_multireddit_failed">"Không thể thêm %1$s vào multireddit %2$s"</string> + <string name="choose_a_user">"Chọn người dùng"</string> + <string name="settings_click_to_show_media_in_gallery_layout">"Nhấn để hiện phương tiện trong bố cục thư viện"</string> + <string name="settings_hide_post_type">"Ẩn loại bài đăng"</string> + <string name="settings_hide_the_number_of_awards">"Ẩn số lượng giải thưởng"</string> + <string name="settings_hide_subreddit_and_user_prefix">"Ẩn subreddit và tiền tố người dùng"</string> + <string name="settings_hide_the_number_of_votes">"Ẩn số lượng vote"</string> + <string name="settings_hide_the_number_of_comments">"Ẩn số lượng bình luận"</string> + <string name="post_layout_gallery">"Bố cục thư viện"</string> + <string name="post_layout_card_2">"Bố cục thẻ 2"</string> + <string name="have_trouble_login_title">"Đang gặp rắc rối khi đăng nhập"</string> + <string name="have_trouble_login_message">"Bạn có muốn thử một cách khác để đăng nhập không?"</string> + <string name="vote">"Vote"</string> + <string name="action_share_link">"Chia sẻ liên kết"</string> + <string name="action_copy_link">"Sao chép liên kết"</string> + <string name="action_add_to_post_filter">"Thêm vào bộ lọc bài đăng"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"Không làm mờ các hình ảnh NSFW trong các subreddit NSFW"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"Hiện ảnh đại diện ở bên trái"</string> + <string name="settings_backup_settings_title">"Sao lưu cài đặt"</string> + <string name="settings_restore_settings_title">"Khôi phục cài đặt"</string> + <string name="settings_credits_love_animation_title">"Hoạt ảnh yêu"</string> + <string name="settings_swipe_between_posts_title">"Vuốt giữa các bài đăng"</string> + <string name="settings_navigation_drawer_title">"Ngăn điều hướng"</string> + <string name="settings_collapse_account_section_title">"Thu gọn khu vực tài khoản"</string> + <string name="settings_collapse_post_section_title">"Thu gọn khu vực bài đăng"</string> + <string name="settings_collapse_preferences_section_title">"Thu gọn khu vực cài đặt"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"Thu gọn khu vực subreddit yêu thích"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"Thu gọn khu vực subreddit đã đăng ký"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"Ẩn khu vực subreddit yêu thích"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"Ẩn khu vực subreddit đã đăng ký"</string> + <string name="settings_default_search_result_tab">"Tab kết quả tìm kiếm mặc định"</string> + <string name="device_default">"Mặc định thiết bị"</string> + <string name="set_by_battery_saver">"Được Trình tiết kiệm pin đặt"</string> + <string name="theme_item_upvote_ratio_icon_tint">"Màu biểu tượng tỉ lệ upvote"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"Đã áp dụng cho: Biểu tượng tỉ lệ upvote"</string> + <string name="theme_item_current_user_color">"Người dùng hiện tại"</string> + <string name="theme_item_current_user_color_detail">"Đã áp dụng vào: Người dùng hiện tại trong bình luận"</string> + <string name="exclude_domains_hint">"Loại trừ các miền"</string> + <string name="anonymous_front_page_no_subscriptions">"Hãy bắt đầu bằng cách tham gia một subreddit!"</string> + <string name="backup_settings_success">"Xuất cài đặt ra thư mục đích thành công. Mật khẩu của tệp zip được tạo ra là 123321. Vui lòng đừng sửa đổi tệp zip đó."</string> + <string name="create_zip_in_destination_directory_failed">"Không thể tạo tệp zip sao lưu trong thư mục đích"</string> + <string name="backup_some_settings_failed">"Không thể sao lưu một số cài đặt nhưng các cài đặt khác đã được xuất ra thư mục đích thành công"</string> + <string name="restore_settings_success">"Khôi phục cài đặt thành công. Hãy khởi động lại ứng dụng để thấy các thay đổi."</string> + <string name="restore_settings_partially_failed">"Một số cài đặt có thể không được khôi phục thành công. Hãy khởi động lại ứng dụng để thấy các thay đổi."</string> + <string name="restore_settings_failed_file_corrupted">"Không thể khôi phục cài đặt. Tệp này có thể là bị hỏng."</string> + <string name="restore_settings_failed_cannot_get_file">"Không thể truy cập tệp"</string> + <string name="suicide_prevention_quote">"Nếu bạn đang tìm một dấu hiệu để không tự tử, thì nó ở đây rồi.\u2764"</string> + <string name="do_not_show_this_again">"Không hiện lại"</string> + <string name="continue_suicide_prevention_activity">"Tiếp tục"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"Lỗi khi lấy video v.redd.it: Không thể lấy URL chuyển hướng"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"Lỗi khi lấy video v.redd.it: Không thể lấy bài đăng"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"Lỗi khi lấy video v.redd.it: Không thể lấy ID bài đăng"</string> + <string name="always_on">"Luôn bật"</string> + <string name="only_on_wifi">"Chỉ khi có Wifi"</string> + <string name="never">"Không bao giờ"</string> + <string name="normal">"Bình thường"</string> + <string name="extra_large">"Rất lớn"</string> + <string name="enormously_large">"Khổng lồ"</string> + <string name="default_in_array">"Mặc định"</string> + <string name="off">"Tắt"</string> + <string name="only_on_cellular_data">"Chỉ khi có dữ liệu di động"</string> + <string name="upvote">"Upvote"</string> + <string name="downvote">"Downvote"</string> + <string name="select">"Chọn"</string> + <string name="exclude_subreddit">"Loại trừ subreddit này"</string> + <string name="exclude_user">"Loại trừ người dùng này"</string> + <string name="exclude_flair">"Loại trừ tư cách này"</string> + <string name="contain_flair">"Chứa tư cách này"</string> + <string name="exclude_domain">"Loại trừ miền"</string> + <string name="suggest_title">"Đề xuất tiêu đề"</string> + <string name="suggest_title_failed">"Đề xuất tiêu đề thất bại"</string> + <string name="action_delete_logs">"Xoá nhật ký"</string> + <string name="inbox_with_count">"Hộp thư đến (%1$d)"</string> + <string name="comment_continue_thread">"Tiếp tục thread"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"Vuốt dọc để quay lại từ phương tiện"</string> + <string name="settings_hide_post_flair">"Ẩn tư cách bài đăng"</string> + <string name="settings_crash_reports_title">"Báo cáo dừng đột ngột"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"Nguy hiểm"</string> + <string name="settings_disable_nsfw_forever_title">"Tắt NSFW mãi mãi"</string> + <string name="settings_show_only_one_comment_level_indicator">"Hiện chỉ một dấu chỉ thị cấp bình luận"</string> + <string name="save_comment">"Lưu"</string> + <string name="unsave_comment">"Huỷ lưu"</string> + <string name="copy_multi_reddit_path">"Sao chép đường dẫn của multireddit"</string> + <string name="copy_multi_reddit_path_failed">"Không thể sao chép đường dẫn của multireddit"</string> + <string name="crash_reports_deleted">"Các báo cáo lỗi đã bị xoá"</string> + <string name="disable_nsfw_forever_message">"Khi được bật, NSFW sẽ bị tắt vĩnh viễn, không kể là cài đặt NSFW có được bật hay không. Và tuỳ chọn này là không thể hoàn tác, cách duy nhất để bật lại NSFW là xoá dữ liệu ứng dụng. + +Bạn có vẫn muốn bật tuỳ chọn này không?"</string> + <string name="reply">"Trả lời"</string> +</resources>
\ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a7255952..d6cc39dd 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -94,7 +94,7 @@ %1$d (%2$d + %3$d)"</string> <string name="cakeday_info">"注册日: %1$s"</string> - <string name="since">"自从:"</string> + <string name="since">"创建于:"</string> <string name="profile">"档案"</string> <string name="subscriptions">"订阅"</string> <string name="multi_reddit">"聚合版块"</string> @@ -153,7 +153,7 @@ <string name="title_required">"帖子需要有标题"</string> <string name="link_required">"嘿!链接在哪呢?"</string> <string name="select_an_image">"请先选择一张图片"</string> - <string name="posting">"发表中"</string> + <string name="posting">"发布中"</string> <string name="post_failed">"无法发表"</string> <string name="error_processing_image">"处理图片错误"</string> <string name="error_processing_video">"处理视频错误"</string> @@ -227,10 +227,12 @@ <string name="gallery">"相册"</string> <string name="best">"精选"</string> <string name="search">"搜索"</string> - <string name="posting_video">"视频发送中"</string> - <string name="posting_image">"图片发送中"</string> + <string name="posting_video">"视频发布中"</string> + <string name="posting_image">"图片发布中"</string> + + <!-- Fuzzy --> <string name="please_wait">"请稍等。"</string> - <string name="add_account">"添加账户"</string> + <string name="add_account">"添加帐户"</string> <string name="anonymous_account">"匿名"</string> <string name="log_out">"注销"</string> <string name="press_here_to_login">"点此登录"</string> @@ -273,15 +275,15 @@ <string name="edit_flair">"编辑头衔"</string> <string name="only_allow_64_chars">"只允许少于 64 个字符"</string> <string name="view_all_comments">"点此查看所有评论"</string> - <string name="notification_summary_account">"账户"</string> + <string name="notification_summary_account">"帐户"</string> <string name="notification_summary_message">"新消息"</string> <string name="notification_summary_subreddit">"版块"</string> <string name="notification_summary_award">"奖励"</string> <string name="notification_new_messages">"%1$d 条新消息"</string> - <string name="label_account">"账户"</string> + <string name="label_account">"帐户"</string> <string name="label_post">"帖子"</string> <string name="label_preferences">"偏好设置"</string> - <string name="account_switched">"账户已切换,所有其他页面已重置。"</string> + <string name="account_switched">"帐户已切换,所有其他页面已重置。"</string> <string name="settings_notification_master_title">"通知"</string> <string name="settings_notification_enable_notification_title">"开启通知"</string> <string name="settings_notification_interval_title">"检查通知的时间间隔"</string> @@ -315,6 +317,8 @@ <string name="settings_volume_keys_navigate_posts_title">"使用音量键浏览帖子"</string> <string name="settings_mute_video_title">"静音视频"</string> <string name="settings_mute_nsfw_video_title">"静音 NSFW 视频"</string> + + <!-- Fuzzy --> <string name="settings_automatically_try_redgifs_title">"如果 Gfycat 上的视频已被删除,则自动尝试访问 Redgifs。"</string> <string name="settings_video_player_ignore_nav_bar_title">"视频播放器中忽略导航栏"</string> @@ -892,7 +896,6 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd 错误信息:%2$s"</string> <string name="give_award_success">"奖励已赠送"</string> <string name="give_award_failed">"失败"</string> - <string name="recent_searches">"最近搜索"</string> <string name="warning">"警告"</string> <string name="this_is_a_nsfw_subreddit">"这是一个 NSFW 版块。"</string> <string name="this_user_has_nsfw_content">"该用户有 NSFW 内容"</string> @@ -1020,4 +1023,132 @@ https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforredd <string name="have_trouble_login_title">"登录遇到问题"</string> <string name="have_trouble_login_message">"您想尝试其他方式登录吗?"</string> <string name="vote">"投票"</string> + <string name="action_share_link">"分享链接"</string> + <string name="action_copy_link">"复制链接"</string> + <string name="action_add_to_post_filter">"添加到帖子过滤器"</string> + <string name="settings_do_not_blur_nsfw_in_nsfw_subreddits_title">"在 NSFW 版块中不模糊 NSFW 图片"</string> + + <!-- Fuzzy --> + <string name="settings_show_avatar_on_the_right">"在左侧显示头像"</string> + <string name="settings_backup_settings_title">"备份设置"</string> + <string name="settings_restore_settings_title">"恢复设置"</string> + <string name="settings_credits_love_animation_title">"喜爱动画"</string> + <string name="settings_swipe_between_posts_title">"在帖子间滑动"</string> + <string name="settings_navigation_drawer_title">"导航抽屉"</string> + <string name="settings_collapse_account_section_title">"折叠帐户区域"</string> + <string name="settings_collapse_post_section_title">"折叠帖子区域"</string> + <string name="settings_collapse_preferences_section_title">"折叠偏好区域"</string> + <string name="settings_collapse_favorite_subreddits_section_title">"折叠收藏版块区域"</string> + <string name="settings_collapse_subscribed_subreddits_section_title">"折叠订阅版块区域"</string> + <string name="settings_hide_favorite_subreddits_sections_title">"隐藏收藏版块区域"</string> + <string name="settings_hide_subscribed_subreddits_sections_title">"折叠订阅版块区域"</string> + <string name="settings_default_search_result_tab">"默认搜索结果标签页"</string> + <string name="device_default">"设备默认"</string> + <string name="set_by_battery_saver">"由省电模式设置"</string> + <string name="theme_item_upvote_ratio_icon_tint">"顶帖率图标颜色"</string> + <string name="theme_item_upvote_ratio_icon_tint_detail">"应用于:顶帖率图标"</string> + <string name="theme_item_current_user_color">"当前用户"</string> + <string name="theme_item_current_user_color_detail">"应用于:评论中的当前用户"</string> + <string name="exclude_domains_hint">"排除域名"</string> + <string name="anonymous_front_page_no_subscriptions">"立刻加入一个版块并开始浏览!"</string> + + <!-- Fuzzy --> + <string name="backup_settings_success">"成功将设置导出到目标文件夹"</string> + <string name="create_zip_in_destination_directory_failed">"无法在目标文件夹创建备份压缩包"</string> + <string name="backup_some_settings_failed">"部分设置无法备份,但其他设置已成功导出到目标文件夹"</string> + <string name="restore_settings_success">"成功恢复设置,重启应用以查看更改。"</string> + <string name="restore_settings_partially_failed">"部分设置可能未成功恢复,重启应用以查看更改。"</string> + <string name="restore_settings_failed_file_corrupted">"无法恢复设置,文件可能已损坏。"</string> + <string name="restore_settings_failed_cannot_get_file">"无法访问文件"</string> + <string name="suicide_prevention_quote">"也许世界并不美好,但还有我们在。\u2764"</string> + <string name="do_not_show_this_again">"不再显示"</string> + <string name="continue_suicide_prevention_activity">"继续"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_redirect_url">"拉取 v.redd.it 视频出错:无法获取跳转 URL"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post">"拉取 v.redd.it 视频出错:无法获取帖子"</string> + <string name="error_fetching_v_redd_it_video_cannot_get_post_id">"拉取 v.redd.it 视频出错:无法获取帖子 ID"</string> + <string name="always_on">"总是打开"</string> + <string name="only_on_wifi">"仅 WiFi 下"</string> + <string name="never">"从不"</string> + <string name="normal">"普通"</string> + <string name="extra_large">"大"</string> + <string name="enormously_large">"更大"</string> + <string name="default_in_array">"默认"</string> + <string name="off">"关闭"</string> + <string name="only_on_cellular_data">"仅在蜂窝数据下"</string> + <string name="upvote">"顶"</string> + <string name="downvote">"踩"</string> + <string name="select">"选择"</string> + <string name="exclude_subreddit">"排除此版块"</string> + <string name="exclude_user">"排除此用户"</string> + <string name="exclude_flair">"排除此头衔"</string> + <string name="contain_flair">"包含此头衔"</string> + <string name="exclude_domain">"排除域名"</string> + <string name="suggest_title">"推荐标题"</string> + <string name="suggest_title_failed">"推荐标题失败"</string> + <string name="action_delete_logs">"删除日志"</string> + <string name="inbox_with_count">"收件箱 (%1$d)"</string> + <string name="comment_continue_thread">"继续帖子"</string> + + <!-- Fuzzy --> + <string name="settings_swipe_vertically_to_go_back_from_media_title">"垂直滑动离开媒体界面"</string> + <string name="settings_hide_post_flair">"隐藏帖子头衔"</string> + <string name="settings_crash_reports_title">"崩溃报告"</string> + <string name="settings_nsfw_and_spoiler_dangerous_group_title">"危险"</string> + <string name="settings_disable_nsfw_forever_title">"永久禁用 NSFW"</string> + <string name="settings_show_only_one_comment_level_indicator">"仅显示一个评论层级指示"</string> + <string name="save_comment">"保存"</string> + <string name="unsave_comment">"取消保存"</string> + <string name="copy_multi_reddit_path">"复制聚合版块路径"</string> + <string name="copy_multi_reddit_path_failed">"无法复制聚合版块路径"</string> + <string name="crash_reports_deleted">"崩溃报告已删除"</string> + <string name="disable_nsfw_forever_message">"启用此选项后,NSFW 内容将被永久禁用,无论您是否开启 NSFW 设置。除非彻底清除应用数据,否则无法撤销此选项。 + +仍然要继续吗?"</string> + <string name="reply">"回复"</string> + <string name="rpan_activity_label">"直播"</string> + <string name="post_gallery_activity_label">"相册帖"</string> + <string name="trending_activity_label">"热门"</string> + <string name="action_share_rpan_link">"分享直播链接"</string> + <string name="action_share_post_link">"分享帖子链接"</string> + <string name="rpan">"直播"</string> + <string name="trending">"热门"</string> + <string name="receive_post_reply_notifications">"接收帖子回复提醒"</string> + <string name="bottom_sheet_post_gallery">"相册"</string> + <string name="posting_gallery">"相册发布中"</string> + <string name="label_reddit">"Reddit"</string> + <string name="settings_default_link_post_layout">"默认链接帖布局"</string> + <string name="settings_category_material_you_title">"Material You"</string> + <string name="settings_enable_material_you_warning_summary">"请确保您没有以下名称的主题: +“Material You”、 +“Material You Dark”、 +“Material You Amoled”。 +否则,您需要在启用 Material You 之前先为它们重命名。"</string> + <string name="settings_enable_material_you_title">"启用 Material You"</string> + <string name="settings_enable_material_you_summary">"根据 Your Wallpaper 个性化 Infinity"</string> + <string name="settings_apply_material_you_title">"应用 Material You"</string> + <string name="settings_apply_material_you_summary">"如果 Infinity 未更改主题"</string> + <string name="settings_more_tabs_show_favorite_multireddits_title">"显示收藏的聚合版块"</string> + <string name="settings_more_tabs_show_multireddits_title">"显示聚合版块"</string> + <string name="settings_collapse_reddit_section_title">"折叠 Reddit 区域"</string> + <string name="settings_video_player_automatic_landscape_orientation">"播放视频时自动切换到横屏"</string> + <string name="settings_remember_muting_option_in_post_feed">"在帖子列表中记住静音"</string> + <string name="link_post_layout_auto">"自动"</string> + <string name="uploaded_images">"已上传图片"</string> + <string name="select_image">"选择一张图片"</string> + <string name="capture">"拍摄"</string> + <string name="uploading_image">"正在上传"</string> + <string name="upload_image_success">"上传图片成功。再次点击图片按钮查看已上传的图片。"</string> + <string name="get_image_bitmap_failed">"无法获取图片位图"</string> + <string name="upload_image_failed">"无法上传图片"</string> + <string name="load_rpan_broadcasts_failed">"无法加载 RPAN 直播"</string> + <string name="parse_rpan_broadcasts_failed">"无法解析 RPAN 直播"</string> + <string name="parse_rpan_broadcast_failed">"无法解析 RPAN 直播"</string> + <string name="search_comments">"搜索评论"</string> + <string name="please_wait_image_is_uploading">"仍有图片正在上传,请稍候。"</string> + <string name="error_fetch_trending_search">"获取热搜失败。 +点击重试。"</string> + <string name="error_parse_trending_search">"解析热搜失败。 +点击重试。"</string> + <string name="no_trending_search">"未找到热搜。 +点击重试。"</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index d662acbc..a2d77399 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -55,6 +55,22 @@ <item>2</item> </string-array> + <string-array name="settings_default_link_post_layout"> + <item>@string/link_post_layout_auto</item> + <item>@string/post_layout_card</item> + <item>@string/post_layout_card_2</item> + <item>@string/post_layout_compact</item> + <item>@string/post_layout_gallery</item> + </string-array> + + <string-array name="settings_default_link_post_layout_values"> + <item>-1</item> + <item>0</item> + <item>3</item> + <item>1</item> + <item>2</item> + </string-array> + <string-array name="settings_video_autoplay"> <item>@string/always_on</item> <item>@string/only_on_wifi</item> @@ -351,9 +367,13 @@ <item>Italiana</item> <item>日本語</item> <item>Polskie</item> + <item>Português</item> <item>Português (BR)</item> + <item>русский</item> + <item>Soomaali</item> <item>Español</item> <item>Türkçe</item> + <item>Tiếng Việt</item> </string-array> <string-array name="settings_language_values"> @@ -369,9 +389,13 @@ <item>it</item> <item>ja</item> <item>pl</item> + <item>pt</item> <item>pt-rBR</item> + <item>ru</item> + <item>so</item> <item>es</item> <item>tr-rTR</item> + <item>vi</item> </string-array> <string-array name="settings_subreddit_default_sort_type"> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f76e009a..9085c9e0 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <color name="colorPrimary">#1565C0</color> - <color name="colorPrimaryDark">#0D47A1</color> - <color name="colorAccent">#FF4081</color> + <color name="colorPrimary">#0336FF</color> + <color name="colorPrimaryDark">#002BF0</color> + <color name="colorAccent">#FF1868</color> <color name="transparentActionBarAndExoPlayerControllerColor">#88000000</color> <color name="backgroundColor">#FFFFFF</color> <color name="playButtonBackgroundColor">#000000</color> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 492d8376..a286248c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,6 +39,10 @@ <string name="post_filter_preference_activity_label">Post Filter</string> <string name="search_users_result_activity_label">Users</string> <string name="multireddit_selection_activity_label">Select a Multireddit</string> + <string name="rpan_activity_label">RPAN</string> + <string name="post_gallery_activity_label">Gallery Post</string> + <string name="trending_activity_label">Trending</string> + <string name="wiki_activity_label">Wiki</string> <string name="navigation_drawer_open">Open navigation drawer</string> <string name="navigation_drawer_close">Close navigation drawer</string> @@ -83,6 +87,8 @@ <string name="action_copy_link">Copy Link</string> <string name="action_add_to_post_filter">Add to Post Filter</string> <string name="action_delete_logs">Delete Logs</string> + <string name="action_share_rpan_link">Share RPAN Link</string> + <string name="action_share_post_link">Share Post Link</string> <string name="parse_json_response_error">Error occurred when parsing the JSON response</string> <string name="retrieve_token_error">Error Retrieving the token</string> @@ -124,6 +130,8 @@ <string name="multi_reddit">Multireddit</string> <string name="inbox">Inbox</string> <string name="inbox_with_count">Inbox (%1$d)</string> + <string name="rpan">RPAN</string> + <string name="trending">Trending</string> <string name="upvoted">Upvoted</string> <string name="downvoted">Downvoted</string> <string name="hidden">Hidden</string> @@ -202,6 +210,7 @@ <string name="choose_a_subreddit">Choose a subreddit</string> <string name="rules">Rules</string> <string name="post_link_hint">URL</string> + <string name="receive_post_reply_notifications">Receive post reply notifications</string> <string name="subreddits">Subreddits</string> <string name="users">Users</string> @@ -214,6 +223,7 @@ <string name="bottom_sheet_post_link">Link</string> <string name="bottom_sheet_post_image">Image</string> <string name="bottom_sheet_post_video">Video</string> + <string name="bottom_sheet_post_gallery">Gallery</string> <string name="post_type_gif">Gif</string> <string name="post_type_gallery">Gallery</string> @@ -281,7 +291,8 @@ <string name="posting_video">Posting Video</string> <string name="posting_image">Posting Image</string> - <string name="please_wait">Please wait.</string> + <string name="posting_gallery">Posting Gallery</string> + <string name="please_wait">Please wait</string> <string name="add_account">Add account</string> <string name="anonymous_account">Anonymous</string> @@ -337,6 +348,7 @@ <string name="notification_new_messages">%1$d New Messages</string> <string name="label_account">Account</string> + <string name="label_reddit">Reddit</string> <string name="label_post">Post</string> <string name="label_preferences">Preferences</string> @@ -390,6 +402,7 @@ <string name="settings_time_format_title">Time Format</string> <string name="settings_category_post_title">Post</string> <string name="settings_default_post_layout">Default Post Layout</string> + <string name="settings_default_link_post_layout">Default Link Post Layout</string> <string name="settings_show_divider_in_compact_layout">Show Divider</string> <string name="settings_show_thumbnail_on_the_left_in_compact_layout">Show Thumbnail on the Left</string> <string name="settings_number_of_columns_in_post_feed_title">The Number of Columns in Post Feed</string> @@ -398,6 +411,7 @@ <string name="settings_swap_tap_and_long_title">Swap Tap and Long Press in Comments</string> <string name="settings_swipe_to_go_back_title">Swipe Right to Go Back</string> <string name="settings_swipe_to_go_back_summary">Does Not Apply to All Pages</string> + <string name="settings_swipe_vertically_to_go_back_from_media_title">Swipe Vertically to Go Back From Image and Gif</string> <string name="settings_lock_jump_to_next_top_level_comment_button_title">Lock Jump to Next Top-level Comment Button</string> <string name="settings_lock_bottom_app_bar_title">Lock Bottom Navigation Bar</string> <string name="settings_swipe_up_to_hide_jump_to_next_top_level_comment_button_title">Swipe Up to Hide Jump to Next Top-level Comment Button</string> @@ -456,6 +470,12 @@ <string name="settings_customize_dark_theme_title">Dark Theme</string> <string name="settings_customize_amoled_theme_title">Amoled Theme</string> <string name="settings_manage_themes_title">Manage Themes</string> + <string name="settings_category_material_you_title">Material You</string> + <string name="settings_enable_material_you_warning_summary">Make sure you don\'t have themes named\n\"Material You\",\n\"Material You Dark\" or\n\"Material You Amoled\".\nOtherwise, rename them before enabling Material You.</string> + <string name="settings_enable_material_you_title">Enable Material You</string> + <string name="settings_enable_material_you_summary">Personalize Infinity based on Your Wallpaper</string> + <string name="settings_apply_material_you_title">Apply Material You</string> + <string name="settings_apply_material_you_summary">In case Infinity did not change the theme</string> <string name="settings_custom_theme_cannot_apply_to_settings_page_summary">Custom themes cannot be applied to settings page (except toolbar, status bar and navigation bar).</string> <string name="settings_advanced_master_title">Advanced</string> <string name="settings_delete_all_subreddits_data_in_database_title">Delete All Subreddits in Database</string> @@ -475,6 +495,8 @@ <string name="settings_tab_3_summary">Tab 3</string> <string name="settings_more_tabs_summary">More Tabs</string> <string name="settings_more_tabs_info_summary">Enabling the following options will cause an unintended behaviour:\nTabs may lose all the content after switching to others. This is the same as refreshing the page.</string> + <string name="settings_more_tabs_show_favorite_multireddits_title">Show Favorite Multireddits</string> + <string name="settings_more_tabs_show_multireddits_title">Show Multireddits</string> <string name="settings_more_tabs_show_favorite_subscribed_subreddits_title">Show Favorite Subscribed Subreddits</string> <string name="settings_more_tabs_show_subscribed_subreddits_title">Show Subscribed Subreddits</string> <string name="settings_tab_title">Title</string> @@ -541,17 +563,19 @@ <string name="settings_user_default_sort_time_title">User Default Sort Time</string> <string name="settings_click_to_show_media_in_gallery_layout">Click to Show Media in Gallery Layout</string> <string name="settings_hide_post_type">Hide Post Type</string> + <string name="settings_hide_post_flair">Hide Post Flair</string> <string name="settings_hide_the_number_of_awards">Hide the Number of Awards</string> <string name="settings_hide_subreddit_and_user_prefix">Hide Subreddit and User Prefix</string> <string name="settings_hide_the_number_of_votes">Hide the Number of Votes</string> <string name="settings_hide_the_number_of_comments">Hide the Number of Comments</string> - <string name="settings_show_avatar_on_the_right">Show Avatar on the Left</string> + <string name="settings_show_avatar_on_the_right">Show Avatar on the Right</string> <string name="settings_backup_settings_title">Backup Settings</string> <string name="settings_restore_settings_title">Restore Settings</string> <string name="settings_credits_love_animation_title">Love Animation</string> <string name="settings_swipe_between_posts_title">Swipe Between Posts</string> <string name="settings_navigation_drawer_title">Navigation Drawer</string> <string name="settings_collapse_account_section_title">Collapse Account Section</string> + <string name="settings_collapse_reddit_section_title">Collapse Reddit Section</string> <string name="settings_collapse_post_section_title">Collapse Post Section</string> <string name="settings_collapse_preferences_section_title">Collapse Preferences Section</string> <string name="settings_collapse_favorite_subreddits_section_title">Collapse Favorite Subreddits Section</string> @@ -562,6 +586,16 @@ <string name="settings_crash_reports_title">Crash Reports</string> <string name="settings_nsfw_and_spoiler_dangerous_group_title">Dangerous</string> <string name="settings_disable_nsfw_forever_title">Disable NSFW Forever</string> + <string name="settings_show_only_one_comment_level_indicator">Show Only One Comment Level Indicator</string> + <string name="settings_video_player_automatic_landscape_orientation">Switch to Landscape Orientation in Video Player Automatically</string> + <string name="settings_remember_muting_option_in_post_feed">Remember Muting Option in Post Feed</string> + <string name="settings_post_details_title">Post Details</string> + <string name="settings_separate_post_and_comments_in_portrait_mode_title">Separate Post And Comments in Portrait Mode</string> + <string name="settings_separate_post_and_comments_in_landscape_mode_title">Separate Post And Comments in Landscape Mode</string> + <string name="settings_separate_post_and_comments_summary">Video autoplay will be disabled in the post detail page</string> + <string name="settings_use_bottom_toolbar_in_media_viewer_title">Use Bottom Toolbar in Media Viewer</string> + <string name="settings_secure_mode_title">Secure Mode</string> + <string name="settings_secure_mode_summary">Screenshot and video recording are not allowed. No preview in recent app screen.</string> <string name="no_link_available">Cannot get the link</string> @@ -573,6 +607,7 @@ <string name="discard_detail">All the draft will NOT be saved.</string> <string name="yes">Yes</string> <string name="no">No</string> + <string name="discard_dialog_button">Discard</string> <string name="no_data_received">No data received</string> <string name="no_image_path_received">No image path received</string> @@ -594,6 +629,7 @@ <string name="favorites">Favorites</string> <string name="all">All</string> + <string name="link_post_layout_auto">Auto</string> <string name="post_layout_card">Card Layout</string> <string name="post_layout_compact">Compact Layout</string> <string name="post_layout_gallery">Gallery Layout</string> @@ -994,8 +1030,6 @@ <string name="give_award_success">Award given</string> <string name="give_award_failed">Failed</string> - <string name="recent_searches">Recent searches</string> - <string name="warning">Warning</string> <string name="this_is_a_nsfw_subreddit">This is a NSFW subreddit.</string> <string name="this_user_has_nsfw_content">This user has NSFW content</string> @@ -1109,4 +1143,29 @@ <string name="reply">Reply</string> + <string name="uploaded_images">Uploaded Images</string> + <string name="select_image">Select an Image</string> + <string name="capture">Capture</string> + <string name="uploading_image">Uploading</string> + <string name="upload_image_success">Upload image successfully. Click the image button again to see the uploaded images.</string> + <string name="get_image_bitmap_failed">Unable to get the bitmap of the image</string> + <string name="upload_image_failed">Unable to upload the image</string> + + <string name="load_rpan_broadcasts_failed">Cannot load RPAN broadcasts</string> + <string name="parse_rpan_broadcasts_failed">Cannot parse RPAN broadcasts</string> + <string name="parse_rpan_broadcast_failed">Cannot parse RPAN broadcast</string> + + <string name="search_comments">Search Comments</string> + + <string name="please_wait_image_is_uploading">An image is still being uploaded. Please wait.</string> + + <string name="error_fetch_trending_search">Fetch trending searches failed.\nTap to retry.</string> + <string name="error_parse_trending_search">Parse trending searches failed.\nTap to retry.</string> + <string name="no_trending_search">No trending searches found.\nTap to retry.</string> + + <string name="error_loading_wiki">Error loading wiki</string> + <string name="no_wiki">This subreddit has no wiki page</string> + + <string name="material_you_notification_title">Applying Material You</string> + </resources> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 9aaa5bbf..350b0f29 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -48,6 +48,10 @@ <item name="android:fontFamily">?attr/font_family</item> </style> + <style name="AppTheme.TranslucentStatusBar" parent="AppTheme"> + <item name="android:windowTranslucentStatus">true</item> + </style> + <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar"> <item name="android:fontFamily">?attr/font_family</item> </style> @@ -422,7 +426,7 @@ <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> - <item name="colorPrimaryLightTheme">#1565C0</item> + <item name="colorPrimaryLightTheme">#0336FF</item> <item name="primaryTextColor">#FFFFFF</item> <item name="secondaryTextColor">#B3FFFFFF</item> <item name="backgroundColor">@color/backgroundColor</item> @@ -433,7 +437,7 @@ <item name="colorPrimary">#000000</item> <item name="colorPrimaryDark">#000000</item> <item name="colorAccent">@color/colorAccent</item> - <item name="colorPrimaryLightTheme">#1565C0</item> + <item name="colorPrimaryLightTheme">#0336FF</item> <item name="primaryTextColor">#FFFFFF</item> <item name="secondaryTextColor">#B3FFFFFF</item> <item name="backgroundColor">#000000</item> diff --git a/app/src/main/res/xml-sw600dp/post_details_preferences.xml b/app/src/main/res/xml-sw600dp/post_details_preferences.xml new file mode 100644 index 00000000..0a8cf2c9 --- /dev/null +++ b/app/src/main/res/xml-sw600dp/post_details_preferences.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <SwitchPreference + app:defaultValue="true" + app:key="separate_post_and_comments_in_portrait_mode" + app:title="@string/settings_separate_post_and_comments_in_portrait_mode_title" + app:summary="@string/settings_separate_post_and_comments_summary" /> + + <SwitchPreference + app:defaultValue="true" + app:key="separate_post_and_comments_in_landscape_mode" + app:title="@string/settings_separate_post_and_comments_in_landscape_mode_title" + app:summary="@string/settings_separate_post_and_comments_summary" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_post_type" + app:title="@string/settings_hide_post_type" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_post_flair" + app:title="@string/settings_hide_post_flair" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_the_number_of_awards" + app:title="@string/settings_hide_the_number_of_awards" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_subreddit_and_user_prefix" + app:title="@string/settings_hide_subreddit_and_user_prefix" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_the_number_of_votes" + app:title="@string/settings_hide_the_number_of_votes" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_the_number_of_comments" + app:title="@string/settings_hide_the_number_of_comments" /> + +</PreferenceScreen>
\ No newline at end of file diff --git a/app/src/main/res/xml/activity_motion_test_scene.xml b/app/src/main/res/xml/activity_motion_test_scene.xml new file mode 100644 index 00000000..d271b2e1 --- /dev/null +++ b/app/src/main/res/xml/activity_motion_test_scene.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<MotionScene xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:motion="http://schemas.android.com/apk/res-auto"> + + <Transition + android:id="@+id/transition_to_end" + motion:constraintSetStart="@+id/start" + motion:constraintSetEnd="@+id/end" + motion:autoTransition="animateToStart" + motion:duration="100"> + <OnSwipe + motion:touchAnchorId="@+id/button" + motion:touchAnchorSide="right" + motion:onTouchUp="autoCompleteToEnd" + motion:dragDirection="dragRight" /> + </Transition> + + <Transition + android:id="@+id/transition_to_start" + motion:constraintSetStart="@+id/end" + motion:constraintSetEnd="@+id/start" + motion:autoTransition="animateToEnd"> + </Transition> + + <ConstraintSet android:id="@+id/start"> + <Constraint + android:id="@+id/button" + android:layout_width="64dp" + android:layout_height="64dp" + motion:layout_constraintBottom_toBottomOf="parent" + motion:layout_constraintStart_toStartOf="parent" + motion:layout_constraintTop_toTopOf="parent" /> + </ConstraintSet> + + <ConstraintSet android:id="@+id/end"> + <Constraint + android:id="@+id/button" + android:layout_width="64dp" + android:layout_height="64dp" + motion:layout_constraintBottom_toBottomOf="parent" + motion:layout_constraintStart_toEndOf="parent" + motion:layout_constraintTop_toTopOf="parent"/> + </ConstraintSet> + +</MotionScene> diff --git a/app/src/main/res/xml/comment_preferences.xml b/app/src/main/res/xml/comment_preferences.xml index 2248d7f3..a9510dc5 100644 --- a/app/src/main/res/xml/comment_preferences.xml +++ b/app/src/main/res/xml/comment_preferences.xml @@ -14,6 +14,11 @@ <SwitchPreference app:defaultValue="false" + app:key="show_only_one_comment_level_indicator" + app:title="@string/settings_show_only_one_comment_level_indicator" /> + + <SwitchPreference + app:defaultValue="false" app:key="comment_toolbar_hidden" app:title="@string/settings_comment_toolbar_hidden" /> diff --git a/app/src/main/res/xml/gestures_and_buttons_preferences.xml b/app/src/main/res/xml/gestures_and_buttons_preferences.xml index b5c30058..fd49d4c0 100644 --- a/app/src/main/res/xml/gestures_and_buttons_preferences.xml +++ b/app/src/main/res/xml/gestures_and_buttons_preferences.xml @@ -8,6 +8,11 @@ app:summary="@string/settings_swipe_to_go_back_summary" /> <SwitchPreference + app:defaultValue="true" + app:key="swipe_vertically_to_go_back_from_media" + app:title="@string/settings_swipe_vertically_to_go_back_from_media_title" /> + + <SwitchPreference app:defaultValue="false" app:key="lock_jump_to_next_top_level_comment_button" app:title="@string/settings_lock_jump_to_next_top_level_comment_button_title" /> diff --git a/app/src/main/res/xml/interface_preferences.xml b/app/src/main/res/xml/interface_preferences.xml index 201b13cd..1a4e0f86 100644 --- a/app/src/main/res/xml/interface_preferences.xml +++ b/app/src/main/res/xml/interface_preferences.xml @@ -37,6 +37,11 @@ app:key="hide_subreddit_description" app:title="@string/settings_hide_subreddit_description_title" /> + <SwitchPreference + app:defaultValue="false" + app:key="use_bottom_toolbar_in_media_viewer" + app:title="@string/settings_use_bottom_toolbar_in_media_viewer_title" /> + <ListPreference app:defaultValue="0" app:entries="@array/settings_default_search_result_tab" @@ -54,6 +59,10 @@ app:fragment="ml.docilealligator.infinityforreddit.settings.PostPreferenceFragment" /> <Preference + app:title="@string/settings_post_details_title" + app:fragment="ml.docilealligator.infinityforreddit.settings.PostDetailsPreferenceFragment" /> + + <Preference app:title="@string/settings_category_comment_title" app:fragment="ml.docilealligator.infinityforreddit.settings.CommentPreferenceFragment" /> diff --git a/app/src/main/res/xml/item_post_with_preview_scene.xml b/app/src/main/res/xml/item_post_with_preview_scene.xml new file mode 100644 index 00000000..dc28317a --- /dev/null +++ b/app/src/main/res/xml/item_post_with_preview_scene.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<MotionScene xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <ConstraintSet android:id="@+id/start"> + <Constraint android:id="@+id/material_card_view_item_post_with_preview" /> + </ConstraintSet> + + <ConstraintSet android:id="@+id/end"> + <Constraint android:id="@id/material_card_view_item_post_with_preview" + android:layout_width="0dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintWidth_percent="0.7" /> + </ConstraintSet> + + <Transition + app:constraintSetEnd="@id/end" + app:constraintSetStart="@+id/start"> + + <OnSwipe + app:dragDirection="dragRight" + app:touchAnchorId="@id/material_card_view_item_post_with_preview" + app:touchAnchorSide="right" /> + + </Transition> +</MotionScene> diff --git a/app/src/main/res/xml/navigation_drawer_preferences.xml b/app/src/main/res/xml/navigation_drawer_preferences.xml index 3fb31b88..b34a32e7 100644 --- a/app/src/main/res/xml/navigation_drawer_preferences.xml +++ b/app/src/main/res/xml/navigation_drawer_preferences.xml @@ -18,6 +18,11 @@ <SwitchPreference app:defaultValue="false" + app:key="collapse_reddit_section" + app:title="@string/settings_collapse_reddit_section_title" /> + + <SwitchPreference + app:defaultValue="false" app:key="collapse_post_section" app:title="@string/settings_collapse_post_section_title" /> diff --git a/app/src/main/res/xml/post_details_preferences.xml b/app/src/main/res/xml/post_details_preferences.xml new file mode 100644 index 00000000..e549cb42 --- /dev/null +++ b/app/src/main/res/xml/post_details_preferences.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <SwitchPreference + app:defaultValue="true" + app:key="separate_post_and_comments_in_landscape_mode" + app:title="@string/settings_separate_post_and_comments_in_landscape_mode_title" + app:summary="@string/settings_separate_post_and_comments_summary" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_post_type" + app:title="@string/settings_hide_post_type" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_post_flair" + app:title="@string/settings_hide_post_flair" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_the_number_of_awards" + app:title="@string/settings_hide_the_number_of_awards" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_subreddit_and_user_prefix" + app:title="@string/settings_hide_subreddit_and_user_prefix" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_the_number_of_votes" + app:title="@string/settings_hide_the_number_of_votes" /> + + <SwitchPreference + app:defaultValue="false" + app:key="hide_the_number_of_comments" + app:title="@string/settings_hide_the_number_of_comments" /> + +</PreferenceScreen>
\ No newline at end of file diff --git a/app/src/main/res/xml/post_preferences.xml b/app/src/main/res/xml/post_preferences.xml index 7e47f86c..55f9f5c2 100644 --- a/app/src/main/res/xml/post_preferences.xml +++ b/app/src/main/res/xml/post_preferences.xml @@ -10,6 +10,14 @@ app:title="@string/settings_default_post_layout" app:useSimpleSummaryProvider="true" /> + <ListPreference + app:defaultValue="-1" + android:entries="@array/settings_default_link_post_layout" + app:entryValues="@array/settings_default_link_post_layout_values" + app:key="default_link_post_layout" + app:title="@string/settings_default_link_post_layout" + app:useSimpleSummaryProvider="true" /> + <Preference app:title="@string/settings_number_of_columns_in_post_feed_title" app:fragment="ml.docilealligator.infinityforreddit.settings.NumberOfColumnsInPostFeedPreferenceFragment" /> @@ -21,6 +29,11 @@ <SwitchPreference app:defaultValue="false" + app:key="hide_post_flair" + app:title="@string/settings_hide_post_flair" /> + + <SwitchPreference + app:defaultValue="false" app:key="hide_the_number_of_awards" app:title="@string/settings_hide_the_number_of_awards" /> diff --git a/app/src/main/res/xml/security_preferences.xml b/app/src/main/res/xml/security_preferences.xml index d43c2384..636f1798 100644 --- a/app/src/main/res/xml/security_preferences.xml +++ b/app/src/main/res/xml/security_preferences.xml @@ -5,4 +5,10 @@ app:key="require_auth_to_account_section" app:title="@string/settings_require_authentication_to_go_to_account_section_in_navigation_drawer_title" /> + <SwitchPreference + app:defaultValue="false" + app:key="secure_mode" + app:title="@string/settings_secure_mode_title" + app:summary="@string/settings_secure_mode_summary" /> + </PreferenceScreen>
\ No newline at end of file diff --git a/app/src/main/res/xml/theme_preferences.xml b/app/src/main/res/xml/theme_preferences.xml index f4fb02a8..6bac18e4 100644 --- a/app/src/main/res/xml/theme_preferences.xml +++ b/app/src/main/res/xml/theme_preferences.xml @@ -12,6 +12,7 @@ <SwitchPreference app:defaultValue="false" app:key="amoled_dark" + app:icon="@drawable/ic_amoled_theme_preference_24dp" app:title="@string/settings_amoled_dark_title" /> <PreferenceCategory @@ -45,4 +46,23 @@ app:summary="@string/settings_custom_theme_cannot_apply_to_settings_page_summary" app:enabled="false" /> + <PreferenceCategory + app:title="@string/settings_category_material_you_title" /> + + <Preference + app:icon="@drawable/ic_info_preference_24dp" + app:summary="@string/settings_enable_material_you_warning_summary" + app:enabled="false" /> + + <SwitchPreference + app:defaultValue="false" + app:key="enable_material_you" + app:title="@string/settings_enable_material_you_title" + app:summary="@string/settings_enable_material_you_summary" /> + + <Preference + app:key="apply_material_you" + app:title="@string/settings_apply_material_you_title" + app:summary="@string/settings_apply_material_you_summary" /> + </PreferenceScreen>
\ No newline at end of file diff --git a/app/src/main/res/xml/video_preferences.xml b/app/src/main/res/xml/video_preferences.xml index a0924140..decf2674 100644 --- a/app/src/main/res/xml/video_preferences.xml +++ b/app/src/main/res/xml/video_preferences.xml @@ -25,6 +25,11 @@ app:title="@string/settings_video_player_ignore_nav_bar_title" app:summary="@string/settings_video_player_ignore_nav_bar_summary" /> + <SwitchPreference + app:defaultValue="false" + app:key="video_player_automatic_landscape_orientation" + app:title="@string/settings_video_player_automatic_landscape_orientation" /> + <PreferenceCategory app:title="@string/settings_video_autoplay_title" /> @@ -43,6 +48,11 @@ app:title="@string/settings_mute_autoplaying_videos_title" /> <SwitchPreference + app:defaultValue="false" + app:key="remember_muting_option_in_post_feed" + app:title="@string/settings_remember_muting_option_in_post_feed" /> + + <SwitchPreference app:defaultValue="true" app:key="autoplay_nsfw_videos" app:title="@string/settings_autoplay_nsfw_videos_title" /> |