diff --git a/.all-contributorsrc b/.all-contributorsrc
index 7a9958b9..a39de36f 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -60,16 +60,6 @@
"bug"
]
},
- {
- "login": "vojta-horanek",
- "name": "Vojtěch Hořánek",
- "avatar_url": "https://avatars.githubusercontent.com/u/12630566?v=4",
- "profile": "https://vojtechh.eu/",
- "contributions": [
- "code",
- "translation"
- ]
- },
{
"login": "MeLlamoPablo",
"name": "Pablo Rodríguez",
@@ -79,6 +69,33 @@
"code"
]
},
+ {
+ "login": "tcely",
+ "name": "tcely",
+ "avatar_url": "https://avatars.githubusercontent.com/u/138864?v=4",
+ "profile": "https://github.com/tcely",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "Vonter",
+ "name": "Vonter",
+ "avatar_url": "https://avatars.githubusercontent.com/u/25414711?v=4",
+ "profile": "https://github.com/Vonter",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "raniapl",
+ "name": "Rania Pilioura",
+ "avatar_url": "https://avatars.githubusercontent.com/u/56370534?v=4",
+ "profile": "https://github.com/raniapl",
+ "contributions": [
+ "code"
+ ]
+ },
{
"login": "stamatiap",
"name": "Stamatia Papageorgiou",
@@ -90,19 +107,29 @@
]
},
{
- "login": "The-EDev",
- "name": "Farook Al-Sammarraie",
- "avatar_url": "https://avatars.githubusercontent.com/u/60552923?v=4",
- "profile": "https://github.com/The-EDev",
+ "login": "Zopieux",
+ "name": "Alexandre Macabies",
+ "avatar_url": "https://avatars.githubusercontent.com/u/81353?v=4",
+ "profile": "https://github.com/Zopieux",
"contributions": [
"code"
]
},
{
- "login": "Zopieux",
- "name": "Alexandre Macabies",
- "avatar_url": "https://avatars.githubusercontent.com/u/81353?v=4",
- "profile": "https://github.com/Zopieux",
+ "login": "vojta-horanek",
+ "name": "Vojtěch Hořánek",
+ "avatar_url": "https://avatars.githubusercontent.com/u/12630566?v=4",
+ "profile": "https://vojtechh.eu/",
+ "contributions": [
+ "code",
+ "translation"
+ ]
+ },
+ {
+ "login": "The-EDev",
+ "name": "Farook Al-Sammarraie",
+ "avatar_url": "https://avatars.githubusercontent.com/u/60552923?v=4",
+ "profile": "https://github.com/The-EDev",
"contributions": [
"code"
]
@@ -135,6 +162,17 @@
"financial"
]
},
+ {
+ "login": "Martin5001",
+ "name": "Martin Krejčí",
+ "avatar_url": "https://avatars.githubusercontent.com/u/35201200?v=4",
+ "profile": "https://github.com/Martin5001",
+ "contributions": [
+ "bug",
+ "ideas",
+ "translation"
+ ]
+ },
{
"login": "Shadowspear123",
"name": "Shadowspear123",
@@ -266,6 +304,15 @@
"translation"
]
},
+ {
+ "login": "Lego8486",
+ "name": "Ten_Lego",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/47414485",
+ "profile": "https://github.com/Lego8486",
+ "contributions": [
+ "translation"
+ ]
+ },
{
"login": "MoaufmKlo",
"name": "MoaufmKlo",
@@ -338,6 +385,15 @@
"translation"
]
},
+ {
+ "login": "rex07",
+ "name": "Rex_sa",
+ "avatar_url": "https://avatars.githubusercontent.com/u/13156001?v=4",
+ "profile": "https://github.com/rex07",
+ "contributions": [
+ "translation"
+ ]
+ },
{
"login": "rikishi0071",
"name": "rikishi0071",
@@ -375,10 +431,10 @@
]
},
{
- "login": "Lego8486",
- "name": "Ten_Lego",
- "avatar_url": "https://avatars1.githubusercontent.com/u/47414485",
- "profile": "https://github.com/Lego8486",
+ "login": "Umeaboy",
+ "name": "Kristoffer Grundström",
+ "avatar_url": "https://avatars.githubusercontent.com/u/714473?v=4",
+ "profile": "https://github.com/Umeaboy",
"contributions": [
"translation"
]
@@ -418,6 +474,15 @@
"contributions": [
"translation"
]
+ },
+ {
+ "login": "2hot2exist",
+ "name": "2hot2exist",
+ "avatar_url": "https://avatars.githubusercontent.com/u/84233003?v=4",
+ "profile": "https://github.com/2hot2exist",
+ "contributions": [
+ "translation"
+ ]
}
],
"contributorsPerLine": 6,
diff --git a/README.md b/README.md
index 7b374c7b..48491466 100755
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://makeapullrequest.com)
[![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/austinhuang0131/instagrabber.svg?style=social&label=Star)](https://GitHub.com/austinhuang0131/barinsta/stargazers/)
-[![All Contributors](https://img.shields.io/badge/all_contributors-44-orange.svg)](#contributors)
+[![All Contributors](https://img.shields.io/badge/all_contributors-51-orange.svg)](#contributors)
Instagram client; previously known as InstaGrabber.
@@ -59,59 +59,68 @@ Prominent contributors are listed here in the [all-contributors](https://allcont
Zerrium 💻 |
Chua Jun Hui 💻 |
Anderson Mesquita 💻 🐛 |
+ Pablo Rodríguez 💻 |
+
+
+ tcely 💻 |
+ Vonter 💻 |
+ Rania Pilioura 💻 |
+ Stamatia Papageorgiou 💻 🌍 |
+ Alexandre Macabies 💻 |
Vojtěch Hořánek 💻 🌍 |
- Pablo Rodríguez 💻 |
- Stamatia Papageorgiou 💻 🌍 |
Farook Al-Sammarraie 💻 |
- Alexandre Macabies 💻 |
Stefan Najdovski 🎨 🌍 |
CrazyMarvin 💵 |
+ Kevin Thomas 💵 |
+ Martin Krejčí 🐛 🤔 🌍 |
+ Shadowspear123 📝 🐛 🤔 💬 |
- Kevin Thomas 💵 |
- Shadowspear123 📝 🐛 🤔 💬 |
Ricardo 🐛 🌍 |
Akrai 🤔 🌍 |
avtkal 🌍 |
Cézar Augusto 🌍 |
-
-
Dimitris T 🌍 |
farzadx 🌍 |
+
+
Fatih Aydın 🌍 |
fouze555 🌍 |
Galang23 🌍 |
Initdebugs 🌍 |
-
-
Jakub Janek 🌍 |
GenosseFlosse 🌍 |
+
+
kernoeb 🌍 |
+ Ten_Lego 🌍 |
MoaufmKlo 🌍 |
nalinalini 🌍 |
peterge1998 🌍 |
+ PierreM0 🌍 |
- PierreM0 🌍 |
Pyrobauve 🌍 |
RAMAR-RAR 🌍 |
rohang02 🌍 |
retiolus 🌍 |
+ Rex_sa 🌍 |
rikishi0071 🌍 |
Alexey Peschany 🌍 |
Sitavi 🌍 |
Still Hsu 🌍 |
- Ten_Lego 🌍 |
+ Kristoffer Grundström 🌍 |
wagnim 🌍 |
wokija 🌍 |
ysakamoto 🌍 |
ZDVokoun 🌍 |
+ 2hot2exist 🌍 |
diff --git a/app/build.gradle b/app/build.gradle
index 6de63314..f184bcc6 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -180,6 +180,7 @@ dependencies {
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
implementation "androidx.preference:preference:1.1.1"
implementation 'androidx.palette:palette:1.0.0'
+ implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'com.google.guava:guava:27.0.1-android'
diff --git a/app/src/main/java/awais/instagrabber/activities/CameraActivity.kt b/app/src/main/java/awais/instagrabber/activities/CameraActivity.kt
index 1eca69d8..1ea124b6 100644
--- a/app/src/main/java/awais/instagrabber/activities/CameraActivity.kt
+++ b/app/src/main/java/awais/instagrabber/activities/CameraActivity.kt
@@ -52,7 +52,7 @@ class CameraActivity : BaseLanguageActivity() {
setContentView(binding.root)
Utils.transparentStatusBar(this, true, false)
displayManager = getSystemService(DISPLAY_SERVICE) as DisplayManager
- outputDirectory = DownloadUtils.getCameraDir()
+ outputDirectory = DownloadUtils.cameraDir
cameraExecutor = Executors.newSingleThreadExecutor()
displayManager.registerDisplayListener(displayListener, null)
binding.viewFinder.post {
diff --git a/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java b/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java
index ac94b02c..102640a6 100644
--- a/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java
+++ b/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java
@@ -226,7 +226,7 @@ public final class FeedAdapterV2 extends ListAdapter extends
- ListAdapter {
-
- private boolean isSelecting;
- private OnItemClickListener internalOnItemClickListener;
- private OnItemLongClickListener internalOnLongItemClickListener;
-
- private final List selectedItems = new ArrayList<>();
-
- protected MultiSelectListAdapter(@NonNull final DiffUtil.ItemCallback diffCallback,
- final OnItemClickListener clickListener,
- final OnItemLongClickListener longClickListener) {
- super(diffCallback);
- internalOnItemClickListener = (item, position) -> {
- if (isSelecting) {
- toggleSelection(item, position);
- }
- if (clickListener == null) {
- return;
- }
- clickListener.onItemClick(item, position);
- };
- internalOnLongItemClickListener = (item, position) -> {
- if (!isSelecting) {
- isSelecting = true;
- }
- toggleSelection(item, position);
- if (longClickListener == null) {
- return true;
- }
- return longClickListener.onItemLongClick(item, position);
- };
- }
-
- public OnItemClickListener getInternalOnItemClickListener() {
- return internalOnItemClickListener;
- }
-
- public OnItemLongClickListener getInternalOnLongItemClickListener() {
- return internalOnLongItemClickListener;
- }
-
- private void toggleSelection(final T item, final int position) {
- if (item == null) {
- return;
- }
- if (selectedItems.size() >= 100) {
- // Toast.makeText(mainActivity, R.string.downloader_too_many, Toast.LENGTH_SHORT);
- return;
- }
- if (item.isSelected()) {
- item.setSelected(false);
- selectedItems.remove(item);
- } else {
- item.setSelected(true);
- selectedItems.add(item);
- }
- if (selectedItems.size() == 0) {
- isSelecting = false;
- }
- notifyItemChanged(position);
- }
-
- public boolean isSelecting() {
- return isSelecting;
- }
-
- public List getSelectedModels() {
- return selectedItems;
- }
-
- public void clearSelection() {
- for (final T item : selectedItems) {
- item.setSelected(false);
- }
- selectedItems.clear();
- isSelecting = false;
- notifyDataSetChanged();
- }
-
- public interface Selectable {
- boolean isSelected();
-
- void setSelected(boolean selected);
- }
-
- public interface OnItemClickListener {
- void onItemClick(T item, int position);
- }
-
- public interface OnItemLongClickListener {
- boolean onItemLongClick(T item, int position);
- }
-}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
index 0643f7cd..bb1d3e03 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
@@ -122,7 +122,6 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
}
private void setLikes(@NonNull final Comment comment, final boolean isReply) {
- // final String likesString = itemView.getResources().getQuantityString(R.plurals.likes_count, likes, likes);
binding.likes.setText(String.valueOf(comment.getCommentLikeCount()));
binding.likes.setOnLongClickListener(v -> {
if (commentCallback == null) return false;
@@ -150,7 +149,6 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
final int replies = comment.getChildCommentCount();
binding.replies.setVisibility(View.VISIBLE);
final String text = isReply ? "" : String.valueOf(replies);
- // final String string = itemView.getResources().getQuantityString(R.plurals.replies_count, replies, replies);
binding.replies.setText(text);
binding.replies.setOnClickListener(v -> {
if (commentCallback == null) return;
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
index 44a3fcae..806faab5 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
@@ -47,7 +47,9 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
setupComments(media);
setupCaption(media);
if (media.getType() != MediaItemType.MEDIA_TYPE_SLIDER) {
- bottomBinding.btnDownload.setOnClickListener(v -> feedItemCallback.onDownloadClick(media, -1));
+ bottomBinding.btnDownload.setOnClickListener(v ->
+ feedItemCallback.onDownloadClick(media, -1, null)
+ );
}
bindItem(media);
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java
index 6931c851..66902340 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java
@@ -59,11 +59,15 @@ public class FeedSliderViewHolder extends FeedItemViewHolder {
final String text = (position + 1) + "/" + sliderItemLen;
binding.mediaCounter.setText(text);
setDimensions(binding.mediaList, sliderItems.get(position));
- binding.itemFeedBottom.btnDownload.setOnClickListener(v -> feedItemCallback.onDownloadClick(feedModel, position));
+ binding.itemFeedBottom.btnDownload.setOnClickListener(v ->
+ feedItemCallback.onDownloadClick(feedModel, position, binding.itemFeedBottom.btnDownload)
+ );
}
});
setDimensions(binding.mediaList, sliderItems.get(0));
- binding.itemFeedBottom.btnDownload.setOnClickListener(v -> feedItemCallback.onDownloadClick(feedModel, 0));
+ binding.itemFeedBottom.btnDownload.setOnClickListener(v ->
+ feedItemCallback.onDownloadClick(feedModel, 0, binding.itemFeedBottom.btnDownload)
+ );
adapter.submitList(sliderItems);
}
diff --git a/app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java b/app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java
index 77e55bbe..f69ebcc9 100644
--- a/app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java
@@ -126,10 +126,10 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
}
@Override
- public void onDownloadClick(final Media feedModel, final int childPosition) {
+ public void onDownloadClick(final Media feedModel, final int childPosition, final View popupLocation) {
final Context context = getContext();
if (context == null) return;
- DownloadUtils.showDownloadDialog(context, feedModel, childPosition);
+ DownloadUtils.showDownloadDialog(context, feedModel, childPosition, popupLocation);
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
index d04c9389..189820f6 100644
--- a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
@@ -145,10 +145,10 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
@Override
- public void onDownloadClick(final Media feedModel, final int childPosition) {
+ public void onDownloadClick(final Media feedModel, final int childPosition, final View popupLocation) {
final Context context = getContext();
if (context == null) return;
- DownloadUtils.showDownloadDialog(context, feedModel, childPosition);
+ DownloadUtils.showDownloadDialog(context, feedModel, childPosition, popupLocation);
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
index 6e18f5f0..17f1f1b9 100644
--- a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
@@ -139,10 +139,10 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
}
@Override
- public void onDownloadClick(final Media feedModel, final int childPosition) {
+ public void onDownloadClick(final Media feedModel, final int childPosition, final View popupLocation) {
final Context context = getContext();
if (context == null) return;
- DownloadUtils.showDownloadDialog(context, feedModel, childPosition);
+ DownloadUtils.showDownloadDialog(context, feedModel, childPosition, popupLocation);
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
index fd6d1ee5..9a987981 100644
--- a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
@@ -446,7 +446,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
private void setupDownload() {
bottom.download.setOnClickListener(v -> {
- DownloadUtils.showDownloadDialog(context, viewModel.getMedia(), sliderPosition);
+ DownloadUtils.showDownloadDialog(context, viewModel.getMedia(), sliderPosition, bottom.download);
});
TooltipCompat.setTooltipText(bottom.download, getString(R.string.action_download));
}
@@ -744,12 +744,6 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
final Media media = viewModel.getMedia();
final User profileModel = media.getUser();
if (profileModel == null) return;
- final boolean isPrivate = profileModel.isPrivate();
- if (isPrivate) {
- final Context context = getContext();
- if (context == null) return;
-// Toast.makeText(context, R.string.share_private_post, Toast.LENGTH_LONG).show();
- }
if (viewModel.isLoggedIn()) {
final Context context = getContext();
if (context == null) return;
@@ -776,7 +770,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
}
return true;
} else if (itemId == R.id.share) {
- shareLink(media, isPrivate);
+ shareLink(media, profileModel.isPrivate());
return true;
}
return false;
@@ -784,7 +778,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme
popupMenu.show();
return;
}
- shareLink(media, isPrivate);
+ shareLink(media, false);
});
}
diff --git a/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java
index 71d517b9..57c40b85 100644
--- a/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java
@@ -109,10 +109,10 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL
}
@Override
- public void onDownloadClick(final Media feedModel, final int childPosition) {
+ public void onDownloadClick(final Media feedModel, final int childPosition, final View popupLocation) {
final Context context = getContext();
if (context == null) return;
- DownloadUtils.showDownloadDialog(context, feedModel, childPosition);
+ DownloadUtils.showDownloadDialog(context, feedModel, childPosition, popupLocation);
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
index 59346a17..d6400c7e 100644
--- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
@@ -473,11 +473,11 @@ public class StoryViewerFragment extends Fragment {
poll = (PollSticker) tag;
final List tallies = poll.getTallies();
final String[] choices = tallies.stream()
- .map(t -> (poll.getViewerVote() == tallies.indexOf(t) ? "√ " : "")
+ .map(t -> (poll.getViewerVote() != null && poll.getViewerVote() == tallies.indexOf(t) ? "√ " : "")
+ t.getText() + " (" + t.getCount() + ")" )
.toArray(String[]::new);
final ArrayAdapter adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, choices);
- if (poll.getViewerVote() > -1) {
+ if (poll.getViewerVote() != null) {
new AlertDialog.Builder(context)
.setTitle(R.string.voted_story_poll)
.setAdapter(adapter, null)
@@ -577,16 +577,17 @@ public class StoryViewerFragment extends Fragment {
.setPositiveButton(R.string.cancel, null)
.show();
} else if (tag instanceof QuizSticker) {
+ quiz = (QuizSticker) tag;
final List tallies = quiz.getTallies();
final String[] choices = tallies.stream().map(
- t -> (quiz.getViewerAnswer() == tallies.indexOf(t) ? "√ " : "") +
+ t -> (quiz.getViewerAnswer() != null && quiz.getViewerAnswer() == tallies.indexOf(t) ? "√ " : "") +
(quiz.getCorrectAnswer() == tallies.indexOf(t) ? "*** " : "") +
t.getText() + " (" + t.getCount() + ")"
).toArray(String[]::new);
new AlertDialog.Builder(context)
- .setTitle(quiz.getViewerAnswer() > -1 ? getString(R.string.story_quizzed) : quiz.getQuestion())
+ .setTitle(quiz.getViewerAnswer() != null ? getString(R.string.story_quizzed) : quiz.getQuestion())
.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, choices), (d, w) -> {
- if (quiz.getViewerAnswer() == -1) {
+ if (quiz.getViewerAnswer() == null) {
sticking = true;
storiesRepository.respondToQuiz(
csrfToken,
@@ -901,7 +902,7 @@ public class StoryViewerFragment extends Fragment {
}
lastSlidePos = slidePos;
- final MediaItemType itemType = currentStory.getMediaType();
+ final MediaItemType itemType = currentStory.getType();
url = itemType == MediaItemType.MEDIA_TYPE_IMAGE
? ResponseBodyUtils.getImageUrl(currentStory)
@@ -966,7 +967,7 @@ public class StoryViewerFragment extends Fragment {
}
if (currentStory.getStoryCta() != null) {
- final StoryCta swipeUp = currentStory.getStoryCta().get(0).getLinks();
+ final StoryCta swipeUp = currentStory.getStoryCta().get(0).getLinks().get(0);
binding.swipeUp.setVisibility(View.VISIBLE);
binding.swipeUp.setText(currentStory.getLinkText());
final String swipeUpUrl = swipeUp.getWebUri();
diff --git a/app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java b/app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java
index bba645a7..acbc2eef 100644
--- a/app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/TopicPostsFragment.java
@@ -120,10 +120,10 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O
}
@Override
- public void onDownloadClick(final Media feedModel, final int childPosition) {
+ public void onDownloadClick(final Media feedModel, final int childPosition, final View popupLocation) {
final Context context = getContext();
if (context == null) return;
- DownloadUtils.showDownloadDialog(context, feedModel, childPosition);
+ DownloadUtils.showDownloadDialog(context, feedModel, childPosition, popupLocation);
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
index ae4e9b6b..593ea96f 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
@@ -116,10 +116,10 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
}
@Override
- public void onDownloadClick(final Media feedModel, final int childPosition) {
+ public void onDownloadClick(final Media feedModel, final int childPosition, final View popupLocation) {
final Context context = getContext();
if (context == null) return;
- DownloadUtils.showDownloadDialog(context, feedModel, childPosition);
+ DownloadUtils.showDownloadDialog(context, feedModel, childPosition, popupLocation);
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt
index 82d6a078..9c2ef9ae 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt
+++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.kt
@@ -127,8 +127,8 @@ class ProfileFragment : Fragment(), OnRefreshListener, ConfirmDialogFragmentCall
NavHostFragment.findNavController(this@ProfileFragment).navigate(commentsAction)
}
- override fun onDownloadClick(media: Media?, childPosition: Int) {
- DownloadUtils.showDownloadDialog(context ?: return, media ?: return, childPosition)
+ override fun onDownloadClick(media: Media?, childPosition: Int, popupLocation: View) {
+ DownloadUtils.showDownloadDialog(context ?: return, media ?: return, childPosition, popupLocation)
}
override fun onEmailClick(emailId: String?) {
diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/PollSticker.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/PollSticker.kt
index d95e1329..537a3d21 100644
--- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/PollSticker.kt
+++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/PollSticker.kt
@@ -6,8 +6,8 @@ import awais.instagrabber.repositories.responses.Location
import awais.instagrabber.repositories.responses.User
data class PollSticker(
- val pollId: Long?,
+ val pollId: Long,
val question: String?,
- val tallies: List?,
- var viewerVote: Int = -1
+ val tallies: List,
+ var viewerVote: Int?
) : Serializable
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/QuestionSticker.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/QuestionSticker.kt
index 7b9f1bf8..7dfec43c 100644
--- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/QuestionSticker.kt
+++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/QuestionSticker.kt
@@ -7,6 +7,6 @@ import awais.instagrabber.repositories.responses.User
data class QuestionSticker(
val questionType: String?,
- val questionId: Long?,
- val question: String?
+ val questionId: Long,
+ val question: String
) : Serializable
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/QuizSticker.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/QuizSticker.kt
index 5a82a88f..45f237f2 100644
--- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/QuizSticker.kt
+++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/QuizSticker.kt
@@ -8,7 +8,7 @@ import awais.instagrabber.repositories.responses.User
data class QuizSticker(
val quizId: Long?,
val question: String?,
- val tallies: List?,
- var viewerAnswer: Int? = -1,
- val correctAnswer: Int?
+ val tallies: List,
+ var viewerAnswer: Int?,
+ val correctAnswer: Int
) : Serializable
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryMedia.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryMedia.kt
index 47af8625..f9559fd0 100644
--- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryMedia.kt
+++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryMedia.kt
@@ -1,6 +1,7 @@
package awais.instagrabber.repositories.responses.stories
import awais.instagrabber.models.enums.MediaItemType
+import awais.instagrabber.models.enums.MediaItemType.Companion.valueOf
import awais.instagrabber.repositories.responses.ImageVersions2
import awais.instagrabber.repositories.responses.MediaCandidate
import awais.instagrabber.repositories.responses.User
@@ -9,36 +10,36 @@ import java.io.Serializable
data class StoryMedia(
// inherited from Media
- val pk: String? = null,
- val id: String? = null,
- val takenAt: Long = -1,
- val user: User? = null,
- val canReshare: Boolean = false,
- val imageVersions2: ImageVersions2? = null,
- val originalWidth: Int = 0,
- val originalHeight: Int = 0,
- val mediaType: MediaItemType? = null,
- val isReelMedia: Boolean = false,
- val videoVersions: List? = null,
- val hasAudio: Boolean = false,
- val videoDuration: Double = 0.0,
- val viewCount: Long = 0,
- val title: String? = null,
- // story-specific
- val canReply: Boolean = false,
- val linkText: String? = null, // required for story_cta
- // stickers
- val reelMentions: List? = null,
- val storyHashtags: List? = null,
- val storyLocations: List? = null,
- val storyFeedMedia: List? = null,
- val storyPolls: List? = null,
- val storyQuestions: List? = null,
- val storyQuizs: List? = null,
- val storyCta: List? = null,
- val storySliders: List? = null,
- // spotify/soundcloud button, not a sticker
- val storyAppAttribution: StoryAppAttribution? = null
+ val pk: String? = null,
+ val id: String? = null,
+ val takenAt: Long = -1,
+ val user: User? = null,
+ val canReshare: Boolean = false,
+ val imageVersions2: ImageVersions2? = null,
+ val originalWidth: Int = 0,
+ val originalHeight: Int = 0,
+ val mediaType: Int = 0,
+ val isReelMedia: Boolean = false,
+ val videoVersions: List? = null,
+ val hasAudio: Boolean = false,
+ val videoDuration: Double = 0.0,
+ val viewCount: Long = 0,
+ val title: String? = null,
+ // story-specific
+ val canReply: Boolean = false,
+ val linkText: String? = null, // required for story_cta
+ // stickers
+ val reelMentions: List? = null,
+ val storyHashtags: List? = null,
+ val storyLocations: List? = null,
+ val storyFeedMedia: List? = null,
+ val storyPolls: List? = null,
+ val storyQuestions: List? = null,
+ val storyQuizs: List? = null,
+ val storyCta: List? = null,
+ val storySliders: List? = null,
+ // spotify/soundcloud button, not a sticker
+ val storyAppAttribution: StoryAppAttribution? = null
) : Serializable {
private var dateString: String? = null
var position = 0
@@ -48,6 +49,9 @@ data class StoryMedia(
// val date: String by lazy {
// if (takenAt <= 0) "" else Utils.datetimeParser.format(Date(takenAt * 1000L))
// }
+ val type: MediaItemType?
+ get() = valueOf(mediaType)
+
val date: String
get() {
if (takenAt <= 0) return ""
diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/StorySticker.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StorySticker.kt
index 7f40f94a..1f154e30 100644
--- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/StorySticker.kt
+++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StorySticker.kt
@@ -14,6 +14,6 @@ data class StorySticker(
val pollSticker: PollSticker?, // story_polls
val questionSticker: QuestionSticker?, // story_questions
val quizSticker: QuizSticker?, // story_quizs
- val links: StoryCta?, // story_cta, requires link_text from the story
+ val links: List?, // story_cta, requires link_text from the story
val sliderSticker: SliderSticker? // story_sliders
) : Serializable
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/utils/DownloadUtils.kt b/app/src/main/java/awais/instagrabber/utils/DownloadUtils.kt
index d5f3eebb..14410239 100644
--- a/app/src/main/java/awais/instagrabber/utils/DownloadUtils.kt
+++ b/app/src/main/java/awais/instagrabber/utils/DownloadUtils.kt
@@ -1,14 +1,16 @@
package awais.instagrabber.utils
import android.content.Context
-import android.content.DialogInterface
import android.content.UriPermission
import android.net.Uri
import android.provider.DocumentsContract
import android.util.Log
-import android.widget.Toast
-import androidx.appcompat.app.AlertDialog
-import androidx.core.util.Pair
+import android.view.MenuItem
+import android.view.View
+import androidx.appcompat.view.ContextThemeWrapper
+import androidx.appcompat.widget.PopupMenu
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
import androidx.documentfile.provider.DocumentFile
import androidx.work.*
import awais.instagrabber.R
@@ -16,6 +18,7 @@ import awais.instagrabber.fragments.settings.PreferenceKeys
import awais.instagrabber.models.enums.MediaItemType
import awais.instagrabber.repositories.responses.Media
import awais.instagrabber.repositories.responses.stories.StoryMedia
+import awais.instagrabber.utils.AppExecutors.tasksThread
import awais.instagrabber.utils.TextUtils.isEmpty
import awais.instagrabber.workers.DownloadWorker
import com.google.gson.Gson
@@ -24,6 +27,7 @@ import java.io.IOException
import java.io.OutputStreamWriter
import java.util.*
import java.util.regex.Pattern
+import kotlin.math.abs
object DownloadUtils {
@@ -36,6 +40,8 @@ object DownloadUtils {
private const val DIR_RECORDINGS = "Sent Recordings"
private const val DIR_TEMP = "Temp"
private const val DIR_BACKUPS = "Backups"
+ private const val MIME_DIR = DocumentsContract.Document.MIME_TYPE_DIR
+ private val dirMap: MutableMap = mutableMapOf()
private var root: DocumentFile? = null
@JvmStatic
@Throws(ReselectDocumentTreeException::class)
@@ -48,18 +54,15 @@ object DownloadUtils {
}
val uri = Uri.parse(barinstaDirUri)
if (!barinstaDirUri!!.startsWith("content://com.android.externalstorage.documents")) {
- // reselect the folder in selector view
throw ReselectDocumentTreeException(uri)
}
val existingPermissions = context.contentResolver.persistedUriPermissions
if (existingPermissions.isEmpty()) {
- // reselect the folder in selector view
throw ReselectDocumentTreeException(uri)
}
val anyMatch = existingPermissions.stream()
.anyMatch { uriPermission: UriPermission -> uriPermission.uri == uri }
if (!anyMatch) {
- // reselect the folder in selector view
throw ReselectDocumentTreeException(uri)
}
root = DocumentFile.fromTreeUri(context, uri)
@@ -68,155 +71,152 @@ object DownloadUtils {
throw ReselectDocumentTreeException(uri)
}
Utils.settingsHelper.putString(PreferenceKeys.PREF_BARINSTA_DIR_URI, uri.toString())
+ // set up directories
+ val dirKeys = mapOf(
+ DIR_DOWNLOADS to MIME_DIR,
+ DIR_CAMERA to MIME_DIR,
+ DIR_EDIT to MIME_DIR,
+ DIR_RECORDINGS to MIME_DIR,
+ DIR_TEMP to MIME_DIR,
+ DIR_BACKUPS to MIME_DIR
+ )
+ dirMap.putAll(checkFiles(context, root, dirKeys, true))
}
fun destroy() {
root = null
+ dirMap.clear()
}
- fun getDownloadDir(vararg dirs: String?): DocumentFile? {
- if (root == null) {
- return null
+ fun checkFiles(context: Context,
+ parent: DocumentFile?,
+ queries: Map, //
+ create: Boolean
+ ): Map {
+ // first we'll find existing ones
+ val result: MutableMap = mutableMapOf()
+ if (root == null || parent == null || !parent.isDirectory) return result.toMap()
+ val docId = DocumentsContract.getDocumentId(parent.uri)
+ val docUri = DocumentsContract.buildChildDocumentsUriUsingTree(root!!.uri, docId)
+ val docCursor = context.contentResolver.query(
+ docUri, arrayOf(
+ DocumentsContract.Document.COLUMN_DISPLAY_NAME,
+ DocumentsContract.Document.COLUMN_DOCUMENT_ID,
+ DocumentsContract.Document.COLUMN_MIME_TYPE
+ ), null, null, null
+ )
+ if (docCursor == null) return result.toMap()
+ while (docCursor.moveToNext()) {
+ val q = queries.get(docCursor.getString(0))
+ if (q == null || !docCursor.getString(2).equals(q)) continue
+ val fileUri = DocumentsContract.buildDocumentUriUsingTree(parent.uri, docCursor.getString(1))
+ val dir = if (q.equals(MIME_DIR)) DocumentFile.fromTreeUri(context, fileUri)
+ else DocumentFile.fromSingleUri(context, fileUri)
+ result.put(docCursor.getString(0), dir)
+ if (result.size >= queries.size) break
}
- var subDir = root
- for (dir in dirs) {
- if (subDir == null || isEmpty(dir)) continue
- val subDirFile = subDir.findFile(dir!!)
- val exists = subDirFile != null && subDirFile.exists()
- subDir = if (exists) subDirFile else subDir.createDirectory(dir)
+ docCursor.close()
+ // next we'll create inexistent ones, if necessary
+ if (create) {
+ for (k in queries) {
+ if (result.get(k.key) == null) {
+ result.put(k.key, if (MIME_DIR.equals(k.value)) parent.createDirectory(k.key)
+ else parent.createFile(k.value, k.key))
+ }
+ }
}
- return subDir
+ return result.toMap()
+ }
+
+ fun getRootDir(dir: String): DocumentFile? {
+ if (root == null) return null
+ return dirMap.get(dir)
}
@JvmStatic
val downloadDir: DocumentFile?
- get() = getDownloadDir(DIR_DOWNLOADS)
+ get() = getRootDir(DIR_DOWNLOADS)
@JvmStatic
- fun getCameraDir(): DocumentFile? {
- return getDownloadDir(DIR_CAMERA)
+ val cameraDir: DocumentFile?
+ get() = getRootDir(DIR_CAMERA)
+
+ @JvmStatic
+ fun getImageEditDir(sessionId: String?, context: Context): DocumentFile? {
+ val editRoot = getRootDir(DIR_EDIT)
+ if (sessionId == null) return editRoot
+ return checkFiles(context,
+ editRoot,
+ mapOf(sessionId to MIME_DIR),
+ true).get(sessionId)
}
@JvmStatic
- fun getImageEditDir(sessionId: String?): DocumentFile? {
- return getDownloadDir(DIR_EDIT, sessionId)
- }
-
- fun getRecordingsDir(): DocumentFile? {
- return getDownloadDir(DIR_RECORDINGS)
- }
+ val recordingsDir: DocumentFile?
+ get() = getRootDir(DIR_RECORDINGS)
@JvmStatic
- fun getBackupsDir(): DocumentFile? {
- return getDownloadDir(DIR_BACKUPS)
- }
+ val backupsDir: DocumentFile?
+ get() = getRootDir(DIR_BACKUPS)
- // @Nullable
- // private static DocumentFile getDownloadDir(@NonNull final Context context, @Nullable final String username) {
- // return getDownloadDir(context, username, false);
- // }
private fun getDownloadDir(
- context: Context?,
- username: String?
+ context: Context,
+ username: String?,
+ shouldCreate: Boolean
): DocumentFile? {
- val userFolderPaths: List = getSubPathForUserFolder(username)
- var dir = root
- for (dirName in userFolderPaths) {
- val file = dir!!.findFile(dirName)
- if (file != null) {
- dir = file
- continue
- }
- dir = dir.createDirectory(dirName)
- if (dir == null) break
- }
- // final String joined = android.text.TextUtils.join("/", userFolderPaths);
- // final Uri userFolderUri = DocumentsContract.buildDocumentUriUsingTree(root.getUri(), joined);
- // final DocumentFile userFolder = DocumentFile.fromSingleUri(context, userFolderUri);
- if (context != null && (dir == null || !dir.exists())) {
- Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show()
- return null
- }
- return dir
+ if (!Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_USER_FOLDER) || username.isNullOrEmpty())
+ return downloadDir
+ return checkFiles(context,
+ downloadDir,
+ mapOf(username to MIME_DIR),
+ shouldCreate).get(username)
}
- private fun getSubPathForUserFolder(username: String?): MutableList {
- val list: MutableList = ArrayList()
- if (!Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_USER_FOLDER) ||
- username.isNullOrEmpty()) {
- list.add(DIR_DOWNLOADS)
- return list
- }
- val finalUsername = if (username.startsWith("@")) username.substring(1) else username
- list.add(DIR_DOWNLOADS)
- list.add(finalUsername)
- return list
- }
-
- private fun getTempDir(): DocumentFile? {
- var file = root!!.findFile(DIR_TEMP)
- if (file == null) {
- file = root!!.createDirectory(DIR_TEMP)
- }
- return file
- }
+ private val tempDir: DocumentFile?
+ get() = getRootDir(DIR_TEMP)
private fun getDownloadSavePaths(
- paths: MutableList,
postId: String?,
displayUrl: String?
- ): Pair, String?>? {
- return getDownloadSavePaths(paths, postId, "", displayUrl, "")
+ ): Pair {
+ return getDownloadFileName(postId, "", displayUrl, "")
}
private fun getDownloadSavePaths(
- paths: MutableList,
postId: String?,
displayUrl: String,
username: String
- ): Pair, String?>? {
- return getDownloadSavePaths(paths, postId, "", displayUrl, username)
+ ): Pair {
+ return getDownloadFileName(postId, "", displayUrl, username)
}
private fun getDownloadChildSavePaths(
- paths: MutableList,
postId: String?,
childPosition: Int,
url: String?,
username: String
- ): Pair, String?>? {
+ ): Pair {
val sliderPostfix = "_slide_$childPosition"
- return getDownloadSavePaths(paths, postId, sliderPostfix, url, username)
+ return getDownloadFileName(postId, sliderPostfix, url, username)
}
- private fun getDownloadSavePaths(
- paths: MutableList?,
+ private fun getDownloadFileName(
postId: String?,
sliderPostfix: String,
displayUrl: String?,
username: String
- ): Pair, String?>? {
- if (paths == null) return null
+ ): Pair {
val extension = getFileExtensionFromUrl(displayUrl)
val usernamePrepend = if (isEmpty(username)) "" else username + "_"
val fileName = usernamePrepend + postId + sliderPostfix + extension
- // return new File(finalDir, fileName);
- // DocumentFile file = finalDir.findFile(fileName);
- // if (file == null) {
val mimeType = Utils.mimeTypeMap.getMimeTypeFromExtension(
if (extension.startsWith(".")) extension.substring(1) else extension
)
- // file = finalDir.createFile(mimeType, fileName);
- // }
- paths.add(fileName)
- return Pair(paths, mimeType)
+ return Pair(fileName, mimeType!!)
}
- // public static DocumentFile getTempFile() {
- // return getTempFile(null, null);
- // }
fun getTempFile(fileName: String?, extension: String): DocumentFile? {
- val dir = getTempDir()
+ val dir = tempDir
var name = fileName
if (isEmpty(name)) {
name = UUID.randomUUID().toString()
@@ -284,26 +284,23 @@ object DownloadUtils {
if (user != null) {
username = user.username
}
- val userFolderPaths: List = getSubPathForUserFolder(username)
+ val userFolder = getDownloadDir(context, username, false)
+ if (userFolder == null) return checkList
when (media.type) {
MediaItemType.MEDIA_TYPE_IMAGE, MediaItemType.MEDIA_TYPE_VIDEO -> {
val url =
if (media.type == MediaItemType.MEDIA_TYPE_VIDEO) ResponseBodyUtils.getVideoUrl(
media
) else ResponseBodyUtils.getImageUrl(media)
- val file = getDownloadSavePaths(ArrayList(userFolderPaths), media.code, url, "")
- val fileExists = file!!.first != null && checkPathExists(file.first, context)
- var usernameFileExists = false
- if (!fileExists) {
- val usernameFile = getDownloadSavePaths(
- ArrayList(userFolderPaths), media.code, url, username
- )
- usernameFileExists = usernameFile!!.first != null && checkPathExists(usernameFile.first, context)
- }
- checkList.add(fileExists || usernameFileExists)
+ val fileName = getDownloadSavePaths(media.code, url)
+ val fileNameWithUser = getDownloadSavePaths(media.code, url, username)
+ val files = checkFiles(context, userFolder, mapOf(fileName, fileNameWithUser), false)
+ checkList.add(files.size > 0)
}
MediaItemType.MEDIA_TYPE_SLIDER -> {
val sliderItems = media.carouselMedia
+ val fileNames: MutableMap = mutableMapOf()
+ val filePairs: MutableMap = mutableMapOf()
var i = 0
while (i < sliderItems!!.size) {
val child = sliderItems[i]
@@ -311,20 +308,17 @@ object DownloadUtils {
if (child.type == MediaItemType.MEDIA_TYPE_VIDEO) ResponseBodyUtils.getVideoUrl(
child
) else ResponseBodyUtils.getImageUrl(child)
- val file = getDownloadChildSavePaths(
- ArrayList(userFolderPaths), media.code, i + 1, url, ""
- )
- val fileExists = file!!.first != null && checkPathExists(file.first, context)
- var usernameFileExists = false
- if (!fileExists) {
- val usernameFile = getDownloadChildSavePaths(
- ArrayList(userFolderPaths), media.code, i + 1, url, username
- )
- usernameFileExists = usernameFile!!.first != null && checkPathExists(usernameFile.first, context)
- }
- checkList.add(fileExists || usernameFileExists)
+ val fileName = getDownloadChildSavePaths(media.code, i+1, url, "")
+ val fileNameWithUser = getDownloadChildSavePaths(media.code, i+1, url, username)
+ fileNames.put(fileName.first, fileName.second)
+ fileNames.put(fileNameWithUser.first, fileNameWithUser.second)
+ filePairs.put(fileName.first, fileNameWithUser.first)
i++
}
+ val files = checkFiles(context, userFolder, fileNames, false)
+ for (p in filePairs) {
+ checkList.add(files.get(p.key) != null || files.get(p.value) != null)
+ }
}
else -> {
}
@@ -332,61 +326,32 @@ object DownloadUtils {
return checkList
}
- private fun checkPathExists(paths: List, context: Context): Boolean {
- if (root == null) return false
- val uri = root!!.uri
- var found = false
- var docId = DocumentsContract.getTreeDocumentId(uri)
- for (path in paths) {
- val docUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, docId)
- val docCursor = context.contentResolver.query(
- docUri, arrayOf(
- DocumentsContract.Document.COLUMN_DISPLAY_NAME,
- DocumentsContract.Document.COLUMN_DOCUMENT_ID
- ), null, null, null
- )
- if (docCursor == null) return false
- while (docCursor.moveToNext() && !found) {
- if (path.equals(docCursor.getString(0))) {
- docId = docCursor.getString(1)
- found = true
- }
- }
- docCursor.close()
- if (!found) return false
- found = false
- }
- return true
- }
-
@JvmStatic
fun showDownloadDialog(
context: Context,
feedModel: Media,
- childPosition: Int
+ childPosition: Int,
+ popupLocation: View?
) {
- if (childPosition >= 0) {
- val clickListener =
- DialogInterface.OnClickListener { dialog: DialogInterface, which: Int ->
- when (which) {
- 0 -> download(context, feedModel, childPosition)
- 1 -> download(context, feedModel)
- DialogInterface.BUTTON_NEGATIVE -> dialog.dismiss()
- else -> dialog.dismiss()
- }
- }
- val items = arrayOf(
- context.getString(R.string.post_viewer_download_current),
- context.getString(R.string.post_viewer_download_album)
- )
- AlertDialog.Builder(context)
- .setTitle(R.string.post_viewer_download_dialog_title)
- .setItems(items, clickListener)
- .setNegativeButton(R.string.cancel, null)
- .show()
+ if (childPosition == -1 || popupLocation == null) {
+ download(context, feedModel)
return
}
- download(context, feedModel)
+ val themeWrapper = ContextThemeWrapper(context, R.style.popupMenuStyle)
+ val popupMenu = PopupMenu(themeWrapper, popupLocation)
+ val menu = popupMenu.menu
+ menu.add(0, R.id.download_current, 0, R.string.post_viewer_download_current)
+ menu.add(0, R.id.download_all, 1, R.string.post_viewer_download_album)
+ popupMenu.setOnMenuItemClickListener { item: MenuItem ->
+ val itemId = item.itemId
+ if (itemId == R.id.download_current) {
+ download(context, feedModel, childPosition)
+ } else if (itemId == R.id.download_all) {
+ download(context, feedModel)
+ }
+ false
+ }
+ popupMenu.show()
}
@JvmStatic
@@ -394,27 +359,19 @@ object DownloadUtils {
context: Context,
storyModel: StoryMedia
) {
- val downloadDir = getDownloadDir(context, storyModel.user?.username) ?: return
+ val downloadDir = getDownloadDir(context, storyModel.user?.username, true) ?: return
val url =
- if (storyModel.mediaType == MediaItemType.MEDIA_TYPE_VIDEO) ResponseBodyUtils.getVideoUrl(storyModel)
+ if (storyModel.type == MediaItemType.MEDIA_TYPE_VIDEO) ResponseBodyUtils.getVideoUrl(storyModel)
else ResponseBodyUtils.getImageUrl(storyModel)
val extension = getFileExtensionFromUrl(url)
- val baseFileName = (storyModel.id + "_"
- + storyModel.takenAt + extension)
+ val mimeType = Utils.mimeTypeMap.getMimeTypeFromExtension(extension)
+ val baseFileName = storyModel.id + "_" + storyModel.takenAt + extension
val usernamePrepend =
if (Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME)
&& storyModel.user?.username != null
) storyModel.user.username + "_" else ""
val fileName = usernamePrepend + baseFileName
- var saveFile = downloadDir.findFile(fileName)
- if (saveFile == null) {
- val mimeType = Utils.mimeTypeMap.getMimeTypeFromExtension(
- if (extension.startsWith(".")) extension.substring(1) else extension
- )
- ?: return
- saveFile = downloadDir.createFile(mimeType, fileName)
- }
- // final File saveFile = new File(downloadDir, fileName);
+ var saveFile = checkFiles(context, downloadDir, mapOf(fileName to mimeType!!), true).get(fileName)
download(context, url, saveFile)
}
@@ -428,12 +385,28 @@ object DownloadUtils {
download(context, listOf(feedModel), position)
}
+ // this must be used for bulk download, but ONLY bulk download
@JvmStatic
fun download(
context: Context,
feedModels: List
) {
- download(context, feedModels, -1)
+ val builder = NotificationCompat.Builder(context, Constants.DOWNLOAD_CHANNEL_ID)
+ .setCategory(NotificationCompat.CATEGORY_PROGRESS)
+ .setSmallIcon(R.drawable.ic_download)
+ .setOngoing(true)
+ .setProgress(1, 0, true)
+ .setAutoCancel(false)
+ .setOnlyAlertOnce(true)
+ .setContentTitle(context.getString(R.string.downloader_preparing))
+ val notification = builder.build()
+ val nid = abs(UUID.randomUUID().hashCode())
+ val nManager = NotificationManagerCompat.from(context.applicationContext)
+ nManager.notify(nid, notification)
+ tasksThread.execute {
+ download(context, feedModels, -1)
+ nManager.cancel(nid)
+ }
}
private fun download(
@@ -441,11 +414,12 @@ object DownloadUtils {
feedModels: List,
childPositionIfSingle: Int
) {
- val map: MutableMap = HashMap()
+ val map: MutableMap> = HashMap()
+ val fileMap: MutableMap = HashMap()
for (media in feedModels) {
val mediaUser = media.user
val username = mediaUser?.username ?: ""
- val userFolderPaths = getSubPathForUserFolder(username)
+ val dir = getDownloadDir(context, username, true)
when (media.type) {
MediaItemType.MEDIA_TYPE_IMAGE, MediaItemType.MEDIA_TYPE_VIDEO -> {
val url = getUrlOfType(media)
@@ -459,9 +433,8 @@ object DownloadUtils {
fileName = mediaUser.username + "_" + fileName
}
}
- val pair = getDownloadSavePaths(userFolderPaths, fileName, url)
- val file = createFile(pair!!) ?: continue
- map[url!!] = file
+ val pair = getDownloadSavePaths(fileName, url)
+ map[url!!] = pair
}
MediaItemType.MEDIA_TYPE_VOICE -> {
val url = getUrlOfType(media)
@@ -469,9 +442,8 @@ object DownloadUtils {
if (mediaUser != null) {
fileName = mediaUser.username + "_" + fileName
}
- val pair = getDownloadSavePaths(userFolderPaths, fileName, url)
- val file = createFile(pair!!) ?: continue
- map[url!!] = file
+ val pair = getDownloadSavePaths(fileName, url)
+ map[url!!] = pair
}
MediaItemType.MEDIA_TYPE_SLIDER -> {
val sliderItems = media.carouselMedia
@@ -485,43 +457,18 @@ object DownloadUtils {
val url = getUrlOfType(child)
val usernamePrepend =
if (Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME) && mediaUser != null) mediaUser.username else ""
- val pair = getDownloadChildSavePaths(
- ArrayList(userFolderPaths), media.code, i + 1, url, usernamePrepend
- )
- val file = createFile(pair!!)
- if (file == null) {
- i++
- continue
- }
- map[url!!] = file
+ val pair = getDownloadChildSavePaths(media.code, i + 1, url, usernamePrepend)
+ map[url!!] = pair
i++
}
}
}
+ fileMap.putAll(checkFiles(context, dir, map.values.toMap(), true))
}
- if (map.isEmpty()) return
- download(context, map)
- }
-
- private fun createFile(pair: Pair, String?>): DocumentFile? {
- if (root == null) return null
- if (pair.first == null || pair.second == null) return null
- var dir = root
- val first = pair.first
- for (i in first.indices) {
- val name = first[i]
- val file = dir!!.findFile(name)
- if (file != null) {
- dir = file
- continue
- }
- dir = if (i == first.size - 1) dir.createFile(
- pair.second!!,
- name
- ) else dir.createDirectory(name)
- if (dir == null) break
- }
- return dir
+ if (map.isEmpty() || fileMap.isEmpty()) return
+ val resultMap: MutableMap = mutableMapOf()
+ map.mapValuesTo(resultMap) { fileMap.get(it.value.first) }
+ download(context, resultMap)
}
private fun getUrlOfType(media: Media): String? {
@@ -559,7 +506,7 @@ object DownloadUtils {
download(context, Collections.singletonMap(url!!, filePath))
}
- private fun download(context: Context?, urlFilePathMap: Map) {
+ private fun download(context: Context?, urlFilePathMap: Map) {
if (context == null) return
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
diff --git a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt
index 200f4deb..479ce01b 100644
--- a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt
+++ b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt
@@ -34,7 +34,7 @@ class DirectThreadViewModel(
// private static final String ERROR_INVALID_THREAD = "Invalid thread";
private val contentResolver: ContentResolver = application.contentResolver
- private val recordingsDir: DocumentFile? = DownloadUtils.getRecordingsDir()
+ private val recordingsDir: DocumentFile? = DownloadUtils.recordingsDir
private var voiceRecorder: VoiceRecorder? = null
private lateinit var threadManager: ThreadManager
diff --git a/app/src/main/java/awais/instagrabber/viewmodels/ImageEditViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/ImageEditViewModel.java
index ebbfc2f6..11c8f15a 100644
--- a/app/src/main/java/awais/instagrabber/viewmodels/ImageEditViewModel.java
+++ b/app/src/main/java/awais/instagrabber/viewmodels/ImageEditViewModel.java
@@ -59,7 +59,7 @@ public class ImageEditViewModel extends AndroidViewModel {
public ImageEditViewModel(final Application application) {
super(application);
sessionId = LocalDateTime.now().format(SIMPLE_DATE_FORMAT);
- outputDir = DownloadUtils.getImageEditDir(sessionId);
+ outputDir = DownloadUtils.getImageEditDir(sessionId, application);
destinationFile = outputDir.createFile(MIME_TYPE, RESULT + ".jpg");
destinationUri = destinationFile.getUri();
cropDestinationUri = outputDir.createFile(MIME_TYPE, CROP + ".jpg").getUri();
diff --git a/app/src/main/java/awais/instagrabber/workers/DownloadWorker.kt b/app/src/main/java/awais/instagrabber/workers/DownloadWorker.kt
index d499c1b2..e0c80664 100644
--- a/app/src/main/java/awais/instagrabber/workers/DownloadWorker.kt
+++ b/app/src/main/java/awais/instagrabber/workers/DownloadWorker.kt
@@ -393,9 +393,10 @@ class DownloadWorker(context: Context, workerParams: WorkerParameters) : Corouti
class Builder {
private var urlToFilePathMap: MutableMap = mutableMapOf()
- fun setUrlToFilePathMap(urlToFilePathMap: Map): Builder {
+ fun setUrlToFilePathMap(urlToFilePathMap: Map): Builder {
this.urlToFilePathMap = urlToFilePathMap
- .mapValues { it.value.uri.toString() }
+ .filter{ it.value != null }
+ .mapValues { it.value!!.uri.toString() }
.toMutableMap()
return this
}
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 5505bf1c..cccace7d 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -40,8 +40,6 @@
حفظ في مجلد مخصص
تحديد مجلد
السمة
- فقط يؤثر على المستخدمين المسجلين:
- يؤثر فقط على مستخدمين مجهولين:
اللغة
- %s\nPosts
@@ -125,10 +123,7 @@
تم الحفظ
مشار إليها
الرسالة
- اعجاب
- إلغاء الإعجاب
Bookmark
- Unbookmark
Follow
Unfollow
Favorite
@@ -156,7 +151,6 @@
Failed to export!
Refresh
Get cookies
- Desktop Mode
Use custom format
Separator
Time Format
@@ -223,14 +217,8 @@
Error creating folder!
Error downloading file
You can only download 100 posts at a time. Don\'t be too greedy!
- Copy comment
- View comment likers
- Reply to comment
- Like comment
- Unlike comment
Translate comment
Delete comment
- No empty comments!
Do you want to search the username?
Do you want to search the hashtag?
Followers
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 91d7f9f2..9fb0f75c 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -40,8 +40,6 @@
Desa a una carpeta personalitzada
Selecciona la carpeta
Tema
- Només afecta als usuaris amb sessió iniciada:
- Només afecta als usuaris anònims:
Llengua
- %s\nPublicació
@@ -109,10 +107,7 @@
Desat
Etiquetat
Missatge
- M\'agrada
- Desfer \"m\'agrada\"
Marcador
- Desfer marcador
Seguir
Deixar de seguir
Preferit
@@ -140,7 +135,6 @@
No s\'ha pogut exportar!
Actualitzar
Obtenir cookies
- Mode escriptori
Utilitza un format personalitzat
Separador
Format d\'hora
@@ -207,14 +201,8 @@
S\'ha produït un error en crear la carpeta!
S\'ha produït un error en descarregar l\'arxiu
Només pots descarregar 100 publicacions alhora. No siguis massa cobdiciós!
- Copiar el comentari
- Veure m\'agrades del comentari
- Respondre al comentari
- Donar \"m\'agrada\" al comentari
- Treure \"m\'agrada\" al comentari
Traduir comentari
Esborrar comentari
- No als comentaris buits!
Vols cercar el nom d\'usuari?
Vols cercar l\'etiqueta?
Seguidors
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index ab3d1865..bc7b3db6 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -40,8 +40,6 @@
Uložit do vlastní složky
Vybrat složku
Motiv
- Týká se pouze přihlášených uživatelů:
- Týká se pouze anonymních uživatelů:
Jazyk
- %s\nPříspěvek
@@ -117,10 +115,7 @@
Uložené
Označení
Zpráva
- To se mi líbí
- Už se mi to nelíbí
Přidat do záložek
- Odebrat záložku
Sledovat
Přestat sledovat
Oblíbené
@@ -148,7 +143,6 @@
Export se nezdařil!
Načíst znovu
Získat cookies
- Režim počítače
Použít vlastní formát
Oddělovač
Formát času
@@ -215,14 +209,8 @@
Chyba při vytváření složky!
Chyba při stahování souboru
Můžete stahovat pouze 100 příspěvků najednou. Nebuďte příliš chamtiví!
- Kopírovat komentář
- Zobrazit, komu se komentář líbí
- Odpovědět na komentář
- Označit komentář lajkem
- Odebrat lajk z komentáře
Přeložit komentář
Odstranit komentář
- Žádné prázdné komentáře!
Chcete vyhledat uživatelské jméno?
Chcete vyhledat hashtag?
Sledující
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 31c1ea3d..93f78af7 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -40,8 +40,6 @@
In benutzerdefiniertem Ordner speichern
Ordner auswählen
Design
- Betrifft nur angemeldete Benutzer:
- Betrifft nur anonyme Benutzer:
Sprache
- %s\nBeitrag
@@ -109,10 +107,7 @@
Gespeichert
Markiert
Nachricht
- Gefällt mir
- Gefällt mir nicht mehr
Lesezeichen
- Lesezeichen entfernen
Folgen
Nicht mehr folgen
Favorit
@@ -140,7 +135,6 @@
Export fehlgeschlagen!
Aktualisieren
Cookies abrufen
- Desktop Modus
Eigenes Format verwenden
Trennzeichen
Zeiformat
@@ -207,14 +201,8 @@
Fehler beim Erstellen des Ordners!
Fehler beim Dateidownload
Du kannst nur 100 Beiträge gleichzeitig herunterladen. Sei nicht zu gierig!
- Kommentar kopieren
- Kommentar-Liker ansehen
- Auf Kommentar antworten
- Kommentar gefällt mir
- Kommentar gefällt mir nicht mehr
Kommentar übersetzen
Kommentar löschen
- Keine leeren Kommentare!
Möchtest du nach dem Benutzernamen suchen?
Möchtest du nach dem Hashtag suchen?
Abonnenten
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 3451b8d6..55810e73 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -40,8 +40,6 @@
Αποθήκευση σε προσαρμοσμένο φάκελο
Επιλογή φακέλου
Θέμα
- Επηρεάζει μόνο τους συνδεδεμένους χρήστες:
- Επηρεάζει μόνο τους ανώνυμους χρήστες:
Γλώσσα
- %s\nΔημοσίευση
@@ -109,10 +107,7 @@
Αποθηκευμένα
Ετικέτες
Μήνυμα
- Μου αρέσει
- Δε μου αρέσει
Αποθήκευση σαν σελιδοδείκτης
- Διαγραφή σελιδοδείκτη
Ακολουθήστε
Να μην ακολουθώ
Αγαπημένα
@@ -140,7 +135,6 @@
Η εξαγωγή απέτυχε!
Ανανέωση
Λήψη cookies
- Λειτουργία Επιφάνειας Εργασίας
Χρήση προσαρμοσμένης μορφής
Διαχωριστικό
Μορφή Ώρας
@@ -207,14 +201,8 @@
Σφάλμα κατά τη δημιουργία φακέλου!
Σφάλμα λήψης αρχείου
Μπορείτε να καταφορτώσετε μόνο 100 δημοσιεύσεις τη φορά. Μην είστε τόσο άπληστος!
- Αντιγραφή σχολίου
- Προβολή όσων δήλωσαν ότι τους αρέσει το σχόλιο
- Απάντηση στο σχόλιο
- Επισήμανση ως «Μου Αρέσει»
- Κατάργηση του «Μου Αρέσει»
Μετάφραση σχολίου
Διαγραφή σχολίου
- Όχι κενά σχόλια!
Θέλετε να αναζητήσετε το όνομα χρήστη;
Θέλετε να αναζητήσετε το hashtag;
Ακόλουθοι
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 9f10ea79..04e9345a 100755
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -40,8 +40,6 @@
Descargar en carpeta personalizada
Seleccionar carpeta
Tema
- Sólo afecta a cuentas que han iniciado sesión:
- Sólo afecta a usuarios anónimos:
Idioma
- %s\nPublicación
@@ -109,10 +107,7 @@
Guardado
Etiquetado
Mensaje
- Me gusta
- No me gusta
Añadir marcador
- Quitar marcador
Seguir
Dejar de seguir
Agregar a favoritos
@@ -140,7 +135,6 @@
¡Falló la exportación!
Actualizar
Obtener cookies
- Modo escritorio
Usar formato personalizado
Separador
Formato de tiempo
@@ -207,14 +201,8 @@
¡Error al crear carpeta!
Error al descargar archivo
Sólo puedes descargar 100 publicaciones a la vez. ¡No seas abaricioso!
- Copiar comentario
- Ver me gustas del comentario
- Responder a comentario
- Dar me gusta a comentario
- Quitar me gusta a comentario
Traducir comentario
Eliminar comentario
- ¡No hay comentarios vacíos!
¿Quieres buscar el nombre de usuario?
¿Quieres buscar el hashtag?
Seguidores
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 7ce2f4df..4888ab74 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -40,8 +40,6 @@
Gorde pertsonalizatutako karpetan
Hautatu karpeta
Gaia
- Saioa hasi duten erabiltzaileei soilik eragiten die:
- Erabiltzaile anonimoei soilik eragiten die:
Hizkuntza
- %s\nPost
@@ -109,10 +107,7 @@
Gordeta
Etiketatuta
Mezua
- Atsegitea
- Ez dut atsegin
Laster-marka
- Laster-marka kendu
Jarraitu
Jarraitzeari utzi
Gogokoa
@@ -140,7 +135,6 @@
Esportatzeak huts egin du!
Freskatu
Eskuratu cookieak
- Mahaigaineko modua
Erabili pertsonalizatutako formatua
Bereizlea
Ordu-formatua
@@ -207,14 +201,8 @@
Errorea karpeta sortzean!
Errorea fitxategia deskargatzean
100 bidalketa deskargatu ditzakezu une berean. Ez izan gutiziatsu!
- Kopiatu iruzkina
- Ikusi iruzkinen atsegiteak
- Erantzun iruzkinari
- Atsegin iruzkina
- Ez dut atsegin
Itzuli iruzkina
Delete comment
- Iruzkin hutsik ez!
Erabiltzaile-izena bilatu nahi duzu?
Traol-hitza bilatu nahi duzu?
Jarraitzaileak
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index c0047461..152614d0 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -40,8 +40,6 @@
ذخیره در پوشه سفارشی
انتخاب پوشه
پوسته
- فقط بر کاربران وارد شده اثر دارد:
- فقط بر کاربران ناشناس اثر دارد:
زبان
- %s\n پست
@@ -110,10 +108,7 @@
ذخیره شد
تگ شده
پیام
- پسند
- ناپسند
نشانک
- حذف نشانک
پیگرفتن
پایان پیگرفتن
برگزیده
@@ -141,7 +136,6 @@
پشتبان گیری با موفقیت نبود!
تازه سازی
گرفتن کوکی ها
- حالت دسکتاپ
استفاده از فرمت سفارشی
تفکیک کننده
فرمت زمان
@@ -208,14 +202,8 @@
خطا در ایجاد پوشه!
خطا در دانلود فایل
شما فقط 100 پست در یک زمان میتوانید دانلود کنید. خیلی حریص نباشید!
- کپی دیدگاه
- View comment likers
- پاسخ به دیدگاه
- پسندیدن دیدگاه
- نپسندیدن دیدگاه
گرداندن دیدگاه
Delete comment
- بدون دیدگاه تهی!
ایا میخواهید نام کاربری جستوجو کنید ؟
آیا میخواهید هشتگ جستوجو کنید؟
پیگیران
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 23c0b358..d1f0fe83 100755
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -40,8 +40,6 @@
Enregistrer dans un dossier personnalisé
Sélectionnez un dossier
Thème
- N\'affecte que les utilisateurs connectés :
- N\'affecte que les utilisateurs anonymes:
Langues
- %s\nPublication
@@ -109,10 +107,7 @@
Sauvegardé
Taggé
Message
- J\'aime
- Ne plus aimer
Ajouter aux marque-pages
- Retirer des marque-pages
Suivre
Ne plus suivre
Mettre en favoris
@@ -140,7 +135,6 @@
Erreur d\'exportation!
Actualiser
Récupérer les cookies
- Mode desktop
Utiliser un format personnalisé
Séparateur
Format de l\'heure
@@ -207,14 +201,8 @@
Erreur de création de dossier !
Erreur de téléchargement du fichier
Vous ne pouvez télécharger que 100 publications à la fois. Ne soyez pas trop gourmands !
- Copier le commentaire
- Voir les \"j\'aime\" du commentaire
- Répondre au commentaire
- Aimer le commentaire
- Retirer le j\'aime du commentaire
Traduire le commentaire
Supprimer le commentaire
- Aucun commentaire vide !
Souhaitez-vous faire une recherche sur le nom d\'utilisateur ?
Souhaitez-vous faire une recherch sur le hashtag ?
Abonnés
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index ff0253dc..b74f6145 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -40,8 +40,6 @@
खुद के द्बारा निर्धारित फोल्डर पे रखें
फोल्डर का चयन करें
थीम
- सिर्फ लग इन किए हुए ब्यबहारकारी के लिये
- गुमनामी लोगों के लिये
भाषा
- %s\nपोस्ट
@@ -110,10 +108,7 @@
सेव किया
टैग किये
संदेश
- पसन्द
- नापसंद
बुकमार्क
- बुकमार्क न करें
अनुसरण करे
अनुसरण ना करें
पसंदीदा
@@ -141,7 +136,6 @@
निर्यात करने में विफल!
ताज़ा करें:
कुकिज पायें
- डेस्कटप मोड करें
कस्टम फर्माट ब्यबहार करें
सेपरेटर
समय का स्बरुप
@@ -208,14 +202,8 @@
फोलडर बनाने में त्रुटि!
फ़ाइल डाउनलोड करने में त्रुटि
आप सिर्फ १०० पोस्टस एक बार में डाउनलोड कर सकते हैं. ज्यादा लोभी बनना हानिकारक हैं!
- टिप्पणी कॉपी करें
- View comment likers
- टिप्पणी का जवाब दें
- टिप्पणी को पसन्द करें
- टिप्पणी को पसन्द न करें
टिप्पणी का अनुवाद करें
टिप्पणी हटाएं
- रिक्त टिप्पणी न करें!
युज़रनेम को ढूंढ़ना चाहते हैं?
हैशटैग को ढूंढ़ना चाहते हैं?
अनुयायी
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 85a94637..84ab0264 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -40,8 +40,6 @@
Simpan ke folder khusus
Pilih folder
Tema
- Hanya memengaruhi pengguna yang sudah masuk:
- Hanya memengaruhi pengguna anonim:
Bahasa
- %s\nKiriman
@@ -105,10 +103,7 @@
Tersimpan
Ditandai
Pesan
- Suka
- Batal Suka
Markah
- Batalkan Markah
Ikuti
Batal Ikuti
Favorit
@@ -136,7 +131,6 @@
Gagal mengekspor!
Muat ulang
Dapatkan cookies
- Desktop Mode\nuntuk 2FA
Gunakan format suaian
Pemisah
Format Jam
@@ -203,14 +197,8 @@
Galat membuat folder!
Galat mengunduh berkas
Anda hanya dapat mengunduh 100 kiriman saat bersamaan. Jangan serakah-serakah!
- Salin komentar
- Lihat penyuka komentar
- Balas komentar
- Suka komentar
- Batal suka komentar
Terjemahkan komentar
Delete comment
- Ups, komentar kosong!
Apakah anda ingin mencari nama pengguna ini?
Apakah anda ingin mencari tagar ini?
Pengikut
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 551a3cfb..43d0d418 100755
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -40,8 +40,6 @@
Salva alla cartella personalizzata
Seleziona cartella
Tema
- Influenza solo gli utenti connessi:
- Influenza solo gli utenti anonimi:
Lingua
- %s\nPubblicazione
@@ -109,10 +107,7 @@
Salvati
Taggati
Messaggio
- Mi Piace
- Non mi Piace
Contrassegna
- Rimuovi dai preferiti
Segui
Non Seguire Più
Preferito
@@ -140,7 +135,6 @@
Impossibile esportare!
Ricarica
Ottieni cookie
- Modalità Desktop
Usa formato personalizzato
Separatore
Formato Ora
@@ -207,14 +201,8 @@
Errore creando la cartella!
Errore scaricando il file
Puoi scaricare solo 100 post per volta. Non essere troppo avido!
- Copia commento
- Visualizza i mi piace del commento
- Rispondi al commento
- Mi Piace il commento
- Il commento Non mi Piace Più
Traduci commento
Elimina commento
- Nessun commento vuoto!
Vuoi cercare il nome utente?
Vuoi cercare l\'hashtag?
Seguaci
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 5b71db6a..3b3575b9 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -40,8 +40,6 @@
カスタムフォルダーに保存
フォルダーを選択
テーマ
- ログインユーザーにのみ影響します:
- 匿名ユーザーにのみ影響します:
言語
- %s\n件
@@ -105,10 +103,7 @@
保存
タグ付き
メッセージ
- いいね!
- いいね!を取り消す
ブックマーク
- ブックマークを解除する
フォローする
フォローを解除
お気に入り
@@ -136,7 +131,6 @@
エクスポートに失敗しました!
更新
Cookie を取得する
- デスクトップモード
カスタム形式を使用する
区切り記号
時刻形式
@@ -203,14 +197,8 @@
フォルダの作成中にエラーが発生しました!
ダウンロード中にエラーが発生しました
一度に100個までの投稿しかダウンロードできません。取り過ぎ注意!
- コメントをコピー
- コメントにいいね!したユーザーを表示
- コメントに返信
- コメントに いいね!
- コメントのいいね!を取り消す
コメントを翻訳
コメントを削除
- メッセージが未入力です!
ユーザー名を検索しますか?
ハッシュタグを検索しますか?
フォロワー
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 06abdaa8..1f8ccbf7 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -40,8 +40,6 @@
Save to custom folder
폴더 선택
테마
- Only affects logged-in users:
- Only affects anonymous users:
언어
- %s\n게시물
@@ -105,10 +103,7 @@
저장됨
태그됨
메시지
- 좋아요
- 좋아요 취소
북마크 하기
- 북마크에서 제거
팔로우
팔로우 취소
즐겨찾기
@@ -136,7 +131,6 @@
Failed to export!
새로고침
Get cookies
- Desktop Mode
Use custom format
Separator
시간 형식
@@ -203,14 +197,8 @@
Error creating folder!
Error downloading file
You can only download 100 posts at a time. Don\'t be too greedy!
- 댓글 복사
- 좋아요 보기
- 답글 달기
- 댓글 좋아요
- 댓글 좋아요 삭제
댓글 번역
댓글 삭제
- 빈 댓글이 안 됍니다.
Do you want to search the username?
Do you want to search the hashtag?
팔로워
diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml
index 5e1d1a60..8999792c 100644
--- a/app/src/main/res/values-mk/strings.xml
+++ b/app/src/main/res/values-mk/strings.xml
@@ -40,8 +40,6 @@
Зачувај во друга папка
Одбери папка
Тема
- Влијае само на корисниците кои се најавени:
- Влијае на анонимните корисници:
Јазик
- %s\nОбјава
@@ -109,10 +107,7 @@
Зачувано
Означен
Порака
- Лајк
- Дислајк
Обележи
- Одобележи
Следи
Одследи
Омилен
@@ -140,7 +135,6 @@
Неуспешно експортиање!
Обнови
Превземи колачиња
- Десктоп изглед
Користи свој формат
Разделувач
Формат на време
@@ -207,14 +201,8 @@
Фатална грешка при креирање папка!
Фатална грешка при превзамање фајл
Можете само 100 постови наеднаш да превземите. Не бидете алчни!
- Копирај Коментар
- Прегледај лајкови на коментар
- Одговори на коментар
- Лајкни коментар
- Одлајкни коментар
Преведи коментар
Избриши коментар
- Не смее празни коментари!
Дали сакате да го пребарате ова корисничко име?
Дали сакате да го пребарате овај хаштаг?
Следачи
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index e56ff754..7bbfc94f 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -40,8 +40,6 @@
Opslaan in aangepaste map
Selecteer map
Thema
- Heeft alleen invloed op ingelogde gebruikers:
- Heeft alleen invloed op anonieme gebruikers:
Taal
- %s\nPost
@@ -109,10 +107,7 @@
Opgeslagen
Getagd
Bericht
- Vind ik leuk
- Vind ik niet meer leuk
Toevoegen aan favorieten
- Verwijderen uit favorieten
Volg
Ontvolg
Toevoegen aan favorieten
@@ -140,7 +135,6 @@
Exporteren mislukt!
Ververs
Cookies ophalen
- Desktop Modus
Aangepaste indeling gebruiken
Scheidingsteken
Tijdnotatie
@@ -207,14 +201,8 @@
Fout bij aanmaken map!
Fout bij downloaden bestand
Je kunt slechts 100 berichten per keer downloaden. Wees niet te hebberig!
- Kopieer reactie
- Bekijk reacties likers
- Reageer op opmerking
- Vind reactie leuk
- Vind reactie niet meer leuk
Reactie vertalen
Verwijder reactie
- Geen lege reacties!
Wil je de gebruikersnaam zoeken?
Wil je de hashtag zoeken?
Volgers
diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml
index 1ed04f22..ea04c162 100644
--- a/app/src/main/res/values-or/strings.xml
+++ b/app/src/main/res/values-or/strings.xml
@@ -40,8 +40,6 @@
ନିଜେ ସ୍ଥିର କରିଥିବା ଫୋଲଡର ରେ ରଖ।
ଫୋଲ୍ଡର୍ ଚୟନ କରନ୍ତୁ
ଥିମ
- କେବଳ ଲଗ ଇନ ହୋଇଥିବା ବ୍ୟବହାରକାରୀଙ୍କ ପାଇଁ:
- କେବଳ ଲଗ ଇନ ହୋଇନଥିବା ବ୍ୟବହାରକାରୀଙ୍କ ପାଇଁ:
ଭାଷା
- %s\nPost
@@ -109,10 +107,7 @@
ସଞ୍ଚୟ ହେଲା
ଟ୍ୟାଗ୍ କରିଛନ୍ତି
ସନ୍ଦେଶ
- ପସନ୍ଦ କରନ୍ତୁ
- Unlike
Bookmark
- Unbookmark
Follow
Unfollow
Favorite
@@ -140,7 +135,6 @@
Failed to export!
Refresh
Get cookies
- Desktop Mode
Use custom format
Separator
Time Format
@@ -207,14 +201,8 @@
Error creating folder!
Error downloading file
You can only download 100 posts at a time. Don\'t be too greedy!
- Copy comment
- View comment likers
- Reply to comment
- Like comment
- Unlike comment
Translate comment
Delete comment
- No empty comments!
Do you want to search the username?
Do you want to search the hashtag?
Followers
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index b44c5e65..217dce32 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -40,8 +40,6 @@
Zapisz w folderze niestandardowym
Wybierz folder
Motyw
- Dotyczy tylko zalogowanych użytkowników:
- Dotyczy tylko anonimowych użytkowników:
Język
- %s\npost
@@ -117,10 +115,7 @@
Zapisane
Oznaczono
Message
- Polub
- Cofnij polubienie
Zapisz
- Usuń z zapisanych
Obserwuj
Przestań obserwować
Ulubiony
@@ -148,7 +143,6 @@
Eksportowanie nie powiodło się!
Odśwież
Pobierz ciasteczka
- Tryb PC
Niestandardowy format
Separator
Format czasu
@@ -215,14 +209,8 @@
Błąd podczas tworzenia folderu!
Błąd podczas pobierania pliku
Możesz pobrać tylko 100 postów jednocześnie. Nie bądź zbyt chciwy!
- Skopiuj komentarz
- Wyświetl polubienia komentarzy
- Odpowiedz na komentarz
- Polub komentarz
- Usuń polubienie komentarza
Tłumacz komentarz
Usuń komentarz
- Brak komentarzy!
Czy chcesz wyszukać przy pomocy nazwy użytkownika?
Czy chcesz wyszukać przy pomocy hashtag\'a?
Obserwujący
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 5bb5b425..092fdffc 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -40,8 +40,6 @@
Salvar em pasta personalizada
Selecionar pasta
Tema
- Afeta apenas usuários logados:
- Afeta apenas usuários anônimos:
Idioma
- %s\nPublicação
@@ -109,10 +107,7 @@
Salvo
Marcado
Mensagem
- Curtir
- Descurtir
Salvar
- Remover
Seguir
Deixar de seguir
Favorito
@@ -140,7 +135,6 @@
Falha ao exportar!
Atualizar
Obter cookies
- Modo Desktop
Usar formato personalizado
Separador
Formato de hora
@@ -207,14 +201,8 @@
Erro ao criar pasta!
Erro ao baixar arquivo
Você só pode baixar 100 publicações por vez. Não seja tão ganancioso!
- Copiar comentário
- Ver quem curtiu o comentário
- Responder comentário
- Curtir comentário
- Descurtir comentário
Traduzir comentário
Excluir comentário
- Comentário em branco!
Você quer buscar o nome de usuário?
Você quer buscar a hashtag?
Seguidores
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 214356c6..4c71160a 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -40,8 +40,6 @@
Сохранить в пользовательскую папку
Выбрать папку
Тема
- Затрагивает только авторизованных пользователей:
- Затрагивает только анонимных пользователей:
Язык
- %s\nПубликация
@@ -117,10 +115,7 @@
Сохранено
Отмечено
Сообщение
- Нравится
- Не нравится
Закладка
- Снять закладку
Подписаться
Отписаться
В избранное
@@ -148,7 +143,6 @@
Не удалось экспортировать!
Обновить
Получить файлы cookie
- Режим настольного ПК
Использовать пользовательский формат
Разделитель
Формат времени
@@ -215,14 +209,8 @@
Ошибка при создании папки!
Ошибка при скачивании файла
Вы можете скачать только 100 сообщений за раз. Не будьте слишком жадным!
- Копировать комментарий
- Просмотр симпатий комментария
- Ответить на комментарий
- Мне нравится комментарий
- Не нравится комментарий
Перевести комментарий
Удалить комментарий
- Нет пустых комментариев!
Вы хотите найти имя пользователя?
Вы хотите найти хештэг?
Подписчики
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 0abc87de..36722b21 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -40,8 +40,6 @@
Uložiť do vlastného priečinku
Vybrať priečinok
Téma
- Platí iba pre prihlásených užívateľov:
- Platí iba pre neprihlásených užívateľov:
Jazyk
- %s\nPríspevok
@@ -117,10 +115,7 @@
Uložené
Označené
Správa
- Páči sa
- Nepáči sa
Záložka
- Zrušiť záložku
Sledovať
Zrušiť sledovanie
Obľúbené
@@ -148,7 +143,6 @@
Export zlyhal!
Obnoviť
Získať cookies
- Režim desktop
Použiť vlastný formát
Oddeľovač
Formát času
@@ -215,14 +209,8 @@
Chyba pri vytváraní priečinka!
Chyba pri sťahovaní súboru
Môžeš stiahnuť len 100 príspevkov v jeden čas. Nebuď chamtivý/á!
- Kopírovať komentár
- Ľudia čo označili \"páči sa mi\"
- Odpovedať na komentár
- Páči sa mi
- Nepáči sa mi
Preložiť komentár
Delete comment
- Komentár je prázdny!
Chcete vyhľadať používeteľské meno?
Chcete vyhľadať hashtag?
Sledovatelia
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index bb43f425..5b3302b8 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -40,8 +40,6 @@
Spara till en anpassad mapp
Välj mapp
Tema
- Påverkar endast inloggade användare:
- Påverkar endast anonyma användare:
Språk
- %s\nPost
@@ -109,10 +107,7 @@
Sparade
Taggade
Meddelande
- Gilla
- Sluta gilla
Bokmärk
- Ta bort bokmärke
Följ
Sluta följa
Favorit
@@ -140,7 +135,6 @@
Misslyckades med exportering!
Uppdatera
Hämta kakor
- Skrivbordsläge
Använd anpassat format
Avskiljare
Tidsformat
@@ -207,14 +201,8 @@
Error creating folder!
Error downloading file
Du kan endast ladda ner 100 inlägg åt gången. Var inte för girig!
- Kopiera kommentaren
- Visa gillare av kommentaren
- Svara till kommentaren
- Gilla kommentaren
- Sluta gilla kommentaren
Översätt kommentaren
Delete comment
- Inga tomma kommentarer!
Vill du söka på användarnamnet?
Vill du söka på hash-taggen?
Följare
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 2dda9e6a..ca6cf993 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -40,8 +40,6 @@
Şu klasöre kaydet:
Klasörü seçin
Tema
- Sadece giriş yapılmış hesapları etkiler:
- Sadece anonim hesapları etkiler:
Dil
- %s\nGönderi
@@ -109,10 +107,7 @@
Kaydedilenler
Etiketlenilenler
Mesaj
- Beğen
- Beğenmekten Vazgeç
Yer İşareti Koy
- Yer İşaretini Kaldır
Takip Et
Takipten Çık
Favorilere Ekle
@@ -140,7 +135,6 @@
Dışa aktarılamadı!
Yenile
Çerezleri al
- Masaüstü Modu
Özel biçim kullan
Ayırıcı
Zaman Biçimi
@@ -207,14 +201,8 @@
Klasör oluşturma hatası!
Dosya indirme hatası
Tek seferde en fazla 100 gönderi indirebilirsin, açgözlü olma!
- Yorumu kopyala
- Yorumu beğenenleri gör
- Yoruma cevap ver
- Yorumu beğen
- Yorum beğenisini geri al
Yorumu çevir
Delete comment
- Boş yorum yapılamaz!
Kullanıcı adını aratmak istiyor musun?
Etiketi aratmak istiyor musun?
Takipçiler
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index c5655dd4..747dcabe 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -40,8 +40,6 @@
Lưu vào thư mục tùy chọn
Chọn thư mục
Giao diện
- Chỉ ảnh hưởng người dùng đã đăng nhập:
- Chỉ ảnh hưởng người dùng ẩn danh:
Ngôn ngữ
- %s\nBài đăng
@@ -105,10 +103,7 @@
Đã lưu
Đã gắn thẻ
Tin nhắn
- Thích
- Bỏ thích
Dấu trang
- Gỡ dấu trang
Theo dõi
Bỏ theo dõi
Yêu thích
@@ -136,7 +131,6 @@
Xuất dữ liệu thất bại!
Làm mới
Lấy cookies
- Chế độ máy tính
Dùng định dạng tuỳ chỉnh
Phân cách
Định dạng Thời gian
@@ -203,14 +197,8 @@
Lỗi khi tạo thư mục!
Lỗi khi tải xuống tệp
Bạn chỉ có thể tải xuống 100 bài cùng một lúc. Đừng tham lam quá!
- Sao chép bình luận
- Xem những người đã thích bình luận
- Trả lời bình luận
- Thích bình luận
- Bỏ thích bình luận
Dịch bình luận
Xóa bình luận
- Không được để trống bình luận!
Bạn có muốn tìm tên người dùng không?
Bạn có muốn tìm hashtag không?
Người theo dõi
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 7534b8f6..076f9ebf 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -40,8 +40,6 @@
保存至自定义文件夹
选择文件夹
主题
- 仅影响登录用户:
- 仅影响匿名用户:
语言
- %s\n帖子
@@ -105,10 +103,7 @@
已保存
已标记
消息
- 赞
- 取消点赞
加入收藏
- 解除收藏
关注
脱粉
加入收藏
@@ -136,7 +131,6 @@
导出失败!
刷新
获取 cookies
- 桌面版
使用自定义格式
分界
时间格式
@@ -203,14 +197,8 @@
创建文件夹时出错!
下载文件时出错
您一次只能下载100个帖子。切勿贪得无厌!
- 复制评论
- 查看评论赞
- 回复评论
- 赞评论
- 取消赞
翻译评论
删除评论
- 评论要写字的!
要搜索用户名吗?
要搜索标签吗?
粉丝
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 356086f6..a23a0f16 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -40,8 +40,6 @@
儲存到自定義資料夾
選擇資料夾
主題
- 僅影響已登入用戶:
- 僅影響匿名用戶:
語言
- %s\n貼文
@@ -105,10 +103,7 @@
已儲存
已標記
訊息
- 讚
- 收回讚
書籤
- 自書籤中移除
追蹤
取消追蹤
收藏
@@ -136,7 +131,6 @@
匯出失敗!
重新整理
取得 Cookies
- 桌面模式
使用自定義格式
分隔
時間格式
@@ -203,14 +197,8 @@
建立資料夾時出錯!
下載檔案時出錯
您一次只能下載100個文章。不要太貪心!
- 複製評論
- 查看為此評論點讚的用戶
- 回覆評論
- 對此評論說讚
- 收回評論的讚
翻譯評論
刪除評論
- 無空評論!
您要搜尋用戶名嗎?
您要搜尋主題標籤嗎?
追蹤者
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
index d94430a5..29c6fecc 100644
--- a/app/src/main/res/values/ids.xml
+++ b/app/src/main/res/values/ids.xml
@@ -6,4 +6,6 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e264fd28..c74b7e82 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5,8 +5,6 @@
Direct Messages
Settings
Download
- GitHub
- F-Droid
Search username…
Compare
Error copying text
@@ -44,8 +42,6 @@
Save to custom folder
Select folder
Theme
- Only affects logged-in users:
- Only affects anonymous users:
Language
- %s\nPost
@@ -73,7 +69,7 @@
Be patient!
View Post
View Post
- Spotify
+ Spotify
Vote
Vote successful!
You have already voted!
@@ -114,10 +110,7 @@
Saved
Tagged
Message
- Like
- Unlike
Bookmark
- Unbookmark
Follow
Unfollow
Favorite
@@ -145,7 +138,6 @@
Failed to export!
Refresh
Get cookies
- Desktop Mode
Use custom format
Separator
Time Format
@@ -205,6 +197,7 @@
Downloads posts directly to the phone!
Fetching post(s)
Download completed
+ Preparing to download…
Downloading post…
Downloading media
Downloading profile picture
@@ -212,14 +205,8 @@
Error creating folder!
Error downloading file
You can only download 100 posts at a time. Don\'t be too greedy!
- Copy comment
- View comment likers
- Reply to comment
- Like comment
- Unlike comment
Translate comment
Delete comment
- No empty comments!
Do you want to search the username?
Do you want to search the hashtag?
Followers