() {
+ @Override
+ public void onSuccess(final Favorite result) {
+ // local has priority since it's more frequently updated
+ }
+
+ @Override
+ public void onDataNotAvailable() {
+ favRepo.insertOrUpdateFavorite(favorite, null);
+ }
+ });
}
}
diff --git a/app/src/main/java/awais/instagrabber/utils/FlavorTown.java b/app/src/main/java/awais/instagrabber/utils/FlavorTown.java
index ee859700..8f06eb8b 100755
--- a/app/src/main/java/awais/instagrabber/utils/FlavorTown.java
+++ b/app/src/main/java/awais/instagrabber/utils/FlavorTown.java
@@ -1,104 +1,72 @@
package awais.instagrabber.utils;
-import android.annotation.SuppressLint;
-import android.content.ActivityNotFoundException;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.Signature;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
-
-import javax.security.cert.CertificateException;
-import javax.security.cert.X509Certificate;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.R;
-import awais.instagrabber.databinding.DialogUpdateBinding;
import static awais.instagrabber.utils.Utils.settingsHelper;
public final class FlavorTown {
private static final String TAG = "FlavorTown";
- private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
- private static AlertDialog dialog;
+ private static final UpdateChecker UPDATE_CHECKER = UpdateChecker.getInstance();
+ private static final Pattern VERSION_NAME_PATTERN = Pattern.compile("v?(\\d+\\.\\d+\\.\\d+)(?:_?)(\\w*)(?:-?)(\\w*)");
+
+ private static boolean checking = false;
public static void updateCheck(@NonNull final AppCompatActivity context) {
updateCheck(context, false);
}
- @SuppressLint("PackageManagerGetSignatures")
- public static void updateCheck(@NonNull final AppCompatActivity context, final boolean force) {
- boolean isInstalledFromFdroid = false;
- final PackageInfo packageInfo;
- try {
- packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
- for (Signature signature : packageInfo.signatures) {
- final X509Certificate cert = X509Certificate.getInstance(signature.toByteArray());
- final String fingerprint = bytesToHex(MessageDigest.getInstance("SHA-1").digest(cert.getEncoded()));
- isInstalledFromFdroid = fingerprint.equals(Constants.FDROID_SHA1_FINGERPRINT);
- // Log.d(TAG, "fingerprint:" + fingerprint);
- }
- } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException | CertificateException e) {
- Log.e(TAG, "Error", e);
- }
- if (isInstalledFromFdroid) return;
- final DialogUpdateBinding binding = DialogUpdateBinding.inflate(context.getLayoutInflater(), null, false);
- binding.skipUpdate.setOnCheckedChangeListener((buttonView, isChecked) -> {
- if (dialog == null) return;
- dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(!isChecked);
- });
- Resources res = context.getResources();
- new UpdateChecker(version -> {
- if (force && version.equals(BuildConfig.VERSION_NAME)) {
- Toast.makeText(context, "You're already on the latest version", Toast.LENGTH_SHORT).show();
+ public static void updateCheck(@NonNull final AppCompatActivity context,
+ final boolean force) {
+ if (checking) return;
+ checking = true;
+ AppExecutors.getInstance().networkIO().execute(() -> {
+ final String onlineVersionName = UPDATE_CHECKER.getLatestVersion();
+ if (onlineVersionName == null) return;
+ final String onlineVersion = getVersion(onlineVersionName);
+ final String localVersion = getVersion(BuildConfig.VERSION_NAME);
+ if (Objects.equals(onlineVersion, localVersion)) {
+ if (force) {
+ AppExecutors.getInstance().mainThread().execute(() -> {
+ final Context applicationContext = context.getApplicationContext();
+ // Check if app was closed or crashed before reaching here
+ if (applicationContext == null) return;
+ // Show toast if version number preference was tapped
+ Toast.makeText(applicationContext, R.string.on_latest_version, Toast.LENGTH_SHORT).show();
+ });
+ }
return;
}
- final String skippedVersion = settingsHelper.getString(Constants.SKIPPED_VERSION);
- final boolean shouldShowDialog = force || (!version.equals(BuildConfig.VERSION_NAME) && !BuildConfig.DEBUG && !skippedVersion
- .equals(version));
+ final boolean shouldShowDialog = UpdateCheckCommon.shouldShowUpdateDialog(force, onlineVersionName);
if (!shouldShowDialog) return;
- dialog = new AlertDialog.Builder(context)
- .setTitle(res.getString(R.string.update_available, version))
- .setView(binding.getRoot())
- .setNeutralButton(R.string.cancel, (dialog, which) -> {
- if (binding.skipUpdate.isChecked()) {
- settingsHelper.putString(Constants.SKIPPED_VERSION, version);
- }
- dialog.dismiss();
- })
- .setPositiveButton(R.string.action_github, (dialog1, which) -> {
- try {
- context.startActivity(new Intent(Intent.ACTION_VIEW).setData(
- Uri.parse("https://github.com/austinhuang0131/instagrabber/releases/latest")));
- } catch (final ActivityNotFoundException e) {
- // do nothing
- }
- })
- // if we don't show dialog for fdroid users, is the below required?
- .setNegativeButton(R.string.action_fdroid, (dialog, which) -> {
- try {
- context.startActivity(new Intent(Intent.ACTION_VIEW).setData(
- Uri.parse("https://f-droid.org/packages/me.austinhuang.instagrabber/")));
- } catch (final ActivityNotFoundException e) {
- // do nothing
- }
- })
- .show();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ UpdateCheckCommon.showUpdateDialog(context, onlineVersionName, (dialog, which) -> {
+ UPDATE_CHECKER.onDownload(context);
+ dialog.dismiss();
+ });
+ });
+ }
+
+ private static String getVersion(@NonNull final String versionName) {
+ final Matcher matcher = VERSION_NAME_PATTERN.matcher(versionName);
+ if (!matcher.matches()) return versionName;
+ try {
+ return matcher.group(1);
+ } catch (Exception e) {
+ Log.e(TAG, "getVersion: ", e);
+ }
+ return versionName;
}
public static void changelogCheck(@NonNull final Context context) {
@@ -121,14 +89,4 @@ public final class FlavorTown {
settingsHelper.putInteger(Constants.PREV_INSTALL_VERSION, BuildConfig.VERSION_CODE);
}
}
-
- public static String bytesToHex(byte[] bytes) {
- char[] hexChars = new char[bytes.length * 2];
- for (int j = 0; j < bytes.length; j++) {
- int v = bytes[j] & 0xFF;
- hexChars[j * 2] = HEX_ARRAY[v >>> 4];
- hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
- }
- return new String(hexChars);
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/utils/ProcessPhoenix.java b/app/src/main/java/awais/instagrabber/utils/ProcessPhoenix.java
new file mode 100644
index 00000000..5dcc6e19
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/utils/ProcessPhoenix.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2014 Jake Wharton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package awais.instagrabber.utils;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Process;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+/**
+ * Process Phoenix facilitates restarting your application process. This should only be used for
+ * things like fundamental state changes in your debug builds (e.g., changing from staging to
+ * production).
+ *
+ * Trigger process recreation by calling {@link #triggerRebirth} with a {@link Context} instance.
+ */
+public final class ProcessPhoenix extends Activity {
+ private static final String KEY_RESTART_INTENTS = "phoenix_restart_intents";
+
+ /**
+ * Call to restart the application process using the {@linkplain Intent#CATEGORY_DEFAULT default}
+ * activity as an intent.
+ *
+ * Behavior of the current process after invoking this method is undefined.
+ */
+ public static void triggerRebirth(Context context) {
+ triggerRebirth(context, getRestartIntent(context));
+ }
+
+ /**
+ * Call to restart the application process using the specified intents.
+ *
+ * Behavior of the current process after invoking this method is undefined.
+ */
+ public static void triggerRebirth(Context context, Intent... nextIntents) {
+ Intent intent = new Intent(context, ProcessPhoenix.class);
+ intent.addFlags(FLAG_ACTIVITY_NEW_TASK); // In case we are called with non-Activity context.
+ intent.putParcelableArrayListExtra(KEY_RESTART_INTENTS, new ArrayList<>(Arrays.asList(nextIntents)));
+ context.startActivity(intent);
+ if (context instanceof Activity) {
+ ((Activity) context).finish();
+ }
+ Runtime.getRuntime().exit(0); // Kill kill kill!
+ }
+
+ private static Intent getRestartIntent(Context context) {
+ String packageName = context.getPackageName();
+ Intent defaultIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
+ if (defaultIntent != null) {
+ defaultIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
+ return defaultIntent;
+ }
+
+ throw new IllegalStateException("Unable to determine default activity for "
+ + packageName
+ + ". Does an activity specify the DEFAULT category in its intent filter?");
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ArrayList intents = getIntent().getParcelableArrayListExtra(KEY_RESTART_INTENTS);
+ startActivities(intents.toArray(new Intent[intents.size()]));
+ finish();
+ Runtime.getRuntime().exit(0); // Kill kill kill!
+ }
+
+ /**
+ * Checks if the current process is a temporary Phoenix Process.
+ * This can be used to avoid initialisation of unused resources or to prevent running code that
+ * is not multi-process ready.
+ *
+ * @return true if the current process is a temporary Phoenix Process
+ */
+ public static boolean isPhoenixProcess(Context context) {
+ int currentPid = Process.myPid();
+ ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ List runningProcesses = manager.getRunningAppProcesses();
+ if (runningProcesses != null) {
+ for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
+ if (processInfo.pid == currentPid && processInfo.processName.endsWith(":phoenix")) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java
index 2722d11e..0d7acc16 100644
--- a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java
+++ b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java
@@ -1090,11 +1090,19 @@ public final class ResponseBodyUtils {
if (imageVersions2 == null) return null;
final List candidates = imageVersions2.getCandidates();
if (candidates == null || candidates.isEmpty()) return null;
+ final boolean isSquare = Integer.compare(media.getOriginalWidth(), media.getOriginalHeight()) == 0;
final List sortedCandidates = candidates.stream()
.sorted((c1, c2) -> Integer.compare(c2.getWidth(), c1.getWidth()))
- .filter(c -> c.getWidth() < type.getValue())
.collect(Collectors.toList());
- final MediaCandidate candidate = sortedCandidates.get(0);
+ if (sortedCandidates.size() == 1) return sortedCandidates.get(0).getUrl();
+ final List filteredCandidates = sortedCandidates.stream()
+ .filter(c ->
+ c.getWidth() <= media.getOriginalWidth()
+ && c.getWidth() <= type.getValue()
+ && (isSquare || Integer.compare(c.getWidth(), c.getHeight()) != 0)
+ )
+ .collect(Collectors.toList());
+ final MediaCandidate candidate = filteredCandidates.get(0);
if (candidate == null) return null;
return candidate.getUrl();
}
diff --git a/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java b/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java
index 9ae6cfd4..fc568d9e 100755
--- a/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java
+++ b/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java
@@ -34,10 +34,12 @@ import static awais.instagrabber.utils.Constants.DATE_TIME_SELECTION;
import static awais.instagrabber.utils.Constants.DEFAULT_TAB;
import static awais.instagrabber.utils.Constants.DEVICE_UUID;
import static awais.instagrabber.utils.Constants.DM_MARK_AS_SEEN;
+import static awais.instagrabber.utils.Constants.DOWNLOAD_PREPEND_USER_NAME;
import static awais.instagrabber.utils.Constants.DOWNLOAD_USER_FOLDER;
import static awais.instagrabber.utils.Constants.FLAG_SECURE;
import static awais.instagrabber.utils.Constants.FOLDER_PATH;
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
+import static awais.instagrabber.utils.Constants.HIDE_MUTED_REELS;
import static awais.instagrabber.utils.Constants.KEYWORD_FILTERS;
import static awais.instagrabber.utils.Constants.MARK_AS_SEEN;
import static awais.instagrabber.utils.Constants.MUTED_VIDEOS;
@@ -159,10 +161,10 @@ public final class SettingsHelper {
STORY_SORT, PREF_EMOJI_VARIANTS, PREF_REACTIONS, PREF_ENABLE_DM_AUTO_REFRESH_FREQ_UNIT, PREF_TAB_ORDER})
public @interface StringSettings {}
- @StringDef({DOWNLOAD_USER_FOLDER, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS,
+ @StringDef({DOWNLOAD_USER_FOLDER, DOWNLOAD_PREPEND_USER_NAME, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS,
SHOW_CAPTIONS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, DM_MARK_AS_SEEN, CHECK_ACTIVITY,
CHECK_UPDATES, SWAP_DATE_TIME_FORMAT_ENABLED, PREF_ENABLE_DM_NOTIFICATIONS, PREF_ENABLE_DM_AUTO_REFRESH,
- FLAG_SECURE, TOGGLE_KEYWORD_FILTER, PREF_ENABLE_SENTRY})
+ FLAG_SECURE, TOGGLE_KEYWORD_FILTER, PREF_ENABLE_SENTRY, HIDE_MUTED_REELS})
public @interface BooleanSettings {}
@StringDef({PREV_INSTALL_VERSION, BROWSER_UA_CODE, APP_UA_CODE, PREF_ENABLE_DM_AUTO_REFRESH_FREQ_NUMBER})
diff --git a/app/src/main/java/awais/instagrabber/utils/UpdateCheckCommon.java b/app/src/main/java/awais/instagrabber/utils/UpdateCheckCommon.java
new file mode 100644
index 00000000..285fbb13
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/utils/UpdateCheckCommon.java
@@ -0,0 +1,38 @@
+package awais.instagrabber.utils;
+
+import android.content.Context;
+import android.content.DialogInterface;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
+import awais.instagrabber.BuildConfig;
+import awais.instagrabber.R;
+
+import static awais.instagrabber.utils.Utils.settingsHelper;
+
+public final class UpdateCheckCommon {
+
+ public static boolean shouldShowUpdateDialog(final boolean force,
+ @NonNull final String version) {
+ final String skippedVersion = settingsHelper.getString(Constants.SKIPPED_VERSION);
+ return force || (!BuildConfig.DEBUG && !skippedVersion.equals(version));
+ }
+
+ public static void showUpdateDialog(@NonNull final Context context,
+ @NonNull final String version,
+ @NonNull final DialogInterface.OnClickListener onDownloadClickListener) {
+ AppExecutors.getInstance().mainThread().execute(() -> {
+ new MaterialAlertDialogBuilder(context)
+ .setTitle(context.getString(R.string.update_available, version))
+ .setNeutralButton(R.string.skip_update, (dialog, which) -> {
+ settingsHelper.putString(Constants.SKIPPED_VERSION, version);
+ dialog.dismiss();
+ })
+ .setPositiveButton(R.string.action_download, onDownloadClickListener)
+ .setNegativeButton(R.string.cancel, null)
+ .show();
+ });
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/utils/UpdateChecker.java b/app/src/main/java/awais/instagrabber/utils/UpdateChecker.java
deleted file mode 100755
index 3ea67ba1..00000000
--- a/app/src/main/java/awais/instagrabber/utils/UpdateChecker.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package awais.instagrabber.utils;
-
-import android.os.AsyncTask;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import org.json.JSONObject;
-
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.interfaces.FetchListener;
-
-public final class UpdateChecker extends AsyncTask {
- private final FetchListener fetchListener;
- private String version;
-
- public UpdateChecker(final FetchListener fetchListener) {
- this.fetchListener = fetchListener;
- }
-
- @NonNull
- @Override
- protected Boolean doInBackground(final Void... voids) {
- try {
- version = "";
-
- HttpURLConnection conn =
- (HttpURLConnection) new URL("https://f-droid.org/api/v1/packages/me.austinhuang.instagrabber").openConnection();
- conn.setUseCaches(false);
- conn.setRequestProperty("User-Agent", "https://Barinsta.AustinHuang.me / mailto:Barinsta@AustinHuang.me");
- conn.connect();
-
- final int responseCode = conn.getResponseCode();
- if (responseCode == HttpURLConnection.HTTP_OK) {
- final JSONObject data = new JSONObject(NetworkUtils.readFromConnection(conn));
- if (BuildConfig.VERSION_CODE < data.getInt("suggestedVersionCode")) {
- version = data.getJSONArray("packages").getJSONObject(0).getString("versionName");
- return true;
- }
- }
-
- conn.disconnect();
- } catch (final Exception e) {
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
- }
-
- return false;
- }
-
- @Override
- protected void onPostExecute(final Boolean result) {
- if (result != null && result && fetchListener != null)
- fetchListener.onResult("v"+version);
- }
-}
diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java
index 6f966c33..6f711a45 100644
--- a/app/src/main/java/awais/instagrabber/utils/Utils.java
+++ b/app/src/main/java/awais/instagrabber/utils/Utils.java
@@ -31,7 +31,6 @@ import android.webkit.MimeTypeMap;
import android.widget.Toast;
import androidx.annotation.DrawableRes;
-import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
@@ -474,7 +473,11 @@ public final class Utils {
final List navGraphNameList = Arrays.asList(navGraphNames);
if (TextUtils.isEmpty(tabOrderString)) {
// Use top 5 entries for default list
- return navGraphNameList.subList(0, 5);
+ final List top5navGraphNames = navGraphNameList.subList(0, 5);
+ final String newOrderString = android.text.TextUtils.join(",", top5navGraphNames);
+ Utils.settingsHelper.putString(PreferenceKeys.PREF_TAB_ORDER, newOrderString);
+ tabOrderString = newOrderString;
+ return top5navGraphNames;
}
// Make sure that the list from preference does not contain any invalid values
final List orderGraphNames = Arrays.stream(tabOrderString.split(","))
@@ -489,6 +492,7 @@ public final class Utils {
}
public static boolean isNavRootInCurrentTabs(final String navRootString) {
+ if (navRootString == null || tabOrderString == null) return false;
return tabOrderString.contains(navRootString);
}
}
diff --git a/app/src/main/java/awais/instagrabber/webservices/NewsService.java b/app/src/main/java/awais/instagrabber/webservices/NewsService.java
index 15b34def..580e2c04 100644
--- a/app/src/main/java/awais/instagrabber/webservices/NewsService.java
+++ b/app/src/main/java/awais/instagrabber/webservices/NewsService.java
@@ -54,9 +54,11 @@ public class NewsService extends BaseService {
callback.onSuccess(null);
return;
}
- final List result = new ArrayList<>();
- result.addAll(body.getNewStories());
- result.addAll(body.getOldStories());
+ final List result = new ArrayList();
+ final List newStories = body.getNewStories();
+ if (newStories != null) result.addAll(newStories);
+ final List oldStories = body.getOldStories();
+ if (oldStories != null) result.addAll(oldStories);
callback.onSuccess(result);
}
diff --git a/app/src/main/java/awais/instagrabber/webservices/StoriesService.java b/app/src/main/java/awais/instagrabber/webservices/StoriesService.java
index 059a8c7b..09a3a6b7 100644
--- a/app/src/main/java/awais/instagrabber/webservices/StoriesService.java
+++ b/app/src/main/java/awais/instagrabber/webservices/StoriesService.java
@@ -135,7 +135,7 @@ public class StoriesService extends BaseService {
final JSONArray feedStoriesReel = new JSONObject(body).getJSONArray("tray");
for (int i = 0; i < feedStoriesReel.length(); ++i) {
final JSONObject node = feedStoriesReel.getJSONObject(i);
- if (node.optBoolean("hide_from_feed_unit")) continue;
+ if (node.optBoolean("hide_from_feed_unit") && Utils.settingsHelper.getBoolean(Constants.HIDE_MUTED_REELS)) continue;
final JSONObject userJson = node.getJSONObject(node.has("user") ? "user" : "owner");
try {
final User user = new User(userJson.getLong("pk"),
@@ -177,18 +177,24 @@ public class StoriesService extends BaseService {
null,
null
);
- final String id = node.getString("id");
final long timestamp = node.getLong("latest_reel_media");
- final int mediaCount = node.getInt("media_count");
final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == timestamp;
final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").optJSONObject(0) : null;
- final boolean isBestie = node.optBoolean("has_besties_media", false);
StoryModel firstStoryModel = null;
if (itemJson != null) {
firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, null);
}
- feedStoryModels.add(new FeedStoryModel(id, user, fullyRead, timestamp, firstStoryModel, mediaCount, false, isBestie));
- } catch (Exception e) {} // to cover promotional reels with non-long user pk's
+ feedStoryModels.add(new FeedStoryModel(
+ node.getString("id"),
+ user,
+ fullyRead,
+ timestamp,
+ firstStoryModel,
+ node.getInt("media_count"),
+ false,
+ node.optBoolean("has_besties_media")));
+ }
+ catch (Exception e) {} // to cover promotional reels with non-long user pk's
}
final JSONArray broadcasts = new JSONObject(body).getJSONArray("broadcasts");
for (int i = 0; i < broadcasts.length(); ++i) {
@@ -239,13 +245,16 @@ public class StoriesService extends BaseService {
null,
null
);
- final String id = node.getString("id");
- final long timestamp = node.getLong("published_time");
- // final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").getJSONObject(0) : null;
- final StoryModel firstStoryModel = ResponseBodyUtils.parseBroadcastItem(node);
- // if (itemJson != null) {
- // }
- feedStoryModels.add(new FeedStoryModel(id, user, false, timestamp, firstStoryModel, 1, true, false));
+ feedStoryModels.add(new FeedStoryModel(
+ node.getString("id"),
+ user,
+ false,
+ node.getLong("published_time"),
+ ResponseBodyUtils.parseBroadcastItem(node),
+ 1,
+ true,
+ false
+ ));
}
callback.onSuccess(sort(feedStoryModels));
} catch (JSONException e) {
diff --git a/app/src/main/res/layout/layout_profile_details.xml b/app/src/main/res/layout/layout_profile_details.xml
index 035a04b0..ea4df164 100644
--- a/app/src/main/res/layout/layout_profile_details.xml
+++ b/app/src/main/res/layout/layout_profile_details.xml
@@ -326,6 +326,7 @@
diff --git a/app/src/main/res/menu/story_menu.xml b/app/src/main/res/menu/story_menu.xml
index a7293f91..8169fd62 100644
--- a/app/src/main/res/menu/story_menu.xml
+++ b/app/src/main/res/menu/story_menu.xml
@@ -5,13 +5,18 @@
+ android:title="@string/reply_story"
+ android:titleCondensed="@string/reply_story"
+ app:showAsAction="never" />
+
+ app:showAsAction="never" />
\ No newline at end of file
diff --git a/app/src/main/res/navigation/notification_viewer_nav_graph.xml b/app/src/main/res/navigation/notification_viewer_nav_graph.xml
index 89df18be..50e2fbdf 100644
--- a/app/src/main/res/navigation/notification_viewer_nav_graph.xml
+++ b/app/src/main/res/navigation/notification_viewer_nav_graph.xml
@@ -5,24 +5,16 @@
android:id="@+id/notification_viewer_nav_graph"
app:startDestination="@id/notificationsViewer">
-
+
+
+
-
-
-
+ app:nullable="true" />
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/profile_nav_graph.xml b/app/src/main/res/navigation/profile_nav_graph.xml
index 8ef07dca..8bff84b8 100644
--- a/app/src/main/res/navigation/profile_nav_graph.xml
+++ b/app/src/main/res/navigation/profile_nav_graph.xml
@@ -71,11 +71,9 @@
app:argType="long" />
-
-
+ app:destination="@id/notificationsViewer">
+
+
+
+
+
Cerca actualitzacions a l\'inici
Block screenshots & app preview
Descarrega les publicacions a carpetes de nom d\'usuari
+ Prepend Username to Filename
Marca les històries com a vistes després de visualitzar-es
L\'autor de la història sabrà que l\'has vista
Marca els missatges com a vists després de visualitzar-los
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 0bb9e0ac..c5bc0f11 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -23,6 +23,7 @@
Zkontrolovat aktualizace při spuštění
Block screenshots & app preview
Stáhnout příspěvky do složek s uživatelským jménem
+ Prepend Username to Filename
Označit příběhy po zhlédnutí jako zobrazené
Autor příběhu bude vědět, že jsi si ho zobrazili
Označovat přímou zprávu po zobrazení jako zobrazenou
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 1f541fcd..e023c6b9 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -23,6 +23,7 @@
Beim Start auf Aktualisierungen prüfen
Block screenshots & app preview
Beiträge in Benutzernamen-Ordner herunterladen
+ Prepend Username to Filename
Stories nach dem Ansehen als gesehen markieren
Die Person wird wissen, dass du dir die Story angesehen hast
Direktnachrichten nach dem Ansehen als gesehen markieren
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index f9817a0a..b8c7df56 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -23,6 +23,7 @@
Έλεγχος για ενημερώσεις στο ξεκίνημα
Block screenshots & app preview
Λήψη δημοσίευσης στους φακέλους με ονόματα χρηστών
+ Prepend Username to Filename
Επισήμανση ιστοριών ως προβληθέντων μετά την προβολή
Ο συντάκτης της ιστορίας θα ξέρει ότι την προβάλατε
Σήμανση ΠΜ ως αναγνωσμένου μετά την προβολή
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index f392ec86..9ee7d1d0 100755
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -23,6 +23,7 @@
Buscar actualizaciones al inicio
Bloquea capturas de pantalla & vista previa de aplicaciones
Usar subcarpetas con el nombre de usuario
+ Prepend Username to Filename
Marcar historias como vistas después de verlas
El autor de la historia sabrá que lo has visto
Marcar Mensaje Directo como visto después de verlo
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index dd0321e2..8f217f17 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -23,6 +23,7 @@
Bilatu eguneratzeak abioan
Block screenshots & app preview
Deskargatu bidalketak erabiltzaile-izena duten karpetetara
+ Prepend Username to Filename
Markatu istorioak ikusita gisa ikusi ondoren
Istorioaren egileak ikusi duzula jakingo du
Markatu MZ ikusita gisa ikusi ondoren
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index c6da89cf..75371835 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -23,6 +23,7 @@
بررسی بروزرسانی هنگام آغاز برنامه
Block screenshots & app preview
بارگیری پست ها در پوشه های به نام کاربر
+ Prepend Username to Filename
نشان کرد استوری ها به عنوان دیده شده بعد از دیدن
نویسنده استوری می داند که شما آن را دیده اید
نشان کردن پیام خصوصی بعنوان دیده شده بعد از دیدن
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 15f8a5cc..d2fd93dd 100755
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -23,6 +23,7 @@
Rechercher les mises à jours au démarrage
Bloquer les captures d\'écran & l\'aperçu de l\'application
Télécharger les messages dans les dossiers des noms d\'utilisateurs
+ Prepend Username to Filename
Marquer les stories comme vues après consultation
L\'auteur de la story saura que vous l\'avez vue
Marquer les messages privés comme vus après consultation
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index bc923135..623bc2ce 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -23,6 +23,7 @@
खुलने पर अपडेट के लिए जाँच करें
Block screenshots & app preview
पोस्ट को ब्यबहारकारी के नाम पर किये फोल्डरस में रखें
+ Prepend Username to Filename
स्टोरि को दिखने के बाद \"दिखा गया\" दिखादें
सटोरि के लेखक जानेगा कि तुम देखे हो इसको
तुम देखने के बाद सीधा संदेश को \"दिखागया\" लिखा जाएगा
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 462c1a2e..6801759b 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -23,6 +23,7 @@
Cek pembaruan saat memulai
Block screenshots & app preview
Unduh kiriman ke folder nama pengguna
+ Prepend Username to Filename
Tandai cerita dibaca setelah melihat
Pembuat cerita akan tahu Anda melihatnya
Tandai DM dibaca setelah melihat
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index d8202389..eefead25 100755
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -23,6 +23,7 @@
Verifica per aggiornamenti all\'avvio
Blocca screenshot & anteprima app
Scarica i post nelle cartelle del nome utente
+ Prepend Username to Filename
Segna le storie come viste dopo la visualizzazione
L\'autore della storia saprà che l\'hai visualizzata
Segna il DM come visto dopo la visualizzazione
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 5a11dc06..178f3726 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -23,6 +23,7 @@
起動時にアップデートを確認
Block screenshots & app preview
ユーザ名のフォルダに投稿をダウンロード
+ Prepend Username to Filename
ストーリーズを表示後に既読にする
ストーリーの作成者は、あなたが閲覧したことを知ることができます。
DMを表示後に既読にする
diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml
index 80d8b915..85c0390c 100644
--- a/app/src/main/res/values-kn/strings.xml
+++ b/app/src/main/res/values-kn/strings.xml
@@ -23,6 +23,7 @@
Check for updates at startup
Block screenshots & app preview
Download posts to username folders
+ Prepend Username to Filename
Mark stories as seen after viewing
Story author will know you viewed it
Mark DM as seen after viewing
diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml
index abb89551..118e07f4 100644
--- a/app/src/main/res/values-mk/strings.xml
+++ b/app/src/main/res/values-mk/strings.xml
@@ -23,6 +23,7 @@
Провери за ажурирање
Block screenshots & app preview
Превземи објави во папката со кориснички имиња
+ Prepend Username to Filename
Означи ги приказните како видени
Авторот на приказната ќе знае дека сте ја погледнале приказната
Означи порака како видена
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index fda4c863..b904bed6 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -23,6 +23,7 @@
Controleer op updates bij het opstarten
Block screenshots & app preview
Download berichten naar gebruikersnaam mappen
+ Prepend Username to Filename
Markeer verhalen als gelezen na bekijken
Verhaalmaker zal het weten als je het bekeken hebt
Markeer privéberichten als gelezen na bekijken
diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml
index ce4427ec..12b95d7b 100644
--- a/app/src/main/res/values-or/strings.xml
+++ b/app/src/main/res/values-or/strings.xml
@@ -23,6 +23,7 @@
ଖୋଲିବା ସମୟରେ ଅପଡେଟ ପାଇଁ ଯାଞ୍ଚ କରନ୍ତୁ
Block screenshots & app preview
ଡାଉନଲୋଡ ପୋଷ୍ଟକୁ ବ୍ୟବହାରକାରୀଙ୍କ ନାମରେ ହୋଇଥିବା ସ୍ଥାନ ରେ ରଖ
+ Prepend Username to Filename
କାହାଣୀଗୁଡିକ ଦେଖିବା ପରେ \'ଦେଖାଗଲା\' ଚିହ୍ନିତ କରନ୍ତୁ |
କାହାଣୀ ପ୍ରେରକ ଜାଣିବେ ତୁମେ ଏହାକୁ ଦେଖିଛ
ବାର୍ତା ଦେଖିବା ପରେ \'ଦେଖାଗଲା\' ଚିହ୍ନିତ କରନ୍ତୁ |
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 93fb3ff8..2c449634 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -23,6 +23,7 @@
Sprawdź aktualizacje przy starcie
Blokuj zrzuty ekranu & podgląd aplikacji
Pobierz posty do folderów o nazwie użytkownika
+ Prepend Username to Filename
Oznacz relacje jako widoczne po wyświetleniu
Autor relacji będzie widział, że to wyświetliłeś
Oznacz wiadomość jako przeczytaną
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 4c7bbbc4..f8c3f401 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -23,6 +23,7 @@
Verificar se há atualizações ao iniciar
Block screenshots & app preview
Baixar publicações para pastas com o nome de usuário
+ Prepend Username to Filename
Marcar stories como vistos após a visualização
O autor do story saberá que você viu
Marcar DM como vista após a visualização
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index b491a1c5..ca3155ef 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -23,6 +23,7 @@
Проверять наличие обновлений при запуске
Block screenshots & app preview
Скачать публикации в папки с именем пользователя
+ Prepend Username to Filename
Отметить истории как увиденные после просмотра
Автор истории узнает, что вы просмотрели её
Отметить ЛС как увиденные после просмотра
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index f12178ec..7b1c175a 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -23,6 +23,7 @@
Kontrolovať aktualizácie pri štarte
Block screenshots & app preview
Ukľadať do priečinkov podľa mena
+ Prepend Username to Filename
Označiť príbehy po videní ako videné
Autor príbehu bude vedieť že ste ho videli
Po prečítaní, označiť správu ako prečítanú
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 4ca6836d..fea3a299 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -23,6 +23,7 @@
Güncellemeleri başlangıçta kontrol et
Block screenshots & app preview
İndirmeleri kullanıcı adından oluşan bir alt klasörün içine yap
+ Prepend Username to Filename
Hikayeleri gördükten sonra görüldü olarak işaretle
Hikayeyi paylaşan gördüğünüzü bilecek
DM\'leri gördükten sonra görüldü olarak işaretle
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index debb92fc..858193f6 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -23,6 +23,7 @@
Kiểm tra cập nhật khi khởi động
Block screenshots & app preview
Tải bài viết xuống theo thư mục tên người dùng trong Downloads
+ Prepend Username to Filename
Đánh dấu story là đã xem sau khi xem
Người đăng story sẽ biết bạn đã xem nó
Đánh dấu DM là đã xem sau khi xem
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index a6fe9c77..0fb2193f 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -23,6 +23,7 @@
启动时检查更新
屏蔽截图及应用预览
下载帖子到用户名文件夹
+ Prepend Username to Filename
查看快拍后将其标记为已读
快拍作者会知道您已看过
查看私信后将其标记为已读
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 26371e94..3ce706fa 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -23,6 +23,7 @@
啟動時檢查更新
Block screenshots & app preview
將貼文下載到用戶名資料夾
+ Prepend Username to Filename
檢視完限時動態後標記為已讀
限時動態的作者會知道您已查看了此限時動態
檢視完訊息後標記為已讀
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e7d2052f..9cf27407 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -26,8 +26,10 @@
Check for updates at startup
Block screenshots & app preview
Download posts to username folders
+ Prepend Username to Filename
Mark stories as seen after viewing
Story author will know you viewed it
+ Hide muted stories from feed
Mark DM as seen after viewing
Other members will know you viewed it
Enable activity notifications
@@ -483,6 +485,8 @@
Select an email app to send crash logs
Not found!
Your IP has been rate limited by Instagram. Wait for an hour and try again.
+ Skip this update
+ You\'re already on the latest version
Screen order
Other tabs
The tab order will be reflected on next launch
diff --git a/app/src/main/resources/feed_response.json b/app/src/main/resources/feed_response.json
deleted file mode 100644
index 9e26dfee..00000000
--- a/app/src/main/resources/feed_response.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/app/src/main/resources/stories_response.json b/app/src/main/resources/stories_response.json
deleted file mode 100644
index 9e26dfee..00000000
--- a/app/src/main/resources/stories_response.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file