diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 9db8f70..24579d2 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -2,7 +2,7 @@ \ No newline at end of file diff --git a/app/src/main/java/uk/openvk/android/refresh/Global.java b/app/src/main/java/uk/openvk/android/refresh/Global.java index 326d526..603367f 100644 --- a/app/src/main/java/uk/openvk/android/refresh/Global.java +++ b/app/src/main/java/uk/openvk/android/refresh/Global.java @@ -2,7 +2,6 @@ import android.app.LocaleManager; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.graphics.Color; @@ -13,15 +12,6 @@ import android.view.View; import android.view.Window; -import androidx.annotation.ColorInt; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.core.content.res.ResourcesCompat; -import androidx.core.graphics.TypefaceCompat; -import androidx.core.os.LocaleListCompat; -import androidx.core.view.WindowInsetsControllerCompat; -import androidx.preference.PreferenceManager; - import com.google.android.material.color.MaterialColors; import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.shape.CornerFamily; @@ -34,17 +24,20 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.models.OvkLink; -import uk.openvk.android.refresh.api.models.WallPost; -import uk.openvk.android.refresh.ui.core.activities.AppActivity; -import uk.openvk.android.refresh.ui.core.activities.WallPostActivity; +import androidx.annotation.ColorInt; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.content.res.ResourcesCompat; +import androidx.core.graphics.TypefaceCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import androidx.preference.PreferenceManager; +import uk.openvk.android.refresh.api.entities.OvkLink; public class Global { public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); - for (int i = 0; i < bytes.length; i++) { - String hex = Integer.toHexString(0xFF & bytes[i]); + for (byte aByte : bytes) { + String hex = Integer.toHexString(0xFF & aByte); if (hex.length() == 1) { sb.append('0'); } @@ -68,37 +61,19 @@ public static String generateSHA256Hash(String text) { public static void setColorTheme(Context ctx, String value, Window window) { switch (value) { - case "blue": - ctx.setTheme(R.style.ApplicationTheme); - break; - case "red": - ctx.setTheme(R.style.ApplicationTheme_Color2); - break; - case "green": - ctx.setTheme(R.style.ApplicationTheme_Color3); - break; - case "violet": - ctx.setTheme(R.style.ApplicationTheme_Color4); - break; - case "orange": - ctx.setTheme(R.style.ApplicationTheme_Color5); - break; - case "teal": - ctx.setTheme(R.style.ApplicationTheme_Color6); - break; - case "ocean": - ctx.setTheme(R.style.ApplicationTheme_Color7); - break; - case "vk5x": - ctx.setTheme(R.style.ApplicationTheme_Color8); - break; - case "gray": - ctx.setTheme(R.style.ApplicationTheme_Color9); - break; - case "monet": + case "blue" -> ctx.setTheme(R.style.ApplicationTheme); + case "red" -> ctx.setTheme(R.style.ApplicationTheme_Color2); + case "green" -> ctx.setTheme(R.style.ApplicationTheme_Color3); + case "violet" -> ctx.setTheme(R.style.ApplicationTheme_Color4); + case "orange" -> ctx.setTheme(R.style.ApplicationTheme_Color5); + case "teal" -> ctx.setTheme(R.style.ApplicationTheme_Color6); + case "ocean" -> ctx.setTheme(R.style.ApplicationTheme_Color7); + case "vk5x" -> ctx.setTheme(R.style.ApplicationTheme_Color8); + case "gray" -> ctx.setTheme(R.style.ApplicationTheme_Color9); + case "monet" -> { ctx.setTheme(R.style.ApplicationTheme_Monet); MonetCompat.setup(ctx); - break; + } } WindowInsetsControllerCompat controllerCompat = new WindowInsetsControllerCompat(window, window.getDecorView()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -156,26 +131,23 @@ public static void setAvatarShape(Context ctx, ShapeableImageView imageView) { public static void setInterfaceFont(AppCompatActivity activity) { SharedPreferences global_prefs = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()); String value = global_prefs.getString("interface_font", "system"); - if(value.equals("inter")) { - activity.getTheme().applyStyle(R.style.ApplicationFont_Inter, true); - } else if(value.equals("open_sans")) { - activity.getTheme().applyStyle(R.style.ApplicationFont_OpenSans, true); - } else if(value.equals("raleway")) { - activity.getTheme().applyStyle(R.style.ApplicationFont_Raleway, true); - } else if(value.equals("roboto")) { - activity.getTheme().applyStyle(R.style.ApplicationFont_Roboto, true); - } else if(value.equals("rubik")) { - activity.getTheme().applyStyle(R.style.ApplicationFont_Rubik, true); + switch (value) { + case "inter" -> + activity.getTheme().applyStyle(R.style.ApplicationFont_Inter, true); + case "open_sans" -> + activity.getTheme().applyStyle(R.style.ApplicationFont_OpenSans, true); + case "raleway" -> + activity.getTheme().applyStyle(R.style.ApplicationFont_Raleway, true); + case "roboto" -> + activity.getTheme().applyStyle(R.style.ApplicationFont_Roboto, true); + case "rubik" -> + activity.getTheme().applyStyle(R.style.ApplicationFont_Rubik, true); } } public static boolean checkMonet(Context ctx) { String value = PreferenceManager.getDefaultSharedPreferences(ctx).getString("theme_color", "blue"); - if(value.equals("monet")) { - return true; - } else { - return false; - } + return value.equals("monet"); } @ColorInt @@ -255,8 +227,9 @@ public static Typeface getFlexibleTypeface(Context ctx, int weight) { public static Spanned formatLinksAsHtml(String original_text) { String[] lines = original_text.split("\r\n|\r|\n"); StringBuilder text_llines = new StringBuilder(); - Pattern pattern = Pattern.compile("\\[(.+?)\\]|" + - "((http|https)://)(www.)?[a-zA-Z0-9@:%._\\+~#?&//=]{1,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%._\\+~#?&//=]*)"); + Pattern pattern = Pattern.compile("\\[(.+?)]|" + + "((http|https)://)(www.)?[a-zA-Z0-9@:%._+~#?&/=]{1,256}\\.[a-z]{2,6}\\b" + + "([-a-zA-Z0-9@:%._+~#?&/=]*)"); Matcher matcher = pattern.matcher(original_text); boolean regexp_search = matcher.find(); String text = original_text.replaceAll("<", "<").replaceAll(">", ">") @@ -267,7 +240,8 @@ public static Spanned formatLinksAsHtml(String original_text) { String block = matcher.group(); if(block.startsWith("[") && block.endsWith("]")) { OvkLink link = new OvkLink(); - String[] markup = block.replace("[", "").replace("]", "").split("\\|"); + String[] markup = block.replace("[", "") + .replace("]", "").split("\\|"); link.screen_name = markup[0]; if (markup.length == 2) { if (markup[0].startsWith("id")) { @@ -295,13 +269,6 @@ public static Spanned formatLinksAsHtml(String original_text) { } } - public static void openPostComments(Account account, WallPost post, Context ctx) { - Intent intent = new Intent(ctx, WallPostActivity.class); - intent.putExtra("post", post); - intent.putExtra("counters", post.counters); - ctx.startActivity(intent); - } - public static int getMonetIntColor(MonetCompat monet, String type, int brightness) { if(type.equals("neutral1")) { return Objects.requireNonNull(monet.getMonetColors() diff --git a/app/src/main/java/uk/openvk/android/refresh/OvkApplication.java b/app/src/main/java/uk/openvk/android/refresh/OvkApplication.java index 02f8b40..be78748 100644 --- a/app/src/main/java/uk/openvk/android/refresh/OvkApplication.java +++ b/app/src/main/java/uk/openvk/android/refresh/OvkApplication.java @@ -9,18 +9,22 @@ import android.os.LocaleList; import android.preference.PreferenceManager; -import androidx.annotation.RequiresApi; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.core.os.LocaleListCompat; - import com.kieronquinn.monetcompat.core.MonetCompat; import java.util.Locale; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.os.LocaleListCompat; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -import uk.openvk.android.refresh.longpoll_api.LongPollService; +import uk.openvk.android.refresh.services.LongPollService; public class OvkApplication extends Application { + public static final String API_TAG = "OVK-API"; + public static final String LP_TAG = "OVK-LP"; + public static final String DL_TAG = "OVK-DLM"; + public static final String UL_TAG = "OVK-ULM"; + public static final String APP_TAG = "OpenVK"; public static boolean isTablet; public String version; public LongPollService longPollService; @@ -143,4 +147,24 @@ public static LocaleListCompat getLocaleList(Context ctx) { } } + public SharedPreferences getAccountPreferences() { + SharedPreferences prefs = getSharedPreferences( + String.format("instance_a%s_%s", getCurrentUserId(), getCurrentInstance()), 0); + if(prefs != null && prefs.contains("server") && + prefs.getString("server", "").equals(getCurrentInstance())) { + return prefs; + } else { + return getSharedPreferences("instance", 0); + } + } + + private long getCurrentUserId() { + return PreferenceManager.getDefaultSharedPreferences(this) + .getLong("current_uid", 0); + } + public String getCurrentInstance() { + return PreferenceManager.getDefaultSharedPreferences(this) + .getString("current_instance", ""); + } + } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Authorization.java b/app/src/main/java/uk/openvk/android/refresh/api/Authorization.java deleted file mode 100644 index 8a6737e..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/Authorization.java +++ /dev/null @@ -1,32 +0,0 @@ -package uk.openvk.android.refresh.api; - -import org.json.JSONException; -import org.json.JSONObject; - -import uk.openvk.android.refresh.api.wrappers.JSONParser; - -/** - * Created by Dmitry on 28.09.2022. - */ -public class Authorization { - private String access_token; - private String response; - private JSONParser jsonParser; - - public Authorization(String response) { - this.response = response; - jsonParser = new JSONParser(); - JSONObject json = jsonParser.parseJSON(response); - if(json != null) { - try { - this.access_token = json.getString("access_token"); - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - - public String getAccessToken() { - return access_token; - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Newsfeed.java b/app/src/main/java/uk/openvk/android/refresh/api/Newsfeed.java deleted file mode 100644 index 18558f3..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/Newsfeed.java +++ /dev/null @@ -1,443 +0,0 @@ -package uk.openvk.android.refresh.api; - -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.attachments.Attachment; -import uk.openvk.android.refresh.api.attachments.PhotoAttachment; -import uk.openvk.android.refresh.api.attachments.PollAttachment; -import uk.openvk.android.refresh.api.attachments.VideoAttachment; -import uk.openvk.android.refresh.api.models.PollAnswer; -import uk.openvk.android.refresh.api.models.VideoFiles; -import uk.openvk.android.refresh.api.models.WallPostSource; -import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.JSONParser; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -import uk.openvk.android.refresh.api.counters.PostCounters; -import uk.openvk.android.refresh.api.models.WallPost; -import uk.openvk.android.refresh.api.models.RepostInfo; - -/** - * Created by Dmitry on 28.09.2022. - */ -public class Newsfeed implements Parcelable { - private JSONParser jsonParser; - private ArrayList items; - private ArrayList photos_msize; - private ArrayList photos_hsize; - private ArrayList photos_osize; - - public long next_from; - private DownloadManager dlm; - - public Newsfeed(String response, DownloadManager downloadManager, String quality, Context ctx) { - jsonParser = new JSONParser(); - if(items == null) { - parse(ctx, downloadManager, response, quality, true); - } - } - - public Newsfeed() { - jsonParser = new JSONParser(); - } - - protected Newsfeed(Parcel in) { - items = in.createTypedArrayList(WallPost.CREATOR); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Newsfeed createFromParcel(Parcel in) { - return new Newsfeed(in); - } - - @Override - public Newsfeed[] newArray(int size) { - return new Newsfeed[size]; - } - }; - - public void parse(Context ctx, DownloadManager downloadManager, String response, String quality, boolean clear) { - this.dlm = downloadManager; - if(clear) { - items = new ArrayList<>(); - photos_osize = new ArrayList<>(); - photos_hsize = new ArrayList<>(); - photos_msize = new ArrayList<>(); - } - ArrayList avatars = new ArrayList<>(); - try { - JSONObject json = jsonParser.parseJSON(response); - if(json != null) { - JSONObject newsfeed = json.getJSONObject("response"); - if(newsfeed.get("next_from") instanceof Long) { - next_from = newsfeed.getLong("next_from"); - } else { - next_from = 0; - } - JSONArray items = newsfeed.getJSONArray("items"); - for(int i = 0; i < items.length(); i++) { - JSONObject post = items.getJSONObject(i); - JSONObject comments = post.getJSONObject("comments"); - JSONObject likes = post.getJSONObject("likes"); - JSONObject reposts = post.getJSONObject("reposts"); - JSONArray attachments = post.getJSONArray("attachments"); - long owner_id = post.getLong("owner_id"); - long post_id = post.getLong("id"); - long author_id = post.getLong("from_id"); - long dt_sec = post.getLong("date"); - String original_author_name; - String original_author_avatar_url; - String author_name = ""; - String owner_name = ""; - String avatar_url = ""; - String owner_avatar_url; - String author_avatar_url = ""; - String content = post.getString("text"); - boolean verified_author = false; - boolean isLiked = false; - if(likes.getInt("user_likes") > 0) { - isLiked = true; - } else { - isLiked = false; - } - PostCounters counters = new PostCounters(likes.getInt("count"), - comments.getInt("count"), reposts.getInt("count"), isLiked, - false); - - ArrayList attachments_list = createAttachmentsList(owner_id, - post_id, quality, attachments); - - WallPost item = new WallPost(String.format("(Unknown author: %s)", - author_id), dt_sec, null, content, counters, "", - attachments_list, owner_id, post_id, ctx); - if(post.has("post_source") && !post.isNull("post_source")) { - if(post.getJSONObject("post_source").getString("type").equals("api")) { - item.post_source = new WallPostSource(post - .getJSONObject("post_source").getString("type"), - post.getJSONObject("post_source").getString("platform")); - } else { - item.post_source = new WallPostSource(post - .getJSONObject("post_source").getString("type"), null); - } - } - if(post.getJSONArray("copy_history").length() > 0) { - JSONObject repost = post.getJSONArray("copy_history") - .getJSONObject(0); - WallPost repost_item = new WallPost(String.format("(Unknown author: %s)", - repost.getLong("from_id")), repost.getLong("date"), - null, repost.getString("text"), null, "", - null, repost.getLong("owner_id"), - repost.getLong("id"), ctx); - RepostInfo repostInfo = new RepostInfo(String.format("(Unknown author: %s)", - repost.getLong("from_id")), repost.getLong("date"), ctx); - repostInfo.newsfeed_item = repost_item; - item.repost = repostInfo; - JSONArray repost_attachments = repost.getJSONArray("attachments"); - attachments_list = createAttachmentsList(owner_id, post_id, quality, - repost_attachments); - repost_item.attachments = attachments_list; - } - item.author_id = author_id; - if(author_id > 0) { - if(newsfeed.has("profiles")) { - JSONArray profiles = newsfeed.getJSONArray("profiles"); - for (int profiles_index = 0; profiles_index < profiles.length(); - profiles_index++) { - JSONObject profile = profiles.getJSONObject(profiles_index); - if (profile.getLong("id") == author_id) { - author_name = String.format("%s %s", - profile.getString("first_name"), - profile.getString("last_name")); - author_avatar_url = profile.getString("photo_100"); - if(profile.has("verified")) { - if(profile.get("verified") instanceof Integer) { - verified_author = profile.getInt("verified") == 1; - } else { - verified_author = profile.getBoolean("verified"); - } - } - } else if (profile.getInt("id") == owner_id) { - owner_name = String.format("%s %s", - profile.getString("first_name"), - profile.getString("last_name")); - owner_avatar_url = profile.getString("photo_100"); - if(profile.has("verified")) { - if(profile.get("verified") instanceof Integer) { - verified_author = profile.getInt("verified") == 1; - } else { - verified_author = profile.getBoolean("verified"); - } - } - } - } - if(author_avatar_url.length() > 0) avatar_url = author_avatar_url; - } - if(owner_id < 0) { - if(newsfeed.has("groups")) { - JSONArray groups = newsfeed.getJSONArray("groups"); - for (int groups_index = 0; groups_index < groups.length(); - groups_index++) { - JSONObject group = groups.getJSONObject(groups_index); - if (-group.getLong("id") == owner_id) { - owner_name = group.getString("name"); - avatar_url = group.getString("photo_100"); - if(group.has("verified")) { - if(group.get("verified") instanceof Integer) { - if (group.getInt("verified") == 1) { - verified_author = true; - } else { - verified_author = false; - } - } else { - if (group.getBoolean("verified")) { - verified_author = true; - } else { - verified_author = false; - } - } - } - } - } - } - } - if(author_id == owner_id) { - item.name = author_name; - } else if(owner_name.length() > 0) { - item.name = ctx.getResources().getString(R.string.on_wall, author_name, owner_name); - } else { - item.name = author_name; - } - } else { - if(newsfeed.has("groups") && newsfeed.has("profiles")) { - JSONArray groups = newsfeed.getJSONArray("groups"); - JSONArray profiles = newsfeed.getJSONArray("profiles"); - for (int groups_index = 0; groups_index < groups.length(); groups_index++) { - JSONObject group = groups.getJSONObject(groups_index); - if (-group.getInt("id") == author_id) { - item.name = group.getString("name"); - avatar_url = group.getString("photo_100"); - if(group.has("verified")) { - if(group.get("verified") instanceof Integer) { - if (group.getInt("verified") == 1) { - verified_author = true; - } else { - verified_author = false; - } - } else { - if (group.getBoolean("verified")) { - verified_author = true; - } else { - verified_author = false; - } - } - } - } - } - } - } - item.verified_author = verified_author; - PhotoAttachment avatar = new PhotoAttachment(); - avatar.url = avatar_url; - avatar.filename = String.format("avatar_%s", author_id); - avatars.add(avatar); - this.items.add(item); - } - if(quality.equals("medium")) { - downloadManager.downloadPhotosToCache(photos_msize, - "newsfeed_photo_attachments"); - } else if(quality.equals("high")) { - downloadManager.downloadPhotosToCache(photos_hsize, - "newsfeed_photo_attachments"); - } else if(quality.equals("original")) { - downloadManager.downloadPhotosToCache(photos_osize, - "newsfeed_photo_attachments"); - } - downloadManager.downloadPhotosToCache(avatars, "newsfeed_avatars"); - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - - public void get(OvkAPIWrapper ovk, int count) { - ovk.sendAPIMethod("Newsfeed.get", String.format("count=%s&extended=1", count)); - } - - public void get(OvkAPIWrapper ovk, int count, long start_from) { - if(start_from > 0) { - ovk.sendAPIMethod("Newsfeed.get", String.format("count=%s&start_from=%s&extended=1", - count, start_from), "more_news"); - } - } - - public void getGlobal(OvkAPIWrapper ovk, int count) { - ovk.sendAPIMethod("Newsfeed.getGlobal", String.format("count=%s&extended=1", count)); - } - - public void getGlobal(OvkAPIWrapper ovk, int count, long start_from) { - if(start_from > 0) { - ovk.sendAPIMethod("Newsfeed.getGlobal", String.format("count=%s&start_from=%s&extended=1", - count, start_from), "more_news"); - } - } - - public ArrayList createAttachmentsList(long owner_id, long post_id, String quality, - JSONArray attachments) { - ArrayList attachments_list = new ArrayList<>(); - try { - for (int attachments_index = 0; attachments_index < attachments.length(); attachments_index++) { - String photo_medium_size; - String photo_high_size; - String photo_original_size; - String attachment_status; - JSONObject attachment = attachments.getJSONObject(attachments_index); - if (attachment.getString("type").equals("photo")) { - JSONObject photo = attachment.getJSONObject("photo"); - PhotoAttachment photoAttachment = new PhotoAttachment(); - photoAttachment.id = photo.getLong("id"); - if(!photo.isNull("sizes")) { - JSONArray photo_sizes = photo.getJSONArray("sizes"); - photo_medium_size = photo_sizes.getJSONObject(5).getString("url"); - photo_high_size = photo_sizes.getJSONObject(8).getString("url"); - photo_original_size = photo_sizes.getJSONObject(10).getString("url"); - switch (quality) { - case "medium": - photoAttachment.url = photo_medium_size; - break; - case "high": - photoAttachment.url = photo_high_size; - break; - case "original": - photoAttachment.url = photo_original_size; - break; - } - photoAttachment.original_url = photo_original_size; - photoAttachment.filename = String.format("newsfeed_attachment_o%sp%s", owner_id, post_id); - if (photo_medium_size.length() > 0 || photo_high_size.length() > 0) { - attachment_status = "loading"; - } else { - attachment_status = "none"; - } - Attachment attachment_obj = new Attachment(attachment.getString("type")); - attachment_obj.status = attachment_status; - attachment_obj.setContent(photoAttachment); - attachments_list.add(attachment_obj); - switch (quality) { - case "medium": - photos_msize.add(photoAttachment); - break; - case "high": - photos_hsize.add(photoAttachment); - break; - case "original": - photos_osize.add(photoAttachment); - break; - } - } - } else if (attachment.getString("type").equals("poll")) { - JSONObject poll_attachment = attachment.getJSONObject("poll"); - PollAttachment pollAttachment = new PollAttachment( - poll_attachment.getString("question"), - poll_attachment.getInt("id"), - poll_attachment.getLong("end_date"), - poll_attachment.getBoolean("multiple"), - poll_attachment.getBoolean("can_vote"), - poll_attachment.getBoolean("anonymous")); - JSONArray answers = poll_attachment.getJSONArray("answers"); - JSONArray votes = poll_attachment.getJSONArray("answer_ids"); - if (votes.length() > 0) { - pollAttachment.user_votes = votes.length(); - } - pollAttachment.votes = poll_attachment.getInt("votes"); - for (int answers_index = 0; answers_index < answers.length(); answers_index++) { - JSONObject answer = answers.getJSONObject(answers_index); - PollAnswer pollAnswer = new PollAnswer(answer.getInt("id"), - answer.getInt("rate"), - answer.getInt("votes"), answer.getString("text")); - for (int votes_index = 0; votes_index < votes.length(); votes_index++) { - if (answer.getInt("id") == votes.getInt(votes_index)) { - pollAnswer.is_voted = true; - } - } - pollAttachment.answers.add(pollAnswer); - } - attachment_status = "done"; - Attachment attachment_obj = new Attachment(attachment.getString("type")); - attachment_obj.status = attachment_status; - attachment_obj.setContent(pollAttachment); - attachments_list.add(attachment_obj); - } else if (attachment.getString("type").equals("video")) { - JSONObject video = attachment.getJSONObject("video"); - VideoAttachment videoAttachment = new VideoAttachment(); - videoAttachment.id = video.getLong("id"); - videoAttachment.title = video.getString("title"); - VideoFiles files = new VideoFiles(); - if(video.has("files")) { - JSONObject videoFiles = video.getJSONObject("files"); - if(videoFiles.has("mp4_144")) { - files.mp4_144 = videoFiles.getString("mp4_144"); - } if(videoFiles.has("mp4_240")) { - files.mp4_240 = videoFiles.getString("mp4_240"); - } if(videoFiles.has("mp4_360")) { - files.mp4_360 = videoFiles.getString("mp4_360"); - } if(videoFiles.has("mp4_480")) { - files.mp4_480 = videoFiles.getString("mp4_480"); - } if(videoFiles.has("mp4_720")) { - files.mp4_720 = videoFiles.getString("mp4_720"); - } if(videoFiles.has("mp4_1080")) { - files.mp4_1080 = videoFiles.getString("mp4_1080"); - } if(videoFiles.has("ogv_480")) { - files.ogv_480 = videoFiles.getString("ogv_480"); - } - } - videoAttachment.files = files; - if(video.has("image")) { - JSONArray thumb_array = video.getJSONArray("image"); - videoAttachment.url_thumb = thumb_array.getJSONObject(0).getString("url"); - dlm.downloadOnePhotoToCache(videoAttachment.url_thumb, String.format("thumbnail_%s", - video.getLong("id")), "video_thumbnails"); - } - videoAttachment.duration = video.getInt("duration"); - attachment_status = "done"; - Attachment attachment_obj = new Attachment(attachment.getString("type")); - attachment_obj.status = attachment_status; - attachment_obj.setContent(videoAttachment); - attachments_list.add(attachment_obj); - } else { - attachment_status = "not_supported"; - Attachment attachment_obj = new Attachment(attachment.getString("type")); - attachment_obj.status = attachment_status; - attachments_list.add(attachment_obj); - } - } - } catch (JSONException ex) { - ex.printStackTrace(); - } - return attachments_list; - } - - public ArrayList getWallPosts() { - return items; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeTypedList(items); - } - -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/OpenVKAPI.java b/app/src/main/java/uk/openvk/android/refresh/api/OpenVKAPI.java new file mode 100644 index 0000000..02c9439 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/OpenVKAPI.java @@ -0,0 +1,96 @@ +package uk.openvk.android.refresh.api; + +import android.content.Context; +import android.content.SharedPreferences; + +import java.util.logging.Handler; + +import uk.openvk.android.refresh.api.entities.Account; +import uk.openvk.android.refresh.api.entities.Ovk; +import uk.openvk.android.refresh.api.entities.User; +import uk.openvk.android.refresh.api.models.Friends; +import uk.openvk.android.refresh.api.models.Groups; +import uk.openvk.android.refresh.api.models.Likes; +import uk.openvk.android.refresh.api.models.Messages; +import uk.openvk.android.refresh.api.models.Newsfeed; +import uk.openvk.android.refresh.api.models.Notes; +import uk.openvk.android.refresh.api.models.Photos; +import uk.openvk.android.refresh.api.models.Users; +import uk.openvk.android.refresh.api.models.Wall; +import uk.openvk.android.refresh.api.wrappers.DownloadManager; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.api.wrappers.UploadManager; + +/** + * Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + */ + +public class OpenVKAPI { + public Account account; + public Newsfeed newsfeed; + public Messages messages; + public Users users; + public Groups groups; + public Friends friends; + public Wall wall; + public User user; + public Likes likes; + public Notes notes; + public Photos photos; + public Ovk ovk; + public OvkAPIWrapper wrapper; + public DownloadManager dlman; + public UploadManager ulman; + public OpenVKAPI(Context ctx, SharedPreferences global_prefs, SharedPreferences instance_prefs, + android.os.Handler handler) { + wrapper = new OvkAPIWrapper(ctx, global_prefs.getBoolean("useHTTPS", true), handler); + wrapper.setProxyConnection(global_prefs.getBoolean("useProxy", false), + global_prefs.getString("proxy_address", "")); + if(instance_prefs != null && instance_prefs.contains("server")) { + wrapper.setServer(instance_prefs.getString("server", "")); + wrapper.setAccessToken(instance_prefs.getString("access_token", "")); + } + dlman = new DownloadManager(ctx, global_prefs.getBoolean("useHTTPS", true), handler); + if(instance_prefs != null && instance_prefs.contains("server")) { + dlman.setInstance(instance_prefs.getString("server", "")); + } + dlman.setProxyConnection(global_prefs.getBoolean("useProxy", false), + global_prefs.getString("proxy_address", "")); + dlman.setForceCaching(global_prefs.getBoolean("forcedCaching", true)); + ulman = new UploadManager(ctx, global_prefs.getBoolean("useHTTPS", true), handler); + ulman.setProxyConnection(global_prefs.getBoolean("useProxy", false), + global_prefs.getString("proxy_address", "")); + if(instance_prefs != null && instance_prefs.contains("server")) { + ulman.setInstance(instance_prefs.getString("server", "")); + } + ulman.setForceCaching(global_prefs.getBoolean("forcedCaching", true)); + account = new Account(ctx); + if(instance_prefs != null && instance_prefs.contains("server")) { + account.getProfileInfo(wrapper); + } + newsfeed = new Newsfeed(); + user = new User(); + likes = new Likes(); + messages = new Messages(); + users = new Users(); + friends = new Friends(); + groups = new Groups(); + wall = new Wall(); + notes = new Notes(); + photos = new Photos(); + ovk = new Ovk(); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/TrackingRequestBody.java b/app/src/main/java/uk/openvk/android/refresh/api/TrackingRequestBody.java new file mode 100644 index 0000000..6617d75 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/TrackingRequestBody.java @@ -0,0 +1,92 @@ +package uk.openvk.android.refresh.api; + +import java.io.File; +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okhttp3.internal.Util; +import okio.Buffer; +import okio.BufferedSink; +import okio.ForwardingSink; +import okio.Okio; +import okio.Sink; +import okio.Source; + +/** + * Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + */ + +public class TrackingRequestBody extends RequestBody { + + private static final int SEGMENT_SIZE = 2048; + + private String contentType; + private File file; + protected LoadTrackListener mListener; + protected CountingSink mCountingSink; + + public TrackingRequestBody(File file, String contentType, LoadTrackListener listener) { + this.file = file; + this.contentType = contentType; + this.mListener = listener; + } + + @Override + public MediaType contentType() { + return MediaType.parse(contentType); + } + + @Override + public long contentLength() { + return file.length(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + Source source = null; + try { + source = Okio.source(file); + long total = 0; + long read; + + while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) { + total += read; + sink.flush(); + this.mListener.onLoad(total, contentLength()); + } + } finally { + Util.closeQuietly(source); + } + } + + protected final class CountingSink extends ForwardingSink { + private long bytesWritten = 0; + public CountingSink(Sink delegate) { + super(delegate); + } + @Override + public void write(Buffer source, long byteCount) throws IOException { + super.write(source, byteCount); + bytesWritten += byteCount; + mListener.onLoad(bytesWritten, byteCount); + } + } + + public interface LoadTrackListener { + void onLoad(long position, long max); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Users.java b/app/src/main/java/uk/openvk/android/refresh/api/Users.java deleted file mode 100644 index ca5b423..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/Users.java +++ /dev/null @@ -1,141 +0,0 @@ -package uk.openvk.android.refresh.api; - -import android.content.Intent; -import android.os.Parcel; -import android.os.Parcelable; - -import org.droidparts.util.Strings; -import org.json.JSONArray; -import org.json.JSONObject; - -import java.net.URLEncoder; -import java.util.ArrayList; - -import uk.openvk.android.refresh.api.models.Conversation; -import uk.openvk.android.refresh.api.models.User; -import uk.openvk.android.refresh.api.wrappers.JSONParser; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; - -/** - * Created by Dmitry on 30.09.2022. - */ -public class Users implements Parcelable { - private JSONParser jsonParser; - private ArrayList users; - public User user; - - public Users() { - jsonParser = new JSONParser(); - users = new ArrayList(); - } - - - public Users(String response) { - jsonParser = new JSONParser(); - parse(response); - } - - protected Users(Parcel in) { - users = in.createTypedArrayList(User.CREATOR); - user = in.readParcelable(User.class.getClassLoader()); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Users createFromParcel(Parcel in) { - return new Users(in); - } - - @Override - public Users[] newArray(int size) { - return new Users[size]; - } - }; - - public void parse(String response) { - try { - JSONObject json = jsonParser.parseJSON(response); - JSONArray users = json.getJSONArray("response"); - if(this.users.size() > 0) { - this.users.clear(); - } - for (int i = 0; i < users.length(); i++) { - User user = new User(users.getJSONObject(i)); - this.users.add(user); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void parseSearch(String response) { - try { - JSONObject json = jsonParser.parseJSON(response); - JSONArray users = json.getJSONObject("response").getJSONArray("items"); - if(this.users.size() > 0) { - this.users.clear(); - } - for (int i = 0; i < users.length(); i++) { - User user = new User(users.getJSONObject(i)); - this.users.add(user); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void getUser(OvkAPIWrapper ovk, long user_id) { - ovk.sendAPIMethod("Users.get", String.format("user_ids=%s&fields=verified,sex,has_photo,photo_200,photo_400,photo_max_orig,status,screen_name,friend_status,last_seen,interests,music,movies,tv,books,city", user_id)); - } - - public void getAccountUser(OvkAPIWrapper ovk, long user_id) { - ovk.sendAPIMethod("Users.get", String.format("user_ids=%s&fields=verified,sex,has_photo,photo_200,photo_400,photo_max_orig,status,screen_name,friend_status,last_seen,interests,music,movies,tv,books,city", user_id), "account_user"); - } - - public void getPeerUsers(OvkAPIWrapper ovk, ArrayList conversations) { - ArrayList user_ids = new ArrayList<>(); - for(int i = 0; i < conversations.size(); i++) { - user_ids.add(conversations.get(i).peer_id); - } - StringBuilder ids_list = new StringBuilder(); - for(int i = 0; i < user_ids.size(); i++) { - if(i < user_ids.size() - 1) { - ids_list.append(String.format("%s,", user_ids.get(i))); - } else { - ids_list.append(user_ids.get(i)); - } - } - ovk.sendAPIMethod("Users.get", String.format("user_ids=%s&fields=verified,sex,has_photo,photo_200,photo_400,photo_max_orig,status,screen_name,friend_status,last_seen,interests,music,movies,tv,books,city", ids_list), "peers"); - } - - public void get(OvkAPIWrapper ovk, ArrayList user_ids) { - StringBuilder ids_list = new StringBuilder(); - for(int i = 0; i < user_ids.size(); i++) { - if(i < user_ids.size() - 1) { - ids_list.append(String.format("%s,", user_ids.get(i))); - } else { - ids_list.append(user_ids.get(i)); - } - } - ovk.sendAPIMethod("Users.get", String.format("user_ids=%s&fields=verified,sex,has_photo,photo_200,photo_400,photo_max_orig,status,screen_name,friend_status,last_seen,interests,music,movies,tv,books,city", ids_list.toString())); - } - - public ArrayList getList() { - return users; - } - - public void search(OvkAPIWrapper ovk, String query) { - ovk.sendAPIMethod("Users.search", String.format("q=%s&count=50&fields=verified,sex,has_photo,photo_200,photo_400,photo_max_orig,status,screen_name,friend_status,last_seen,interests,music,movies,tv,books,city", Strings.urlEncode(query))); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeTypedList(users); - parcel.writeParcelable(user, i); - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Wall.java b/app/src/main/java/uk/openvk/android/refresh/api/Wall.java deleted file mode 100644 index 4a71750..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/Wall.java +++ /dev/null @@ -1,465 +0,0 @@ -package uk.openvk.android.refresh.api; - -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; - -import org.droidparts.util.Strings; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.URLEncoder; -import java.util.ArrayList; - -import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.attachments.Attachment; -import uk.openvk.android.refresh.api.attachments.PhotoAttachment; -import uk.openvk.android.refresh.api.attachments.PollAttachment; -import uk.openvk.android.refresh.api.attachments.VideoAttachment; -import uk.openvk.android.refresh.api.models.Comment; -import uk.openvk.android.refresh.api.models.PollAnswer; -import uk.openvk.android.refresh.api.models.VideoFiles; -import uk.openvk.android.refresh.api.models.WallPostSource; -import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.JSONParser; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -import uk.openvk.android.refresh.api.counters.PostCounters; -import uk.openvk.android.refresh.api.models.WallPost; -import uk.openvk.android.refresh.api.models.RepostInfo; - -/** - * Created by Dmitry on 28.09.2022. - */ -public class Wall implements Parcelable { - private JSONParser jsonParser; - private ArrayList items; - private ArrayList comments; - private ArrayList photos_msize; - private ArrayList photos_hsize; - private ArrayList photos_osize; - private DownloadManager dlm; - - public Wall(String response, DownloadManager downloadManager, String quality, Context ctx) { - jsonParser = new JSONParser(); - parse(ctx, downloadManager, quality, response); - } - - public Wall() { - jsonParser = new JSONParser(); - } - - protected Wall(Parcel in) { - items = in.createTypedArrayList(WallPost.CREATOR); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Wall createFromParcel(Parcel in) { - return new Wall(in); - } - - @Override - public Wall[] newArray(int size) { - return new Wall[size]; - } - }; - - public void parse(Context ctx, DownloadManager downloadManager, String quality, String response) { - this.dlm = downloadManager; - items = new ArrayList(); - photos_msize = new ArrayList(); - photos_hsize = new ArrayList(); - photos_osize = new ArrayList(); - ArrayList avatars = new ArrayList(); - try { - JSONObject json = jsonParser.parseJSON(response); - if(json != null) { - JSONObject newsfeed = json.getJSONObject("response"); - JSONArray items = newsfeed.getJSONArray("items"); - for(int i = 0; i < items.length(); i++) { - JSONObject post = items.getJSONObject(i); - JSONObject comments = post.getJSONObject("comments"); - JSONObject likes = post.getJSONObject("likes"); - JSONObject reposts = post.getJSONObject("reposts"); - JSONArray attachments = post.getJSONArray("attachments"); - long owner_id = post.getLong("owner_id"); - long post_id = post.getLong("id"); - long author_id = post.getLong("from_id"); - long dt_sec = post.getLong("date"); - String original_author_name = ""; - String original_author_avatar_url = ""; - String author_name = ""; - String owner_name = ""; - String avatar_url = ""; - String owner_avatar_url = ""; - String author_avatar_url = ""; - String content = post.getString("text"); - boolean isLiked = false; - boolean verified_author = false; - if(likes.getInt("user_likes") > 0) { - isLiked = true; - } else { - isLiked = false; - } - PostCounters counters = new PostCounters(likes.getInt("count"), - comments.getInt("count"), reposts.getInt("count"), isLiked, - false); - - ArrayList attachments_list = createAttachmentsList(owner_id, post_id, - quality, attachments); - - WallPost item = new WallPost(String.format("(Unknown author: %s)", author_id), - dt_sec, null, content, counters, "", attachments_list, - owner_id, post_id, ctx); - if(post.has("post_source") && !post.isNull("post_source")) { - if(post.getJSONObject("post_source").getString("type").equals("api")) { - item.post_source = new WallPostSource( - post.getJSONObject("post_source").getString("type"), - post.getJSONObject("post_source").getString("platform")); - } else { - item.post_source = new WallPostSource( - post.getJSONObject("post_source").getString("type"), null); - } - } - if(post.getJSONArray("copy_history").length() > 0) { - JSONObject repost = post.getJSONArray("copy_history").getJSONObject(0); - WallPost repost_item = new WallPost(String.format("(Unknown author: %s)", - repost.getInt("from_id")), repost.getInt("date"), null, - repost.getString("text"), null, "", - null, repost.getInt("owner_id"), repost.getInt("id"), ctx); - RepostInfo repostInfo = new RepostInfo(String.format("(Unknown author: %s)", - repost.getInt("from_id")), repost.getInt("date"), ctx); - repostInfo.newsfeed_item = repost_item; - item.repost = repostInfo; - JSONArray repost_attachments = repost.getJSONArray("attachments"); - attachments_list = createAttachmentsList(owner_id, post_id, quality, repost_attachments); - repost_item.attachments = attachments_list; - } - item.author_id = author_id; - if(author_id > 0) { - if(newsfeed.has("profiles")) { - JSONArray profiles = newsfeed.getJSONArray("profiles"); - for (int profiles_index = 0; profiles_index < profiles.length(); profiles_index++) { - JSONObject profile = profiles.getJSONObject(profiles_index); - if (profile.getInt("id") == author_id) { - author_name = String.format("%s %s", profile.getString("first_name"), - profile.getString("last_name")); - author_avatar_url = profile.getString("photo_50"); - if(profile.get("verified") instanceof Integer) { - verified_author = profile.getInt("verified") == 1; - } else { - verified_author = profile.getBoolean("verified"); - } - } else if (profile.getInt("id") == owner_id) { - owner_name = String.format("%s %s", profile.getString("first_name"), - profile.getString("last_name")); - owner_avatar_url = profile.getString("photo_50"); - if(profile.get("verified") instanceof Integer) { - verified_author = profile.getInt("verified") == 1; - } else { - verified_author = profile.getBoolean("verified"); - } - } - } - if(author_avatar_url.length() > 0) - avatar_url = author_avatar_url; - } - if(owner_id < 0) { - if(newsfeed.has("groups")) { - JSONArray groups = newsfeed.getJSONArray("groups"); - for (int groups_index = 0; groups_index < groups.length(); groups_index++) { - JSONObject group = groups.getJSONObject(groups_index); - if (-group.getInt("id") == owner_id) { - owner_name = group.getString("name"); - avatar_url = group.getString("photo_50"); - verified_author = group.getBoolean("verified"); - } - } - } - } - if(author_id == owner_id) { - item.name = author_name; - } else { - item.name = ctx.getResources().getString(R.string.on_wall, author_name, owner_name); - } - } else { - if(newsfeed.has("groups") && newsfeed.has("profiles")) { - JSONArray groups = newsfeed.getJSONArray("groups"); - JSONArray profiles = newsfeed.getJSONArray("profiles"); - for (int groups_index = 0; groups_index < groups.length(); groups_index++) { - JSONObject group = groups.getJSONObject(groups_index); - if (-group.getInt("id") == author_id) { - item.name = group.getString("name"); - avatar_url = group.getString("photo_50"); - verified_author = group.getBoolean("verified"); - } - } - } - } - PhotoAttachment avatar = new PhotoAttachment(); - avatar.url = avatar_url; - avatar.filename = String.format("avatar_%s", author_id); - avatars.add(avatar); - item.verified_author = verified_author; - this.items.add(item); - } - switch (quality) { - case "medium": - downloadManager.downloadPhotosToCache(photos_msize, "wall_photo_attachments"); - break; - case "high": - downloadManager.downloadPhotosToCache(photos_hsize, "wall_photo_attachments"); - break; - case "original": - downloadManager.downloadPhotosToCache(photos_osize, "wall_photo_attachments"); - break; - } - downloadManager.downloadPhotosToCache(avatars, "wall_avatars"); - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - - public ArrayList parseComments(Context ctx, DownloadManager downloadManager, String response) { - comments = new ArrayList(); - try { - JSONObject json = jsonParser.parseJSON(response); - if (json != null) { - JSONObject comments = json.getJSONObject("response"); - JSONArray items = comments.getJSONArray("items"); - ArrayList avatars = new ArrayList<>(); - for(int i = 0; i < items.length(); i++) { - JSONObject item = items.getJSONObject(i); - String text = item.getString("text"); - long comment_id = item.getLong("id"); - long author_id = item.getLong("from_id"); - long date = item.getLong("date"); - Comment comment = new Comment(); - comment.id = comment_id; - comment.author_id = author_id; - comment.text = text; - comment.author = String.format("(Unknown author: %s)", author_id); - comment.date = date; - PhotoAttachment photoAttachment = new PhotoAttachment(); - photoAttachment.url = ""; - photoAttachment.filename = ""; - if(author_id > 0) { - if(comments.has("profiles")) { - JSONArray profiles = comments.getJSONArray("profiles"); - for (int profiles_index = 0; profiles_index < profiles.length(); profiles_index++) { - JSONObject profile = profiles.getJSONObject(profiles_index); - if (profile.getLong("id") == author_id) { - comment.author = String.format("%s %s", profile.getString("first_name"), - profile.getString("last_name")); - if(profile.has("photo_100")) { - comment.avatar_url = profile.getString("photo_100"); - } - photoAttachment.url = comment.avatar_url; - photoAttachment.filename = String.format("avatar_%s", author_id); - } - } - } - } else { - if(comments.has("groups")) { - JSONArray groups = comments.getJSONArray("groups"); - for (int groups_index = 0; groups_index < groups.length(); groups_index++) { - JSONObject group = groups.getJSONObject(groups_index); - if (group.getLong("id") == author_id) { - comment.author = group.getString("name"); - if(group.has("photo_100")) { - comment.avatar_url = group.getString("photo_100"); - } - photoAttachment.url = comment.avatar_url; - photoAttachment.filename = String.format("avatar_%s", author_id); - } - } - } - } - avatars.add(photoAttachment); - this.comments.add(comment); - } - downloadManager.downloadPhotosToCache(avatars, "comment_avatars"); - } - } catch(JSONException e) { - e.printStackTrace(); - } - return comments; - } - - public ArrayList createAttachmentsList(long owner_id, long post_id, String quality, - JSONArray attachments) { - ArrayList attachments_list = new ArrayList<>(); - try { - for (int attachments_index = 0; attachments_index < attachments.length(); attachments_index++) { - String photo_medium_size; - String photo_high_size; - String photo_original_size; - String attachment_status; - JSONObject attachment = attachments.getJSONObject(attachments_index); - if (attachment.getString("type").equals("photo")) { - JSONObject photo = attachment.getJSONObject("photo"); - PhotoAttachment photoAttachment = new PhotoAttachment(); - photoAttachment.id = photo.getLong("id"); - JSONArray photo_sizes = photo.getJSONArray("sizes"); - photo_medium_size = photo_sizes.getJSONObject(5).getString("url"); - photo_high_size = photo_sizes.getJSONObject(8).getString("url"); - photo_original_size = photo_sizes.getJSONObject(10).getString("url"); - switch (quality) { - case "medium": - photoAttachment.url = photo_medium_size; - break; - case "high": - photoAttachment.url = photo_high_size; - break; - case "original": - photoAttachment.url = photo_original_size; - break; - } - photoAttachment.filename = String.format("wall_attachment_o%sp%s", owner_id, post_id); - photoAttachment.original_url = photo_original_size; - if (photo_medium_size.length() > 0 || photo_high_size.length() > 0) { - attachment_status = "loading"; - } else { - attachment_status = "none"; - } - Attachment attachment_obj = new Attachment(attachment.getString("type")); - attachment_obj.status = attachment_status; - attachment_obj.setContent(photoAttachment); - attachments_list.add(attachment_obj); - switch (quality) { - case "medium": - photos_msize.add(photoAttachment); - break; - case "high": - photos_hsize.add(photoAttachment); - break; - case "original": - photos_osize.add(photoAttachment); - break; - } - } else if (attachment.getString("type").equals("video")) { - JSONObject video = attachment.getJSONObject("video"); - VideoAttachment videoAttachment = new VideoAttachment(); - videoAttachment.id = video.getLong("id"); - videoAttachment.title = video.getString("title"); - VideoFiles files = new VideoFiles(); - if(video.has("files")) { - JSONObject videoFiles = video.getJSONObject("files"); - if(videoFiles.has("mp4_144")) { - files.mp4_144 = videoFiles.getString("mp4_144"); - } if(videoFiles.has("mp4_240")) { - files.mp4_240 = videoFiles.getString("mp4_240"); - } if(videoFiles.has("mp4_360")) { - files.mp4_360 = videoFiles.getString("mp4_360"); - } if(videoFiles.has("mp4_480")) { - files.mp4_480 = videoFiles.getString("mp4_480"); - } if(videoFiles.has("mp4_720")) { - files.mp4_720 = videoFiles.getString("mp4_720"); - } if(videoFiles.has("mp4_1080")) { - files.mp4_1080 = videoFiles.getString("mp4_1080"); - } if(videoFiles.has("ogv_480")) { - files.ogv_480 = videoFiles.getString("ogv_480"); - } - } - videoAttachment.files = files; - if(video.has("image")) { - JSONArray thumb_array = video.getJSONArray("image"); - videoAttachment.url_thumb = thumb_array.getJSONObject(0).getString("url"); - dlm.downloadOnePhotoToCache(videoAttachment.url_thumb, String.format("thumbnail_%s", - video.getLong("id")), "video_thumbnails"); - } - videoAttachment.duration = video.getInt("duration"); - attachment_status = "done"; - Attachment attachment_obj = new Attachment(attachment.getString("type")); - attachment_obj.status = attachment_status; - attachment_obj.setContent(videoAttachment); - attachments_list.add(attachment_obj); - } else if (attachment.getString("type").equals("poll")) { - JSONObject poll_attachment = attachment.getJSONObject("poll"); - PollAttachment pollAttachment = new PollAttachment(poll_attachment - .getString("question"), - poll_attachment.getInt("id"), poll_attachment - .getLong("end_date"), - poll_attachment.getBoolean("multiple"), poll_attachment - .getBoolean("can_vote"), - poll_attachment.getBoolean("anonymous")); - JSONArray answers = poll_attachment.getJSONArray("answers"); - JSONArray votes = poll_attachment.getJSONArray("answer_ids"); - if (votes.length() > 0) { - pollAttachment.user_votes = votes.length(); - } - pollAttachment.votes = poll_attachment.getInt("votes"); - for (int answers_index = 0; answers_index < answers.length(); answers_index++) { - JSONObject answer = answers.getJSONObject(answers_index); - PollAnswer pollAnswer = new PollAnswer(answer.getInt("id"), - answer.getInt("rate"), - answer.getInt("votes"), answer.getString("text")); - for (int votes_index = 0; votes_index < votes.length(); votes_index++) { - if (answer.getInt("id") == votes.getInt(votes_index)) { - pollAnswer.is_voted = true; - } - } - pollAttachment.answers.add(pollAnswer); - } - attachment_status = "done"; - Attachment attachment_obj = new Attachment(attachment.getString("type")); - attachment_obj.status = attachment_status; - attachment_obj.setContent(pollAttachment); - attachments_list.add(attachment_obj); - } else { - attachment_status = "not_supported"; - Attachment attachment_obj = new Attachment(attachment.getString("type")); - attachment_obj.status = attachment_status; - attachments_list.add(attachment_obj); - } - } - } catch (JSONException ex) { - ex.printStackTrace(); - } - return attachments_list; - } - - public void get(OvkAPIWrapper ovk, long owner_id, int count) { - ovk.sendAPIMethod("Wall.get", String.format("owner_id=%s&count=%s&extended=1", - owner_id, count)); - } - - public ArrayList getWallItems() { - return items; - } - - public void post(OvkAPIWrapper ovk, long owner_id, String post) { - ovk.sendAPIMethod("Wall.post", String.format("owner_id=%s&message=%s", owner_id, - Strings.urlEncode(post))); - } - - public void getComments(OvkAPIWrapper ovk, long owner_id, long post_id) { - ovk.sendAPIMethod("Wall.getComments", String.format("owner_id=%s&post_id=%s&extended=1" + - "&count=50", - owner_id, post_id)); - } - - public void createComment(OvkAPIWrapper ovk, long owner_id, long post_id, String text) { - ovk.sendAPIMethod("Wall.createComment", String.format("owner_id=%s&post_id=%s&message=%s", - owner_id, - post_id, Strings.urlEncode(text))); - } - - public void repost(OvkAPIWrapper ovk, long owner_id, long post_id, String text) { - ovk.sendAPIMethod("Wall.repost", String.format("object=wall%s_%s&message=%s", owner_id, - post_id, - Strings.urlEncode(text))); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeTypedList(items); - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/attachments/Attachment.java b/app/src/main/java/uk/openvk/android/refresh/api/attachments/Attachment.java index fefed0f..49a1903 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/attachments/Attachment.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/attachments/Attachment.java @@ -1,12 +1,22 @@ package uk.openvk.android.refresh.api.attachments; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.NonNull; - -public class Attachment implements Parcelable { +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Attachment { public String type; public String status; private Object content; @@ -16,32 +26,19 @@ public Attachment(String type) { case "photo": content = new PhotoAttachment(); break; + case "video": + content = new VideoAttachment(); + break; case "poll": content = new PollAttachment(); break; + case "note": + content = new CommonAttachment(); default: - content = null; break; } } - protected Attachment(Parcel in) { - type = in.readString(); - status = in.readString(); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Attachment createFromParcel(Parcel in) { - return new Attachment(in); - } - - @Override - public Attachment[] newArray(int size) { - return new Attachment[size]; - } - }; - public Object getContent() { return content; } @@ -49,15 +46,4 @@ public Object getContent() { public void setContent(Object content) { this.content = content; } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeString(type); - dest.writeString(status); - } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/attachments/CommonAttachment.java b/app/src/main/java/uk/openvk/android/refresh/api/attachments/CommonAttachment.java new file mode 100644 index 0000000..4a8aa23 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/attachments/CommonAttachment.java @@ -0,0 +1,30 @@ +package uk.openvk.android.refresh.api.attachments; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class CommonAttachment { + public String title; + public String text; + public CommonAttachment(String title, String text) { + this.title = title; + this.text = text; + } + + public CommonAttachment() { + + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/attachments/PhotoAttachment.java b/app/src/main/java/uk/openvk/android/refresh/api/attachments/PhotoAttachment.java index 6dc9f3d..b32d5fe 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/attachments/PhotoAttachment.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/attachments/PhotoAttachment.java @@ -4,15 +4,30 @@ import android.os.Parcel; import android.os.Parcelable; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class PhotoAttachment implements Parcelable { public long id; public String url; public String original_url; public String filename; - public boolean loaded; - public String error; + public int[] size; public Bitmap photo; + public String error; public int displayW; public int displayH; @@ -22,7 +37,6 @@ public PhotoAttachment() { protected PhotoAttachment(Parcel in) { url = in.readString(); filename = in.readString(); - original_url = in.readString(); } public static final Creator CREATOR = new Creator() { @@ -46,6 +60,5 @@ public int describeContents() { public void writeToParcel(Parcel parcel, int i) { parcel.writeString(url); parcel.writeString(filename); - parcel.writeString(original_url); } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/attachments/PollAttachment.java b/app/src/main/java/uk/openvk/android/refresh/api/attachments/PollAttachment.java index 45bb01b..27b036f 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/attachments/PollAttachment.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/attachments/PollAttachment.java @@ -2,9 +2,25 @@ import java.util.ArrayList; -import uk.openvk.android.refresh.api.models.PollAnswer; +import uk.openvk.android.refresh.api.entities.PollAnswer; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class PollAttachment { public long id; public long end_date; @@ -29,11 +45,11 @@ public PollAttachment() { } - public void vote(OvkAPIWrapper ovk, int answer_id) { - ovk.sendAPIMethod("Polls.addVote", String.format("poll_id=%s&answers_ids=%s", id, answer_id)); + public void vote(OvkAPIWrapper wrapper, int answer_id) { + wrapper.sendAPIMethod("Polls.addVote", String.format("poll_id=%s&answers_ids=%s", id, answer_id)); } - public void unvote(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Polls.deleteVote", String.format("poll_id=%s", id)); + public void unvote(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Polls.deleteVote", String.format("poll_id=%s", id)); } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/attachments/VideoAttachment.java b/app/src/main/java/uk/openvk/android/refresh/api/attachments/VideoAttachment.java index 2828fb9..cc949b6 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/attachments/VideoAttachment.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/attachments/VideoAttachment.java @@ -1,13 +1,26 @@ package uk.openvk.android.refresh.api.attachments; +import android.graphics.Bitmap; import android.os.Parcel; import android.os.Parcelable; -import uk.openvk.android.refresh.api.models.VideoFiles; +import uk.openvk.android.refresh.api.entities.VideoFiles; -/** - * File created by Dmitry on 14.02.2023. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class VideoAttachment implements Parcelable { public VideoFiles files; @@ -22,8 +35,7 @@ public VideoAttachment() { } - public VideoAttachment(long id, String title, VideoFiles files, String url_thumb, int duration, - String filename) { + public VideoAttachment(long id, String title, VideoFiles files, String url_thumb, int duration, String filename) { this.id = id; this.title = title; this.files = files; @@ -67,4 +79,4 @@ public VideoAttachment[] newArray(int size) { return new VideoAttachment[size]; } }; -} \ No newline at end of file +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/counters/AccountCounters.java b/app/src/main/java/uk/openvk/android/refresh/api/counters/AccountCounters.java index d7d942e..c795f24 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/counters/AccountCounters.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/counters/AccountCounters.java @@ -3,9 +3,21 @@ import android.os.Parcel; import android.os.Parcelable; -/** - * Created by Dmitry on 11.10.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class AccountCounters implements Parcelable { public int friends_requests; diff --git a/app/src/main/java/uk/openvk/android/refresh/api/counters/PostCounters.java b/app/src/main/java/uk/openvk/android/refresh/api/counters/PostCounters.java index 8d9c991..c5ac19e 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/counters/PostCounters.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/counters/PostCounters.java @@ -3,6 +3,22 @@ import android.os.Parcel; import android.os.Parcelable; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class PostCounters implements Parcelable { public int likes; public int comments; @@ -11,8 +27,7 @@ public class PostCounters implements Parcelable { public boolean isReposted; public boolean enabled = true; - public PostCounters(int likes_count, int comments_count, int reposts_count, boolean likes_selected, - boolean reposts_selected) { + public PostCounters(int likes_count, int comments_count, int reposts_count, boolean likes_selected, boolean reposts_selected) { likes = likes_count; comments = comments_count; reposts = reposts_count; diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Account.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Account.java similarity index 65% rename from app/src/main/java/uk/openvk/android/refresh/api/Account.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/Account.java index 1c9ef32..7d63a8d 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/Account.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Account.java @@ -1,4 +1,4 @@ -package uk.openvk.android.refresh.api; +package uk.openvk.android.refresh.api.entities; import android.content.Context; import android.os.Parcel; @@ -7,11 +7,28 @@ import org.json.JSONException; import org.json.JSONObject; +import uk.openvk.android.refresh.api.models.Users; +import uk.openvk.android.refresh.ui.core.activities.AppActivity; import uk.openvk.android.refresh.api.counters.AccountCounters; -import uk.openvk.android.refresh.api.models.User; import uk.openvk.android.refresh.api.wrappers.JSONParser; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class Account implements Parcelable { public String first_name; public String last_name; @@ -35,13 +52,13 @@ public Account(Context ctx) { this.ctx = ctx; } - public Account(String response, Context ctx, OvkAPIWrapper ovk) { + public Account(String response, Context ctx, OvkAPIWrapper wrapper) { retryConnection = false; jsonParser = new JSONParser(); this.user = new User(); this.users = new Users(); this.ctx = ctx; - parse(response, ovk); + parse(response, wrapper); } public Account(String first_name, String last_name, long id, String status, String birthdate) { @@ -76,7 +93,7 @@ public Account[] newArray(int size) { } }; - public void parse(String response, OvkAPIWrapper ovk) { + public void parse(String response, OvkAPIWrapper wrapper) { try { JSONObject json = jsonParser.parseJSON(response); if(json != null) { @@ -97,7 +114,7 @@ public void parse(String response, OvkAPIWrapper ovk) { } if(retryConnection) { if (ctx.getClass().getSimpleName().equals("AppActivity")) { - //((AppActivity) ctx).retryConnection(queue_method, queue_args); + ((AppActivity) ctx).retryConnection(queue_method, queue_args); } } } @@ -105,22 +122,26 @@ public void parse(String response, OvkAPIWrapper ovk) { public void parseCounters(String response) { try { JSONObject json = jsonParser.parseJSON(response); - JSONObject counters = json.getJSONObject("response"); - int friends = counters.getInt("friends"); - int messages = counters.getInt("messages"); - int notifications = counters.getInt("notifications"); - this.counters = new AccountCounters(friends, messages, notifications); + if(json == null || json.isNull("response")) { + this.counters = new AccountCounters(0, 0, 0); + } else { + JSONObject counters = json.getJSONObject("response"); + int friends = counters.getInt("friends"); + int messages = counters.getInt("messages"); + int notifications = counters.getInt("notifications"); + this.counters = new AccountCounters(friends, messages, notifications); + } } catch (JSONException e) { e.printStackTrace(); } } - public void getProfileInfo(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Account.getProfileInfo"); + public void getProfileInfo(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Account.getProfileInfo"); } - public void getCounters(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Account.getCounters"); + public void getCounters(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Account.getCounters"); } @Override diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/Authorization.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Authorization.java new file mode 100644 index 0000000..449c14b --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Authorization.java @@ -0,0 +1,46 @@ +package uk.openvk.android.refresh.api.entities; + +import org.json.JSONException; +import org.json.JSONObject; + +import uk.openvk.android.refresh.api.wrappers.JSONParser; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Authorization { + private String access_token; + private String response; + private JSONParser jsonParser; + public static String ACCOUNT_TYPE = "uk.openvk.android.refresh.account"; + + public Authorization(String response) { + this.response = response; + jsonParser = new JSONParser(); + JSONObject json = jsonParser.parseJSON(response); + if(json != null) { + try { + this.access_token = json.getString("access_token"); + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + + public String getAccessToken() { + return access_token; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/Comment.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Comment.java new file mode 100644 index 0000000..a4c6269 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Comment.java @@ -0,0 +1,50 @@ +package uk.openvk.android.refresh.api.entities; + +import android.graphics.Bitmap; + +import java.util.ArrayList; + +import uk.openvk.android.refresh.api.attachments.Attachment; +import uk.openvk.android.refresh.api.wrappers.JSONParser; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Comment { + public String author; + public long author_id; + public long date; + public String text; + public long id; + public Bitmap avatar; + public String avatar_url; + private JSONParser jsonParser; + public ArrayList attachments; + + public Comment() { + jsonParser = new JSONParser(); + } + + public Comment(int id, long author_id, String author, int date, String text, + ArrayList attachments) { + this.author_id = author_id; + this.author = author; + this.date = date; + this.text = text; + this.id = id; + this.attachments = attachments; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/Conversation.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Conversation.java new file mode 100644 index 0000000..b571109 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Conversation.java @@ -0,0 +1,84 @@ +package uk.openvk.android.refresh.api.entities; + +import android.content.Context; +import android.graphics.Bitmap; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.net.URLEncoder; +import java.util.ArrayList; + +import uk.openvk.android.refresh.api.wrappers.JSONParser; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Conversation { + public String title; + public long peer_id; + public int online; + public Bitmap avatar; + public Bitmap lastMsgAvatar; + public long lastMsgAuthorId; + public String lastMsgText; + public long lastMsgTime; + public String avatar_url; + private ArrayList history; + private JSONParser jsonParser; + + public Conversation() { + jsonParser = new JSONParser(); + history = new ArrayList(); + } + + public void getHistory(OvkAPIWrapper wrapper, long peer_id) { + this.peer_id = peer_id; + wrapper.sendAPIMethod("Messages.getHistory", + String.format("peer_id=%s&count=150&rev=1", peer_id)); + } + + public ArrayList parseHistory(Context ctx, String response) { + JSONObject json = jsonParser.parseJSON(response); + if(json != null) { + try { + JSONArray items = json.getJSONObject("response").getJSONArray("items"); + history = new ArrayList(); + for(int i = 0; i < items.length(); i++) { + JSONObject item = items.getJSONObject(i); + boolean incoming = false; + if(item.getInt("out") == 1) { + incoming = false; + } else { + incoming = true; + } + Message message = new Message(item.getLong("id"), incoming, false, item.getLong("date"), item.getString("text"), ctx); + message.author_id = item.getLong("from_id"); + history.add(message); + } + } catch(JSONException ex) { + ex.printStackTrace(); + } + } + return history; + } + + public void sendMessage(OvkAPIWrapper wrapper, String text) { + wrapper.sendAPIMethod("Messages.send", String.format("peer_id=%s&message=%s", peer_id, URLEncoder.encode(text))); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/Error.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Error.java new file mode 100644 index 0000000..2f704f5 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Error.java @@ -0,0 +1,77 @@ +package uk.openvk.android.refresh.api.entities; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import uk.openvk.android.refresh.api.wrappers.JSONParser; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Error { + public String description; + public int code; + private JSONParser jsonParser; + + public Error() { + jsonParser = new JSONParser(); + } + + public Error(String response) { + jsonParser = new JSONParser(); + JSONObject json = jsonParser.parseJSON(response); + if(json != null) { + try { + description = json.getString("error_msg"); + code = json.getInt("error_code"); + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + + public void parse(String response) { + if(response.startsWith("{") && response.endsWith("}")) { + JSONObject json = jsonParser.parseJSON(response); + if (json != null) { + try { + description = json.getString("error_msg"); + code = json.getInt("error_code"); + } catch (JSONException e) { + e.printStackTrace(); + } + } + } else { + JSONArray json = jsonParser.parseJSONArray(response); + if (json != null) { + try { + if(json.length() > 0) { + description = json.getJSONObject(0).getString("error_msg"); + code = json.getJSONObject(0).getInt("error_code"); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + } + + public Error(String description, int code) { + this.description = description; + this.code = code; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Friend.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Friend.java similarity index 80% rename from app/src/main/java/uk/openvk/android/refresh/api/models/Friend.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/Friend.java index bba7a15..c491f15 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/Friend.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Friend.java @@ -1,4 +1,4 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.graphics.Bitmap; import android.os.Parcel; @@ -11,9 +11,21 @@ import uk.openvk.android.refresh.api.wrappers.DownloadManager; import uk.openvk.android.refresh.api.wrappers.JSONParser; -/** - * Created by Dmitry on 30.09.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class Friend implements Parcelable { public String first_name; public String last_name; @@ -33,8 +45,8 @@ public Friend(String response, int position) { parse(response, position); } - public Friend(String first_name, String last_name, int id, String status, String city, String screen_name, - String avatar_url, int friends_status, int ls_date, String birthdate, + public Friend(String first_name, String last_name, int id, String status, String city, + String screen_name, String avatar_url, int friends_status, int ls_date, String birthdate, String interests, String movies, String music, String tv, String books, boolean verified) { this.first_name = first_name; this.last_name = last_name; @@ -65,10 +77,6 @@ public Friend[] newArray(int size) { } }; - public Friend() { - - } - public void parse(JSONObject user) { try { if(user != null) { @@ -76,26 +84,14 @@ public void parse(JSONObject user) { last_name = user.getString("last_name"); id = user.getInt("id"); avatar_url = ""; - if(user.has("verified")) { - if (user.getInt("verified") == 1) { - verified = true; - } else { - verified = false; - } + if (user.has("verified")) { + verified = user.getInt("verified") == 1; } else { verified = false; } - if(user.has("online")) { - if (user.getInt("online") == 1) { - online = true; - } else { - online = false; - } - } else { - online = false; - } + online = user.has("online") && user.getInt("online") == 1; if (user.has("last_seen") && !user.isNull("last_seen")) { - if(user.getJSONObject("last_seen").getInt("platform") != 7) { + if (user.getJSONObject("last_seen").getInt("platform") != 7) { from_mobile = true; } } @@ -134,16 +130,8 @@ public void parse(String response, int position) { first_name = user.getString("first_name"); last_name = user.getString("last_name"); id = user.getInt("id"); - if(user.getInt("verified") == 1) { - verified = true; - } else { - verified = false; - } - if(user.getInt("online") == 1) { - online = true; - } else { - online = false; - } + verified = user.getInt("verified") == 1; + online = user.getInt("online") == 1; if (user.has("photo_50")) { avatar_url = user.getString("photo_50"); } else if (user.has("photo_100")) { diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Group.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Group.java similarity index 52% rename from app/src/main/java/uk/openvk/android/refresh/api/models/Group.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/Group.java index d9ec176..372ebc0 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/Group.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Group.java @@ -1,21 +1,34 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.graphics.Bitmap; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; +import org.json.JSONArray; import org.json.JSONObject; -import java.net.URLEncoder; +import java.util.ArrayList; +import uk.openvk.android.refresh.api.attachments.PhotoAttachment; import uk.openvk.android.refresh.api.wrappers.DownloadManager; import uk.openvk.android.refresh.api.wrappers.JSONParser; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -/** - * Created by Dmitry on 09.10.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class Group implements Parcelable { public String name; @@ -27,10 +40,13 @@ public class Group implements Parcelable { public String avatar_msize_url; public String avatar_hsize_url; public String avatar_osize_url; + public String avatar_url; + public long avatar_id; public long members_count; public int is_member; public String description; public String site; + public ArrayList members; public Group() { jsonParser = new JSONParser(); @@ -73,14 +89,18 @@ public void parse(JSONObject group) { avatar_msize_url = group.getString("photo_200"); } if (group.has("photo_200_orig")) { avatar_msize_url = group.getString("photo_200_orig"); + avatar_url = avatar_msize_url; } if (group.has("photo_400")) { avatar_hsize_url = group.getString("photo_400"); } if (group.has("photo_400_orig")) { avatar_hsize_url = group.getString("photo_400_orig"); + avatar_url = avatar_hsize_url; } if (group.has("photo_max")) { avatar_osize_url = group.getString("photo_max"); } if (group.has("photo_max_orig")) { avatar_osize_url = group.getString("photo_max_orig"); + // вова, жду фикса шакалистых авок в photo_max_orig хд + // avatar_url = avatar_osize_url; } if(group.has("members_count")) { members_count = group.getLong("members_count"); @@ -139,25 +159,82 @@ public void writeToParcel(Parcel parcel, int i) { public void downloadAvatar(DownloadManager downloadManager, String quality) { if(quality.equals("medium")) { - downloadManager.downloadOnePhotoToCache(avatar_msize_url, String.format("avatar_%s", id), "group_avatars"); + downloadManager.downloadOnePhotoToCache(avatar_msize_url, String.format("avatar_%s", id), + "group_avatars"); } else if(quality.equals("high")) { if(avatar_hsize_url.length() == 0) { avatar_hsize_url = avatar_msize_url; } - downloadManager.downloadOnePhotoToCache(avatar_hsize_url, String.format("avatar_%s", id), "group_avatars"); + downloadManager.downloadOnePhotoToCache(avatar_hsize_url, String.format("avatar_%s", id), + "group_avatars"); } else if(quality.equals("original")) { if(avatar_osize_url.length() == 0) { avatar_osize_url = avatar_msize_url; } - downloadManager.downloadOnePhotoToCache(avatar_osize_url, String.format("avatar_%s", id), "group_avatars"); + downloadManager.downloadOnePhotoToCache(avatar_osize_url, String.format("avatar_%s", id), + "group_avatars"); } } - public void join(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Groups.join", String.format("group_id=%s", id)); + public void join(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Groups.join", String.format("group_id=%s", id)); } - public void leave(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Groups.leave", String.format("group_id=%s", id)); + public void leave(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Groups.leave", String.format("group_id=%s", id)); + } + + public void getMembers(OvkAPIWrapper wrapper, int count, String where) { + wrapper.sendAPIMethod("Groups.getMembers", + String.format("group_id=%s&fields=verified,online,photo_100," + + "photo_200_orig,photo_200,last_seen&count=%s", id, count), where); + } + + public void parseMembers(String response, DownloadManager downloadManager, boolean downloadPhoto) { + try { + this.members.clear(); + JSONObject json = jsonParser.parseJSON(response).getJSONObject("response"); + if(json != null) { + members_count = json.getInt("count"); + JSONArray members = json.getJSONArray("items"); + ArrayList avatars; + avatars = new ArrayList(); + for (int i = 0; i < members.length(); i++) { + User member = new User(); + JSONObject user = members.getJSONObject(i); + if(user.has("name")) { + member.first_name = user.getString("name").split(" ")[0]; + if (user.getString("name").split(" ").length > 1) { + if (user.getString("name").split(" ")[1] != null) { + member.last_name = user.getString("name").split(" ")[1]; + } else { + member.last_name = ""; + } + } + } else if(user.has("first_name") && user.has("last_name")) { + member.first_name = user.getString("first_name"); + if (!user.isNull("last_name")) { + member.last_name = user.getString("last_name"); + } else { + member.last_name = ""; + } + } + member.id = user.getLong("id"); + member.avatar_url = user.getString("photo_100"); + PhotoAttachment photoAttachment = new PhotoAttachment(); + if(member.avatar_url != null && member.avatar_url.length() > 0) { + photoAttachment.url = member.avatar_url; + photoAttachment.filename = String.format("avatar_%s", member.id); + avatars.add(photoAttachment); + } + this.members.add(member); + } + if (downloadPhoto) { + downloadManager.downloadPhotosToCache(avatars, "group_members_avatars"); + } + } + } catch (Exception e) { + e.printStackTrace(); + } } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/InstanceAdmin.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceAdmin.java similarity index 55% rename from app/src/main/java/uk/openvk/android/refresh/api/models/InstanceAdmin.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceAdmin.java index 258acf0..66b85ad 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/InstanceAdmin.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceAdmin.java @@ -1,13 +1,23 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.os.Parcel; import android.os.Parcelable; -import java.io.Serializable; - -/** - * Created by Dmitry on 07.10.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class InstanceAdmin implements Parcelable { public String first_name; diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceLink.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceLink.java new file mode 100644 index 0000000..3791a29 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceLink.java @@ -0,0 +1,26 @@ +package uk.openvk.android.refresh.api.entities; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class InstanceLink { + public String name; + public String url; + public InstanceLink(String name, String url) { + this.name = name; + this.url = url; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceStatistics.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceStatistics.java new file mode 100644 index 0000000..6d19236 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/InstanceStatistics.java @@ -0,0 +1,33 @@ +package uk.openvk.android.refresh.api.entities; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class InstanceStatistics { + public long users_count; + public long online_users_count; + public long active_users_count; + public long groups_count; + public long wall_posts_count; + public InstanceStatistics(long users_count, long online_users_count, long active_users_count, + long groups_count, long wall_posts_count) { + this.users_count = users_count; + this.online_users_count = online_users_count; + this.active_users_count = active_users_count; + this.groups_count = groups_count; + this.wall_posts_count = wall_posts_count; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/LongPollServer.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/LongPollServer.java new file mode 100644 index 0000000..690a9f7 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/LongPollServer.java @@ -0,0 +1,33 @@ +package uk.openvk.android.refresh.api.entities; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class LongPollServer { + public String address; + public String key; + public int ts; + + public LongPollServer() { + + } + + public LongPollServer(String address, String key, int ts) { + this.address = address; + this.key = key; + this.ts = ts; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Message.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Message.java similarity index 54% rename from app/src/main/java/uk/openvk/android/refresh/api/models/Message.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/Message.java index 63dc2ac..94497dd 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/Message.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Message.java @@ -1,8 +1,7 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.annotation.SuppressLint; import android.content.Context; -import android.util.Log; import org.json.JSONObject; @@ -12,8 +11,23 @@ import uk.openvk.android.refresh.api.wrappers.JSONParser; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class Message { - public final int type; public long id; public boolean isIncoming; public boolean isError; @@ -22,12 +36,12 @@ public class Message { public String text; public boolean sending; public long author_id; + public int type = 0; private JSONParser parser; @SuppressLint("SimpleDateFormat") - public Message(int type, long id, boolean incoming, boolean error, long _timestamp, String _text, + public Message(long id, boolean incoming, boolean error, long _timestamp, String _text, Context ctx) { - this.type = type; this.id = id; isIncoming = incoming; isError = error; diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/Note.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Note.java new file mode 100644 index 0000000..3c3565c --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Note.java @@ -0,0 +1,37 @@ +package uk.openvk.android.refresh.api.entities; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Note { + public long id; + public long owner_id; + public long date; + public String content; + public String title; + + public Note(long id, long owner_id, String title, String content, long date) { + this.id = id; + this.owner_id = owner_id; + this.title = title; + this.content = content; + this.date = date; + } + + public Note() { + + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Ovk.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Ovk.java similarity index 62% rename from app/src/main/java/uk/openvk/android/refresh/api/Ovk.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/Ovk.java index adcf9da..208309a 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/Ovk.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Ovk.java @@ -1,4 +1,4 @@ -package uk.openvk.android.refresh.api; +package uk.openvk.android.refresh.api.entities; import android.os.Parcel; import android.os.Parcelable; @@ -8,15 +8,25 @@ import java.util.ArrayList; -import uk.openvk.android.refresh.api.models.InstanceAdmin; -import uk.openvk.android.refresh.api.models.InstanceLink; -import uk.openvk.android.refresh.api.models.InstanceStatistics; import uk.openvk.android.refresh.api.wrappers.JSONParser; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -/** - * Created by Dmitry on 01.10.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class Ovk implements Parcelable { private JSONParser jsonParser; public String version; @@ -53,12 +63,12 @@ public Ovk[] newArray(int size) { } }; - public void getVersion(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Ovk.version"); + public void getVersion(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Ovk.version"); } - public void aboutInstance(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Ovk.aboutInstance", "fields=statistics,links,administrators"); + public void aboutInstance(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Ovk.aboutInstance", "fields=statistics,links,administrators"); } public void parseVersion(String response) { @@ -75,24 +85,28 @@ public void parseAboutInstance(String response) { JSONObject json = jsonParser.parseJSON(response); if(json != null) { JSONObject statistics = json.getJSONObject("response").getJSONObject("statistics"); - int users_count = 0; - int online_users_count = 0; - int active_users_count = 0; - int groups_count = 0; - int wall_posts_count = 0; - if(statistics.has("users_count")) users_count = statistics.getInt("users_count"); - if(statistics.has("online_users_count")) online_users_count = statistics.getInt("online_users_count"); - if(statistics.has("active_users_count")) active_users_count = statistics.getInt("active_users_count"); - if(statistics.has("groups_count")) groups_count = statistics.getInt("groups_count"); - if(statistics.has("wall_posts_count")) wall_posts_count = statistics.getInt("wall_posts_count"); - instance_stats = new InstanceStatistics(users_count, online_users_count, active_users_count, groups_count, wall_posts_count); + long users_count = 0; + long online_users_count = 0; + long active_users_count = 0; + long groups_count = 0; + long wall_posts_count = 0; + if(statistics.has("users_count")) users_count = statistics.getLong("users_count"); + if(statistics.has("online_users_count")) online_users_count = + statistics.getLong("online_users_count"); + if(statistics.has("active_users_count")) active_users_count = + statistics.getLong("active_users_count"); + if(statistics.has("groups_count")) groups_count = statistics.getLong("groups_count"); + if(statistics.has("wall_posts_count")) wall_posts_count = statistics.getLong("wall_posts_count"); + instance_stats = new InstanceStatistics(users_count, online_users_count, active_users_count, + groups_count, wall_posts_count); JSONObject admins = json.getJSONObject("response").getJSONObject("administrators"); JSONArray admin_items = json.getJSONObject("response").getJSONObject("administrators").getJSONArray("items"); JSONArray links_items = json.getJSONObject("response").getJSONObject("links").getJSONArray("items"); instance_admins = new ArrayList(); for(int i = 0; i < admin_items.length(); i++) { JSONObject admin = admin_items.getJSONObject(i); - instance_admins.add(new InstanceAdmin(admin.getString("first_name"), admin.getString("last_name"), admin.getInt("id"))); + instance_admins.add(new InstanceAdmin(admin.getString("first_name"), admin.getString("last_name"), + admin.getInt("id"))); } instance_links = new ArrayList(); for(int i = 0; i < links_items.length(); i++) { diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/OvkExpandableText.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/OvkExpandableText.java new file mode 100644 index 0000000..4e3aef7 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/OvkExpandableText.java @@ -0,0 +1,30 @@ +package uk.openvk.android.refresh.api.entities; + +import android.text.Spanned; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class OvkExpandableText { + public Spanned sp_text; + public long real_length; + public boolean expandable; + public OvkExpandableText(Spanned sp_text, long real_length, long limit) { + this.sp_text = sp_text; + this.real_length = real_length; + expandable = real_length >= limit; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/OvkLink.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/OvkLink.java new file mode 100644 index 0000000..373df47 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/OvkLink.java @@ -0,0 +1,33 @@ +package uk.openvk.android.refresh.api.entities; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class OvkLink { + public String name; + public String screen_name; + public String url; + public OvkLink() { + this.name = ""; + this.screen_name = ""; + this.url = ""; + } + public OvkLink(String name, String screen_name, String url) { + this.name = name; + this.screen_name = screen_name; + this.url = url; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/Photo.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/Photo.java new file mode 100644 index 0000000..76fef7a --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/Photo.java @@ -0,0 +1,29 @@ +package uk.openvk.android.refresh.api.entities; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Photo { + public long id; + public long album_id; + public long owner_id; + public String url; + public String original_url; + + public Photo() { + + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/PhotoAlbum.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/PhotoAlbum.java new file mode 100644 index 0000000..b71aeb7 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/PhotoAlbum.java @@ -0,0 +1,46 @@ +package uk.openvk.android.refresh.api.entities; + +import java.util.ArrayList; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class PhotoAlbum { + public long[] ids = new long[2]; + public String title; + public long size; + public String thumbnail_url; + public ArrayList photos; + public PhotoAlbum(String str_ids) { + String[] ids = str_ids.split("_"); + try { + if (ids.length >= 2) { + long owner_id = Long.parseLong(ids[0]); + long album_id = Long.parseLong(ids[1]); + this.ids[0] = owner_id; + this.ids[1] = album_id; + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public PhotoAlbum(long owner_id, long album_id) { + ids = new long[2]; + this.ids[0] = owner_id; + this.ids[1] = album_id; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/PollAnswer.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/PollAnswer.java new file mode 100644 index 0000000..22095ba --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/PollAnswer.java @@ -0,0 +1,31 @@ +package uk.openvk.android.refresh.api.entities; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class PollAnswer { + public int id; + public int rate; + public int votes; + public String text; + public boolean is_voted; + public PollAnswer(int id, int rate, int votes, String text) { + this.id = id; + this.rate = rate; + this.votes = votes; + this.text = text; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/RepostInfo.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/RepostInfo.java similarity index 74% rename from app/src/main/java/uk/openvk/android/refresh/api/models/RepostInfo.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/RepostInfo.java index d8fbde6..2901a26 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/RepostInfo.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/RepostInfo.java @@ -1,4 +1,4 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.annotation.SuppressLint; import android.content.Context; @@ -11,6 +11,22 @@ import uk.openvk.android.refresh.R; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class RepostInfo implements Parcelable { public String name; public String time; diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/User.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/User.java similarity index 86% rename from app/src/main/java/uk/openvk/android/refresh/api/models/User.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/User.java index f69206e..7594aa3 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/User.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/User.java @@ -1,9 +1,8 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.graphics.Bitmap; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; import org.json.JSONArray; import org.json.JSONException; @@ -11,11 +10,23 @@ import uk.openvk.android.refresh.api.wrappers.DownloadManager; import uk.openvk.android.refresh.api.wrappers.JSONParser; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -/** - * Created by Dmitry on 30.09.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class User implements Parcelable { public String first_name; public String last_name; @@ -32,6 +43,7 @@ public class User implements Parcelable { public String avatar_msize_url; public String avatar_hsize_url; public String avatar_osize_url; + public long avatar_id; public int friends_status; public String interests; public String movies; @@ -41,6 +53,8 @@ public class User implements Parcelable { public String deactivated; private JSONParser jsonParser; public int sex; + public String avatar_url; + public String ban_reason; public User(JSONObject user) { parse(user); @@ -50,9 +64,8 @@ public User(String response, int position) { parse(response, position); } - public User(String first_name, String last_name, int id, String status, String city, - String screen_name, String avatar_msize_url, int friends_status, int ls_date, - String birthdate, + public User(String first_name, String last_name, int id, String status, String city, String screen_name, + String avatar_msize_url, int friends_status, int ls_date, String birthdate, String interests, String movies, String music, String tv, String books, boolean verified) { this.first_name = first_name; this.last_name = last_name; @@ -130,30 +143,34 @@ public void parse(JSONObject user) { } else { status = ""; } - if(user.has("screen_name") && !user.isNull("screen_name")) { - screen_name = user.getString("screen_name"); - } else { - screen_name = ""; - } + //screen_name = user.getString("screen_name"); if (user.has("photo_50")) { avatar_msize_url = user.getString("photo_50"); } else if (user.has("photo_100")) { avatar_msize_url = user.getString("photo_100"); - } else if (user.has("photo_200_orig")) { - avatar_msize_url = user.getString("photo_200_orig"); } else if (user.has("photo_200")) { avatar_msize_url = user.getString("photo_200"); + } else if (user.has("photo_200_orig")) { + avatar_msize_url = user.getString("photo_200_orig"); + avatar_url = avatar_msize_url; } else if (user.has("photo_400")) { avatar_hsize_url = user.getString("photo_400"); } else if (user.has("photo_400_orig")) { avatar_hsize_url = user.getString("photo_400_orig"); + avatar_url = avatar_hsize_url; } else if (user.has("photo_max")) { avatar_osize_url = user.getString("photo_max"); } else if (user.has("photo_max_orig")) { avatar_osize_url = user.getString("photo_max_orig"); + avatar_url = avatar_osize_url; } if(user.has("deactivated")) { deactivated = user.getString("deactivated"); + if(deactivated.equals("banned") && user.isNull("ban_reason")) { + ban_reason = user.getString("ban_reason"); + } else { + ban_reason = ""; + } } else { friends_status = user.getInt("friend_status"); if (!user.isNull("interests")) { @@ -191,16 +208,8 @@ public void parse(JSONObject user) { if (!user.isNull("city")) { city = user.getString("city"); } - if (user.getInt("verified") == 1) { - verified = true; - } else { - verified = false; - } - if (user.getInt("online") == 1) { - online = true; - } else { - online = false; - } + verified = user.getInt("verified") == 1; + online = user.getInt("online") == 1; if(user.has("sex")) { sex = user.getInt("sex"); } @@ -231,16 +240,19 @@ public void parse(String response, int position) { avatar_msize_url = user.getString("photo_100"); } if (user.has("photo_200_orig")) { avatar_msize_url = user.getString("photo_200_orig"); + avatar_url = avatar_msize_url; } if (user.has("photo_200")) { avatar_msize_url = user.getString("photo_200"); } if (user.has("photo_400")) { avatar_hsize_url = user.getString("photo_400"); } if (user.has("photo_400_orig")) { avatar_hsize_url = user.getString("photo_400_orig"); + avatar_url = avatar_hsize_url; } if (user.has("photo_max")) { avatar_osize_url = user.getString("photo_max"); } if (user.has("photo_max_orig")) { avatar_osize_url = user.getString("photo_max_orig"); + avatar_url = avatar_osize_url; } friends_status = user.getInt("friend_status"); @@ -295,17 +307,20 @@ public void parse(String response, int position) { public void downloadAvatar(DownloadManager downloadManager, String quality) { if(quality.equals("medium")) { - downloadManager.downloadOnePhotoToCache(avatar_msize_url, String.format("avatar_%s", id), "profile_avatars"); + downloadManager.downloadOnePhotoToCache(avatar_msize_url, String.format("avatar_%s", id), + "profile_avatars"); } else if(quality.equals("high")) { if(avatar_hsize_url.length() == 0) { avatar_hsize_url = avatar_msize_url; } - downloadManager.downloadOnePhotoToCache(avatar_hsize_url, String.format("avatar_%s", id), "profile_avatars"); + downloadManager.downloadOnePhotoToCache(avatar_hsize_url, String.format("avatar_%s", id), + "profile_avatars"); } else if(quality.equals("original")) { if(avatar_osize_url.length() == 0) { avatar_osize_url = avatar_msize_url; } - downloadManager.downloadOnePhotoToCache(avatar_osize_url, String.format("avatar_%s", id), "profile_avatars"); + downloadManager.downloadOnePhotoToCache(avatar_osize_url, String.format("avatar_%s", id), + "profile_avatars"); } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/UserPostInfo.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/UserPostInfo.java similarity index 58% rename from app/src/main/java/uk/openvk/android/refresh/api/models/UserPostInfo.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/UserPostInfo.java index 1cd5af8..d160320 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/UserPostInfo.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/UserPostInfo.java @@ -1,8 +1,24 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.os.Parcel; import android.os.Parcelable; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class UserPostInfo implements Parcelable { int postId; int postUserId; diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/VideoFiles.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/VideoFiles.java similarity index 60% rename from app/src/main/java/uk/openvk/android/refresh/api/models/VideoFiles.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/VideoFiles.java index e5c9a00..81635da 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/VideoFiles.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/VideoFiles.java @@ -1,11 +1,23 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.os.Parcel; import android.os.Parcelable; -/** - * File created by Dmitry on 24.02.2023. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class VideoFiles implements Parcelable { public String mp4_144; diff --git a/app/src/main/java/uk/openvk/android/refresh/api/entities/WallPost.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/WallPost.java new file mode 100644 index 0000000..f929142 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/WallPost.java @@ -0,0 +1,346 @@ +package uk.openvk.android.refresh.api.entities; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.Bitmap; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.R; +import uk.openvk.android.refresh.api.attachments.Attachment; +import uk.openvk.android.refresh.api.attachments.PhotoAttachment; +import uk.openvk.android.refresh.api.attachments.PollAttachment; +import uk.openvk.android.refresh.api.attachments.VideoAttachment; +import uk.openvk.android.refresh.api.counters.PostCounters; +import uk.openvk.android.refresh.api.wrappers.JSONParser; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class WallPost implements Parcelable { + + private int type; + private String avatar_url; + public Bitmap avatar; + public String name; + public RepostInfo repost; + public String info; + public String text; + public long owner_id; + public long post_id; + public PostCounters counters; + public long author_id; + public boolean verified_author; + public boolean is_explicit; + public ArrayList attachments; + public WallPostSource post_source; + private String json_str; + + @SuppressLint("SimpleDateFormat") + public WallPost(String author, long dt_sec, RepostInfo repostInfo, String post_text, + PostCounters nICI, String avatar_url, ArrayList attachments, + long o_id, long p_id, Context ctx) { + name = author; + Date dt = new Date(TimeUnit.SECONDS.toMillis(dt_sec)); + Date dt_midnight = new Date(System.currentTimeMillis() + 86400000); + dt_midnight.setHours(0); + dt_midnight.setMinutes(0); + dt_midnight.setSeconds(0); + if((dt_midnight.getTime() - (TimeUnit.SECONDS.toMillis(dt_sec))) < 86400000) { + info = String.format("%s %s", ctx.getResources().getString(R.string.today_at), new SimpleDateFormat("HH:mm").format(dt)); + } else if((dt_midnight.getTime() - (TimeUnit.SECONDS.toMillis(dt_sec))) < (86400000 * 2)) { + info = String.format("%s %s", ctx.getResources().getString(R.string.yesterday_at), new SimpleDateFormat("HH:mm").format(dt)); + } else if((dt_midnight.getTime() - (TimeUnit.SECONDS.toMillis(dt_sec))) < 31536000000L) { + info = String.format("%s %s %s", new SimpleDateFormat("d MMMM").format(dt), ctx.getResources().getString(R.string.date_at), + new SimpleDateFormat("HH:mm").format(dt)); + } else { + info = String.format("%s %s %s", new SimpleDateFormat("d MMMM yyyy").format(dt), ctx.getResources().getString(R.string.date_at), + new SimpleDateFormat("HH:mm").format(dt)); + } + repost = repostInfo; + counters = nICI; + text = post_text; + this.avatar_url = avatar_url; + owner_id = o_id; + post_id = p_id; + this.attachments = attachments; + } + + public WallPost() { + + } + + public WallPost(int type) { + this.type = type; + } + + @SuppressLint("SimpleDateFormat") + public WallPost(String json_str, Context ctx) { + try { + JSONParser jsonParser = new JSONParser(); + JSONObject post = jsonParser.parseJSON(json_str); + JSONObject comments = null; + JSONObject likes = null; + JSONObject reposts = null; + try { + comments = post.getJSONObject("comments"); + likes = post.getJSONObject("likes"); + reposts = post.getJSONObject("reposts"); + } catch (Exception ignore) { + + } + JSONArray attachments = post.getJSONArray("attachments"); + owner_id = post.getLong("owner_id"); + post_id = post.getLong("id"); + author_id = post.getLong("from_id"); + if(post.has("is_explicit")) { + is_explicit = post.getBoolean("is_explicit"); + } + createAttachmentsList(owner_id, post_id, attachments); + long dt_sec = post.getLong("date"); + Date dt = new Date(TimeUnit.SECONDS.toMillis(dt_sec)); + Date dt_midnight = new Date(System.currentTimeMillis() + 86400000); + dt_midnight.setHours(0); + dt_midnight.setMinutes(0); + dt_midnight.setSeconds(0); + setJSONString(post.toString()); + if((dt_midnight.getTime() - (TimeUnit.SECONDS.toMillis(dt_sec))) < 86400000) { + info = String.format("%s %s", ctx.getResources().getString(R.string.today_at), + new SimpleDateFormat("HH:mm").format(dt)); + } else if((dt_midnight.getTime() - (TimeUnit.SECONDS.toMillis(dt_sec))) < (86400000 * 2)) { + info = String.format("%s %s", ctx.getResources().getString(R.string.yesterday_at), + new SimpleDateFormat("HH:mm").format(dt)); + } else if((dt_midnight.getTime() - (TimeUnit.SECONDS.toMillis(dt_sec))) < 31536000000L) { + info = String.format("%s %s %s", new SimpleDateFormat("d MMMM").format(dt), + ctx.getResources().getString(R.string.date_at), + new SimpleDateFormat("HH:mm").format(dt)); + } else { + info = String.format("%s %s %s", new SimpleDateFormat("d MMMM yyyy").format(dt), + ctx.getResources().getString(R.string.date_at), + new SimpleDateFormat("HH:mm").format(dt)); + } + String avatar_url = ""; + String owner_avatar_url = ""; + String author_avatar_url = ""; + text = post.getString("text"); + boolean isLiked = false; + boolean verified_author = false; + if(likes != null && reposts != null && comments != null) { + isLiked = likes.getInt("user_likes") > 0; + counters = new PostCounters(likes.getInt("count"), comments.getInt("count"), + reposts.getInt("count"), isLiked, false); + } else { + counters = new PostCounters(0, 0, 0, false, false); + } + if(post.has("post_source") && !post.isNull("post_source")) { + if(post.getJSONObject("post_source").getString("type").equals("api")) { + post_source = new WallPostSource(post.getJSONObject("post_source").getString("type"), + post.getJSONObject("post_source").getString("platform")); + } else { + post_source = new WallPostSource(post.getJSONObject("post_source").getString("type"), null); + } + } + if(post.getJSONArray("copy_history").length() > 0) { + JSONObject repost = post.getJSONArray("copy_history").getJSONObject(0); + WallPost repost_item = new WallPost(String.format("(Unknown author: %s)", + repost.getInt("from_id")), + repost.getInt("date"), null, repost.getString("text"), null, "", + null, repost.getInt("owner_id"), repost.getInt("id"), ctx); + repost_item.setJSONString(repost.toString()); + RepostInfo repostInfo = new RepostInfo(String.format("(Unknown author: %s)", + repost.getInt("from_id")), + repost.getInt("date"), ctx); + repostInfo.newsfeed_item = repost_item; + this.repost = repostInfo; + JSONArray repost_attachments = repost.getJSONArray("attachments"); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public void setExplicit(boolean value) { + this.is_explicit = value; + } + + private ArrayList createAttachmentsList( + long owner_id, long post_id, JSONArray attachments) { + this.attachments = new ArrayList<>(); + try { + for (int attachments_index = 0; attachments_index < attachments.length(); attachments_index++) { + String photo_medium_size; + String photo_high_size; + String photo_original_size; + String attachment_status; + JSONObject attachment = attachments.getJSONObject(attachments_index); + if (attachment.getString("type").equals("photo")) { + JSONObject photo = attachment.getJSONObject("photo"); + PhotoAttachment photoAttachment = new PhotoAttachment(); + photoAttachment.id = photo.getLong("id"); + JSONArray photo_sizes = photo.getJSONArray("sizes"); + photo_medium_size = photo_sizes.getJSONObject(5).getString("url"); + photo_high_size = photo_sizes.getJSONObject(8).getString("url"); + photo_original_size = photo_sizes.getJSONObject(10).getString("url"); + photoAttachment.filename = String.format("wall_o%sp%s", owner_id, post_id); + photoAttachment.original_url = photo_original_size; + if (photo_medium_size.length() > 0 || photo_high_size.length() > 0) { + attachment_status = "loading"; + } else { + attachment_status = "none"; + } + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = attachment_status; + attachment_obj.setContent(photoAttachment); + this.attachments.add(attachment_obj); + } else if (attachment.getString("type").equals("video")) { + JSONObject video = attachment.getJSONObject("video"); + VideoAttachment videoAttachment = new VideoAttachment(); + videoAttachment.id = video.getLong("id"); + videoAttachment.title = video.getString("title"); + VideoFiles files = new VideoFiles(); + if(video.has("files") && !video.isNull("files")) { + JSONObject videoFiles = video.getJSONObject("files"); + if(videoFiles.has("mp4_144")) { + files.mp4_144 = videoFiles.getString("mp4_144"); + } if(videoFiles.has("mp4_240")) { + files.mp4_240 = videoFiles.getString("mp4_240"); + } if(videoFiles.has("mp4_360")) { + files.mp4_360 = videoFiles.getString("mp4_360"); + } if(videoFiles.has("mp4_480")) { + files.mp4_480 = videoFiles.getString("mp4_480"); + } if(videoFiles.has("mp4_720")) { + files.mp4_720 = videoFiles.getString("mp4_720"); + } if(videoFiles.has("mp4_1080")) { + files.mp4_1080 = videoFiles.getString("mp4_1080"); + } if(videoFiles.has("ogv_480")) { + files.ogv_480 = videoFiles.getString("ogv_480"); + } + } + videoAttachment.files = files; + if(video.has("image")) { + JSONArray thumb_array = video.getJSONArray("image"); + videoAttachment.url_thumb = thumb_array.getJSONObject(0).getString("url"); + } + videoAttachment.duration = video.getInt("duration"); + attachment_status = "done"; + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = attachment_status; + attachment_obj.setContent(videoAttachment); + this.attachments.add(attachment_obj); + } else if (attachment.getString("type").equals("poll")) { + JSONObject poll_attachment = attachment.getJSONObject("poll"); + PollAttachment pollAttachment = new PollAttachment(poll_attachment.getString("question"), + poll_attachment.getInt("id"), poll_attachment.getLong("end_date"), + poll_attachment.getBoolean("multiple"), + poll_attachment.getBoolean("can_vote"), + poll_attachment.getBoolean("anonymous")); + JSONArray answers = poll_attachment.getJSONArray("answers"); + JSONArray votes = poll_attachment.getJSONArray("answer_ids"); + if (votes.length() > 0) { + pollAttachment.user_votes = votes.length(); + } + pollAttachment.votes = poll_attachment.getInt("votes"); + for (int answers_index = 0; answers_index < answers.length(); answers_index++) { + JSONObject answer = answers.getJSONObject(answers_index); + PollAnswer pollAnswer = new PollAnswer(answer.getInt("id"), answer.getInt("rate"), + answer.getInt("votes"), answer.getString("text")); + for (int votes_index = 0; votes_index < votes.length(); votes_index++) { + if (answer.getInt("id") == votes.getInt(votes_index)) { + pollAnswer.is_voted = true; + } + } + pollAttachment.answers.add(pollAnswer); + } + attachment_status = "done"; + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = attachment_status; + attachment_obj.setContent(pollAttachment); + this.attachments.add(attachment_obj); + } else { + attachment_status = "not_supported"; + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = attachment_status; + this.attachments.add(attachment_obj); + } + } + } catch (JSONException ex) { + ex.printStackTrace(); + } + if(this.attachments == null) { + Log.e(OvkApplication.API_TAG, "Oops!"); + } + return this.attachments; + } + + public WallPost(Parcel in) { + avatar_url = in.readString(); + avatar = in.readParcelable(Bitmap.class.getClassLoader()); + name = in.readString(); + info = in.readString(); + text = in.readString(); + owner_id = in.readLong(); + post_id = in.readLong(); + author_id = in.readInt(); + } + + public void setJSONString(String json) { + this.json_str = json; + } + + public String getJSONString() { + return json_str; + } + + public static final Creator CREATOR = new Creator() { + @Override + public WallPost createFromParcel(Parcel in) { + return new WallPost(in); + } + + @Override + public WallPost[] newArray(int size) { + return new WallPost[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(avatar_url); + parcel.writeParcelable(avatar, i); + parcel.writeString(name); + parcel.writeString(info); + parcel.writeString(text); + parcel.writeLong(owner_id); + parcel.writeLong(post_id); + parcel.writeLong(author_id); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/WallPostSource.java b/app/src/main/java/uk/openvk/android/refresh/api/entities/WallPostSource.java similarity index 52% rename from app/src/main/java/uk/openvk/android/refresh/api/models/WallPostSource.java rename to app/src/main/java/uk/openvk/android/refresh/api/entities/WallPostSource.java index cfe9bfb..58605a4 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/WallPostSource.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/entities/WallPostSource.java @@ -1,8 +1,24 @@ -package uk.openvk.android.refresh.api.models; +package uk.openvk.android.refresh.api.entities; import android.os.Parcel; import android.os.Parcelable; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class WallPostSource implements Parcelable { public String type; public String platform; diff --git a/app/src/main/java/uk/openvk/android/refresh/api/enumerations/HandlerMessages.java b/app/src/main/java/uk/openvk/android/refresh/api/enumerations/HandlerMessages.java index ec12ba1..7f74579 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/enumerations/HandlerMessages.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/enumerations/HandlerMessages.java @@ -1,125 +1,153 @@ package uk.openvk.android.refresh.api.enumerations; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class HandlerMessages { - // Authorization - public static int OVKAPI_AUTHORIZED = 1; - public static int OVKAPI_INVALID_USERNAME_OR_PASSWORD = 2; - public static int OVKAPI_TWOFACTOR_CODE_REQUIRED = 3; - - // Account - public static int OVKAPI_ACCOUNT_PROFILE_INFO = 100; - public static int OVKAPI_ACCOUNT_INFO = 101; - public static int OVKAPI_ACCOUNT_SET_TO_ONLINE = 102; - public static int OVKAPI_ACCOUNT_SET_TO_OFFLINE = 103; - public static int OVKAPI_ACCOUNT_COUNTERS = 104; - - // Friends - public static int OVKAPI_FRIENDS_GET = 200; - public static int OVKAPI_FRIENDS_GET_MORE = 201; - public static int OVKAPI_FRIENDS_GET_ALT = 202; - public static int OVKAPI_FRIENDS_ADD = 203; - public static int OVKAPI_FRIENDS_DELETE = 204; - public static int OVKAPI_FRIENDS_CHECK = 205; - public static int OVKAPI_FRIENDS_REQUESTS = 206; - - // Groups - public static int OVKAPI_GROUPS_GET = 300; - public static int OVKAPI_GROUPS_GET_MORE = 301; - public static int OVKAPI_GROUPS_GET_ALT = 302; - public static int OVKAPI_GROUPS_GET_BY_ID = 303; - public static int OVKAPI_GROUPS_SEARCH = 304; - public static int OVKAPI_GROUPS_JOIN = 305; - public static int OVKAPI_GROUPS_LEAVE = 306; - - // Likes - public static int OVKAPI_LIKES_ADD = 400; - public static int OVKAPI_LIKES_DELETE = 401; - public static int OVKAPI_LIKES_CHECK = 402; - - // Messages - public static int OVKAPI_MESSAGES_GET_BY_ID = 500; - public static int OVKAPI_MESSAGES_SEND = 501; - public static int OVKAPI_MESSAGES_DELETE = 502; - public static int OVKAPI_MESSAGES_RESTORE = 503; - public static int OVKAPI_MESSAGES_CONVERSATIONS = 504; - public static int OVKAPI_MESSAGES_GET_CONVERSATIONS_BY_ID = 505; - public static int OVKAPI_MESSAGES_GET_HISTORY = 506; - public static int OVKAPI_MESSAGES_GET_LONGPOLL_HISTORY = 507; - public static int OVKAPI_MESSAGES_GET_LONGPOLL_SERVER = 508; - - // Users - public static int OVKAPI_USERS_GET = 600; - public static int OVKAPI_USERS_GET_ALT = 601; - public static int OVKAPI_USERS_GET_ALT2 = 602; - public static int OVKAPI_USERS_FOLLOWERS = 603; - public static int OVKAPI_USERS_SEARCH = 604; - - // Wall - public static int OVKAPI_WALL_GET = 700; - public static int OVKAPI_WALL_GET_BY_ID = 701; - public static int OVKAPI_WALL_POST = 702; - public static int OVKAPI_WALL_REPOST = 703; - public static int OVKAPI_WALL_CREATE_COMMENT = 704; - public static int OVKAPI_WALL_DELETE_COMMENT = 705; - public static int OVKAPI_WALL_COMMENT = 706; - public static int OVKAPI_WALL_ALL_COMMENTS = 707; - - // Newsfeed - public static int OVKAPI_NEWSFEED_GET = 800; - public static int OVKAPI_NEWSFEED_GET_GLOBAL = 801; - public static int OVKAPI_NEWSFEED_GET_MORE = 802; - public static int OVKAPI_NEWSFEED_GET_MORE_GLOBAL = 803; - - // OpenVK specific - public static int OVKAPI_OVK_VERSION = 900; - public static int OVKAPI_OVK_TEST = 901; - public static int OVKAPI_OVK_CHICKEN_WINGS = 902; - public static int OVKAPI_OVK_ABOUTINSTANCE = 903; - public static int OVKAPI_OVK_CHECK_HTTP = 904; - public static int OVKAPI_OVK_CHECK_HTTPS = 905; - - // PollAttachment - public static int OVKAPI_POLL_ADD_VOTE = 1000; - public static int OVKAPI_POLL_DELETE_VOTE = 1001; - - // Misc - public static int DLM_ACCOUNT_AVATAR = 1100; - public static int DLM_NEWSFEED_ATTACHMENTS = 1101; - public static int DLM_WALL_ATTACHMENTS = 1102; - public static int DLM_WALL_AVATARS = 1103; - public static int DLM_NEWSFEED_AVATARS = 1104; - public static int DLM_PROFILE_AVATARS = 1105; - public static int DLM_GROUP_AVATARS = 1106; - public static int DLM_GROUP_AVATARS_ALT = 1107; - public static int DLM_FRIEND_AVATARS = 1108; - public static int DLM_COMMENT_AVATARS = 1109; - public static int DLM_CONVERSATIONS_AVATARS = 1110; - public static int LONGPOLL = 1111; - public static int DLM_ORIGINAL_PHOTO = 1112; + // Authorization (token) + public static int AUTHORIZED = 1; + public static int INVALID_USERNAME_OR_PASSWORD = 2; + public static int TWOFACTOR_CODE_REQUIRED = 3; + + // Account (/method/Account) + public static int ACCOUNT_PROFILE_INFO = 100; + public static int ACCOUNT_INFO = 101; + public static int ACCOUNT_SET_TO_ONLINE = 102; + public static int ACCOUNT_SET_TO_OFFLINE = 103; + public static int ACCOUNT_COUNTERS = 104; + + // Friends (/method/Friends) + public static int FRIENDS_GET = 200; + public static int FRIENDS_GET_MORE = 201; + public static int FRIENDS_GET_ALT = 202; + public static int FRIENDS_ADD = 203; + public static int FRIENDS_DELETE = 204; + public static int FRIENDS_CHECK = 205; + public static int FRIENDS_REQUESTS = 206; + + // Groups (/method/Groups) + public static int GROUPS_GET = 300; + public static int GROUPS_GET_MORE = 301; + public static int GROUPS_GET_ALT = 302; + public static int GROUPS_GET_BY_ID = 303; + public static int GROUPS_SEARCH = 304; + public static int GROUPS_JOIN = 305; + public static int GROUPS_LEAVE = 306; + public static int GROUP_MEMBERS = 307; + + // Likes (/method/Likes) + public static int LIKES_ADD = 400; + public static int LIKES_DELETE = 401; + public static int LIKES_CHECK = 402; + + // Messages (/method/Messages) + public static int MESSAGES_GET_BY_ID = 500; + public static int MESSAGES_SEND = 501; + public static int MESSAGES_DELETE = 502; + public static int MESSAGES_RESTORE = 503; + public static int MESSAGES_CONVERSATIONS = 504; + public static int MESSAGES_GET_CONVERSATIONS_BY_ID = 505; + public static int MESSAGES_GET_HISTORY = 506; + public static int MESSAGES_GET_LONGPOLL_HISTORY = 507; + public static int MESSAGES_GET_LONGPOLL_SERVER = 508; + + // Users (/method/Users) + public static int USERS_GET = 600; + public static int USERS_GET_ALT = 601; + public static int USERS_GET_ALT2 = 602; + public static int USERS_FOLLOWERS = 603; + public static int USERS_SEARCH = 604; + + // Wall (/method/Wall) + public static int WALL_GET = 700; + public static int WALL_GET_BY_ID = 701; + public static int WALL_GET_MORE = 702; + public static int WALL_POST = 703; + public static int WALL_REPOST = 704; + public static int WALL_CREATE_COMMENT = 705; + public static int WALL_DELETE_COMMENT = 706; + public static int WALL_COMMENT = 707; + public static int WALL_ALL_COMMENTS = 708; + + // Newsfeed (/method/Newsfeed) + public static int NEWSFEED_GET = 800; + public static int NEWSFEED_GET_GLOBAL = 801; + public static int NEWSFEED_GET_MORE = 802; + public static int NEWSFEED_GET_MORE_GLOBAL = 803; + + // Notes (/method/Notes) + public static int NOTES_GET = 900; + public static int NOTES_GET_BY_ID = 901; + + // Photos (/method/Photos) + public static int PHOTOS_GET = 1000; + public static int PHOTOS_UPLOAD_SERVER = 1001; + public static int PHOTOS_SAVE = 1002; + public static int PHOTOS_GETALBUMS = 1003; + + // OpenVK specific (/method/Ovk) + public static int OVK_VERSION = 1100; + public static int OVK_TEST = 1101; + public static int OVK_CHICKEN_WINGS = 1102; + public static int OVK_ABOUTINSTANCE = 1103; + public static int OVK_CHECK_HTTP = 1104; + public static int OVK_CHECK_HTTPS = 1105; + + // Poll (/method/Poll) + public static int POLL_ADD_VOTE = 1200; + public static int POLL_DELETE_VOTE = 1201; + + // Misc (LongPoll API, avatars, attachments and etc.) + public static int ACCOUNT_AVATAR = 2000; + public static int NEWSFEED_ATTACHMENTS = 2001; + public static int WALL_ATTACHMENTS = 2002; + public static int WALL_AVATARS = 2003; + public static int NEWSFEED_AVATARS = 2004; + public static int PROFILE_AVATARS = 2005; + public static int GROUP_AVATARS = 2006; + public static int GROUP_AVATARS_ALT = 2007; + public static int FRIEND_AVATARS = 2008; + public static int COMMENT_AVATARS = 2009; + public static int COMMENT_PHOTOS = 2010; + public static int COMMENT_VIDEO_THUMBNAILS = 2011; + public static int ALBUM_PHOTOS = 2012; + public static int PHOTO_ALBUM_THUMBNAILS = 2013; + public static int CONVERSATIONS_AVATARS = 2014; + public static int LONGPOLL = 2015; + public static int ORIGINAL_PHOTO = 2016; + public static int VIDEO_THUMBNAILS = 2017; + public static int PARSE_JSON = 2018; + public static int UPLOAD_PROGRESS = 2019; + public static int UPLOADED_SUCCESSFULLY = 2020; // Errors - public static int OVKAPI_NO_INTERNET_CONNECTION = -1; - public static int OVKAPI_CONNECTION_TIMEOUT = -2; - public static int OVKAPI_INVALID_JSON_RESPONSE = -3; - public static int OVKAPI_INVALID_USAGE = -4; - public static int OVKAPI_INVALID_TOKEN = -5; - public static int OVKAPI_CHAT_DISABLED = -6; - public static int OVKAPI_METHOD_NOT_FOUND = -7; - public static int OVKAPI_ACCESS_DENIED = -8; - public static int OVKAPI_ACCESS_DENIED_MARSHMALLOW = -9; - public static int OVKAPI_BROKEN_SSL_CONNECTION = -10; - public static int OVKAPI_INTERNAL_ERROR = -11; - public static int OVKAPI_INSTANCE_UNAVAILABLE = -12; - public static int OVKAPI_NOT_OPENVK_INSTANCE = -13; - public static int OVKAPI_UNKNOWN_ERROR = -14; - - public static int DLM_NO_INTERNET_CONNECTION = -101; - public static int DLM_CONNECTION_TIMEOUT = -2; - public static int DLM_INVALID_USAGE = -4; - public static int DLM_ACCESS_DENIED = -8; - public static int DLM_BROKEN_SSL_CONNECTION = -10; - public static int DLM_INTERNAL_ERROR = -11; - public static int DLM_INSTANCE_UNAVAILABLE = -12; - public static int DLM_NOT_OPENVK_INSTANCE = -13; - public static int DLM_UNKNOWN_ERROR = -14; + public static int NO_INTERNET_CONNECTION = -1; + public static int CONNECTION_TIMEOUT = -2; + public static int INVALID_JSON_RESPONSE = -3; + public static int INVALID_USAGE = -4; + public static int INVALID_TOKEN = -5; + public static int CHAT_DISABLED = -6; + public static int METHOD_NOT_FOUND = -7; + public static int BANNED_ACCOUNT = -8; + public static int ACCESS_DENIED = -9; + public static int ACCESS_DENIED_MARSHMALLOW = -10; + public static int BROKEN_SSL_CONNECTION = -11; + public static int INTERNAL_ERROR = -12; + public static int INSTANCE_UNAVAILABLE = -13; + public static int NOT_OPENVK_INSTANCE = -14; + public static int UNKNOWN_ERROR = -15; + public static int UPLOAD_ERROR = -16; } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/interfaces/OvkAPIListeners.java b/app/src/main/java/uk/openvk/android/refresh/api/interfaces/OvkAPIListeners.java new file mode 100644 index 0000000..c840f3b --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/interfaces/OvkAPIListeners.java @@ -0,0 +1,62 @@ +package uk.openvk.android.refresh.api.interfaces; + +import android.content.Context; +import android.os.Bundle; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class OvkAPIListeners { + public String from; + + public static interface OnAPIProcessListener { + public void onAPIProcess(Context ctx, Bundle data, long value, long length); + } + + public static interface OnAPISuccessListener { + public void onAPISuccess(Context ctx, int msg_code, Bundle data); + } + + public static interface OnAPIFailListener { + public void onAPIFailed(Context ctx, int msg_code, Bundle data); + } + + public OnAPIProcessListener processListener; + public OnAPIFailListener failListener; + public OnAPISuccessListener successListener; + + public OvkAPIListeners() { + processListener = new OnAPIProcessListener() { + @Override + public void onAPIProcess(Context ctx, Bundle data, long value, long length) { + + } + }; + failListener = new OnAPIFailListener() { + @Override + public void onAPIFailed(Context ctx, int http_code, Bundle data) { + + } + }; + successListener = new OnAPISuccessListener() { + @Override + public void onAPISuccess(Context ctx, int http_code, Bundle data) { + + } + }; + } +} + diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Comment.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Comment.java deleted file mode 100644 index 66d0857..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/Comment.java +++ /dev/null @@ -1,32 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -import android.graphics.Bitmap; - -import uk.openvk.android.refresh.api.wrappers.JSONParser; - -/** - * Created by Dmitry on 04.10.2022. - */ - -public class Comment { - public String author; - public long author_id; - public long date; - public String text; - public long id; - public Bitmap avatar; - public String avatar_url; - private JSONParser jsonParser; - - public Comment() { - jsonParser = new JSONParser(); - } - - public Comment(int id, long author_id, String author, int date, String text) { - this.author_id = author_id; - this.author = author; - this.date = date; - this.text = text; - this.id = id; - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Conversation.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Conversation.java deleted file mode 100644 index e10237f..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/Conversation.java +++ /dev/null @@ -1,121 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Bitmap; -import android.util.Log; - -import org.droidparts.util.Strings; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.URLEncoder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.concurrent.TimeUnit; - -import uk.openvk.android.refresh.api.wrappers.JSONParser; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; - -public class Conversation { - public String title; - public long peer_id; - public int online; - public Bitmap avatar; - public Bitmap lastMsgAvatar; - public long lastMsgAuthorId; - public String lastMsgText; - public long lastMsgTime; - public String avatar_url; - private ArrayList history; - private JSONParser jsonParser; - - public Conversation() { - jsonParser = new JSONParser(); - history = new ArrayList(); - } - - public void getHistory(OvkAPIWrapper ovk, long peer_id) { - this.peer_id = peer_id; - ovk.sendAPIMethod("Messages.getHistory", - String.format("peer_id=%s&count=150&rev=1", peer_id)); - } - - @SuppressLint("SimpleDateFormat") - public ArrayList parseHistory(Context ctx, String response) { - JSONObject json = jsonParser.parseJSON(response); - if(json != null) { - try { - JSONArray items = json.getJSONObject("response").getJSONArray("items"); - history = new ArrayList(); - JSONObject prevItem = null; - for(int i = 0; i < items.length(); i++) { - JSONObject item = items.getJSONObject(i); - boolean incoming = false; - int type = 0; - if(item.getInt("out") == 1) { - incoming = false; - type = 1; - } else { - incoming = true; - type = 0; - } - if(prevItem != null) { - Date startOfDay = new Date(TimeUnit.SECONDS.toMillis( - item.getLong("date"))); - Calendar startOfDay_calendar = Calendar.getInstance(); - startOfDay_calendar.setTime(startOfDay); - startOfDay_calendar.set(Calendar.HOUR_OF_DAY, 0); - startOfDay_calendar.set(Calendar.MINUTE, 0); - startOfDay_calendar.set(Calendar.SECOND, 0); - startOfDay = startOfDay_calendar.getTime(); - Date prev_startOfDay = null; - Calendar prevStartOfDay_calendar = Calendar.getInstance(); - if (i > 1) { - prevStartOfDay_calendar.setTime(new Date(TimeUnit.SECONDS.toMillis( - prevItem.getLong("date")))); - prevStartOfDay_calendar.set(Calendar.HOUR_OF_DAY, 0); - prevStartOfDay_calendar.set(Calendar.MINUTE, 0); - prevStartOfDay_calendar.set(Calendar.SECOND, 0); - prev_startOfDay = prevStartOfDay_calendar.getTime(); - } - if(prev_startOfDay != null) { - Log.d("compare", String.format("%s", startOfDay.compareTo(prev_startOfDay))); - if (startOfDay.compareTo(prev_startOfDay) > 0) { - history.add(new Message(2, 0, false, false, - item.getLong("date"), new SimpleDateFormat("d MMMM yyyy") - .format(startOfDay), ctx)); - } - } else { - history.add(new Message(2, 0, false, false, - item.getLong("date"), new SimpleDateFormat("d MMMM yyyy") - .format(startOfDay), ctx)); - } - } else { - history.add(new Message(2, 0, false, false, - item.getLong("date"), new SimpleDateFormat("d MMMM yyyy").format( - new Date(TimeUnit.SECONDS.toMillis(item.getLong("date")))), ctx)); - } - Message message = new Message(type, item.getLong("id"), incoming, false, - item.getLong("date"), item.getString("text"), ctx); - message.timestamp = new SimpleDateFormat("HH:mm").format(TimeUnit.SECONDS.toMillis( - item.getLong("date"))); - message.author_id = item.getLong("from_id"); - prevItem = item; - history.add(message); - } - } catch(JSONException ex) { - ex.printStackTrace(); - } - } - return history; - } - - public void sendMessage(OvkAPIWrapper ovk, String text) { - ovk.sendAPIMethod("Messages.send", String.format("peer_id=%s&message=%s", peer_id, - Strings.urlEncode(text))); - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Error.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Error.java deleted file mode 100644 index 4727365..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/Error.java +++ /dev/null @@ -1,49 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -import org.json.JSONException; -import org.json.JSONObject; - -import uk.openvk.android.refresh.api.wrappers.JSONParser; - -/** - * Created by Dmitry on 27.09.2022. - */ -public class Error { - public String description; - public int code; - private JSONParser jsonParser; - - public Error() { - jsonParser = new JSONParser(); - } - - public Error(String response) { - jsonParser = new JSONParser(); - JSONObject json = jsonParser.parseJSON(response); - if(json != null) { - try { - description = json.getString("error_msg"); - code = json.getInt("error_code"); - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - - public void parse(String response) { - JSONObject json = jsonParser.parseJSON(response); - if(json != null) { - try { - description = json.getString("error_msg"); - code = json.getInt("error_code"); - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - - public Error(String description, int code) { - this.description = description; - this.code = code; - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Friends.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Friends.java similarity index 63% rename from app/src/main/java/uk/openvk/android/refresh/api/Friends.java rename to app/src/main/java/uk/openvk/android/refresh/api/models/Friends.java index a800a91..c4faf7b 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/Friends.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Friends.java @@ -1,19 +1,37 @@ -package uk.openvk.android.refresh.api; +package uk.openvk.android.refresh.api.models; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; import org.json.JSONArray; import org.json.JSONObject; import java.util.ArrayList; +import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.api.attachments.PhotoAttachment; -import uk.openvk.android.refresh.api.models.Friend; +import uk.openvk.android.refresh.api.entities.Friend; import uk.openvk.android.refresh.api.wrappers.DownloadManager; import uk.openvk.android.refresh.api.wrappers.JSONParser; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class Friends implements Parcelable { private JSONParser jsonParser; private ArrayList friends; @@ -67,7 +85,12 @@ public void parse(String response, DownloadManager downloadManager, boolean down photoAttachment.url = friend.avatar_url; photoAttachment.filename = String.format("avatar_%s", friend.id); avatars.add(photoAttachment); - this.friends.add(friend); + try { // handle floating crash + this.friends.add(friend); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } } if (downloadPhoto) { downloadManager.downloadPhotosToCache(avatars, "friend_avatars"); @@ -106,13 +129,16 @@ public void parseRequests(String response, DownloadManager downloadManager, bool } } - public void get(OvkAPIWrapper ovk, long user_id, int count, String where) { - ovk.sendAPIMethod("Friends.get", String.format("user_id=%s&fields=verified,online,photo_100,photo_200_orig,photo_200,last_seen&count=%s", user_id, count), where); + public void get(OvkAPIWrapper wrapper, long user_id, int count, String where) { + wrapper.sendAPIMethod("Friends.get", String.format("user_id=%s&fields=verified,online,photo_100," + + "photo_200_orig,photo_200,last_seen&count=%s", user_id, count), where); } - public void get(OvkAPIWrapper ovk, long user_id, int count, int offset) { + public void get(OvkAPIWrapper wrapper, long user_id, int count, int offset) { this.offset++; - ovk.sendAPIMethod("Friends.get", String.format("user_id=%s&fields=verified,online,photo_100,photo_200_orig,photo_200,last_seen&count=%s&offset=%s", user_id, count, this.offset), "more_friends"); + wrapper.sendAPIMethod("Friends.get", String.format("user_id=%s&fields=verified,online,photo_100," + + "photo_200_orig,photo_200,last_seen&count=%s&offset=%s", user_id, count, this.offset), + "more_friends"); } public ArrayList getFriends() { @@ -128,15 +154,15 @@ public int describeContents() { public void writeToParcel(Parcel parcel, int i) { } - public void add(OvkAPIWrapper ovk, long user_id) { - ovk.sendAPIMethod("Friends.add", String.format("user_id=%d", user_id)); + public void add(OvkAPIWrapper wrapper, long user_id) { + wrapper.sendAPIMethod("Friends.add", String.format("user_id=%s", user_id)); } - public void delete(OvkAPIWrapper ovk, long user_id) { - ovk.sendAPIMethod("Friends.delete", String.format("user_id=%d", user_id)); + public void delete(OvkAPIWrapper wrapper, long user_id) { + wrapper.sendAPIMethod("Friends.delete", String.format("user_id=%s", user_id)); } - public void getRequests(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Friends.getRequests", String.format("fields=verified,online,photo_100,photo_200_orig,photo_200")); + public void getRequests(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Friends.getRequests", String.format("fields=verified,online,photo_100,photo_200_orig,photo_200")); } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Groups.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Groups.java similarity index 55% rename from app/src/main/java/uk/openvk/android/refresh/api/Groups.java rename to app/src/main/java/uk/openvk/android/refresh/api/models/Groups.java index 6f1e8db..65b7957 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/Groups.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Groups.java @@ -1,24 +1,37 @@ -package uk.openvk.android.refresh.api; +package uk.openvk.android.refresh.api.models; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; -import org.droidparts.util.Strings; import org.json.JSONArray; import org.json.JSONObject; import java.net.URLEncoder; import java.util.ArrayList; +import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.api.attachments.PhotoAttachment; -import uk.openvk.android.refresh.api.models.Group; +import uk.openvk.android.refresh.api.entities.Group; import uk.openvk.android.refresh.api.wrappers.DownloadManager; import uk.openvk.android.refresh.api.wrappers.JSONParser; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -/** - * Created by Dmitry on 09.10.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class Groups implements Parcelable { private JSONParser jsonParser; @@ -69,17 +82,31 @@ public void parse(String response) { } } - public void parseSearch(String response) { + public void parseSearch(String response, DownloadManager downloadManager) { try { groups = new ArrayList(); JSONObject json = jsonParser.parseJSON(response); JSONArray groups = json.getJSONObject("response").getJSONArray("items"); + ArrayList avatars; + avatars = new ArrayList(); if(this.groups.size() > 0) { this.groups.clear(); } for (int i = 0; i < groups.length(); i++) { Group group = new Group(groups.getJSONObject(i)); - this.groups.add(group); + PhotoAttachment photoAttachment = new PhotoAttachment(); + photoAttachment.url = group.avatar_msize_url; + photoAttachment.filename = String.format("avatar_%s", group.id); + avatars.add(photoAttachment); + try { // handle floating crash + this.groups.add(group); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + } + if(downloadManager != null) { + downloadManager.downloadPhotosToCache(avatars, "group_avatars"); } } catch (Exception e) { e.printStackTrace(); @@ -90,8 +117,8 @@ public ArrayList getList() { return groups; } - public void search(OvkAPIWrapper ovk, String query) { - ovk.sendAPIMethod("Groups.search", String.format("q=%s&count=50", Strings.urlEncode(query))); + public void search(OvkAPIWrapper wrapper, String query) { + wrapper.sendAPIMethod("Groups.search", String.format("q=%s&count=50", URLEncoder.encode(query))); } @Override @@ -104,20 +131,26 @@ public void writeToParcel(Parcel parcel, int i) { parcel.writeTypedList(groups); } - public void getGroupByID(OvkAPIWrapper ovk, long id) { - if (id < 0) { - ovk.sendAPIMethod("Groups.getById", String.format("group_id=%s&fields=verified,photo_200,photo_400,photo_max_orig,is_member,members_count,site,description,contacts", -id)); - } else { - ovk.sendAPIMethod("Groups.getById", String.format("group_id=%s&fields=verified,photo_200,photo_400,photo_max_orig,is_member,members_count,site,description,contacts", id)); - } + public void getGroupByID(OvkAPIWrapper wrapper, long id) { + wrapper.sendAPIMethod("Groups.getById", + String.format("group_id=%s&fields=verified,photo_200," + + "photo_200_orig,photo_400,photo_max_orig,is_member," + + "members_count,site,description,contacts", id)); } - public void getGroups(OvkAPIWrapper ovk, long user_id, long count) { - ovk.sendAPIMethod("Groups.get", String.format("user_id=%s&count=%s&fields=verified,photo_200,photo_400,photo_max_orig,is_member,members_count,site,description,contacts&extended=1", user_id, count)); + public void getGroups(OvkAPIWrapper wrapper, long user_id, long count) { + wrapper.sendAPIMethod("Groups.get", + String.format("user_id=%s&count=%s&fields=verified,photo_200," + + "photo_200_orig,photo_400,photo_400_orig,photo_max_orig,is_member," + + "members_count,site,description,contacts&extended=1", user_id, count)); } - public void getGroups(OvkAPIWrapper ovk, long user_id, int count, int offset) { - ovk.sendAPIMethod("Groups.get", String.format("user_id=%s&count=%s&fields=verified,photo_200,photo_400,photo_max_orig,is_member,members_count,site,description,contacts&offset=%s&extended=1", user_id, count, offset), "more_groups"); + public void getGroups(OvkAPIWrapper wrapper, long user_id, int count, int offset) { + wrapper.sendAPIMethod("Groups.get", + String.format("user_id=%s&count=%s&fields=verified,photo_200," + + "photo_200_orig,photo_400,photo_400_orig,photo_max_orig,is_member," + + "members_count,site,description,contacts&offset=%s" + + "&extended=1", user_id, count, offset), "more_groups"); } public void parse(String response, DownloadManager downloadManager, String quality, boolean downloadPhoto, boolean clear) { @@ -143,7 +176,7 @@ public void parse(String response, DownloadManager downloadManager, String quali if(photoAttachment.url.length() == 0) { photoAttachment.url = group.avatar_msize_url; } - photoAttachment.filename = String.format("avatar_%d", group.id); + photoAttachment.filename = String.format("avatar_%s", group.id); avatars.add(photoAttachment); this.groups.add(group); } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/InstanceLink.java b/app/src/main/java/uk/openvk/android/refresh/api/models/InstanceLink.java deleted file mode 100644 index fe5a595..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/InstanceLink.java +++ /dev/null @@ -1,14 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -/** - * Created by Dmitry on 07.10.2022. - */ - -public class InstanceLink { - public String name; - public String url; - public InstanceLink(String name, String url) { - this.name = name; - this.url = url; - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/InstanceStatistics.java b/app/src/main/java/uk/openvk/android/refresh/api/models/InstanceStatistics.java deleted file mode 100644 index 153e995..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/InstanceStatistics.java +++ /dev/null @@ -1,21 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -/** - * Created by Dmitry on 07.10.2022. - */ - -public class InstanceStatistics { - public int users_count; - public int online_users_count; - public int active_users_count; - public int groups_count; - public int wall_posts_count; - public InstanceStatistics(int users_count, int online_users_count, int active_users_count, - int groups_count, int wall_posts_count) { - this.users_count = users_count; - this.online_users_count = online_users_count; - this.active_users_count = active_users_count; - this.groups_count = groups_count; - this.wall_posts_count = wall_posts_count; - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Likes.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Likes.java similarity index 57% rename from app/src/main/java/uk/openvk/android/refresh/api/Likes.java rename to app/src/main/java/uk/openvk/android/refresh/api/models/Likes.java index c19ec58..aaeeb22 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/Likes.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Likes.java @@ -1,4 +1,4 @@ -package uk.openvk.android.refresh.api; +package uk.openvk.android.refresh.api.models; import android.os.Parcel; import android.os.Parcelable; @@ -9,6 +9,22 @@ import uk.openvk.android.refresh.api.wrappers.JSONParser; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + public class Likes implements Parcelable { private JSONParser jsonParser; public long owner_id; @@ -39,18 +55,20 @@ public Likes[] newArray(int size) { } }; - public void add(OvkAPIWrapper ovk, long owner_id, long post_id, int position) { + public void add(OvkAPIWrapper wrapper, long owner_id, long post_id, int position) { this.owner_id = owner_id; this.item_id = post_id; this.position = position; - ovk.sendAPIMethod("Likes.add", String.format("type=post&owner_id=%s&item_id=%s", owner_id, post_id)); + wrapper.sendAPIMethod("Likes.add", String.format("type=post&owner_id=%s&item_id=%s", + owner_id, post_id)); } - public void delete(OvkAPIWrapper ovk, long owner_id, long post_id, int position) { + public void delete(OvkAPIWrapper wrapper, long owner_id, long post_id, int position) { this.owner_id = owner_id; this.item_id = post_id; this.position = position; - ovk.sendAPIMethod("Likes.delete", String.format("type=post&owner_id=%s&item_id=%s", owner_id, post_id)); + wrapper.sendAPIMethod("Likes.delete", String.format("type=post&owner_id=%s&item_id=%s", + owner_id, post_id)); } public void parse(String response) { diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/LongPollServer.java b/app/src/main/java/uk/openvk/android/refresh/api/models/LongPollServer.java deleted file mode 100644 index 0cb5540..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/LongPollServer.java +++ /dev/null @@ -1,20 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -/** - * Created by Dmitry on 27.09.2022. - */ -public class LongPollServer { - public String address; - public String key; - public int ts; - - public LongPollServer() { - - } - - public LongPollServer(String address, String key, int ts) { - this.address = address; - this.key = key; - this.ts = ts; - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/Messages.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Messages.java similarity index 71% rename from app/src/main/java/uk/openvk/android/refresh/api/Messages.java rename to app/src/main/java/uk/openvk/android/refresh/api/models/Messages.java index df080e0..275a8c1 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/Messages.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Messages.java @@ -1,17 +1,36 @@ -package uk.openvk.android.refresh.api; +package uk.openvk.android.refresh.api.models; + +import android.util.Log; import org.json.JSONArray; import org.json.JSONObject; -import java.net.URLEncoder; import java.util.ArrayList; +import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.api.attachments.PhotoAttachment; -import uk.openvk.android.refresh.api.models.Conversation; -import uk.openvk.android.refresh.api.models.LongPollServer; +import uk.openvk.android.refresh.api.entities.Conversation; +import uk.openvk.android.refresh.api.entities.LongPollServer; import uk.openvk.android.refresh.api.wrappers.DownloadManager; import uk.openvk.android.refresh.api.wrappers.JSONParser; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.OvkApplication; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class Messages { private JSONParser jsonParser; @@ -22,8 +41,8 @@ public Messages() { jsonParser = new JSONParser(); } - public void getConversations(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Messages.getConversations", "count=30&extended=1&fields=photo_100"); + public void getConversations(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Messages.getConversations", "count=30&extended=1&fields=photo_100"); } public ArrayList parseConversationsList(String response, DownloadManager downloadManager) { @@ -48,7 +67,8 @@ public ArrayList parseConversationsList(String response, DownloadM for (int profiles_index = 0; profiles_index < profiles.length(); profiles_index++) { JSONObject profile = profiles.getJSONObject(profiles_index); if(peer_id == profile.getInt("id")) { - conversation.title = String.format("%s %s", profile.getString("first_name"), profile.getString("last_name")); + conversation.title = String.format("%s %s", profile.getString("first_name"), + profile.getString("last_name")); conversation.avatar_url = ""; if(profile.has("photo_100")) { conversation.avatar_url = profile.getString("photo_100"); @@ -78,7 +98,12 @@ public ArrayList parseConversationsList(String response, DownloadM conversation.lastMsgTime = last_msg.getInt("date"); conversation.lastMsgText = last_msg.getString("text"); conversation.lastMsgAuthorId = last_msg.getInt("from_id"); - conversations.add(conversation); + try { // handle floating crash + conversations.add(conversation); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } } downloadManager.downloadPhotosToCache(avatars, "conversations_avatars"); } catch (Exception ex) { @@ -88,8 +113,8 @@ public ArrayList parseConversationsList(String response, DownloadM return conversations; } - public void getLongPollServer(OvkAPIWrapper ovk) { - ovk.sendAPIMethod("Messages.getLongPollServer"); + public void getLongPollServer(OvkAPIWrapper wrapper) { + wrapper.sendAPIMethod("Messages.getLongPollServer"); } public LongPollServer parseLongPollServer(String response) { @@ -108,7 +133,7 @@ public LongPollServer parseLongPollServer(String response) { return longPollServer; } - public void delete(OvkAPIWrapper ovk, long id) { - ovk.sendAPIMethod("Messages.delete", String.format("message_ids=%s", id)); + public void delete(OvkAPIWrapper wrapper, long id) { + wrapper.sendAPIMethod("Messages.delete", String.format("message_ids=%s", id)); } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Newsfeed.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Newsfeed.java new file mode 100644 index 0000000..924f4c3 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Newsfeed.java @@ -0,0 +1,127 @@ +package uk.openvk.android.refresh.api.models; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.R; +import uk.openvk.android.refresh.api.attachments.Attachment; +import uk.openvk.android.refresh.api.attachments.CommonAttachment; +import uk.openvk.android.refresh.api.attachments.PhotoAttachment; +import uk.openvk.android.refresh.api.attachments.PollAttachment; +import uk.openvk.android.refresh.api.attachments.VideoAttachment; +import uk.openvk.android.refresh.api.entities.PollAnswer; +import uk.openvk.android.refresh.api.entities.VideoFiles; +import uk.openvk.android.refresh.api.entities.WallPostSource; +import uk.openvk.android.refresh.api.wrappers.DownloadManager; +import uk.openvk.android.refresh.api.wrappers.JSONParser; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.api.counters.PostCounters; +import uk.openvk.android.refresh.api.entities.WallPost; +import uk.openvk.android.refresh.api.entities.RepostInfo; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Newsfeed implements Parcelable { + private JSONParser jsonParser; + private ArrayList items; + private ArrayList photos_lsize; + private ArrayList photos_msize; + private ArrayList photos_hsize; + private ArrayList photos_osize; + private ArrayList video_thumbnails; + + public long next_from; + private DownloadManager dlm; + + public Newsfeed(String response, DownloadManager downloadManager, String quality, Context ctx) { + jsonParser = new JSONParser(); + if(items == null) { + parse(ctx, downloadManager, response, quality, true); + } + } + + public Newsfeed() { + jsonParser = new JSONParser(); + } + + protected Newsfeed(Parcel in) { + items = in.createTypedArrayList(WallPost.CREATOR); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Newsfeed createFromParcel(Parcel in) { + return new Newsfeed(in); + } + + @Override + public Newsfeed[] newArray(int size) { + return new Newsfeed[size]; + } + }; + + public void parse(Context ctx, DownloadManager downloadManager, String response, String quality, boolean clear) { + this.dlm = downloadManager; + if(clear) { + items = new ArrayList<>(); + } + Wall wall = new Wall(); + wall.setWallItems(items); + wall.parse(ctx, downloadManager, quality, response, clear, false); + items = wall.getWallItems(); + } + + public void get(OvkAPIWrapper wrapper, int count) { + wrapper.sendAPIMethod("Newsfeed.get", String.format("count=%s&extended=1", count)); + } + + public void get(OvkAPIWrapper wrapper, int count, long start_from) { + wrapper.sendAPIMethod("Newsfeed.get", String.format("count=%s&start_from=%s&extended=1", count, start_from), "more_news"); + } + + public void getGlobal(OvkAPIWrapper wrapper, int count) { + wrapper.sendAPIMethod("Newsfeed.getGlobal", String.format("count=%s&extended=1", count)); + } + + public void getGlobal(OvkAPIWrapper wrapper, int count, long start_from) { + wrapper.sendAPIMethod("Newsfeed.getGlobal", String.format("count=%s&start_from=%s&extended=1", count, start_from), "more_news"); + } + + public ArrayList getWallPosts() { + return items; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeTypedList(items); + } + +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Notes.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Notes.java new file mode 100644 index 0000000..392855c --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Notes.java @@ -0,0 +1,69 @@ +package uk.openvk.android.refresh.api.models; + +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; + +import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.api.entities.Note; +import uk.openvk.android.refresh.api.wrappers.JSONParser; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Notes { + private JSONParser jsonParser; + public ArrayList list; + public Notes() { + list = new ArrayList<>(); + jsonParser = new JSONParser(); + } + + public void get(OvkAPIWrapper wrapper, long user_id, int count, int sort) { + wrapper.sendAPIMethod("Notes.get", + String.format("user_id=%s&count=%s&sort=%s", user_id, count, sort) + ); + } + + public void parse(String response) { + try { + JSONObject json = jsonParser.parseJSON(response); + JSONArray notes = json.getJSONObject("response").getJSONArray("notes"); + list = new ArrayList<>(); + for(int i = 0; i < notes.length(); i++) { + JSONObject item = notes.getJSONObject(i); + Note note = new Note(); + note.id = item.getLong("id"); + note.owner_id = item.getLong("owner_id"); + note.title = item.getString("title"); + note.content = item.getString("text"); + note.date = item.getLong("date"); + try { // handle floating crash + list.add(note); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/OvkLink.java b/app/src/main/java/uk/openvk/android/refresh/api/models/OvkLink.java deleted file mode 100644 index e987b33..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/OvkLink.java +++ /dev/null @@ -1,21 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -/** - * Created by Dmitry on 12.10.2022. - */ - -public class OvkLink { - public String name; - public String screen_name; - public String url; - public OvkLink() { - this.name = ""; - this.screen_name = ""; - this.url = ""; - } - public OvkLink(String name, String screen_name, String url) { - this.name = name; - this.screen_name = screen_name; - this.url = url; - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/PhotoUploadParams.java b/app/src/main/java/uk/openvk/android/refresh/api/models/PhotoUploadParams.java new file mode 100644 index 0000000..8afc06a --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/PhotoUploadParams.java @@ -0,0 +1,41 @@ +package uk.openvk.android.refresh.api.models; + +import org.json.JSONException; +import org.json.JSONObject; + +import uk.openvk.android.refresh.api.wrappers.JSONParser; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class PhotoUploadParams { + private JSONParser jsonParser; + public String server; + public String photo; + public String hash; + + public PhotoUploadParams(String response) { + try { + jsonParser = new JSONParser(); + JSONObject json = jsonParser.parseJSON(response); + server = json.getString("server"); + photo = json.getString("photo"); + hash = json.getString("hash"); + } catch (JSONException e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Photos.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Photos.java new file mode 100644 index 0000000..903b104 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Photos.java @@ -0,0 +1,268 @@ +package uk.openvk.android.refresh.api.models; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; + +import uk.openvk.android.refresh.api.attachments.Attachment; +import uk.openvk.android.refresh.api.attachments.PhotoAttachment; +import uk.openvk.android.refresh.api.entities.Photo; +import uk.openvk.android.refresh.api.entities.PhotoAlbum; +import uk.openvk.android.refresh.api.wrappers.DownloadManager; +import uk.openvk.android.refresh.api.wrappers.JSONParser; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Photos { + private JSONParser jsonParser; + public String wallUploadServer; + public String ownerPhotoUploadServer; + public ArrayList list; + public ArrayList albumsList; + public PhotoAlbum album; + + public Photos() { + jsonParser = new JSONParser(); + } + + public void parseUploadServer(String response, String method) { + try { + if (method.equals("Photos.getOwnerPhotoUploadServer")) { + JSONObject json = jsonParser.parseJSON(response); + ownerPhotoUploadServer = json.getJSONObject("response").getString("upload_url"); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void parseUploadedPhotos(String response) { + try { + list = new ArrayList<>(); + JSONObject json = jsonParser.parseJSON(response); + JSONArray photos = json.getJSONObject("response").getJSONArray("photos"); + for(int i = 0; i < photos.length(); i++) { + JSONObject item = photos.getJSONObject(i); + Photo photo = new Photo(); + photo.id = item.getLong("id"); + if(item.isNull("album_id")) { + photo.album_id = 0; + } else { + photo.album_id = item.getLong("album_id"); + } + photo.owner_id = item.getLong("owner_id"); + list.add(photo); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void parseUploadedPhotos(String response, PhotoAlbum album) { + try { + album.photos = new ArrayList<>(); + JSONObject json = jsonParser.parseJSON(response); + JSONArray photos = json.getJSONObject("response").getJSONArray("photos"); + for(int i = 0; i < photos.length(); i++) { + JSONObject item = photos.getJSONObject(i); + Photo photo = new Photo(); + photo.id = item.getLong("id"); + if(item.isNull("album_id")) { + photo.album_id = 0; + } else { + photo.album_id = item.getLong("album_id"); + } + photo.owner_id = item.getLong("owner_id"); + album.photos.add(photo); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void parse(String response, PhotoAlbum album, DownloadManager dlman) { + try { + album.photos = new ArrayList<>(); + JSONObject json = jsonParser.parseJSON(response); + album.size = json.getJSONObject("response").getInt("count"); + JSONArray photos = json.getJSONObject("response").getJSONArray("items"); + ArrayList photoAttachs = new ArrayList<>(); + for(int i = 0; i < photos.length(); i++) { + JSONObject item = photos.getJSONObject(i); + Photo photo = new Photo(); + photo.id = item.getLong("id"); + if(album.ids[0] == 0) { + if (item.isNull("album_id")) { + photo.album_id = album.ids[0]; + } else { + photo.album_id = item.getLong("album_id"); + } + } else { + photo.album_id = album.ids[0]; + } + photo.owner_id = item.getLong("owner_id"); + if(dlman != null && item.has("sizes")) { + PhotoAttachment attach = new PhotoAttachment(); + if(item.getJSONObject("sizes").has("q")) { + photo.url = item.getJSONObject("sizes").getJSONObject("q").getString("url"); + attach.url = photo.url; + attach.filename = String.format( + "photo%s_a%s_o%s", + photo.id, + photo.album_id, + photo.owner_id); + + } + if(item.getJSONObject("sizes").has("UPLOADED_MAXRES")) { + photo.original_url = + item.getJSONObject("sizes") + .getJSONObject("UPLOADED_MAXRES").getString("url"); + attach.original_url = photo.original_url; + } + photoAttachs.add(attach); + } + album.photos.add(photo); + } + if(dlman != null) { + dlman.downloadPhotosToCache(photoAttachs, "album_photos"); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + this.album = album; + } + + public void parseOnePhoto(String response) { + try { + if(list == null) { + list = new ArrayList<>(); + } + JSONObject json = jsonParser.parseJSON(response); + JSONObject item = json.getJSONArray("response").getJSONObject(0); + Photo photo = new Photo(); + photo.id = item.getLong("id"); + if(item.isNull("album_id")) { + photo.album_id = 0; + } else { + photo.album_id = item.getLong("album_id"); + } + photo.owner_id = item.getLong("owner_id"); + list.add(photo); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void parseAlbums(String response, DownloadManager dl_man, boolean clear) { + try { + if(albumsList == null || clear) { + albumsList = new ArrayList<>(); + } + ArrayList thumbnails = new ArrayList<>(); + JSONObject json = jsonParser.parseJSON(response); + JSONArray albums = json.getJSONObject("response").getJSONArray("items"); + for(int i = 0; i < albums.length(); i++) { + JSONObject item = albums.getJSONObject(i); + PhotoAlbum album = new PhotoAlbum(item.getString("id")); + album.title = item.getString("title"); + if(item.has("size")) { + album.size = item.getLong("size"); + } + if(item.has("thumb_src")) { + album.thumbnail_url = item.getString("thumb_src"); + } else { + album.thumbnail_url = ""; + } + albumsList.add(album); + if(item.has("thumb_src")) { + PhotoAttachment attachment = new PhotoAttachment(); + attachment.url = album.thumbnail_url; + attachment.filename = String.format("photo_album_%s_%s", + album.ids[0], album.ids[1]); + thumbnails.add(attachment); + } + } + dl_man.downloadPhotosToCache(thumbnails, "photo_albums"); + } catch(Exception ex) { + ex.printStackTrace(); + } + } + + public void getOwnerUploadServer(OvkAPIWrapper wrapper, long owner_id) { + wrapper.sendAPIMethod("Photos.getOwnerPhotoUploadServer", String.format("owner_id=%s", owner_id)); + } + + public void getWallUploadServer(OvkAPIWrapper wrapper, long group_id) { + wrapper.sendAPIMethod("Photos.getWallUploadServer", String.format("group_id=%s", group_id)); + } + + public void saveWallPhoto(OvkAPIWrapper wrapper, String photo, String hash) { + wrapper.sendAPIMethod("Photos.saveWallPhoto", String.format("photo=%s&hash=%s", photo, hash)); + } + + + public void getAlbums(OvkAPIWrapper wrapper, long owner_id, int count, + boolean need_system, boolean need_covers, boolean photo_sizes) { + String bl_need_system; + if(need_system) { + bl_need_system = "1"; + } else { + bl_need_system = "0"; + } + String bl_need_covers; + if(need_covers) { + bl_need_covers = "1"; + } else { + bl_need_covers = "0"; + } + String bl_photo_sizes; + if(photo_sizes) { + bl_photo_sizes = "1"; + } else { + bl_photo_sizes = "0"; + } + + wrapper.sendAPIMethod("Photos.getAlbums", + String.format("owner_id=%s" + + "&count=%s" + + "&need_system=%s" + + "&need_covers=%s" + + "&photo_sizes=%s", owner_id, count, + bl_need_system, bl_need_covers, bl_photo_sizes)); + } + + public void getByAlbumId(OvkAPIWrapper wrapper, long owner_id, long album_id, int count) { + wrapper.sendAPIMethod("Photos.get", "owner_id=%s&album_id=%s"); + } + + public void getByAlbumId(OvkAPIWrapper wrapper, long owner_id, long album_id, int count, boolean photo_sizes) { + String bl_photo_sizes; + if(photo_sizes) { + bl_photo_sizes = "1"; + } else { + bl_photo_sizes = "0"; + } + wrapper.sendAPIMethod( + "Photos.get", + String.format("owner_id=%s&album_id=%s&count=%s&photo_sizes=%s", + owner_id, album_id, count, bl_photo_sizes + ) + ); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/PollAnswer.java b/app/src/main/java/uk/openvk/android/refresh/api/models/PollAnswer.java deleted file mode 100644 index e194dfc..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/PollAnswer.java +++ /dev/null @@ -1,19 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -/** - * Created by Dmitry on 16.10.2022. - */ - -public class PollAnswer { - public int id; - public int rate; - public int votes; - public String text; - public boolean is_voted; - public PollAnswer(int id, int rate, int votes, String text) { - this.id = id; - this.rate = rate; - this.votes = votes; - this.text = text; - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Users.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Users.java new file mode 100644 index 0000000..f0bbd51 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Users.java @@ -0,0 +1,195 @@ +package uk.openvk.android.refresh.api.models; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.net.URLEncoder; +import java.util.ArrayList; + +import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.api.attachments.PhotoAttachment; +import uk.openvk.android.refresh.api.entities.Conversation; +import uk.openvk.android.refresh.api.entities.User; +import uk.openvk.android.refresh.api.wrappers.DownloadManager; +import uk.openvk.android.refresh.api.wrappers.JSONParser; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Users implements Parcelable { + private JSONParser jsonParser; + private ArrayList users; + public User user; + + public Users() { + jsonParser = new JSONParser(); + users = new ArrayList(); + } + + + public Users(String response) { + jsonParser = new JSONParser(); + parse(response); + } + + protected Users(Parcel in) { + users = in.createTypedArrayList(User.CREATOR); + user = in.readParcelable(User.class.getClassLoader()); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Users createFromParcel(Parcel in) { + return new Users(in); + } + + @Override + public Users[] newArray(int size) { + return new Users[size]; + } + }; + + public void parse(String response) { + try { + JSONObject json = jsonParser.parseJSON(response); + JSONArray users = json.getJSONArray("response"); + if(this.users.size() > 0) { + this.users.clear(); + } + for (int i = 0; i < users.length(); i++) { + User user = new User(users.getJSONObject(i)); + try { + this.users.add(user); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void parseSearch(String response, DownloadManager downloadManager) { + try { + JSONObject json = jsonParser.parseJSON(response); + JSONArray users = json.getJSONObject("response").getJSONArray("items"); + ArrayList avatars; + avatars = new ArrayList(); + if(this.users.size() > 0) { + this.users.clear(); + } + for (int i = 0; i < users.length(); i++) { + User user = new User(users.getJSONObject(i)); + PhotoAttachment photoAttachment = new PhotoAttachment(); + photoAttachment.url = user.avatar_msize_url; + photoAttachment.filename = String.format("avatar_%s", user.id); + avatars.add(photoAttachment); + try { // handle floating crash + this.users.add(user); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + } + if(downloadManager != null) { + downloadManager.downloadPhotosToCache(avatars, "profile_avatars"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void getUser(OvkAPIWrapper wrapper, long user_id) { + wrapper.sendAPIMethod("Users.get", + String.format("user_ids=%s&fields=verified,sex,has_photo,photo_200," + + "photo_200_orig,photo_400,photo_max_orig,status,screen_name,friend_status,last_seen," + + "interests,music,movies,tv,books,city", + user_id)); + } + + public void getAccountUser(OvkAPIWrapper wrapper, long user_id) { + wrapper.sendAPIMethod("Users.get", + String.format("user_ids=%s&fields=verified,sex,has_photo,photo_200," + + "photo_200_orig,photo_400,photo_max_orig,status,screen_name,friend_status,last_seen," + + "interests,music,movies,tv,books,city", + user_id), "account_user"); + } + + public void getPeerUsers(OvkAPIWrapper wrapper, ArrayList conversations) { + ArrayList user_ids = new ArrayList<>(); + for(int i = 0; i < conversations.size(); i++) { + user_ids.add(conversations.get(i).peer_id); + } + StringBuilder ids_list = new StringBuilder(); + for(int i = 0; i < user_ids.size(); i++) { + if(i < user_ids.size() - 1) { + ids_list.append(String.format("%s,", user_ids.get(i))); + } else { + ids_list.append(user_ids.get(i)); + } + } + wrapper.sendAPIMethod("Users.get", + String.format("user_ids=%s&fields=verified,sex,has_photo,photo_200," + + "photo_400,photo_max_orig,status,screen_name,friend_status,last_seen," + + "interests,music,movies,tv,books,city", + ids_list), "peers"); + } + + public void get(OvkAPIWrapper wrapper, ArrayList user_ids) { + StringBuilder ids_list = new StringBuilder(); + for(int i = 0; i < user_ids.size(); i++) { + if(i < user_ids.size() - 1) { + ids_list.append(String.format("%s,", user_ids.get(i))); + } else { + ids_list.append(user_ids.get(i)); + } + } + wrapper.sendAPIMethod("Users.get", + String.format("user_ids=%s&fields=verified,sex,has_photo,photo_200," + + "photo_400,photo_max_orig,status,screen_name,friend_status,last_seen," + + "interests,music,movies,tv,books,city", + ids_list.toString())); + } + + public ArrayList getList() { + return users; + } + + public void search(OvkAPIWrapper wrapper, String query) { + wrapper.sendAPIMethod("Users.search", + String.format("q=%s&count=50&fields=verified,sex,has_photo,photo_200," + + "photo_400,photo_max_orig,status,screen_name,friend_status,last_seen," + + "interests,music,movies,tv,books,city", + URLEncoder.encode(query))); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeTypedList(users); + parcel.writeParcelable(user, i); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/Wall.java b/app/src/main/java/uk/openvk/android/refresh/api/models/Wall.java new file mode 100644 index 0000000..1e57f58 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/models/Wall.java @@ -0,0 +1,734 @@ +package uk.openvk.android.refresh.api.models; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.net.URLEncoder; +import java.util.ArrayList; + +import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.R; +import uk.openvk.android.refresh.api.attachments.Attachment; +import uk.openvk.android.refresh.api.attachments.CommonAttachment; +import uk.openvk.android.refresh.api.attachments.PhotoAttachment; +import uk.openvk.android.refresh.api.attachments.PollAttachment; +import uk.openvk.android.refresh.api.attachments.VideoAttachment; +import uk.openvk.android.refresh.api.entities.Comment; +import uk.openvk.android.refresh.api.entities.PollAnswer; +import uk.openvk.android.refresh.api.entities.VideoFiles; +import uk.openvk.android.refresh.api.entities.WallPostSource; +import uk.openvk.android.refresh.api.wrappers.DownloadManager; +import uk.openvk.android.refresh.api.wrappers.JSONParser; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.api.counters.PostCounters; +import uk.openvk.android.refresh.api.entities.WallPost; +import uk.openvk.android.refresh.api.entities.RepostInfo; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +public class Wall implements Parcelable { + private JSONParser jsonParser; + private ArrayList items; + private ArrayList comments; + private ArrayList photos_lsize; + private ArrayList photos_msize; + private ArrayList photos_hsize; + private ArrayList photos_osize; + private ArrayList video_thumbnails; + private DownloadManager dlm; + public long next_from; + + public Wall(String response, DownloadManager downloadManager, String quality, Context ctx) { + jsonParser = new JSONParser(); + parse(ctx, downloadManager, quality, response, true, true); + } + + public Wall() { + jsonParser = new JSONParser(); + } + + protected Wall(Parcel in) { + items = in.createTypedArrayList(WallPost.CREATOR); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Wall createFromParcel(Parcel in) { + return new Wall(in); + } + + @Override + public Wall[] newArray(int size) { + return new Wall[size]; + } + }; + + public void parse(Context ctx, DownloadManager downloadManager, String quality, + String response, + boolean clear, boolean isWall) { + this.dlm = downloadManager; + if(items == null) { + items = new ArrayList<>(); + } else { + next_from = items.size(); + if(clear) { + items.clear(); + } + } + photos_lsize = new ArrayList(); + photos_msize = new ArrayList(); + photos_hsize = new ArrayList(); + photos_osize = new ArrayList(); + video_thumbnails = new ArrayList<>(); + ArrayList avatars = new ArrayList(); + try { + JSONObject json = jsonParser.parseJSON(response); + if(json != null) { + JSONObject newsfeed = json.getJSONObject("response"); + JSONArray items = newsfeed.getJSONArray("items"); + if(newsfeed.has("next_from")) { + next_from = newsfeed.getLong("next_from"); + } else { + if(next_from > 0) { + next_from += items.length() + 1; + } else { + next_from = items.length() + 1; + } + } + for(int i = 0; i < items.length(); i++) { + JSONObject post = items.getJSONObject(i); + JSONObject comments = post.getJSONObject("comments"); + JSONObject likes = post.getJSONObject("likes"); + JSONObject reposts = post.getJSONObject("reposts"); + JSONArray attachments = post.getJSONArray("attachments"); + long owner_id = post.getLong("owner_id"); + long post_id = post.getLong("id"); + long author_id = post.getLong("from_id"); + long dt_sec = post.getLong("date"); + String original_author_name = ""; + String original_author_avatar_url = ""; + String author_name = ""; + String owner_name = ""; + String avatar_url = ""; + String owner_avatar_url = ""; + String author_avatar_url = ""; + String content = post.getString("text"); + boolean isLiked = false; + boolean verified_author = false; + isLiked = likes.getInt("user_likes") > 0; + PostCounters counters = new PostCounters(likes.getInt("count"), + comments.getInt("count"), + reposts.getInt("count"), isLiked, false); + ArrayList attachments_list = null; + if(isWall) { + attachments_list = + createAttachmentsList(owner_id, post_id, quality, + attachments, "wall_attachment"); + } else { + attachments_list = + createAttachmentsList(owner_id, post_id, quality, + attachments, "newsfeed_attachment"); + } + WallPost item = new WallPost(String.format("(Unknown author: %s)", + author_id), dt_sec, null, + content, counters, "", attachments_list, owner_id, post_id, ctx); + item.setJSONString(post.toString()); + if(post.has("post_source") && !post.isNull("post_source")) { + if(post.getJSONObject("post_source").getString("type").equals("api")) { + item.post_source = new WallPostSource( + post.getJSONObject("post_source").getString("type"), + post.getJSONObject("post_source").getString("platform") + ); + } else { + item.post_source = + new WallPostSource(post.getJSONObject("post_source") + .getString("type"), null); + } + } + if(post.getJSONArray("copy_history").length() > 0) { + JSONObject repost = post.getJSONArray("copy_history").getJSONObject(0); + WallPost repost_item = new WallPost(String.format("(Unknown author: %s)", + repost.getInt("from_id")), + repost.getInt("date"), null, + repost.getString("text"), null, "", + null, repost.getInt("owner_id"), + repost.getInt("id"), ctx); + repost_item.setJSONString(repost.toString()); + RepostInfo repostInfo = + new RepostInfo(String.format("(Unknown author: %s)", + repost.getInt("from_id")), + repost.getInt("date"), ctx); + repostInfo.newsfeed_item = repost_item; + item.repost = repostInfo; + JSONArray repost_attachments = repost.getJSONArray("attachments"); + if(isWall) { + attachments_list = createAttachmentsList(owner_id, post_id, quality, + repost_attachments, "wall_attachment"); + } else { + attachments_list = createAttachmentsList(owner_id, post_id, quality, + repost_attachments, "newsfeed_attachment"); + } + repost_item.attachments = attachments_list; + } + item.author_id = author_id; + if(author_id > 0) { + if(newsfeed.has("profiles")) { + JSONArray profiles = newsfeed.getJSONArray("profiles"); + for (int profiles_index = 0; profiles_index < profiles.length(); profiles_index++) { + JSONObject profile = profiles.getJSONObject(profiles_index); + if (profile.getInt("id") == author_id) { + author_name = String.format("%s %s", profile.getString("first_name"), + profile.getString("last_name")); + author_avatar_url = profile.getString("photo_50"); + if(profile.has("verified")) { + if(profile.get("verified") instanceof Integer) { + verified_author = profile.getInt("verified") == 1; + } else { + verified_author = profile.getBoolean("verified"); + } + } + } else if (profile.getInt("id") == owner_id) { + owner_name = String.format("%s %s", profile.getString("first_name"), + profile.getString("last_name")); + owner_avatar_url = profile.getString("photo_50"); + if(profile.has("verified")) { + if(profile.get("verified") instanceof Integer) { + verified_author = profile.getInt("verified") == 1; + } else { + verified_author = profile.getBoolean("verified"); + } + } + } + } + if(author_avatar_url.length() > 0) + avatar_url = author_avatar_url; + } + if(owner_id < 0) { + if(newsfeed.has("groups")) { + JSONArray groups = newsfeed.getJSONArray("groups"); + for (int groups_index = 0; groups_index < groups.length(); groups_index++) { + JSONObject group = groups.getJSONObject(groups_index); + if (-group.getInt("id") == owner_id) { + owner_name = group.getString("name"); + avatar_url = group.getString("photo_50"); + if(group.get("verified") instanceof Integer) { + verified_author = group.getInt("verified") == 1; + } else { + verified_author = group.getBoolean("verified"); + } + } + } + } + } + if(author_id == owner_id) { + item.name = author_name; + } else { + item.name = ctx.getResources().getString(R.string.on_wall, author_name, owner_name); + } + } else { + if(newsfeed.has("groups") && newsfeed.has("profiles")) { + JSONArray groups = newsfeed.getJSONArray("groups"); + JSONArray profiles = newsfeed.getJSONArray("profiles"); + for (int groups_index = 0; groups_index < groups.length(); groups_index++) { + JSONObject group = groups.getJSONObject(groups_index); + if (-group.getInt("id") == author_id) { + item.name = group.getString("name"); + avatar_url = group.getString("photo_50"); + if(group.has("verified")) { + if(group.get("verified") instanceof Integer) { + verified_author = group.getInt("verified") == 1; + } else { + verified_author = group.getBoolean("verified"); + } + } + } + } + } + } + PhotoAttachment avatar = new PhotoAttachment(); + avatar.url = avatar_url; + avatar.filename = String.format("avatar_%s", author_id); + try { // handle floating crash + avatars.add(avatar); + item.verified_author = verified_author; + if(post.has("is_explicit")) { + item.is_explicit = post.getBoolean("is_explicit"); + } + this.items.add(item); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + } + if(isWall) { + switch (quality) { + case "low": + downloadManager.downloadPhotosToCache(photos_lsize, "wall_photo_attachments"); + break; + case "medium": + downloadManager.downloadPhotosToCache(photos_msize, "wall_photo_attachments"); + break; + case "high": + downloadManager.downloadPhotosToCache(photos_hsize, "wall_photo_attachments"); + break; + case "original": + downloadManager.downloadPhotosToCache(photos_osize, "wall_photo_attachments"); + break; + } + downloadManager.downloadPhotosToCache(avatars, "wall_avatars"); + } else { + switch (quality) { + case "low": + downloadManager.downloadPhotosToCache(photos_lsize, "newsfeed_photo_attachments"); + break; + case "medium": + downloadManager.downloadPhotosToCache(photos_msize, "newsfeed_photo_attachments"); + break; + case "high": + downloadManager.downloadPhotosToCache(photos_hsize, "newsfeed_photo_attachments"); + break; + case "original": + downloadManager.downloadPhotosToCache(photos_osize, "newsfeed_photo_attachments"); + break; + } + downloadManager.downloadPhotosToCache(avatars, "newsfeed_avatars"); + } + downloadManager.downloadPhotosToCache(video_thumbnails, "video_thumbnails"); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public ArrayList parseComments(Context ctx, DownloadManager downloadManager, String quality, + String response) { + comments = new ArrayList(); + photos_lsize = new ArrayList<>(); + photos_msize = new ArrayList(); + photos_hsize = new ArrayList(); + photos_osize = new ArrayList(); + try { + JSONObject json = jsonParser.parseJSON(response); + if (json != null) { + JSONObject comments = json.getJSONObject("response"); + JSONArray items = comments.getJSONArray("items"); + ArrayList avatars = new ArrayList<>(); + for(int i = 0; i < items.length(); i++) { + JSONObject item = items.getJSONObject(i); + String text = item.getString("text"); + long comment_id = item.getLong("id"); + long author_id = item.getLong("from_id"); + long date = item.getLong("date"); + JSONArray attachments = items.getJSONObject(i).getJSONArray("attachments"); + ArrayList attachments_list = createAttachmentsList(author_id, comment_id, + quality, attachments, "comment_photo"); + Comment comment = new Comment(); + comment.id = comment_id; + comment.author_id = author_id; + comment.text = text; + comment.author = String.format("(Unknown author: %s)", author_id); + comment.date = date; + PhotoAttachment photoAttachment = new PhotoAttachment(); + photoAttachment.url = ""; + photoAttachment.filename = ""; + if(author_id > 0) { + if(comments.has("profiles")) { + JSONArray profiles = comments.getJSONArray("profiles"); + for (int profiles_index = 0; profiles_index < profiles.length(); profiles_index++) { + JSONObject profile = profiles.getJSONObject(profiles_index); + if (profile.getLong("id") == author_id) { + comment.author = String.format("%s %s", profile.getString("first_name"), + profile.getString("last_name")); + if(profile.has("photo_100")) { + comment.avatar_url = profile.getString("photo_100"); + } + photoAttachment.url = comment.avatar_url; + photoAttachment.filename = String.format("avatar_%s", author_id); + } + } + } + } else { + if(comments.has("groups")) { + JSONArray groups = comments.getJSONArray("groups"); + for (int groups_index = 0; groups_index < groups.length(); groups_index++) { + JSONObject group = groups.getJSONObject(groups_index); + if (group.getLong("id") == author_id) { + comment.author = group.getString("name"); + if(group.has("photo_100")) { + comment.avatar_url = group.getString("photo_100"); + } + photoAttachment.url = comment.avatar_url; + photoAttachment.filename = String.format("avatar_%s", author_id); + } + } + } + } + comment.attachments = attachments_list; + try { // handle floating crash + avatars.add(photoAttachment); + this.comments.add(comment); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + } + switch (quality) { + case "low": + downloadManager.downloadPhotosToCache(photos_lsize, "comment_photos"); + break; + case "medium": + downloadManager.downloadPhotosToCache(photos_msize, "comment_photos"); + break; + case "high": + downloadManager.downloadPhotosToCache(photos_hsize, "comment_photos"); + break; + case "original": + downloadManager.downloadPhotosToCache(photos_osize, "comment_photos"); + break; + } + downloadManager.downloadPhotosToCache(avatars, "comment_avatars"); + } + } catch(JSONException e) { + e.printStackTrace(); + } + return comments; + } + + public ArrayList createAttachmentsList(long owner_id, long post_id, String quality, + JSONArray attachments, String prefix) { + ArrayList attachments_list = new ArrayList<>(); + try { + for (int attachments_index = 0; attachments_index < attachments.length(); attachments_index++) { + String photo_low_size; + String photo_medium_size; + String photo_high_size; + String photo_original_size; + String attachment_status; + JSONObject attachment = attachments.getJSONObject(attachments_index); + switch (attachment.getString("type")) { + case "photo": { + JSONObject photo = attachment.getJSONObject("photo"); + PhotoAttachment photoAttachment = new PhotoAttachment(); + photoAttachment.id = photo.getLong("id"); + JSONArray photo_sizes = photo.getJSONArray("sizes"); + photo_low_size = photo_sizes.getJSONObject(2).getString("url"); + photo_medium_size = photo_sizes.getJSONObject(5).getString("url"); + photo_high_size = photo_sizes.getJSONObject(8).getString("url"); + photo_original_size = photo_sizes.getJSONObject(10).getString("url"); + photoAttachment.size = new int[2]; + switch (quality) { + case "low": + photoAttachment.url = photo_low_size; + if (!photo_sizes.getJSONObject(2).isNull("width")) { + photoAttachment.size[0] = photo_sizes.getJSONObject(2).getInt("width"); + } else { + photoAttachment.size[0] = 384; + } + if (!photo_sizes.getJSONObject(2).isNull("height")) { + photoAttachment.size[1] = photo_sizes.getJSONObject(2).getInt("height"); + } else { + photoAttachment.size[1] = 288; + } + break; + case "medium": + photoAttachment.url = photo_medium_size; + if (!photo_sizes.getJSONObject(5).isNull("width")) { + photoAttachment.size[0] = photo_sizes.getJSONObject(5).getInt("width"); + } else { + photoAttachment.size[0] = 480; + } + if (!photo_sizes.getJSONObject(5).isNull("height")) { + photoAttachment.size[1] = photo_sizes.getJSONObject(5).getInt("height"); + } else { + photoAttachment.size[1] = 360; + } + break; + case "high": + if (photo_high_size != null && photo_high_size.length() > 0) { + photoAttachment.url = photo_high_size; + } else { + photoAttachment.url = photo_medium_size; + } + if (!photo_sizes.getJSONObject(5).isNull("width")) { + photoAttachment.size[0] = photo_sizes.getJSONObject(8).getInt("width"); + } else { + photoAttachment.size[0] = 1024; + } + if (!photo_sizes.getJSONObject(5).isNull("height")) { + photoAttachment.size[1] = photo_sizes.getJSONObject(8).getInt("height"); + } else { + photoAttachment.size[1] = 768; + } + break; + case "original": + if (photo_original_size != null && photo_original_size.length() > 0) { + photoAttachment.url = photo_original_size; + } else if (photo_high_size != null && photo_high_size.length() > 0) { + photoAttachment.url = photo_high_size; + } else { + photoAttachment.url = photo_medium_size; + } + if (!photo_sizes.getJSONObject(5).isNull("width")) { + photoAttachment.size[0] = photo_sizes.getJSONObject(8).getInt("width"); + } else { + photoAttachment.size[0] = 2560; + } + if (!photo_sizes.getJSONObject(5).isNull("height")) { + photoAttachment.size[1] = photo_sizes.getJSONObject(8).getInt("height"); + } else { + photoAttachment.size[1] = 1920; + } + break; + } + photoAttachment.filename = String.format("%s_o%sp%s", prefix, owner_id, post_id); + photoAttachment.original_url = photo_original_size; + if (photo_medium_size.length() > 0 || photo_high_size.length() > 0) { + attachment_status = "loading"; + } else { + attachment_status = "none"; + } + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = attachment_status; + attachment_obj.setContent(photoAttachment); + try { // handle floating crash + attachments_list.add(attachment_obj); + switch (quality) { + case "low": + photos_lsize.add(photoAttachment); + break; + case "medium": + photos_msize.add(photoAttachment); + break; + case "high": + photos_hsize.add(photoAttachment); + break; + case "original": + photos_osize.add(photoAttachment); + break; + } + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + break; + } + case "video": { + JSONObject video = attachment.getJSONObject("video"); + VideoAttachment videoAttachment = new VideoAttachment(); + videoAttachment.id = video.getLong("id"); + videoAttachment.title = video.getString("title"); + VideoFiles files = new VideoFiles(); + if (video.has("files") && !video.isNull("files")) { + JSONObject videoFiles = video.getJSONObject("files"); + if (videoFiles.has("mp4_144")) { + files.mp4_144 = videoFiles.getString("mp4_144"); + } + if (videoFiles.has("mp4_240")) { + files.mp4_240 = videoFiles.getString("mp4_240"); + } + if (videoFiles.has("mp4_360")) { + files.mp4_360 = videoFiles.getString("mp4_360"); + } + if (videoFiles.has("mp4_480")) { + files.mp4_480 = videoFiles.getString("mp4_480"); + } + if (videoFiles.has("mp4_720")) { + files.mp4_720 = videoFiles.getString("mp4_720"); + } + if (videoFiles.has("mp4_1080")) { + files.mp4_1080 = videoFiles.getString("mp4_1080"); + } + if (videoFiles.has("ogv_480")) { + files.ogv_480 = videoFiles.getString("ogv_480"); + } + } + videoAttachment.files = files; + if (video.has("image")) { + JSONArray thumb_array = video.getJSONArray("image"); + videoAttachment.url_thumb = thumb_array.getJSONObject(0).getString("url"); + PhotoAttachment thumbnail = new PhotoAttachment(); + thumbnail.url = videoAttachment.url_thumb; + thumbnail.filename = String.format("thumbnail_%so%s", + video.getLong("id"), owner_id); + video_thumbnails.add(thumbnail); + } + videoAttachment.duration = video.getInt("duration"); + attachment_status = "done"; + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = attachment_status; + attachment_obj.setContent(videoAttachment); + try { + attachments_list.add(attachment_obj); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + break; + } + case "poll": { + JSONObject poll_attachment = attachment.getJSONObject("poll"); + PollAttachment pollAttachment = new PollAttachment(poll_attachment.getString("question"), + poll_attachment.getInt("id"), poll_attachment.getLong("end_date"), + poll_attachment.getBoolean("multiple"), + poll_attachment.getBoolean("can_vote"), + poll_attachment.getBoolean("anonymous")); + JSONArray answers = poll_attachment.getJSONArray("answers"); + JSONArray votes = poll_attachment.getJSONArray("answer_ids"); + if (votes.length() > 0) { + pollAttachment.user_votes = votes.length(); + } + pollAttachment.votes = poll_attachment.getInt("votes"); + for (int answers_index = 0; answers_index < answers.length(); answers_index++) { + JSONObject answer = answers.getJSONObject(answers_index); + PollAnswer pollAnswer = new PollAnswer(answer.getInt("id"), answer.getInt("rate"), + answer.getInt("votes"), answer.getString("text")); + for (int votes_index = 0; votes_index < votes.length(); votes_index++) { + if (answer.getInt("id") == votes.getInt(votes_index)) { + pollAnswer.is_voted = true; + } + } + pollAttachment.answers.add(pollAnswer); + } + attachment_status = "done"; + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = attachment_status; + attachment_obj.setContent(pollAttachment); + try { // handle floating crash + attachments_list.add(attachment_obj); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + break; + } + case "note": { + CommonAttachment commonAttachment = new CommonAttachment( + attachment.getString("title"), attachment.getString("text")); + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = "done"; + attachment_obj.setContent(commonAttachment); + try { // handle floating crash + attachments_list.add(attachment_obj); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + break; + } + default: { + attachment_status = "not_supported"; + Attachment attachment_obj = new Attachment(attachment.getString("type")); + attachment_obj.status = attachment_status; + try { // handle floating crash + attachments_list.add(attachment_obj); + } catch (ArrayIndexOutOfBoundsException ignored) { + Log.e(OvkApplication.API_TAG, "WTF? The length itself in an array must not " + + "be overestimated."); + } + break; + } + } + } + } catch (JSONException ex) { + ex.printStackTrace(); + } + return attachments_list; + } + + public void get(OvkAPIWrapper wrapper, long owner_id, int count) { + wrapper.sendAPIMethod("Wall.get", String.format("owner_id=%s&count=%s&extended=1", + owner_id, count)); + } + + public ArrayList getWallItems() { + return items; + } + + public void setWallItems(ArrayList wallItems) { + this.items = wallItems; + } + + public void post(OvkAPIWrapper wrapper, long owner_id, String post, + boolean from_group, + boolean signed) { + int from_group_int = 0; + int signed_int = 0; + if(from_group) { + from_group_int = 1; + } + if(signed) { + signed_int = 1; + } + wrapper.sendAPIMethod("Wall.post", String.format("owner_id=%s&message=%s" + + "&from_group=%s&signed=%s", + owner_id, URLEncoder.encode(post), from_group_int, signed_int)); + } + + public void post(OvkAPIWrapper wrapper, long owner_id, String post, + boolean from_group, boolean signed, String attachments) { + int from_group_int = 0; + int signed_int = 0; + if(from_group) { + from_group_int = 1; + } + if(signed) { + signed_int = 1; + } + wrapper.sendAPIMethod("Wall.post", + String.format("owner_id=%s&message=%s&attachments=%s" + + "&from_group=%s&signed=%s", + owner_id, URLEncoder.encode(post), URLEncoder.encode(attachments), + from_group_int, signed_int)); + } + + public void getComments(OvkAPIWrapper wrapper, long owner_id, long post_id) { + wrapper.sendAPIMethod("Wall.getComments", String.format("owner_id=%s&post_id=%s&extended=1&count=50", + owner_id, post_id)); + } + + public void createComment(OvkAPIWrapper wrapper, long owner_id, long post_id, String text) { + wrapper.sendAPIMethod("Wall.createComment", String.format("owner_id=%s&post_id=%s&message=%s", owner_id, + post_id, URLEncoder.encode(text))); + } + + public void repost(OvkAPIWrapper wrapper, long owner_id, long post_id, String text) { + wrapper.sendAPIMethod("Wall.repost", String.format("object=wall%s_%s&message=%s", owner_id, + post_id, URLEncoder.encode(text))); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeTypedList(items); + } + + public void get(OvkAPIWrapper wrapper, long owner_id, int count, long offset) { + wrapper.sendAPIMethod("Wall.get", + String.format("owner_id=%s&count=%s&extended=1&offset=%s", + owner_id, count, offset), "more_wall_posts"); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/models/WallPost.java b/app/src/main/java/uk/openvk/android/refresh/api/models/WallPost.java deleted file mode 100644 index 1d11173..0000000 --- a/app/src/main/java/uk/openvk/android/refresh/api/models/WallPost.java +++ /dev/null @@ -1,122 +0,0 @@ -package uk.openvk.android.refresh.api.models; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.concurrent.TimeUnit; - -import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.attachments.Attachment; -import uk.openvk.android.refresh.api.counters.PostCounters; - -public class WallPost implements Parcelable { - - public long dt_sec; - private String avatar_url; - public Bitmap avatar; - public String name; - public RepostInfo repost; - public String info; - public String text; - public long owner_id; - public long post_id; - public PostCounters counters; - public long author_id; - public boolean verified_author; - public ArrayList attachments; - public WallPostSource post_source; - - @SuppressLint("SimpleDateFormat") - public WallPost(String author, long dt_sec, RepostInfo repostInfo, String post_text, - PostCounters nICI, String avatar_url, ArrayList attachments, - long o_id, long p_id, Context ctx) { - name = author; - Date dt = new Date(TimeUnit.SECONDS.toMillis(dt_sec)); - Date dt_midnight = new Date(System.currentTimeMillis() + 86400000); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(dt_midnight); - calendar.set(Calendar.HOUR_OF_DAY, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - this.dt_sec = dt_sec; - if((calendar.getTimeInMillis() - (TimeUnit.SECONDS.toMillis(dt_sec))) < 86400000) { - info = String.format("%s %s", ctx.getResources().getString(R.string.today_at), new SimpleDateFormat("HH:mm").format(dt)); - } else if((calendar.getTimeInMillis() - (TimeUnit.SECONDS.toMillis(dt_sec))) < (86400000 * 2)) { - info = String.format("%s %s", ctx.getResources().getString(R.string.yesterday_at), new SimpleDateFormat("HH:mm").format(dt)); - } else if((calendar.getTimeInMillis() - (TimeUnit.SECONDS.toMillis(dt_sec))) < 31536000000L) { - info = String.format("%s %s %s", new SimpleDateFormat("d MMMM").format(dt), ctx.getResources().getString(R.string.date_at), - new SimpleDateFormat("HH:mm").format(dt)); - } else { - info = String.format("%s %s %s", new SimpleDateFormat("d MMMM yyyy").format(dt), ctx.getResources().getString(R.string.date_at), - new SimpleDateFormat("HH:mm").format(dt)); - } - repost = repostInfo; - counters = nICI; - text = post_text; - this.avatar_url = avatar_url; - owner_id = o_id; - post_id = p_id; - this.attachments = attachments; - } - - public WallPost() { - - } - - protected WallPost(Parcel in) { - avatar_url = in.readString(); - //avatar = in.readParcelable(Bitmap.class.getClassLoader()); - name = in.readString(); - info = in.readString(); - text = in.readString(); - owner_id = in.readLong(); - post_id = in.readLong(); - author_id = in.readLong(); - verified_author = in.readInt() != 0; - post_source = in.readParcelable(WallPostSource.class.getClassLoader()); - } - - public static final Creator CREATOR = new Creator() { - @Override - public WallPost createFromParcel(Parcel in) { - return new WallPost(in); - } - - @Override - public WallPost[] newArray(int size) { - return new WallPost[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(avatar_url); - //parcel.writeParcelable(avatar, i); - parcel.writeString(name); - parcel.writeString(info); - parcel.writeString(text); - parcel.writeLong(owner_id); - parcel.writeLong(post_id); - parcel.writeLong(author_id); - int verified_author_temp = 0; - if(verified_author) { - verified_author_temp = 1; - } - parcel.writeInt(verified_author_temp); - parcel.writeParcelable(post_source, i); - } -} diff --git a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/DownloadManager.java b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/DownloadManager.java index 99d027c..9a685bc 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/DownloadManager.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/DownloadManager.java @@ -5,6 +5,7 @@ import android.content.pm.PackageInfo; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.os.Message; import android.util.Log; @@ -16,7 +17,6 @@ import java.net.Proxy; import java.util.ArrayList; import java.util.Date; -import java.util.Objects; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLContext; @@ -26,24 +26,32 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import okhttp3.internal.http.StatusLine; import uk.openvk.android.refresh.BuildConfig; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.api.attachments.PhotoAttachment; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.ui.core.activities.AppActivity; -import uk.openvk.android.refresh.ui.core.activities.AuthActivity; -import uk.openvk.android.refresh.ui.core.activities.FriendsIntentActivity; -import uk.openvk.android.refresh.ui.core.activities.GroupIntentActivity; -import uk.openvk.android.refresh.ui.core.activities.PhotoViewerActivity; -import uk.openvk.android.refresh.ui.core.activities.ProfileIntentActivity; +import uk.openvk.android.refresh.api.interfaces.OvkAPIListeners; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; -/** - * File created by Dmitry on 27.09.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ -@SuppressWarnings({"ResultOfMethodCallIgnored", "StatementWithEmptyBody"}) +@SuppressWarnings({"ResultOfMethodCallIgnored", "StatementWithEmptyBody", "ConstantConditions"}) public class DownloadManager { + public String server; public boolean use_https; public boolean legacy_mode; @@ -52,66 +60,89 @@ public class DownloadManager { private boolean logging_enabled = true; // default for beta releases private OkHttpClient httpClient = null; + private boolean forceCaching; + private String instance; + OvkAPIListeners apiListeners; + Handler handler; - public DownloadManager(Context ctx) { + public DownloadManager(Context ctx, boolean use_https, Handler handler) { + this.handler = handler; + apiListeners = new OvkAPIListeners(); + if(handler == null) { + searchHandler(); + } this.ctx = ctx; + this.use_https = use_https; + this.legacy_mode = legacy_mode; if(BuildConfig.BUILD_TYPE.equals("release")) { logging_enabled = false; } try { - SSLContext sslContext = null; - try { - sslContext = SSLContext.getInstance("SSL"); - @SuppressLint("CustomX509TrustManager") TrustManager[] trustAllCerts = - new TrustManager[]{ - new X509TrustManager() { - @SuppressLint("TrustAllX509TrustManager") - @Override - public void checkClientTrusted(java.security.cert.X509Certificate[] - chain, String authType) { - } + Log.v(OvkApplication.DL_TAG, "Starting DownloadManager..."); + SSLContext sslContext = null; + try { + sslContext = SSLContext.getInstance("SSL"); + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @SuppressLint("TrustAllX509TrustManager") + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] chain, + String authType) { + } - @SuppressLint("TrustAllX509TrustManager") - @Override - public void checkServerTrusted(java.security.cert.X509Certificate[] - chain, String authType) { - } + @SuppressLint("TrustAllX509TrustManager") + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, + String authType) { + } - @Override - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return new java.security.cert.X509Certificate[]{}; - } + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[]{}; } - }; - sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); - javax.net.ssl.SSLSocketFactory ssf = (javax.net.ssl.SSLSocketFactory) sslContext - .getSocketFactory(); - httpClient = new OkHttpClient.Builder().sslSocketFactory(sslContext.getSocketFactory()) - .connectTimeout(30, TimeUnit.SECONDS).writeTimeout(30, - TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS) - .retryOnConnectionFailure(false).build(); - } catch (Exception e) { - httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(30, TimeUnit.SECONDS).readTimeout(30, - TimeUnit.SECONDS).retryOnConnectionFailure(false).build(); - } + } + }; + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + javax.net.ssl.SSLSocketFactory ssf = (javax.net.ssl.SSLSocketFactory) + sslContext.getSocketFactory(); + httpClient = new OkHttpClient.Builder() + .sslSocketFactory(sslContext.getSocketFactory()) + .connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false) + .build(); + } catch (Exception e) { + httpClient = new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false) + .build(); + } } catch (Exception ex) { ex.printStackTrace(); } } + + public void setInstance(String instance) { + this.instance = instance; + } + + public void setForceCaching(boolean value) { + forceCaching = value; + } public void setProxyConnection(boolean useProxy, String address) { try { if(useProxy) { String[] address_array = address.split(":"); if (address_array.length == 2) { - httpClient = new OkHttpClient.Builder().connectTimeout(30, - TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS).readTimeout(30, - TimeUnit.SECONDS) + httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS) .retryOnConnectionFailure(false).proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(address_array[0], - Integer.parseInt(address_array[1])))).build(); + Integer.parseInt(address_array[1])))).build(); } } } catch (Exception ex) { @@ -123,29 +154,28 @@ private String generateUserAgent(Context ctx) { String version_name = ""; String user_agent = ""; try { - PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo( - ctx.getApplicationContext().getPackageName(), 0); + PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo(ctx.getApplicationContext().getPackageName(), 0); version_name = packageInfo.versionName; } catch (Exception e) { OvkApplication app = ((OvkApplication) ctx.getApplicationContext()); version_name = app.version; } finally { - user_agent = String.format("OpenVK Refresh/%s (Android %s; SDK %s; %s; %s %s; %s)", - version_name, - Build.VERSION.RELEASE, Build.VERSION.SDK_INT, Build.SUPPORTED_ABIS[0], - Build.MANUFACTURER, Build.MODEL, System.getProperty("user.language")); + user_agent = String.format("OpenVK Legacy/%s (Android %s; SDK %s; %s; %s %s; %s)", version_name, + Build.VERSION.RELEASE, Build.VERSION.SDK_INT, Build.CPU_ABI, Build.MANUFACTURER, + Build.MODEL, System.getProperty("user.language")); } return user_agent; } - public void downloadPhotosToCache(final ArrayList photoAttachments, - final String where) { - Log.v("DownloadManager", String.format("Downloading %d photos...", - photoAttachments.size())); + public void downloadPhotosToCache(final ArrayList photoAttachments, final String where) { + if(photoAttachments == null) { + Log.e(OvkApplication.DL_TAG, "Attachments array is empty. Download canceled."); + return; + } + Log.v("DownloadManager", String.format("Downloading %d photos...", photoAttachments.size())); Runnable httpRunnable = new Runnable() { private Request request = null; - StatusLine statusLine = null; int response_code = 0; long filesize = 0; long content_length = 0; @@ -156,8 +186,8 @@ public void downloadPhotosToCache(final ArrayList photoAttachme @Override public void run() { try { - File directory = new File(String.format("%s/photos_cache", - ctx.getCacheDir().getAbsolutePath()), where); + File directory = new File(String.format("%s/%s/photos_cache", + ctx.getCacheDir().getAbsolutePath(), instance), where); if (!directory.exists()) { directory.mkdirs(); } @@ -167,8 +197,8 @@ public void run() { for (int i = 0; i < photoAttachments.size(); i++) { filesize = 0; filename = photoAttachments.get(i).filename; - File downloadedFile = new File(String.format("%s/photos_cache/%s", - ctx.getCacheDir(), where), filename); + File downloadedFile = new File(String.format("%s/%s/photos_cache/%s", + ctx.getCacheDir().getAbsolutePath(), instance, where), filename); PhotoAttachment photoAttachment = photoAttachments.get(i); if(photoAttachment.url == null) { photoAttachment.url = ""; @@ -181,19 +211,22 @@ public void run() { } long time_diff = System.currentTimeMillis() - lastModDate.getTime(); TimeUnit timeUnit = TimeUnit.MILLISECONDS; - if(downloadedFile.exists() && downloadedFile.length() >= 5120 && - timeUnit.convert(time_diff,TimeUnit.MILLISECONDS) >= 60000L && + // photo autocaching + if(forceCaching && downloadedFile.exists() && downloadedFile.length() >= 5120 && + timeUnit.convert(time_diff,TimeUnit.MILLISECONDS) >= 360000L && timeUnit.convert(time_diff,TimeUnit.MILLISECONDS) < 259200000L) { - if(logging_enabled) Log.e("OVK DL", "Duplicated filename. Skipping..." + + if(logging_enabled) Log.e(OvkApplication.DL_TAG, "Duplicated filename. Skipping..." + "\r\nTimeDiff: " + timeUnit.convert(time_diff,TimeUnit.MILLISECONDS) + " ms | Filesize: " + downloadedFile.length() + " bytes"); } else if (photoAttachment.url.length() == 0) { filename = photoAttachment.filename; - //Log.e("DownloadManager", "Invalid address. Skipping..."); + if(logging_enabled) Log.e(OvkApplication.DL_TAG, + "Invalid or empty URL. Skipping..."); try { - if(downloadedFile.exists()) { + if(downloadedFile.exists() && !downloadedFile.isDirectory()) { FileOutputStream fos = new FileOutputStream(downloadedFile); byte[] bytes = new byte[1]; + bytes[0] = 0; fos.write(bytes); fos.close(); } @@ -212,75 +245,92 @@ public void run() { //Log.v("DownloadManager", String.format("Downloading %s (%d/%d)...", // short_address, i + 1, photoAttachments.size())); url = photoAttachments.get(i).url; + if(!url.startsWith("http://") && !url.startsWith("https://")) { + Log.e(OvkApplication.DL_TAG, + String.format("Invalid URL: %s. Download canceled.", url)); + return; + } + request = new Request.Builder() .url(url) + .addHeader("User-Agent", generateUserAgent(ctx)) .build(); Response response = httpClient.newCall(request).execute(); response_code = response.code(); - content_length = Objects.requireNonNull(response.body()).contentLength(); + content_length = response.body().contentLength(); + downloadedFile = new File(String.format("%s/%s/photos_cache/%s", + ctx.getCacheDir().getAbsolutePath(), instance, where), filename); if(!downloadedFile.exists() || content_length != downloadedFile.length()) { FileOutputStream fos = new FileOutputStream(downloadedFile); int inByte; - while ((inByte = Objects.requireNonNull(response.body()).byteStream().read()) != -1) { + while ((inByte = response.body().byteStream().read()) != -1) { fos.write(inByte); filesize++; } fos.close(); } else { - if(logging_enabled) Log.w("DownloadManager", - "Filesizes match, skipping..."); + if(logging_enabled) Log.w("DownloadManager", "Filesizes match, skipping..."); } response.body().byteStream().close(); - if(logging_enabled) Log.d("DownloadManager", + if(logging_enabled) Log.d(OvkApplication.DL_TAG, String.format("Downloaded from %s (%s): %d kB (%d/%d)", short_address, response_code, (int) (filesize / 1024), i + 1, photoAttachments.size())); - } catch (IOException e) { - if(logging_enabled) Log.e("DownloadManager", - String.format("Download error: %s (%d/%d)", - e.getMessage(), i + 1, photoAttachments.size())); + } catch (IOException | OutOfMemoryError ex) { + if(logging_enabled) Log.e(OvkApplication.DL_TAG, + String.format("Download error: %s (%d/%d)", ex.getMessage(), i + 1, + photoAttachments.size())); + if(ex.getMessage() != null) { + if (ex.getMessage().startsWith("Authorization required")) { + response_code = 401; + } else if (ex.getMessage().startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 3); + response_code = Integer.parseInt(code_str); + } + } } catch (Exception e) { photoAttachment.error = e.getClass().getSimpleName(); - if(logging_enabled) Log.e("DownloadManager", - String.format("Download error: %s (%d/%d)", - e.getMessage(), i + 1, photoAttachments.size())); + if(logging_enabled) Log.e(OvkApplication.DL_TAG, + String.format("Download error: %s (%d/%d)", e.getMessage(), i + 1, + photoAttachments.size())); + } + } + if(i % 15 == 0 || i == photoAttachments.size() - 1) { + switch (where) { + case "account_avatar" -> + sendMessage(HandlerMessages.ACCOUNT_AVATAR, where); + case "profile_avatars" -> + sendMessage(HandlerMessages.PROFILE_AVATARS, where); + case "newsfeed_avatars" -> + sendMessage(HandlerMessages.NEWSFEED_AVATARS, where); + case "photo_albums" -> + sendMessage(HandlerMessages.PHOTO_ALBUM_THUMBNAILS, where); + case "group_avatars" -> + sendMessage(HandlerMessages.GROUP_AVATARS, where); + case "newsfeed_photo_attachments" -> + sendMessage(HandlerMessages.NEWSFEED_ATTACHMENTS, where); + case "wall_photo_attachments" -> + sendMessage(HandlerMessages.WALL_ATTACHMENTS, where); + case "wall_avatars" -> + sendMessage(HandlerMessages.WALL_AVATARS, where); + case "friend_avatars" -> + sendMessage(HandlerMessages.FRIEND_AVATARS, where); + case "comment_avatars" -> + sendMessage(HandlerMessages.COMMENT_AVATARS, where); + case "comment_photos" -> + sendMessage(HandlerMessages.COMMENT_PHOTOS, where); + case "album_photos" -> + sendMessage(HandlerMessages.ALBUM_PHOTOS, where); + case "conversations_avatars" -> + sendMessage(HandlerMessages.CONVERSATIONS_AVATARS, where); + case "video_thumbnails" -> + sendMessage(HandlerMessages.VIDEO_THUMBNAILS, where); } } } Log.v("DownloadManager", "Downloaded!"); - switch (where) { - case "account_avatar": - sendMessage(HandlerMessages.DLM_ACCOUNT_AVATAR, where); - break; - case "profile_avatars": - sendMessage(HandlerMessages.DLM_PROFILE_AVATARS, where); - break; - case "newsfeed_avatars": - sendMessage(HandlerMessages.DLM_NEWSFEED_AVATARS, where); - break; - case "group_avatars": - sendMessage(HandlerMessages.DLM_GROUP_AVATARS, where); - break; - case "newsfeed_photo_attachments": - sendMessage(HandlerMessages.DLM_NEWSFEED_ATTACHMENTS, where); - break; - case "wall_photo_attachments": - sendMessage(HandlerMessages.DLM_WALL_ATTACHMENTS, where); - break; - case "wall_avatars": - sendMessage(HandlerMessages.DLM_WALL_AVATARS, where); - break; - case "friend_avatars": - sendMessage(HandlerMessages.DLM_FRIEND_AVATARS, where); - break; - case "comment_avatars": - sendMessage(HandlerMessages.DLM_COMMENT_AVATARS, where); - break; - case "conversations_avatars": - sendMessage(HandlerMessages.DLM_CONVERSATIONS_AVATARS, where); - break; - } } }; @@ -289,9 +339,16 @@ public void run() { } public void downloadOnePhotoToCache(final String url, final String filename, final String where) { + if(url == null) { + Log.e(OvkApplication.DL_TAG, "URL is empty. Download canceled."); + return; + } + if(!url.startsWith("http://") && !url.startsWith("https://")) { + Log.e(OvkApplication.DL_TAG, String.format("Invalid URL: %s. Download canceled.", url)); + return; + } Runnable httpRunnable = new Runnable() { private Request request = null; - StatusLine statusLine = null; int response_code = 0; long filesize = 0; long content_length = 0; @@ -301,8 +358,8 @@ public void downloadOnePhotoToCache(final String url, final String filename, fin public void run() { Log.v("DownloadManager", String.format("Downloading %s...", url)); try { - File directory = new File(String.format("%s/photos_cache", - ctx.getCacheDir().getAbsolutePath()), where); + File directory = new File(String.format("%s/%s/photos_cache", + ctx.getCacheDir().getAbsolutePath(), instance), where); if (!directory.exists()) { directory.mkdirs(); } @@ -310,14 +367,29 @@ public void run() { ex.printStackTrace(); } filesize = 0; - if (url.length() == 0) { - if(logging_enabled) Log.e("DownloadManager", "Invalid address. Skipping..."); + File downloadedFile = new File(String.format("%s/%s/photos_cache/%s", + ctx.getCacheDir().getAbsolutePath(), instance, where), filename); + Date lastModDate; + if(downloadedFile.exists()) { + lastModDate = new Date(downloadedFile.lastModified()); + } else { + lastModDate = new Date(0); + } + long time_diff = System.currentTimeMillis() - lastModDate.getTime(); + TimeUnit timeUnit = TimeUnit.MILLISECONDS; + if(forceCaching && downloadedFile.exists() && downloadedFile.length() >= 5120 && + timeUnit.convert(time_diff,TimeUnit.MILLISECONDS) >= 360000L && + timeUnit.convert(time_diff,TimeUnit.MILLISECONDS) < 259200000L) { + if(logging_enabled) Log.e(OvkApplication.DL_TAG, "Duplicated filename. Skipping..." + + "\r\nTimeDiff: " + timeUnit.convert(time_diff,TimeUnit.MILLISECONDS) + + " ms | Filesize: " + downloadedFile.length() + " bytes"); + } else if (url.length() == 0) { + if(logging_enabled) Log.e(OvkApplication.DL_TAG, "Invalid address. Skipping..."); try { - File downloadedFile = new File(String.format("%s/photos_cache/%s", - ctx.getCacheDir(), where), filename); if(downloadedFile.exists()) { FileOutputStream fos = new FileOutputStream(downloadedFile); byte[] bytes = new byte[1]; + bytes[0] = 0; fos.write(bytes); fos.close(); } @@ -331,69 +403,78 @@ public void run() { } else { short_address = url; } + + if(logging_enabled) Log.v("DownloadManager", + String.format("Downloading %s...", short_address)); + request = new Request.Builder() + .url(url) + .addHeader("User-Agent", generateUserAgent(ctx)) + .build(); try { - if(logging_enabled) Log.v("DownloadManager", - String.format("Downloading %s...", short_address)); - request = new Request.Builder() - .url(url) - .build(); Response response = httpClient.newCall(request).execute(); response_code = response.code(); - File downloadedFile = new File(String.format("%s/photos_cache/%s", - ctx.getCacheDir(), where), filename); - if(!downloadedFile.exists() || content_length != downloadedFile.length()) { - FileOutputStream fos = new FileOutputStream(downloadedFile); - int inByte; - while ((inByte = Objects.requireNonNull(response.body()).byteStream().read()) != -1) { - fos.write(inByte); - filesize++; - } - fos.close(); + FileOutputStream fos = new FileOutputStream(downloadedFile); + int inByte; + while ((inByte = response.body().byteStream().read()) != -1) { + fos.write(inByte); + filesize++; + } + fos.close(); + response.body().byteStream().close(); + if (response != null){ + response.close(); + } + if(response_code == 200) { + if (logging_enabled) Log.v("DownloadManager", + String.format("Downloaded from %s (%s): %d kB", short_address, + response_code, (int) (filesize / 1024))); } else { - if(logging_enabled) Log.w("DownloadManager", "Filesizes match, skipping..."); + if(logging_enabled) Log.e(OvkApplication.DL_TAG, + String.format("Download error: %s", response_code)); + } + } catch (IOException ex) { + if(ex.getMessage() != null) { + if (ex.getMessage().startsWith("Authorization required")) { + response_code = 401; + } else if (ex.getMessage().startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 3); + response_code = Integer.parseInt(code_str); + } } - Objects.requireNonNull(response.body()).byteStream().close(); - response.close(); - if(logging_enabled) Log.v("DownloadManager", - String.format("Downloaded from %s (%s): %d kB", short_address, - response_code, (int) (filesize / 1024))); } catch (Exception e) { - if(logging_enabled) Log.e("DownloadManager", + if(logging_enabled) Log.e(OvkApplication.DL_TAG, String.format("Download error: %s", e.getMessage())); } } - Log.v("DownloadManager", String.format("Downloaded!")); + Log.v("DownloadManager", "Downloaded!"); switch (where) { - case "account_avatar": - sendMessage(HandlerMessages.DLM_ACCOUNT_AVATAR, where); - break; - case "profile_avatars": - sendMessage(HandlerMessages.DLM_PROFILE_AVATARS, where); - break; - case "newsfeed_avatars": - sendMessage(HandlerMessages.DLM_NEWSFEED_AVATARS, where); - break; - case "newsfeed_photo_attachments": - sendMessage(HandlerMessages.DLM_NEWSFEED_ATTACHMENTS, where); - break; - case "group_avatars": - sendMessage(HandlerMessages.DLM_GROUP_AVATARS, where); - break; - case "wall_photo_attachments": - sendMessage(HandlerMessages.DLM_WALL_ATTACHMENTS, where); - break; - case "wall_avatars": - sendMessage(HandlerMessages.DLM_WALL_AVATARS, where); - break; - case "friend_avatars": - sendMessage(HandlerMessages.DLM_FRIEND_AVATARS, where); - break; - case "comment_avatars": - sendMessage(HandlerMessages.DLM_COMMENT_AVATARS, where); - break; - case "original_photos": - sendMessage(HandlerMessages.DLM_ORIGINAL_PHOTO, where); - break; + case "account_avatar" -> + sendMessage(HandlerMessages.ACCOUNT_AVATAR, where); + case "profile_avatars" -> + sendMessage(HandlerMessages.PROFILE_AVATARS, where); + case "newsfeed_avatars" -> + sendMessage(HandlerMessages.NEWSFEED_AVATARS, where); + case "newsfeed_photo_attachments" -> + sendMessage(HandlerMessages.NEWSFEED_ATTACHMENTS, where); + case "group_avatars" -> + sendMessage(HandlerMessages.GROUP_AVATARS, where); + case "wall_photo_attachments" -> + sendMessage(HandlerMessages.WALL_ATTACHMENTS, where); + case "wall_avatars" -> + sendMessage(HandlerMessages.WALL_AVATARS, where); + case "friend_avatars" -> + sendMessage(HandlerMessages.FRIEND_AVATARS, where); + case "comment_avatars" -> + sendMessage(HandlerMessages.COMMENT_AVATARS, where); + case "comment_photos" -> + sendMessage(HandlerMessages.COMMENT_PHOTOS, where); + case "album_photos" -> + sendMessage(HandlerMessages.ALBUM_PHOTOS, where); + case "video_thumbnails" -> + sendMessage(HandlerMessages.VIDEO_THUMBNAILS, where); + case "original_photos" -> + sendMessage(HandlerMessages.ORIGINAL_PHOTO, where); } } }; @@ -402,48 +483,46 @@ public void run() { thread.start(); } - private void sendMessage(int message, String response) { + private void sendMessage(final int message, String response) { Message msg = new Message(); msg.what = message; - Bundle bundle = new Bundle(); + final Bundle bundle = new Bundle(); bundle.putString("response", response); msg.setData(bundle); - if(ctx.getClass().getSimpleName().equals("AuthActivity")) { - ((AuthActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("ProfileIntentActivity")) { - ((ProfileIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("FriendsIntentActivity")) { - ((FriendsIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("GroupIntentActivity")) { - ((GroupIntentActivity) ctx).handler.sendMessage(msg); -// } else if(ctx.getClass().getSimpleName().equals("WallPostActivity")) { -// ((WallPostActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("PhotoViewerActivity")) { - ((PhotoViewerActivity) ctx).handler.sendMessage(msg); - } + handler.post(new Runnable() { + @Override + public void run() { + if(message < 0) { + apiListeners.failListener.onAPIFailed(ctx, message, bundle); + } else { + apiListeners.successListener.onAPISuccess(ctx, message, bundle); + } + } + }); } - private void sendMessage(int message, String response, int id) { + private void sendMessage(final int message, String response, int id) { Message msg = new Message(); msg.what = message; - Bundle bundle = new Bundle(); + final Bundle bundle = new Bundle(); bundle.putString("response", response); bundle.putInt("id", id); msg.setData(bundle); - if(ctx.getClass().getSimpleName().equals("AuthActivity")) { - ((AuthActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("ProfileIntentActivity")) { - ((ProfileIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("FriendsIntentActivity")) { - ((FriendsIntentActivity) ctx).handler.sendMessage(msg); -// } else if(ctx.getClass().getSimpleName().equals("GroupIntentActivity")) { -// ((GroupIntentActivity) ctx).handler.sendMessage(msg); -// } else if(ctx.getClass().getSimpleName().equals("CommentsIntentActivity")) { -// ((WallPostActivity) ctx).handler.sendMessage(msg); + handler.post(new Runnable() { + @Override + public void run() { + if(message < 0) { + apiListeners.failListener.onAPIFailed(ctx, message, bundle); + } else { + apiListeners.successListener.onAPISuccess(ctx, message, bundle); + } + } + }); + } + + private void searchHandler() { + if(ctx instanceof NetworkActivity) { + this.handler = ((NetworkActivity) ctx).handler; } } @@ -452,32 +531,26 @@ public boolean clearCache(File dir) { dir = ctx.getCacheDir(); if (dir != null && dir.isDirectory()) { String[] children = dir.list(); - for (int i = 0; i < Objects.requireNonNull(children).length; i++) { - boolean success = clearCache(new File(dir, children[i])); + for (String aChildren : children) { + boolean success = clearCache(new File(dir, aChildren)); if (!success) { return false; } } return dir.delete(); - } else if (dir != null && dir.isFile()) { - return dir.delete(); - } else { - return false; - } - } else if (dir.isDirectory()) { + } else + return dir != null && dir.isFile() && dir.delete(); + } else if (dir != null && dir.isDirectory()) { String[] children = dir.list(); - for (int i = 0; i < Objects.requireNonNull(children).length; i++) { - boolean success = clearCache(new File(dir, children[i])); + for (String aChildren : children) { + boolean success = clearCache(new File(dir, aChildren)); if (!success) { return false; } } return dir.delete(); - } else if (dir.isFile()) { - return dir.delete(); - } else { - return false; - } + } else + return dir != null && dir.isFile() && dir.delete(); } public long getCacheSize() { @@ -487,21 +560,24 @@ public long getCacheSize() { public void run() { long foldersize = 0; File[] filelist = new File(ctx.getCacheDir().getAbsolutePath()).listFiles(); - for (int i = 0; i < Objects.requireNonNull(filelist).length; i++) { - if (filelist[i].isDirectory()) { - File[] filelist2 = new File(filelist[i].getAbsolutePath()).listFiles(); - for(int file_index = 0; file_index < Objects.requireNonNull(filelist2).length; - file_index++) { - foldersize += filelist2.length; + for (File aFilelist : filelist) { + if (aFilelist.isDirectory()) { + File[] filelist2 = new File(aFilelist.getAbsolutePath()).listFiles(); + for (File aFilelist2 : filelist2) { + foldersize += aFilelist2.length(); } } else { - foldersize += filelist[i].length(); + foldersize += aFilelist.length(); } } size[0] = foldersize; } }; - new Thread(runnable).start(); + new Thread(runnable).run(); return size[0]; } + + public void setAPIListeners(OvkAPIListeners apiListeners) { + this.apiListeners = apiListeners; + } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/JSONParser.java b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/JSONParser.java index f6f18ed..7ddb904 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/JSONParser.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/JSONParser.java @@ -1,9 +1,26 @@ package uk.openvk.android.refresh.api.wrappers; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import uk.openvk.android.refresh.api.Account; +import uk.openvk.android.refresh.api.entities.Account; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class JSONParser { @@ -20,15 +37,24 @@ public JSONObject parseJSON(String string) { return jsonObject; } + public JSONArray parseJSONArray(String string) { + JSONArray jsonArray = null; + try { + jsonArray = new JSONArray(string); + } catch (JSONException ex){ + ex.printStackTrace(); + } + return jsonArray; + } + public Account getAccount(String jsonString) { Account account = null; JSONObject json = parseJSON(jsonString); if(json != null) { try { JSONObject response = json.getJSONObject("response"); - account = new Account(response.getString("first_name"), - response.getString("last_name"), response.getInt("id"), - response.getString("status"), response.getString("birthday")); + account = new Account(response.getString("first_name"), response.getString("last_name"), + response.getInt("id"), response.getString("status"), response.getString("birthday")); } catch (JSONException e) { e.printStackTrace(); } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/NotificationManager.java b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/NotificationManager.java index 99272e9..b3a0cdb 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/NotificationManager.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/NotificationManager.java @@ -7,19 +7,34 @@ import android.content.Context; import android.content.Intent; import android.media.AudioAttributes; +import android.media.MediaPlayer; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import androidx.core.app.NotificationCompat; - import java.util.ArrayList; +import androidx.core.app.NotificationCompat; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Conversation; +import uk.openvk.android.refresh.api.entities.Conversation; import uk.openvk.android.refresh.longpoll_api.MessageEvent; -import uk.openvk.android.refresh.ui.core.activities.AppActivity; -import uk.openvk.android.refresh.ui.core.activities.MainActivity; +import uk.openvk.android.refresh.ui.core.activities.ConversationActivity; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class NotificationManager { @@ -31,13 +46,12 @@ public class NotificationManager { public boolean vibrate; public boolean playSound; - public NotificationManager(Context ctx, boolean ledIndicate, boolean vibrate, boolean playSound, - String ringtone_url) { + public NotificationManager(Context ctx, boolean ledIndicate, boolean vibrate, boolean playSound, String ringtone_url) { this.ctx = ctx; if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notifMan = ctx.getSystemService(android.app.NotificationManager.class); int importance = android.app.NotificationManager.IMPORTANCE_DEFAULT; - notifChannel = new NotificationChannel("direct_messages", ctx.getResources().getString(R.string.messages_notifch_title), importance); + notifChannel = new NotificationChannel("lp_updates", "LongPoll Updates", importance); notifChannel.enableLights(ledIndicate); notifChannel.enableVibration(vibrate); if(playSound) { @@ -57,8 +71,8 @@ public NotificationManager(Context ctx, boolean ledIndicate, boolean vibrate, bo } } - public void buildDirectMsgNotification(Context ctx, ArrayList conversations, Bundle data, - boolean notify, boolean is_repeat) { + public void buildDirectMsgNotification(Context ctx, ArrayList conversations, + Bundle data, boolean notify, boolean is_repeat) { int notification_id = 0; MessageEvent msg_event = new MessageEvent(data.getString("response")); if(msg_event.peer_id > 0 && notify) { @@ -81,33 +95,9 @@ public void buildDirectMsgNotification(Context ctx, ArrayList conv } } - public Notification createServiceNotification(Context ctx) { - String CHANNEL_ID = "service_notifch"; - NotificationChannel channel = null; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - channel = new NotificationChannel(CHANNEL_ID, - ctx.getResources().getString(R.string.service_notifch_title), - android.app.NotificationManager.IMPORTANCE_NONE); - - - ((android.app.NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE)) - .createNotificationChannel(channel); - return new NotificationCompat.Builder(ctx, CHANNEL_ID) - .setSmallIcon(R.drawable.ic_ovk_notif) - .setStyle(new NotificationCompat.BigTextStyle()) - .setContentTitle(ctx.getResources().getString(R.string.longpoll_notification_title)) - .setContentText(ctx.getResources().getString(R.string.longpoll_notification_subtitle)).build(); - } - return null; - } - public boolean isRepeat(String last_longpoll_response, String response) { try { - if (last_longpoll_response.equals(response)) { - return true; - } else { - return false; - } + return last_longpoll_response.equals(response); } catch (Exception ex) { return false; } @@ -124,7 +114,7 @@ public Notification createNotification(android.app.NotificationManager notifMan, .setContentText(description) .setChannelId("lp_updates"); notification = builder.build(); - Intent notificationIntent = new Intent(ctx, MainActivity.class); + Intent notificationIntent = new Intent(ctx, ConversationActivity.class); notification.contentIntent = PendingIntent.getActivity(ctx, 2, notificationIntent, 0); } else { NotificationCompat.Builder builder = @@ -144,22 +134,24 @@ public Notification createNotification(android.app.NotificationManager notifMan, if(playSound) { notification.defaults = Notification.DEFAULT_SOUND; + /* This code doesn't work yet if(ringtone_url.equals("content://settings/system/notification_sound")) { -// MediaPlayer mp = MediaPlayer.create(ctx, R.raw.notify); -// mp.start(); + MediaPlayer mp = MediaPlayer.create(ctx, R.raw.notify); + mp.start(); } else { notification.sound = Uri.parse(ringtone_url); } + */ } } return notification; } public PendingIntent createConversationIntent(int peer_id, String title) { - Intent notificationIntent = new Intent(ctx, MainActivity.class); + Intent notificationIntent = new Intent(ctx, ConversationActivity.class); notificationIntent.putExtra("peer_id", peer_id); notificationIntent.putExtra("conv_title", title); notificationIntent.putExtra("online", 1); - return PendingIntent.getActivity(ctx, 0, notificationIntent, 0); + return PendingIntent.getActivity(ctx, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE); } } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/OvkAPIWrapper.java b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/OvkAPIWrapper.java index c97f141..8ba5be2 100644 --- a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/OvkAPIWrapper.java +++ b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/OvkAPIWrapper.java @@ -4,85 +4,153 @@ import android.content.pm.PackageInfo; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.os.Message; import android.util.Log; -import org.droidparts.util.Strings; - +import java.io.IOException; import java.net.ConnectException; +import java.net.InetSocketAddress; import java.net.ProtocolException; +import java.net.Proxy; import java.net.SocketException; import java.net.SocketTimeoutException; +import java.net.URLEncoder; import java.net.UnknownHostException; +import java.text.ParseException; import java.util.Objects; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import okhttp3.internal.http.StatusLine; import uk.openvk.android.refresh.BuildConfig; import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.api.entities.Error; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.Error; -import uk.openvk.android.refresh.ui.core.activities.AppActivity; -import uk.openvk.android.refresh.ui.core.activities.AuthActivity; -import uk.openvk.android.refresh.ui.core.activities.ConversationActivity; -import uk.openvk.android.refresh.ui.core.activities.FriendsIntentActivity; -import uk.openvk.android.refresh.ui.core.activities.GroupIntentActivity; -import uk.openvk.android.refresh.ui.core.activities.MainSettingsActivity; -import uk.openvk.android.refresh.ui.core.activities.NewPostActivity; -import uk.openvk.android.refresh.ui.core.activities.ProfileIntentActivity; -import uk.openvk.android.refresh.ui.core.activities.QuickSearchActivity; -import uk.openvk.android.refresh.ui.core.activities.WallPostActivity; +import uk.openvk.android.refresh.api.interfaces.OvkAPIListeners; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ +@SuppressWarnings("deprecation") public class OvkAPIWrapper { public String server; private boolean use_https; + private boolean legacy_mode; public boolean proxy_connection; public String proxy_type; private String status; public Error error; private Context ctx; private String access_token; + private OkHttpClient httpClient = null; private boolean logging_enabled = true; // default for beta releases - private String client_name = "openvk_refresh_android"; + private String client_name = "openvk_legacy_android"; + public Handler handler; + OvkAPIListeners apiListeners; - public OvkAPIWrapper(Context ctx) { + + public OvkAPIWrapper(Context ctx, boolean use_https, Handler handler) { if(BuildConfig.BUILD_TYPE.equals("release")) { logging_enabled = false; } + setAPIListeners(); + this.handler = handler; + if(handler == null) { + searchHandler(); + } this.ctx = ctx; + this.use_https = use_https; + this.legacy_mode = legacy_mode; error = new Error(); try { - httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).build(); + Log.v(OvkApplication.API_TAG, "Starting OvkAPIWrapper..."); + if (use_https) { + httpClient = new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS).writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false).build(); + } else { + httpClient = new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS).writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false).followSslRedirects(false).build(); + } } catch (Exception ex) { ex.printStackTrace(); } } + private void setAPIListeners() { + apiListeners = new OvkAPIListeners(); + apiListeners.failListener = new OvkAPIListeners.OnAPIFailListener() { + @Override + public void onAPIFailed(Context ctx, int msg_code, Bundle data) { + Log.e(OvkApplication.API_TAG, + String.format("This is dummy API listener. " + + "\r\nStatus: Failed" + + "\r\nMessage code: %s" + + "\r\nContext class: %s", + msg_code, ctx.getClass().getSimpleName())); + } + }; + apiListeners.successListener = new OvkAPIListeners.OnAPISuccessListener() { + @Override + public void onAPISuccess(Context ctx, int msg_code, Bundle data) { + Log.d(OvkApplication.API_TAG, + String.format("This is dummy API listener. " + + "\r\nStatus: Success" + + "\r\nMessage code: %s" + + "\r\nContext class: %s", + msg_code, ctx.getClass().getSimpleName())); + } + }; + } + + private void searchHandler() { + this.handler = ((NetworkActivity) ctx).handler; + } + + public String getStatus() { + return status; + } + + public Error getError() { + return error; + } + + public void setAccessToken(String token) { + this.access_token = token; + } + public void setProxyConnection(boolean useProxy, String address) { try { if(useProxy) { String[] address_array = address.split(":"); if (address_array.length == 2) { - if (use_https) { - httpClient = new OkHttpClient.Builder() - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .retryOnConnectionFailure(false).build(); - } else { - httpClient = new OkHttpClient.Builder() - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .retryOnConnectionFailure(false) - .followSslRedirects(false).build(); - } + httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false).proxy(new Proxy(Proxy.Type.HTTP, + new InetSocketAddress(address_array[0], + Integer.parseInt(address_array[1])))).build(); + this.proxy_connection = true; } } } catch (Exception ex) { @@ -94,17 +162,15 @@ private String generateUserAgent(Context ctx) { String version_name = ""; String user_agent; try { - PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo(ctx. - getApplicationContext().getPackageName(), 0); + PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo(ctx.getApplicationContext().getPackageName(), 0); version_name = packageInfo.versionName; } catch (Exception e) { OvkApplication app = ((OvkApplication) ctx.getApplicationContext()); version_name = app.version; } finally { - user_agent = String.format("OpenVK Legacy/%s (Android %s; SDK %s; %s; %s %s; %s)", - version_name, - Build.VERSION.RELEASE, Build.VERSION.SDK_INT, Build.SUPPORTED_ABIS[0], - Build.MANUFACTURER, Build.MODEL, System.getProperty("user.language")); + user_agent = String.format("OpenVK Legacy/%s (Android %s; SDK %s; %s; %s %s; %s)", version_name, + Build.VERSION.RELEASE, Build.VERSION.SDK_INT, Build.CPU_ABI, Build.MANUFACTURER, + Build.MODEL, System.getProperty("user.language")); } return user_agent; } @@ -113,6 +179,10 @@ public void setServer(String server) { this.server = server; } + public void requireHTTPS(boolean value) { + this.use_https = value; + } + public void log(boolean value) { this.logging_enabled = value; } @@ -120,9 +190,17 @@ public void log(boolean value) { public void authorize(String username, String password) { error.description = ""; String url; - url = String.format("http://%s/token?username=%s&password=%s&grant_type=password&client_name=%s&2fa_supported=1", - server, Strings.urlEncode(username), Strings.urlEncode(password), client_name); - if(logging_enabled) Log.v("OpenVK API", String.format("Connecting to %s... (Secured)", server)); + if(use_https) { + url = String.format("https://%s/token?username=%s&password=%s&grant_type=password" + + "&client_name=%s&2fa_supported=1", server, URLEncoder.encode(username), + URLEncoder.encode(password), client_name); + if(logging_enabled) Log.d(OvkApplication.API_TAG, String.format("Connecting to %s... (Secured)", server)); + } else { + url = String.format("http://%s/token?username=%s&password=%s&grant_type=password" + + "&client_name=%s&2fa_supported=1", server, URLEncoder.encode(username), + URLEncoder.encode(password), client_name); + if(logging_enabled) Log.d(OvkApplication.API_TAG, String.format("Connecting to %s...", server)); + } final String fUrl = url; Runnable httpRunnable = new Runnable() { private Request request = null; @@ -137,44 +215,80 @@ public void run() throws OutOfMemoryError { .addHeader("User-Agent", generateUserAgent(ctx)).build(); try { Response response = httpClient.newCall(request).execute(); - response_body = Objects.requireNonNull(response.body()).string(); + assert response.body() != null; + response_body = response.body().string(); response_code = response.code(); if (response_body.length() > 0) { if (logging_enabled) - Log.v("OpenVK API", String.format("Connected (%d)", response_code)); + Log.d(OvkApplication.API_TAG, String.format("Connected (%d)", response_code)); if (response_code == 400) { - sendMessage(HandlerMessages.OVKAPI_INVALID_USERNAME_OR_PASSWORD, response_body); + sendMessage(HandlerMessages.INVALID_USERNAME_OR_PASSWORD, response_body); } else if (response_code == 401) { - sendMessage(HandlerMessages.OVKAPI_TWOFACTOR_CODE_REQUIRED, response_body); + sendMessage(HandlerMessages.TWOFACTOR_CODE_REQUIRED, response_body); } else if (response_code == 404) { - sendMessage(HandlerMessages.OVKAPI_NOT_OPENVK_INSTANCE, response_body); + sendMessage(HandlerMessages.NOT_OPENVK_INSTANCE, response_body); } else if (response_code == 200) { - sendMessage(HandlerMessages.OVKAPI_AUTHORIZED, response_body); + if(!(response_body.startsWith("{") && response_body.endsWith("}"))) { + if(response_body.length() > 16) { + throw new java.text.ParseException(String.format("Response data " + + "must be in JSON format only. Start of response: [%s...]", + response_body.replace("\r", "").replace("\n", "").substring(0, 16)), 0); + } else { + throw new java.text.ParseException(String.format("Response data " + + "must be in JSON format only. Start of response: [%s]", + response_body.replace("\r", "").replace("\n", "")), 0); + } + } + sendMessage(HandlerMessages.AUTHORIZED, response_body); } else if (response_code == 502) { - sendMessage(HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE, response_body); + sendMessage(HandlerMessages.INSTANCE_UNAVAILABLE, response_body); } else if (response_code == 503) { - sendMessage(HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE, response_body); + sendMessage(HandlerMessages.INSTANCE_UNAVAILABLE, response_body); } else { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, response_body); + sendMessage(HandlerMessages.UNKNOWN_ERROR, response_body); } + } else if (response_code == 301 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, response_body); + } else if (response_code == 302 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, response_body); } } catch (ProtocolException | UnknownHostException | ConnectException e) { - if (logging_enabled) - Log.e("OpenVK API", String.format("Connection error: %s", e.getMessage())); - error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION, error.description); + if (logging_enabled) { + if (e.getMessage() != null) { + Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); + error.description = e.getMessage(); + } else { + Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getClass().getSimpleName())); + error.description = e.getClass().getSimpleName(); + } + } + sendMessage(HandlerMessages.NO_INTERNET_CONNECTION, error.description); } catch (SocketTimeoutException e) { if (logging_enabled) - Log.e("OpenVK API", String.format("Connection error: %s", e.getMessage())); + Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, error.description); + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, error.description); + } catch (ParseException e) { e.printStackTrace(); + sendMessage(HandlerMessages.NOT_OPENVK_INSTANCE, ""); + } catch (IOException ex) { + if (Objects.requireNonNull(ex.getMessage()).startsWith("Authorization required")) { + response_code = 401; + sendMessage(HandlerMessages.TWOFACTOR_CODE_REQUIRED, response_body); + } else if(ex.getMessage().startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 3); + response_code = Integer.parseInt(code_str); + if(response_code == 400) { + sendMessage(HandlerMessages.INVALID_USERNAME_OR_PASSWORD, response_body); + } + } } catch (Exception e) { e.printStackTrace(); - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, ""); } } catch (Exception ex) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, ""); ex.printStackTrace(); } } @@ -186,15 +300,22 @@ public void run() throws OutOfMemoryError { public void authorize(String username, String password, String code) { error.description = ""; String url; - url = String.format("http://%s" + - "/token?username=%s&password=%s&grant_type=password&code=%s&" + - "client_name=%s&2fa_supported=1", server, Strings.urlEncode(username), - Strings.urlEncode(password), code, client_name); - if(logging_enabled) Log.v("OpenVK API", String.format("Connecting to %s...", server)); + if(use_https) { + url = String.format("https://%s/token?username=%s&password=%s&grant_type=password&code=%s" + + "&client_name=%s&2fa_supported=1", server, URLEncoder.encode(username), + URLEncoder.encode(password), code, client_name); + if(logging_enabled) Log.d(OvkApplication.API_TAG, + String.format("Connecting to %s (Secured)...", server)); + } else { + url = String.format("http://%s/token?username=%s&password=%s&grant_type=password&code=%s" + + "&client_name=%s&2fa_supported=1", server, URLEncoder.encode(username), + URLEncoder.encode(password), code, client_name); + if(logging_enabled) Log.d(OvkApplication.API_TAG, + String.format("Connecting to %s...", server)); + } final String fUrl = url; Runnable httpRunnable = new Runnable() { private Request request = null; - StatusLine statusLine = null; int response_code = 0; private String response_body = ""; @@ -206,48 +327,88 @@ public void run() { .addHeader("User-Agent", generateUserAgent(ctx)).build(); try { Response response = httpClient.newCall(request).execute(); - response_body = Objects.requireNonNull(response.body()).string(); + assert response.body() != null; + response_body = response.body().string(); response_code = response.code(); if (response_body.length() > 0) { if (logging_enabled) - Log.v("OpenVK API", String.format("Connected (%d)", response_code)); + Log.d(OvkApplication.API_TAG, String.format("Connected (%d)", response_code)); if (response_code == 400) { - sendMessage(HandlerMessages.OVKAPI_INVALID_USERNAME_OR_PASSWORD, response_body); + sendMessage(HandlerMessages.INVALID_USERNAME_OR_PASSWORD, response_body); } else if (response_code == 401) { - sendMessage(HandlerMessages.OVKAPI_TWOFACTOR_CODE_REQUIRED, response_body); + sendMessage(HandlerMessages.TWOFACTOR_CODE_REQUIRED, response_body); } else if (response_code == 404) { - sendMessage(HandlerMessages.OVKAPI_NOT_OPENVK_INSTANCE, response_body); + sendMessage(HandlerMessages.NOT_OPENVK_INSTANCE, response_body); } else if (response_code == 200) { - sendMessage(HandlerMessages.OVKAPI_AUTHORIZED, response_body); + if(!(response_body.startsWith("{") && response_body.endsWith("}"))) { + if(response_body.length() > 16) { + throw new java.text.ParseException(String.format("Response data " + + "must be in JSON format only. Start of response: [%s...]", + response_body.substring(0, 16)), 0); + } else { + throw new java.text.ParseException(String.format("Response data " + + "must be in JSON format only. Start of response: [%s]", + response_body), 0); + } + } + sendMessage(HandlerMessages.AUTHORIZED, response_body); + } else if (response_code == 301 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, response_body); + } else if (response_code == 302 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, response_body); } else if (response_code == 503) { - sendMessage(HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE, response_body); + sendMessage(HandlerMessages.INSTANCE_UNAVAILABLE, response_body); } else { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, response_body); + sendMessage(HandlerMessages.UNKNOWN_ERROR, response_body); } } - } catch (ProtocolException | ConnectException - | javax.net.ssl.SSLProtocolException - | UnknownHostException e) { - if (logging_enabled) - Log.e("OpenVK API", String.format("Connection error: %s", e.getMessage())); - error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION, error.description); + } catch (ProtocolException | ConnectException | + javax.net.ssl.SSLProtocolException | UnknownHostException e) { + if (logging_enabled) { + if (e.getMessage() != null) { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); + error.description = e.getMessage(); + } else { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getClass().getSimpleName())); + error.description = e.getClass().getSimpleName(); + } + } + sendMessage(HandlerMessages.NO_INTERNET_CONNECTION, error.description); } catch (SocketTimeoutException e) { if (logging_enabled) - Log.e("OpenVK API", String.format("Connection error: %s", e.getMessage())); + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, error.description); + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, error.description); } catch (javax.net.ssl.SSLException | OutOfMemoryError e) { if (logging_enabled) - Log.e("OpenVK API", String.format("Connection error: %s", e.getMessage())); + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_BROKEN_SSL_CONNECTION, error.description); + sendMessage(HandlerMessages.BROKEN_SSL_CONNECTION, error.description); + } catch (ParseException e) { + e.printStackTrace(); + sendMessage(HandlerMessages.NOT_OPENVK_INSTANCE, ""); + } catch (IOException ex) { + if (Objects.requireNonNull(ex.getMessage()).startsWith("Authorization required")) { + response_code = 401; + sendMessage(HandlerMessages.TWOFACTOR_CODE_REQUIRED, response_body); + } else if(ex.getMessage().startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 3); + response_code = Integer.parseInt(code_str); + if(response_code == 400) { + sendMessage(HandlerMessages.INVALID_USERNAME_OR_PASSWORD, response_body); + } + } } catch (Exception e) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, ""); e.printStackTrace(); } } catch (Exception ex) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, ""); ex.printStackTrace(); } } @@ -259,13 +420,29 @@ public void run() { public void sendAPIMethod(final String method, final String args, final String where) { error.description = ""; String url; - url = String.format("http://%s/method/%s?%s&access_token=%s", server, method, args, access_token); - if(logging_enabled) Log.v("OpenVK API", String.format("Connecting to %s...\r\nMethod: %s" + - "\r\nArguments: %s\r\nWhere: %s", server, method, args, where)); + if(server.length() == 0) { + sendMessage(HandlerMessages.INTERNAL_ERROR, "Instance may not be without address!"); + return; + } + if(use_https) { + url = String.format("https://%s/method/%s?%s&access_token=%s", server, method, args, access_token); + if(logging_enabled) Log.d(OvkApplication.API_TAG, String.format("Connecting to %s (Secured)..." + + "\r\nMethod: %s\r\n" + + "Arguments: %s\r\n" + + "Where: %s", + server, method, args, where)); + } else { + url = String.format("http://%s/method/%s?%s&access_token=%s", server, method, args, access_token); + if(logging_enabled) Log.d(OvkApplication.API_TAG, + String.format("Connecting to %s..." + + "\r\nMethod: %s\r\n" + + "Arguments: %s\r\n" + + "Where: %s", + server, method, args, where)); + } final String fUrl = url; Runnable httpRunnable = new Runnable() { private Request request = null; - StatusLine statusLine = null; int response_code = 0; private String response_body = ""; @@ -277,293 +454,108 @@ public void run() { .addHeader("User-Agent", generateUserAgent(ctx)).build(); try { Response response = httpClient.newCall(request).execute(); - response_body = Objects.requireNonNull(response.body()).string(); + assert response.body() != null; + response_body = response.body().string(); response_code = response.code(); if (response_body.length() > 0) { if (response_code == 200) { - if(logging_enabled) Log.v("OpenVK API", String.format("" + - "Getting response from %s (%s): [%s]", server, response_code, - response_body)); - switch (method) { - case "Account.getProfileInfo": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_PROFILE_INFO, method, - args, response_body); - break; - case "Account.setOnline": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_SET_TO_ONLINE, method, - args, response_body); - break; - case "Account.setOffline": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_SET_TO_OFFLINE, method, - args, response_body); - break; - case "Account.getCounters": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_COUNTERS, method, - args, response_body); - break; - case "Friends.get": - switch (where) { - case "friends_list": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_GET, method, - args, response_body); - break; - case "profile_counter": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_GET_ALT, method, - args, response_body); - break; - case "more_friends": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_GET_MORE, method, - args, response_body); - break; - } - break; - case "Friends.add": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_ADD, method, args, - response_body); - break; - case "Friends.delete": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_DELETE, method, args, - response_body); - break; - case "Friends.areFriends": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_CHECK, method, args, - response_body); - break; - case "Friends.getRequests": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_REQUESTS, method, args, - response_body); - break; - case "Groups.get": - if (where.equals("more_groups")) { - sendMessage(HandlerMessages.OVKAPI_GROUPS_GET_MORE, method, args, - response_body); - } else { - sendMessage(HandlerMessages.OVKAPI_GROUPS_GET, method, args, - response_body); - } - break; - case "Groups.getById": - sendMessage(HandlerMessages.OVKAPI_GROUPS_GET_BY_ID, method, args, - response_body); - break; - case "Groups.search": - sendMessage(HandlerMessages.OVKAPI_GROUPS_SEARCH, method, - response_body); - break; - case "Groups.join": - sendMessage(HandlerMessages.OVKAPI_GROUPS_JOIN, method, - response_body); - break; - case "Groups.leave": - sendMessage(HandlerMessages.OVKAPI_GROUPS_LEAVE, method, - response_body); - break; - case "Likes.add": - sendMessage(HandlerMessages.OVKAPI_LIKES_ADD, method, args, - response_body); - break; - case "Likes.delete": - sendMessage(HandlerMessages.OVKAPI_LIKES_DELETE, method, args, - response_body); - break; - case "Likes.isLiked": - sendMessage(HandlerMessages.OVKAPI_LIKES_CHECK, method, args, - response_body); - break; - case "Messages.getById": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_BY_ID, method, args, - response_body); - break; - case "Messages.send": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_SEND, method, args, - response_body); - break; - case "Messages.delete": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_DELETE, method, args, - response_body); - break; - case "Messages.restore": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_RESTORE, method, args, - response_body); - break; - case "Messages.getConverstaions": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_CONVERSATIONS, method, args, - response_body); - break; - case "Messages.getConverstaionsByID": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_CONVERSATIONS_BY_ID, - method, args, response_body); - break; - case "Messages.getHistory": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_HISTORY, method, args, - response_body); - break; - case "Messages.getLongPollHistory": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_LONGPOLL_HISTORY, - method, args, response_body); - break; - case "Messages.getLongPollServer": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_LONGPOLL_SERVER, - method, args, response_body); - break; - case "Ovk.version": - sendMessage(HandlerMessages.OVKAPI_OVK_VERSION, method, args, - response_body); - break; - case "Ovk.test": - sendMessage(HandlerMessages.OVKAPI_OVK_TEST, method, args, - response_body); - break; - case "Ovk.chickenWings": - sendMessage(HandlerMessages.OVKAPI_OVK_CHICKEN_WINGS, method, args, - response_body); - break; - case "Ovk.aboutInstance": - sendMessage(HandlerMessages.OVKAPI_OVK_ABOUTINSTANCE, method, args, - response_body); - break; - case "Users.getFollowers": - sendMessage(HandlerMessages.OVKAPI_USERS_FOLLOWERS, method, args, - response_body); - break; - case "Users.search": - sendMessage(HandlerMessages.OVKAPI_USERS_SEARCH, method, args, - response_body); - break; - case "Users.get": - switch (where) { - case "profile": - sendMessage(HandlerMessages.OVKAPI_USERS_GET, method, args, - response_body); - break; - case "account_user": - sendMessage(HandlerMessages.OVKAPI_USERS_GET_ALT, method, args, - response_body); - break; - case "peers": - sendMessage(HandlerMessages.OVKAPI_USERS_GET_ALT2, method, args, - response_body); - break; - } - break; - case "Wall.get": - sendMessage(HandlerMessages.OVKAPI_WALL_GET, method, args, - response_body); - break; - case "Wall.getById": - sendMessage(HandlerMessages.OVKAPI_WALL_GET_BY_ID, method, args, - response_body); - break; - case "Wall.post": - sendMessage(HandlerMessages.OVKAPI_WALL_POST, method, args, - response_body); - break; - case "Wall.repost": - sendMessage(HandlerMessages.OVKAPI_WALL_REPOST, method, args, - response_body); - break; - case "Wall.createComment": - sendMessage(HandlerMessages.OVKAPI_WALL_DELETE_COMMENT, method, args, - response_body); - break; - case "Wall.getComment": - sendMessage(HandlerMessages.OVKAPI_WALL_COMMENT, method, args, - response_body); - break; - case "Wall.getComments": - sendMessage(HandlerMessages.OVKAPI_WALL_ALL_COMMENTS, method, args, - response_body); - break; - case "Newsfeed.get": - if (where.equals("more_news")) { - sendMessage(HandlerMessages.OVKAPI_NEWSFEED_GET_MORE, method, args, - response_body); - } else { - sendMessage(HandlerMessages.OVKAPI_NEWSFEED_GET, method, args, - response_body); - } - break; - case "Newsfeed.getGlobal": - if (where.equals("more_news")) { - sendMessage(HandlerMessages.OVKAPI_NEWSFEED_GET_MORE_GLOBAL, - method, args, response_body); - } else { - sendMessage(HandlerMessages.OVKAPI_NEWSFEED_GET_GLOBAL, - method, args, response_body); - } - break; - case "Polls.addVote": - sendMessage(HandlerMessages.OVKAPI_POLL_ADD_VOTE, method, args, - response_body); - break; - case "Polls.deleteVote": - sendMessage(HandlerMessages.OVKAPI_POLL_DELETE_VOTE, method, args, - response_body); - break; - } + if(logging_enabled) Log.d(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s): [%s]", + server, method, response_code, response_body)); + sendMessage(HandlerMessages.PARSE_JSON, method, args, where, response_body); } else if (response_code == 400) { error = new Error(); error.parse(response_body); - if(logging_enabled) Log.v("OpenVK API", - String.format("Getting response from %s (%s): [%s / Error code: %d]", - server, response_code, error.description, error.code)); + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s): [%s / Error code: %d]", + server, method, response_code, error.description, error.code)); if (error.code == 3) { - sendMessage(HandlerMessages.OVKAPI_METHOD_NOT_FOUND, method, args, - error.description); + sendMessage(HandlerMessages.METHOD_NOT_FOUND, method, args, + where, error.description); } else if (error.code == 5) { - sendMessage(HandlerMessages.OVKAPI_INVALID_TOKEN, method, args, + sendMessage(HandlerMessages.INVALID_TOKEN, method, args, where, error.description); } else if (error.code == 15) { - sendMessage(HandlerMessages.OVKAPI_ACCESS_DENIED, method, args, + sendMessage(HandlerMessages.ACCESS_DENIED, method, args, where, error.description); - } else if (error.code == 100) { - sendMessage(HandlerMessages.OVKAPI_INVALID_USAGE, method, args, + } else if (error.code == 10 || error.code == 100) { + sendMessage(HandlerMessages.INVALID_USAGE, method, args, where, error.description); } + } else if (response_code == 301 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, response_body); + } else if (response_code == 302 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, response_body); } else if (response_code == 503) { - sendMessage(HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE, - method, args, response_body); + sendMessage(HandlerMessages.INSTANCE_UNAVAILABLE, method, + args, where, response_body); } else if (response_code >= 500 && response_code <= 526) { - if(logging_enabled) Log.e("OpenVK API", - String.format("Getting response from %s (%s)", - server, response_code)); - sendMessage(HandlerMessages.OVKAPI_INTERNAL_ERROR, method, ""); + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s)", server, method, + response_code)); + sendMessage(HandlerMessages.INTERNAL_ERROR, method, args, where,""); } } } catch (ConnectException | ProtocolException e) { - if(logging_enabled) Log.e("OpenVK API", - String.format("Connection error: %s", e.getMessage())); - error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION, error.description); + if (logging_enabled) { + if (e.getMessage() != null) { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); + error.description = e.getMessage(); + } else { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getClass().getSimpleName())); + error.description = e.getClass().getSimpleName(); + } + } + sendMessage(HandlerMessages.NO_INTERNET_CONNECTION, error.description); } catch (SocketException e) { if(Objects.requireNonNull(e.getMessage()).contains("ETIMEDOUT")) { - if(logging_enabled) Log.e("OpenVK API", + if(logging_enabled) Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage( - HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, method, args, error.description); + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, method, + args, where, error.description); } } catch (SocketTimeoutException e) { - if(logging_enabled) Log.e("OpenVK API", - String.format("Connection error: %s", e.getMessage())); - error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, method, args, error.description); + if (logging_enabled) { + if (e.getMessage() != null) { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); + error.description = e.getMessage(); + } else { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getClass().getSimpleName())); + error.description = e.getClass().getSimpleName(); + } + } + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, method, + args, where, error.description); } catch (UnknownHostException e) { - if(logging_enabled) Log.e("OpenVK API", + if(logging_enabled) Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION, method, args, error.description); + sendMessage(HandlerMessages.NO_INTERNET_CONNECTION, method, + args, where, error.description); } catch(javax.net.ssl.SSLException e) { - if(logging_enabled) Log.e("OpenVK API", + if(logging_enabled) Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_BROKEN_SSL_CONNECTION, error.description); + sendMessage(HandlerMessages.BROKEN_SSL_CONNECTION, error.description); + } catch (IOException ex) { + if (ex.getMessage().startsWith("Authorization required")) { + response_code = 401; + } else if(ex.getMessage().startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 4, ex.getMessage().length() - 1); + response_code = Integer.parseInt(code_str); + } } catch (OutOfMemoryError | Exception e) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, ""); e.printStackTrace(); } } catch (Exception ex) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, ""); ex.printStackTrace(); } } @@ -573,16 +565,24 @@ public void run() { } public void sendAPIMethod(final String method, final String args) { + if(server.length() == 0) { + sendMessage(HandlerMessages.INTERNAL_ERROR, "Instance may not be without address!"); + return; + } error.description = ""; - String url; - url = String.format("http://%s/method/%s?%s&access_token=%s", - server, method, args, access_token); - Log.v("OpenVK API", String.format("Connecting to %s..." + - "\r\nMethod: %s\r\nArguments: %s", server, method, args)); + String url = ""; + if(use_https) { + url = String.format("https://%s/method/%s?%s&access_token=%s", server, method, args, access_token); + Log.d(OvkApplication.API_TAG, String.format("Connecting to %s (Secured)..." + + "\r\nMethod: %s\r\nArguments: %s", server, method, args)); + } else { + url = String.format("http://%s/method/%s?%s&access_token=%s", server, method, args, access_token); + Log.d(OvkApplication.API_TAG, String.format("Connecting to %s..." + + "\r\nMethod: %s\r\nArguments: %s", server, method, args)); + } final String fUrl = url; Runnable httpRunnable = new Runnable() { private Request request = null; - StatusLine statusLine = null; int response_code = 0; private String response_body = ""; @@ -594,254 +594,98 @@ public void run() { .addHeader("User-Agent", generateUserAgent(ctx)).build(); try { Response response = httpClient.newCall(request).execute(); - response_body = Objects.requireNonNull(response.body()).string(); + assert response.body() != null; + response_body = response.body().string(); response_code = response.code(); if (response_body.length() > 0) { if(response_code == 200) { - if(logging_enabled) Log.v("OpenVK API", - String.format("Getting response from %s (%s): [%s]", - server, response_code, response_body)); - switch (method) { - case "Account.getProfileInfo": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_PROFILE_INFO, method, - args, response_body); - break; - case "Account.setOnline": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_SET_TO_ONLINE, method, - args, response_body); - break; - case "Account.setOffline": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_SET_TO_OFFLINE, method, - args, response_body); - break; - case "Account.getCounters": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_COUNTERS, method, - args, response_body); - break; - case "Friends.get": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_GET, method, - args, response_body); - break; - case "Friends.add": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_ADD, method, - args, response_body); - break; - case "Friends.delete": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_DELETE, method, - args, response_body); - break; - case "Friends.areFriends": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_CHECK, method, - args, response_body); - break; - case "Groups.get": - sendMessage(HandlerMessages.OVKAPI_GROUPS_GET, method, - args, response_body); - break; - case "Groups.getById": - sendMessage(HandlerMessages.OVKAPI_GROUPS_GET_BY_ID, method, - args, response_body); - break; - case "Groups.search": - sendMessage(HandlerMessages.OVKAPI_GROUPS_SEARCH, method, - args, response_body); - break; - case "Groups.join": - sendMessage(HandlerMessages.OVKAPI_GROUPS_JOIN, method, - args, response_body); - break; - case "Groups.leave": - sendMessage(HandlerMessages.OVKAPI_GROUPS_LEAVE, method, - args, response_body); - break; - case "Friends.getRequests": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_REQUESTS, method, - args, response_body); - break; - case "Likes.add": - sendMessage(HandlerMessages.OVKAPI_LIKES_ADD, method, - args, response_body); - break; - case "Likes.delete": - sendMessage(HandlerMessages.OVKAPI_LIKES_DELETE, method, - args, response_body); - break; - case "Likes.isLiked": - sendMessage(HandlerMessages.OVKAPI_LIKES_CHECK, method, - args, response_body); - break; - case "Messages.getById": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_BY_ID, method, - args, response_body); - break; - case "Messages.send": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_SEND, method, - args, response_body); - break; - case "Messages.delete": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_DELETE, method, - args, response_body); - break; - case "Messages.restore": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_RESTORE, method, - args, response_body); - break; - case "Messages.getConversations": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_CONVERSATIONS, method, - args, response_body); - break; - case "Messages.getConverstaionsByID": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_CONVERSATIONS_BY_ID, - method, args, response_body); - break; - case "Messages.getHistory": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_HISTORY, - method, args, response_body); - break; - case "Messages.getLongPollHistory": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_LONGPOLL_HISTORY, - method, args, response_body); - break; - case "Messages.getLongPollServer": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_LONGPOLL_SERVER, - method, args, response_body); - break; - case "Ovk.version": - sendMessage(HandlerMessages.OVKAPI_OVK_VERSION, - method, args, response_body); - break; - case "Ovk.test": - sendMessage(HandlerMessages.OVKAPI_OVK_TEST, - method, args, response_body); - break; - case "Ovk.chickenWings": - sendMessage(HandlerMessages.OVKAPI_OVK_CHICKEN_WINGS, - method, args, response_body); - break; - case "Ovk.aboutInstance": - sendMessage(HandlerMessages.OVKAPI_OVK_ABOUTINSTANCE, - method, args, response_body); - break; - case "Users.getFollowers": - sendMessage(HandlerMessages.OVKAPI_USERS_FOLLOWERS, - method, args, response_body); - break; - case "Users.search": - sendMessage(HandlerMessages.OVKAPI_USERS_SEARCH, - method, args, response_body); - break; - case "Users.get": - sendMessage(HandlerMessages.OVKAPI_USERS_GET, - method, args, response_body); - break; - case "Wall.get": - sendMessage(HandlerMessages.OVKAPI_WALL_GET, - method, args, response_body); - break; - case "Wall.getById": - sendMessage(HandlerMessages.OVKAPI_WALL_GET_BY_ID, - method, args, response_body); - break; - case "Wall.post": - sendMessage(HandlerMessages.OVKAPI_WALL_POST, - method, args, response_body); - break; - case "Wall.repost": - sendMessage(HandlerMessages.OVKAPI_WALL_REPOST, - method, args, response_body); - break; - case "Wall.createComment": - sendMessage(HandlerMessages.OVKAPI_WALL_DELETE_COMMENT, - method, args, response_body); - break; - case "Wall.getComment": - sendMessage(HandlerMessages.OVKAPI_WALL_COMMENT, - method, args, response_body); - break; - case "Wall.getComments": - sendMessage(HandlerMessages.OVKAPI_WALL_ALL_COMMENTS, - method, args, response_body); - break; - case "Newsfeed.get": - sendMessage(HandlerMessages.OVKAPI_NEWSFEED_GET, - method, args, response_body); - break; - case "Newsfeed.getGlobal": - sendMessage(HandlerMessages.OVKAPI_NEWSFEED_GET_GLOBAL, - method, args, response_body); - break; - case "Polls.addVote": - sendMessage(HandlerMessages.OVKAPI_POLL_ADD_VOTE, - method, args, response_body); - break; - case "Polls.deleteVote": - sendMessage(HandlerMessages.OVKAPI_POLL_DELETE_VOTE, - method, args, response_body); - break; - } + if(logging_enabled) Log.d(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s): [%s]", + server, method, response_code, response_body)); + sendMessage(HandlerMessages.PARSE_JSON, method, args, response_body); } else if(response_code == 400) { error = new Error(); error.parse(response_body); - if(logging_enabled) Log.v("OpenVK API", - String.format("Getting response from %s (%s): [%s / Error code: %d]", - server, response_code, error.description, error.code)); + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s): [%s / Error code: %d]", + server, method, response_code, error.description, error.code)); if(error.code == 3) { - sendMessage(HandlerMessages.OVKAPI_METHOD_NOT_FOUND, method, args, - error.description); + sendMessage(HandlerMessages.METHOD_NOT_FOUND, method, args, error.description); } else if(error.code == 5) { - sendMessage(HandlerMessages.OVKAPI_INVALID_TOKEN, method, args, - error.description); + sendMessage(HandlerMessages.INVALID_TOKEN, method, args, error.description); } else if (error.code == 15) { - sendMessage(HandlerMessages.OVKAPI_ACCESS_DENIED, method, args, - error.description); - } else if(error.code == 100) { - sendMessage(HandlerMessages.OVKAPI_INVALID_USAGE, method, args, - error.description); + sendMessage(HandlerMessages.ACCESS_DENIED, method, args, error.description); + } else if(error.code == 10 || error.code == 100) { + sendMessage(HandlerMessages.INVALID_USAGE, method, args, error.description); } else if(error.code == 945) { - sendMessage(HandlerMessages.OVKAPI_CHAT_DISABLED, method, args, - error.description); + sendMessage(HandlerMessages.CHAT_DISABLED, method, args, error.description); } + } else if (response_code == 301 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, method, args, response_body); + } else if (response_code == 302 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, method, args, response_body); } else if (response_code == 503) { - sendMessage(HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE, method, args, response_body); - } else if (response_code >= 500 && response_code <= 526) { - if(logging_enabled) Log.e("OpenVK API", - String.format("Getting response from %s (%s)", - server, response_code)); - sendMessage(HandlerMessages.OVKAPI_INTERNAL_ERROR, method, ""); + sendMessage(HandlerMessages.INSTANCE_UNAVAILABLE, method, args, response_body); + } else if (response_code >= 500 && response_code <= 526) { + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s)", + server, method, response_code)); + sendMessage(HandlerMessages.INTERNAL_ERROR, method, args, ""); } - } + }; } catch (ConnectException | ProtocolException | UnknownHostException e) { - if(logging_enabled) Log.e("OpenVK API", - String.format("Connection error: %s", e.getMessage())); + if (logging_enabled) { + if (e.getMessage() != null) { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); + error.description = e.getMessage(); + } else { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getClass().getSimpleName())); + error.description = e.getClass().getSimpleName(); + } + } error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION, method, args, - error.description); + sendMessage(HandlerMessages.NO_INTERNET_CONNECTION, method, args, error.description); } catch (SocketException e) { - if(Objects.requireNonNull(e.getMessage()).contains("ETIMEDOUT")) { - if(logging_enabled) Log.e("OpenVK API", + if(e.getMessage().contains("ETIMEDOUT")) { + if(logging_enabled) Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, method, args, - error.description); + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, method, args, error.description); } } catch (SocketTimeoutException e) { - if(logging_enabled) Log.e("OpenVK API", - String.format("Connection error: %s", e.getMessage())); - error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, method, args, - error.description); + if (logging_enabled) { + if (e.getMessage() != null) { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); + error.description = e.getMessage(); + } else { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getClass().getSimpleName())); + error.description = e.getClass().getSimpleName(); + } + } + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, method, args, error.description); } catch(javax.net.ssl.SSLException e) { - if(logging_enabled) Log.e("OpenVK API", + if(logging_enabled) Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_BROKEN_SSL_CONNECTION, method, - args, error.description); + sendMessage(HandlerMessages.BROKEN_SSL_CONNECTION, method, args, error.description); + } catch (IOException ex) { + if (Objects.requireNonNull(ex.getMessage()).startsWith("Authorization required")) { + response_code = 401; + } else if(ex.getMessage().startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 3); + response_code = Integer.parseInt(code_str); + } } catch (OutOfMemoryError | Exception e) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, method, args, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, method, args, ""); e.printStackTrace(); } } catch (Exception ex) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, method, args, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, method, args, ""); ex.printStackTrace(); } } @@ -851,15 +695,30 @@ public void run() { } public void sendAPIMethod(final String method) { + if(server.length() == 0) { + sendMessage(HandlerMessages.INTERNAL_ERROR, "Instance may not be without address!"); + return; + } error.description = ""; - String url; - url = String.format("http://%s/method/%s?access_token=%s", server, method, access_token); - if(logging_enabled) Log.v("OpenVK API", String.format("Connecting to %s..." + - "\r\nMethod: %s\r\nArguments: [without arguments]", server, method)); + String url = ""; + if(use_https) { + url = String.format("https://%s/method/%s?access_token=%s", server, method, access_token); + if(logging_enabled) Log.d(OvkApplication.API_TAG, + String.format("Connecting to %s (Secured)..." + + "\r\nMethod: %s\r\n" + + "Arguments: [without arguments]", + server, method)); + } else { + url = String.format("http://%s/method/%s?access_token=%s", server, method, access_token); + if(logging_enabled) Log.d(OvkApplication.API_TAG, + String.format("Connecting to %s..." + + "\r\nMethod: %s\r\n" + + "Arguments: [without arguments]", + server, method)); + } final String fUrl = url; Runnable httpRunnable = new Runnable() { private Request request = null; - StatusLine statusLine = null; int response_code = 0; private String response_body = ""; @@ -871,230 +730,125 @@ public void run() { .addHeader("User-Agent", generateUserAgent(ctx)).build(); try { Response response = httpClient.newCall(request).execute(); - response_body = Objects.requireNonNull(response.body()).string(); + assert response.body() != null; + response_body = response.body().string(); response_code = response.code(); if (response_body.length() > 0) { if(response_code == 200) { - if(logging_enabled) Log.v("OpenVK API", String.format("Getting " + - "response from %s (%s): [%s]", server, response_code, response_body)); - switch (method) { - case "Account.getProfileInfo": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_PROFILE_INFO, method, - response_body); - break; - case "Account.setOnline": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_SET_TO_ONLINE, method, - response_body); - break; - case "Account.setOffline": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_SET_TO_OFFLINE, method, - response_body); - break; - case "Account.getCounters": - sendMessage(HandlerMessages.OVKAPI_ACCOUNT_COUNTERS, method, - response_body); - break; - case "Friends.get": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_GET, method, - response_body); - break; - case "Friends.add": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_ADD, method, - response_body); - break; - case "Friends.delete": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_DELETE, method, - response_body); - break; - case "Friends.areFriends": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_CHECK, method, - response_body); - break; - case "Friends.getRequests": - sendMessage(HandlerMessages.OVKAPI_FRIENDS_REQUESTS, method, - response_body); - break; - case "Groups.get": - sendMessage(HandlerMessages.OVKAPI_GROUPS_GET, method, - response_body); - break; - case "Groups.getById": - sendMessage(HandlerMessages.OVKAPI_GROUPS_GET_BY_ID, method, - response_body); - break; - case "Groups.search": - sendMessage(HandlerMessages.OVKAPI_GROUPS_SEARCH, method, - response_body); - break; - case "Groups.join": - sendMessage(HandlerMessages.OVKAPI_GROUPS_JOIN, method, - response_body); - break; - case "Groups.leave": - sendMessage(HandlerMessages.OVKAPI_GROUPS_LEAVE, method, - response_body); - break; - case "Likes.add": - sendMessage(HandlerMessages.OVKAPI_LIKES_ADD, method, - response_body); - break; - case "Likes.delete": - sendMessage(HandlerMessages.OVKAPI_LIKES_DELETE, method, - response_body); - break; - case "Likes.isLiked": - sendMessage(HandlerMessages.OVKAPI_LIKES_CHECK, method, - response_body); - break; - case "Messages.getById": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_BY_ID, method, - response_body); - break; - case "Messages.send": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_SEND, method, - response_body); - break; - case "Messages.delete": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_DELETE, method, - response_body); - break; - case "Messages.restore": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_RESTORE, method, - response_body); - break; - case "Messages.getConverstaions": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_CONVERSATIONS, method, - response_body); - break; - case "Messages.getConverstaionsByID": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_CONVERSATIONS_BY_ID, - method, response_body); - break; - case "Messages.getHistory": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_HISTORY, - method, response_body); - break; - case "Messages.getLongPollHistory": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_LONGPOLL_HISTORY, - method, response_body); - break; - case "Messages.getLongPollServer": - sendMessage(HandlerMessages.OVKAPI_MESSAGES_GET_LONGPOLL_SERVER, - method, response_body); - break; - case "Ovk.version": - sendMessage(HandlerMessages.OVKAPI_OVK_VERSION, method, response_body); - break; - case "Ovk.test": - sendMessage(HandlerMessages.OVKAPI_OVK_TEST, method, response_body); - break; - case "Ovk.chickenWings": - sendMessage(HandlerMessages.OVKAPI_OVK_CHICKEN_WINGS, method, response_body); - break; - case "Ovk.aboutInstance": - sendMessage(HandlerMessages.OVKAPI_OVK_ABOUTINSTANCE, method, response_body); - break; - case "Users.getFollowers": - sendMessage(HandlerMessages.OVKAPI_USERS_FOLLOWERS, method, response_body); - break; - case "Users.search": - sendMessage(HandlerMessages.OVKAPI_USERS_SEARCH, method, response_body); - break; - case "Users.get": - sendMessage(HandlerMessages.OVKAPI_USERS_GET, method, response_body); - break; - case "Wall.get": - sendMessage(HandlerMessages.OVKAPI_WALL_GET, method, response_body); - break; - case "Wall.getById": - sendMessage(HandlerMessages.OVKAPI_WALL_GET_BY_ID, method, response_body); - break; - case "Wall.post": - sendMessage(HandlerMessages.OVKAPI_WALL_POST, method, response_body); - break; - case "Wall.repost": - sendMessage(HandlerMessages.OVKAPI_WALL_REPOST, method, response_body); - break; - case "Wall.createComment": - sendMessage(HandlerMessages.OVKAPI_WALL_DELETE_COMMENT, method, response_body); - break; - case "Wall.getComment": - sendMessage(HandlerMessages.OVKAPI_WALL_COMMENT, method, response_body); - break; - case "Wall.getComments": - sendMessage(HandlerMessages.OVKAPI_WALL_ALL_COMMENTS, method, response_body); - break; - case "Newsfeed.get": - sendMessage(HandlerMessages.OVKAPI_NEWSFEED_GET, method, response_body); - break; - case "Newsfeed.getGlobal": - sendMessage(HandlerMessages.OVKAPI_NEWSFEED_GET_GLOBAL, method, response_body); - break; - case "Polls.addVote": - sendMessage(HandlerMessages.OVKAPI_POLL_ADD_VOTE, method, response_body); - break; - case "Polls.deleteVote": - sendMessage(HandlerMessages.OVKAPI_POLL_DELETE_VOTE, method, response_body); - break; - } + if(logging_enabled) Log.d(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s):\r\n[%s]", + server, method, response_code, response_body)); + sendMessage(HandlerMessages.PARSE_JSON, method, response_body); } else if(response_code == 400) { error = new Error(); error.parse(response_body); - if(logging_enabled) Log.v("OpenVK API", - String.format("Getting response from %s (%s): [%s / Error code: %d]", - server, response_code, error.description, error.code)); + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s): [%s / Error code: %d]", + server, method, response_code, error.description, error.code)); if(error.code == 3) { - sendMessage(HandlerMessages.OVKAPI_METHOD_NOT_FOUND, method, error.description); + sendMessage(HandlerMessages.METHOD_NOT_FOUND, method, error.description); } else if(error.code == 5) { - sendMessage(HandlerMessages.OVKAPI_INVALID_TOKEN, method, error.description); + sendMessage(HandlerMessages.INVALID_TOKEN, method, error.description); } else if (error.code == 15) { - sendMessage(HandlerMessages.OVKAPI_ACCESS_DENIED, method, error.description); - } else if(error.code == 100) { - sendMessage(HandlerMessages.OVKAPI_INVALID_USAGE, method, error.description); + sendMessage(HandlerMessages.ACCESS_DENIED, method, error.description); + } else if (error.code == 18) { + sendMessage(HandlerMessages.BANNED_ACCOUNT, method, error.description); + } else if (error.code == 10 || error.code == 100) { + sendMessage(HandlerMessages.INVALID_USAGE, method, error.description); } else if(error.code == 945) { - sendMessage(HandlerMessages.OVKAPI_CHAT_DISABLED, method, error.description); + sendMessage(HandlerMessages.CHAT_DISABLED, method, error.description); } + } else if (response_code == 301 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, method, response_body); + } else if (response_code == 302 && !use_https) { + sendMessage(HandlerMessages.INTERNAL_ERROR, method, response_body); } else if (response_code == 503) { - sendMessage(HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE, method, response_body); - } else if (response_code >= 500 && response_code <= 526) { - Log.e("OpenVK API", String.format("Getting response from %s (%s)", server, response_code)); - sendMessage(HandlerMessages.OVKAPI_INTERNAL_ERROR, method, ""); + sendMessage(HandlerMessages.INSTANCE_UNAVAILABLE, method, response_body); + } else if (response_code >= 500 && response_code <= 526) { + Log.e(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s)", server, + method, response_code)); + sendMessage(HandlerMessages.INTERNAL_ERROR, method, ""); } } } catch (ConnectException | ProtocolException e) { - if(logging_enabled) Log.e("OpenVK API", String.format("Connection error:" + - " %s", e.getMessage())); + if (logging_enabled) { + if (e.getMessage() != null) { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); + error.description = e.getMessage(); + } else { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getClass().getSimpleName())); + error.description = e.getClass().getSimpleName(); + } + } error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION, error.description); + sendMessage(HandlerMessages.NO_INTERNET_CONNECTION, method, error.description); } catch (SocketException e) { - if(Objects.requireNonNull(e.getMessage()).contains("ETIMEDOUT")) { - if(logging_enabled) Log.e("OpenVK API", String.format("Connection error:" + - " %s", e.getMessage())); + if(e.getMessage().contains("ETIMEDOUT")) { + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, method, error.description); + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, method, error.description); } } catch (SocketTimeoutException e) { - if(logging_enabled) Log.e("OpenVK API", String.format("Connection error:" + - " %s", e.getMessage())); - error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, method, error.description); + if (logging_enabled) { + if (e.getMessage() != null) { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); + error.description = e.getMessage(); + } else { + Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getClass().getSimpleName())); + error.description = e.getClass().getSimpleName(); + } + } + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, method, error.description); } catch (UnknownHostException e) { - if(logging_enabled) Log.e("OpenVK API", String.format("Connection error:" + - " %s", e.getMessage())); + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION, method, error.description); + sendMessage(HandlerMessages.NO_INTERNET_CONNECTION, method, error.description); } catch(javax.net.ssl.SSLException e) { - if(logging_enabled) Log.e("OpenVK API", String.format("Connection error:" + - " %s", e.getMessage())); + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_BROKEN_SSL_CONNECTION, error.description); + sendMessage(HandlerMessages.BROKEN_SSL_CONNECTION, method, error.description); + } catch (IOException ex) { + if (Objects.requireNonNull(ex.getMessage()).startsWith("Authorization required")) { + response_code = 401; + } else if(ex.getMessage().startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 3); + response_code = Integer.parseInt(code_str); + if (response_code == 400) { + error = new Error(); + error.parse(response_body); + if(logging_enabled) Log.e(OvkApplication.API_TAG, + String.format("Getting response from %s (%s, %s): [%s / Error code: %d]", + server, method, response_code, error.description, error.code)); + if (error.code == 3) { + sendMessage(HandlerMessages.METHOD_NOT_FOUND, method, error.description); + } else if (error.code == 5) { + sendMessage(HandlerMessages.INVALID_TOKEN, method, error.description); + } else if (error.code == 15) { + sendMessage(HandlerMessages.ACCESS_DENIED, method, error.description); + } else if (error.code == 10 || error.code == 100) { + sendMessage(HandlerMessages.INVALID_USAGE, method, error.description); + } + } + } } catch (Exception e) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, ""); + if(Objects.equals(e.getMessage(), "Scheme 'https' not registered.")) { + Log.e(OvkApplication.API_TAG, String.format("WTF? %s", fUrl)); + } + sendMessage(HandlerMessages.UNKNOWN_ERROR, method, ""); e.printStackTrace(); error.description = e.getMessage(); } } catch (Exception ex) { - sendMessage(HandlerMessages.OVKAPI_UNKNOWN_ERROR, ""); + sendMessage(HandlerMessages.UNKNOWN_ERROR, method, ""); ex.printStackTrace(); } } @@ -1103,105 +857,123 @@ public void run() { thread.start(); } - private void sendMessage(int message, String response) { - Message msg = new Message(); - msg.what = message; - Bundle bundle = new Bundle(); - bundle.putString("response", response); - msg.setData(bundle); - if(ctx.getClass().getSimpleName().equals("AuthActivity")) { - ((AuthActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("ProfileIntentActivity")) { - ((ProfileIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("FriendsIntentActivity")) { - ((FriendsIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("GroupIntentActivity")) { - ((GroupIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("ConversationActivity")) { - ((ConversationActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("NewPostActivity")) { - ((NewPostActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("QuickSearchActivity")) { - ((QuickSearchActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("WallPostActivity")) { - ((WallPostActivity) ctx).handler.sendMessage(msg); + private void sendMessage(final int message, String response) { + try { + Message msg = new Message(); + msg.what = message; + final Bundle bundle = new Bundle(); + bundle.putString("response", response); + msg.setData(bundle); + + handler.post(new Runnable() { + @Override + public void run() { + if(message < 0) { + apiListeners.failListener.onAPIFailed(ctx, message, bundle); + } else { + apiListeners.successListener.onAPISuccess(ctx, message, bundle); + } + } + }); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private void sendMessage(final int message, String method, String response) { + try { + Message msg = new Message(); + msg.what = message; + final Bundle bundle = new Bundle(); + bundle.putString("response", response); + bundle.putString("method", method); + msg.setData(bundle); + handler.post(new Runnable() { + @Override + public void run() { + if(apiListeners != null) { + if (message < 0) { + apiListeners.failListener.onAPIFailed(ctx, message, bundle); + } else { + apiListeners.successListener.onAPISuccess(ctx, message, bundle); + } + } else { + Log.e(OvkApplication.API_TAG, + "API Listener not found! Handling is not possible."); + } + } + }); + } catch (Exception ex) { + ex.printStackTrace(); } } - private void sendMessage(int message, String method, String response) { - Message msg = new Message(); - msg.what = message; - Bundle bundle = new Bundle(); - bundle.putString("response", response); - bundle.putString("method", method); - msg.setData(bundle); - if(ctx.getClass().getSimpleName().equals("AuthActivity")) { - ((AuthActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("ProfileIntentActivity")) { - ((ProfileIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("FriendsIntentActivity")) { - ((FriendsIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("GroupIntentActivity")) { - ((GroupIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("MainSettingsActivity")) { - ((MainSettingsActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("ConversationActivity")) { - ((ConversationActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("NewPostActivity")) { - ((NewPostActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("QuickSearchActivity")) { - ((QuickSearchActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("WallPostActivity")) { - ((WallPostActivity) ctx).handler.sendMessage(msg); + private void sendMessage(final int message, String method, String args, String response) { + try { + Message msg = new Message(); + msg.what = message; + final Bundle bundle = new Bundle(); + bundle.putString("response", response); + bundle.putString("method", method); + bundle.putString("args", args); + msg.setData(bundle); + handler.post(new Runnable() { + @Override + public void run() { + if(message < 0) { + apiListeners.failListener.onAPIFailed(ctx, message, bundle); + } else { + apiListeners.successListener.onAPISuccess(ctx, message, bundle); + } + } + }); + } catch (Exception ex) { + ex.printStackTrace(); } } - private void sendMessage(int message, String method, String args, String response) { - Message msg = new Message(); - msg.what = message; - Bundle bundle = new Bundle(); - bundle.putString("response", response); - bundle.putString("method", method); - bundle.putString("args", args); - msg.setData(bundle); - if(ctx.getClass().getSimpleName().equals("AuthActivity")) { - ((AuthActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("ProfileIntentActivity")) { - ((ProfileIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("GroupIntentActivity")) { - ((GroupIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("FriendsIntentActivity")) { - ((FriendsIntentActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("MainSettingsActivity")) { - ((MainSettingsActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("ConversationActivity")) { - ((ConversationActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("NewPostActivity")) { - ((NewPostActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("QuickSearchActivity")) { - ((QuickSearchActivity) ctx).handler.sendMessage(msg); - } else if(ctx.getClass().getSimpleName().equals("WallPostActivity")) { - ((WallPostActivity) ctx).handler.sendMessage(msg); + private void sendMessage(final int message, String method, String args, String where, String response) { + try { + Message msg = new Message(); + msg.what = message; + final Bundle bundle = new Bundle(); + bundle.putString("response", response); + bundle.putString("method", method); + bundle.putString("args", args); + bundle.putString("where", where); + msg.setData(bundle); + handler.post(new Runnable() { + @Override + public void run() { + if(message < 0) { + apiListeners.failListener.onAPIFailed(ctx, message, bundle); + } else { + apiListeners.successListener.onAPISuccess(ctx, message, bundle); + } + } + }); + } catch (Exception ex) { + ex.printStackTrace(); } } public void checkHTTPS() { - httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS).followRedirects(false) - .followSslRedirects(true).build(); - String url; + OkHttpClient httpClient = null; + if (use_https) + httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS).followRedirects(false) + .followSslRedirects(true).build(); + else + httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS).followRedirects(false) + .followSslRedirects(false).build(); + String url = ""; url = String.format("http://%s", server); - if(logging_enabled) Log.v("OpenVK API", String.format("Checking %s...", server)); + if(logging_enabled) Log.e(OvkApplication.API_TAG, String.format("Checking %s...", server)); final String fUrl = url; + final OkHttpClient finalHttpClient = httpClient; Runnable httpRunnable = new Runnable() { private Request request = null; - StatusLine statusLine = null; int response_code = 0; private String response_body = ""; @@ -1211,26 +983,32 @@ public void run() { .url(fUrl) .build(); try { - Response response = httpClient.newCall(request).execute(); - response_body = Objects.requireNonNull(response.body()).string(); + Response response = finalHttpClient.newCall(request).execute(); + assert response.body() != null; + response_body = response.body().string(); response_code = response.code(); if(response_code == 200) { - sendMessage(HandlerMessages.OVKAPI_OVK_CHECK_HTTP, response_body); + sendMessage(HandlerMessages.OVK_CHECK_HTTP, response_body); } else if(response_code == 301) { - sendMessage(HandlerMessages.OVKAPI_OVK_CHECK_HTTPS, response_body); + sendMessage(HandlerMessages.OVK_CHECK_HTTPS, response_body); } - httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).build(); } catch (SocketTimeoutException e) { - if(logging_enabled) Log.e("OpenVK API", String.format("Connection error: %s", - e.getMessage())); + if(logging_enabled) Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_CONNECTION_TIMEOUT, error.description); + sendMessage(HandlerMessages.CONNECTION_TIMEOUT, error.description); } catch (UnknownHostException e) { - if(logging_enabled) Log.e("OpenVK API", String.format("Connection error: %s", - e.getMessage())); + if(logging_enabled) Log.e(OvkApplication.API_TAG, String.format("Connection error: %s", e.getMessage())); error.description = e.getMessage(); - sendMessage(HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION, error.description); + sendMessage(HandlerMessages.NO_INTERNET_CONNECTION, error.description); + } catch (IOException ex) { + if(Objects.requireNonNull(ex.getMessage()).startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 3); + response_code = Integer.parseInt(code_str); + if(response_code == 301) { + sendMessage(HandlerMessages.OVK_CHECK_HTTPS, ""); + } + } } catch (Exception e) { e.printStackTrace(); } @@ -1240,16 +1018,7 @@ public void run() { thread.start(); } - public String getStatus() { - return status; - } - - public Error getError() { - return error; - } - - public void setAccessToken(String token) { - this.access_token = token; + public void setAPIListeners(OvkAPIListeners apiListeners) { + this.apiListeners = apiListeners; } - } diff --git a/app/src/main/java/uk/openvk/android/refresh/api/wrappers/UploadManager.java b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/UploadManager.java new file mode 100644 index 0000000..37d1574 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/api/wrappers/UploadManager.java @@ -0,0 +1,321 @@ +package uk.openvk.android.refresh.api.wrappers; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import okhttp3.Headers; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import uk.openvk.android.refresh.BuildConfig; +import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.api.TrackingRequestBody; +import uk.openvk.android.refresh.api.attachments.PhotoAttachment; +import uk.openvk.android.refresh.api.enumerations.HandlerMessages; +import uk.openvk.android.refresh.api.interfaces.OvkAPIListeners; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ + +@SuppressWarnings({"ResultOfMethodCallIgnored", "StatementWithEmptyBody", "ConstantConditions"}) +public class UploadManager { + + public String server; + public boolean use_https; + public boolean legacy_mode; + private Context ctx; + public ArrayList photoAttachments; + private boolean logging_enabled = true; // default for beta releases + + private OkHttpClient httpClient = null; + private boolean forceCaching; + private String instance; + private Handler handler; + private OvkAPIListeners apiListeners; + + public UploadManager(Context ctx, boolean use_https, Handler handler) { + this.handler = handler; + apiListeners = new OvkAPIListeners(); + if(handler == null) { + searchHandler(); + } + this.ctx = ctx; + this.use_https = use_https; + this.legacy_mode = legacy_mode; + if(BuildConfig.BUILD_TYPE.equals("release")) { + logging_enabled = false; + } + try { + Log.v(OvkApplication.UL_TAG, "Starting UploadManager..."); + SSLContext sslContext = null; + try { + sslContext = SSLContext.getInstance("SSL"); + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @SuppressLint("TrustAllX509TrustManager") + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] chain, + String authType) { + } + + @SuppressLint("TrustAllX509TrustManager") + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, + String authType) { + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[]{}; + } + } + }; + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + javax.net.ssl.SSLSocketFactory ssf = (javax.net.ssl.SSLSocketFactory) + sslContext.getSocketFactory(); + httpClient = new OkHttpClient.Builder() + .sslSocketFactory(sslContext.getSocketFactory()) + .connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false) + .build(); + } catch (Exception e) { + httpClient = new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false) + .build(); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void setInstance(String instance) { + this.instance = instance; + } + + public void setForceCaching(boolean value) { + forceCaching = value; + } + + public void setProxyConnection(boolean useProxy, String address) { + try { + if(useProxy) { + String[] address_array = address.split(":"); + if (address_array.length == 2) { + httpClient = new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS + ).readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false) + .proxy(new Proxy(Proxy.Type.HTTP, + new InetSocketAddress(address_array[0], + Integer.parseInt(address_array[1])))) + .build(); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private String generateUserAgent(Context ctx) { + String version_name = ""; + String user_agent = ""; + try { + PackageInfo packageInfo = ctx.getPackageManager() + .getPackageInfo(ctx.getApplicationContext().getPackageName(), 0); + version_name = packageInfo.versionName; + } catch (Exception e) { + OvkApplication app = ((OvkApplication) ctx.getApplicationContext()); + version_name = app.version; + } finally { + user_agent = String.format("OpenVK Legacy/%s (Android %s; SDK %s; %s; %s %s; %s)", version_name, + Build.VERSION.RELEASE, Build.VERSION.SDK_INT, Build.CPU_ABI, Build.MANUFACTURER, + Build.MODEL, System.getProperty("user.language")); + } + return user_agent; + } + + + public void uploadFile(final String address, final File file, final String where) { + if (file == null) { + Log.e(OvkApplication.UL_TAG, "File is empty. Upload canceled."); + return; + } + Log.v(OvkApplication.UL_TAG, String.format("Uploading file to %s...", address)); + final File file_f = file; + Runnable httpRunnable = new Runnable() { + private Request request = null; + int response_code = 0; + private String response_body = ""; + + @Override + public void run() { + try { + String mime = "application/octet-stream"; + if (file_f.getName().endsWith(".jpeg") || file_f.getName().endsWith(".jpg")) { + mime = "image/jpeg"; + } else if (file_f.getName().endsWith(".png")) { + mime = "image/png"; + } else if (file_f.getName().endsWith(".gif")) { + mime = "image/gif"; + } + String short_address = address; + if(address.length() > 50) { + short_address = address.substring(0, 49); + } + MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); + builder.addPart( + Headers.of( + "Content-Disposition", + "form-data; name=\"photo\"; filename=\"" + file.getName() + "\""), + new TrackingRequestBody(file_f, mime, + new TrackingRequestBody.LoadTrackListener() { + @Override + public void onLoad(long position, long max) { + if ((max >= 1048576L && position % 4096 == 0)) { + updateLoadProgress(file_f.getName(), address, position, max); + } else if(max >= 8192L && position % 64 == 0) { + updateLoadProgress(file_f.getName(), address, position, max); + } else if(max < 8192L) { + updateLoadProgress(file_f.getName(), address, position, max); + } else if(position == max) { + updateLoadProgress(file_f.getName(), address, position, max); + } + } + } + ) + ); + + RequestBody requestBody = builder.build(); + Request request = new Request.Builder() + .addHeader("Content-Type", "multipart/form-data") + .url(address) + .post(requestBody) + .addHeader("User-Agent", generateUserAgent(ctx)) + .build(); + if (logging_enabled) Log.d(OvkApplication.UL_TAG, + String.format("Uploading to %s... (%d kB)\r\nHeaders: %s", + short_address, file_f.length() / 1024, request.headers() + .toMultimap())); + Response response = httpClient.newCall(request).execute(); + response_body = response.body().string(); + response_code = response.code(); + if (response_code == 202) { + Log.v(OvkApplication.UL_TAG, "Uploaded!"); + if(logging_enabled) Log.d(OvkApplication.UL_TAG, + String.format("Getting response from %s (%s): [%s]", + short_address, response_code, response_body)); + sendMessage(HandlerMessages.UPLOADED_SUCCESSFULLY, file_f.getName(), response_body); + } else { + if(logging_enabled) Log.e(OvkApplication.UL_TAG, + String.format("Getting response from %s (%s): [%s]", + short_address, response_code, response_body)); + sendMessage(HandlerMessages.UPLOAD_ERROR, file_f.getName(), ""); + } + } catch (IOException ex) { + ex.printStackTrace(); + if (ex.getMessage().startsWith("Authorization required")) { + response_code = 401; + } else if(ex.getMessage().startsWith("Expected status code 2xx")) { + String code_str = ex.getMessage().substring + (ex.getMessage().length() - 3); + response_code = Integer.parseInt(code_str); + if(logging_enabled) Log.e(OvkApplication.UL_TAG, + String.format("Getting response from %s (%s)", + address, response_code)); + } + } catch (Exception e) { + sendMessage(HandlerMessages.UPLOAD_ERROR, file_f.getName(), ""); + } + } + }; + Thread thread = new Thread(httpRunnable); + thread.start(); + } + + private void sendMessage(final int message, String filename, String response) { + Message msg = new Message(); + msg.what = message; + final Bundle bundle = new Bundle(); + bundle.putString("filename", filename); + bundle.putString("response", response); + msg.setData(bundle); + handler.post(new Runnable() { + @Override + public void run() { + if(message < 0) { + apiListeners.failListener.onAPIFailed(ctx, message, bundle); + } else { + apiListeners.successListener.onAPISuccess(ctx, message, bundle); + } + } + }); + } + + + public void updateLoadProgress(String filename, String url, final long position, final long length) { + Message msg = new Message(); + msg.what = HandlerMessages.UPLOAD_PROGRESS; + final Bundle bundle = new Bundle(); + bundle.putString("filename", filename); + bundle.putString("url", url); + bundle.putLong("position", position); + bundle.putLong("length", length); + msg.setData(bundle); + handler.post(new Runnable() { + @Override + public void run() { + apiListeners.processListener.onAPIProcess(ctx, bundle, position, length); + } + }); + } + + private void searchHandler() { + if(ctx instanceof NetworkActivity) { + this.handler = ((NetworkActivity) ctx).handler; + } + } + + public void setAPIListeners(OvkAPIListeners apiListeners) { + this.apiListeners = apiListeners; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/longpoll_api/MessageEvent.java b/app/src/main/java/uk/openvk/android/refresh/longpoll_api/MessageEvent.java index 2f00994..76599f1 100644 --- a/app/src/main/java/uk/openvk/android/refresh/longpoll_api/MessageEvent.java +++ b/app/src/main/java/uk/openvk/android/refresh/longpoll_api/MessageEvent.java @@ -5,9 +5,21 @@ import uk.openvk.android.refresh.api.wrappers.JSONParser; -/** - * Created by Dmitry on 14.10.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class MessageEvent { public int event_type; diff --git a/app/src/main/java/uk/openvk/android/refresh/longpoll_api/wrappers/LongPollWrapper.java b/app/src/main/java/uk/openvk/android/refresh/longpoll_api/wrappers/LongPollWrapper.java index 42694fa..85f04b5 100644 --- a/app/src/main/java/uk/openvk/android/refresh/longpoll_api/wrappers/LongPollWrapper.java +++ b/app/src/main/java/uk/openvk/android/refresh/longpoll_api/wrappers/LongPollWrapper.java @@ -4,6 +4,7 @@ import android.content.Intent; import android.content.pm.PackageInfo; import android.os.Build; +import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; @@ -22,28 +23,34 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import okhttp3.internal.http.StatusLine; import uk.openvk.android.refresh.OvkApplication; -//import uk.openvk.android.refresh.user_interface.core.activities.ConversationActivity; -//import uk.openvk.android.refresh.user_interface.core.activities.FriendsIntentActivity; -//import uk.openvk.android.refresh.user_interface.core.activities.GroupIntentActivity; -//import uk.openvk.android.refresh.user_interface.core.activities.MainSettingsActivity; -//import uk.openvk.android.refresh.user_interface.core.activities.NewPostActivity; -//import uk.openvk.android.refresh.user_interface.core.activities.ProfileIntentActivity; -//import uk.openvk.android.refresh.user_interface.core.activities.QuickSearchActivity; -//import uk.openvk.android.refresh.user_interface.core.activities.WallPostActivity; +import uk.openvk.android.refresh.api.enumerations.HandlerMessages; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -/** - * Created by Dmitry on 29.09.2022. - */ +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-legacy + **/ + +@SuppressWarnings("BusyWait") public class LongPollWrapper { public String server; public boolean use_https; public boolean legacy_mode; private String status; - private uk.openvk.android.refresh.api.models.Error error; + private uk.openvk.android.refresh.api.entities.Error error; private Context ctx; private Handler handler; private String access_token; @@ -56,25 +63,24 @@ public class LongPollWrapper { public LongPollWrapper(Context ctx, boolean use_https) { this.ctx = ctx; - this.use_https = use_https; - httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).build(); + httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS).build(); } private String generateUserAgent(Context ctx) { String version_name = ""; String user_agent = ""; try { - PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo( - ctx.getApplicationContext().getPackageName(), 0); + PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo(ctx.getApplicationContext().getPackageName(), 0); version_name = packageInfo.versionName; } catch (Exception e) { OvkApplication app = ((OvkApplication) ctx.getApplicationContext()); version_name = app.version; } finally { - user_agent = String.format("OpenVK Refresh/%s (Android %s; SDK %s; %s; %s %s; %s)", version_name, - Build.VERSION.RELEASE, Build.VERSION.SDK_INT, Build.SUPPORTED_ABIS[0], - Build.MANUFACTURER, Build.MODEL, System.getProperty("user.language")); + user_agent = String.format("OpenVK Legacy/%s (Android %s; SDK %s; %s; %s %s; %s)", version_name, + Build.VERSION.RELEASE, Build.VERSION.SDK_INT, Build.CPU_ABI, Build.MANUFACTURER, + Build.MODEL, System.getProperty("user.language")); } return user_agent; } @@ -95,13 +101,12 @@ public void longPoll(String lp_server, String key, int ts) { this.server = lp_server; String url = ""; url = String.format("%s?act=a_check&key=%s&ts=%s&wait=15", lp_server, key, ts); - Log.v("OpenVK LPW", String.format("Activating LongPoll via %s...", lp_server)); + Log.v(OvkApplication.LP_TAG, String.format("Activating LongPoll via %s...", lp_server)); final String fUrl = url; isActivated = true; Thread thread = null; Runnable longPollRunnable = new Runnable() { private Request request = null; - StatusLine statusLine = null; int response_code = 0; private String response_body = ""; @@ -112,47 +117,66 @@ public void run() { .build(); try { if(isActivated) { - Log.v("OpenVK LPW", String.format("LongPoll activated.")); + Log.v(OvkApplication.LP_TAG, "LongPoll activated."); } while(isActivated) { Response response = httpClient.newCall(request).execute(); + assert response.body() != null; response_body = response.body().string(); response_code = response.code(); if (response_code == 200) { - if(logging_enabled) Log.v("OpenVK LPW", - String.format("Getting response from %s (%s): [%s]", - server, response_code, response_body)); - sendLongPollMessageToActivity(response_body); + if(logging_enabled && + ((response_body.startsWith("[") && response_body.endsWith("]")) + || (response_body.startsWith("{") && response_body.endsWith("}")))) { + Log.v(OvkApplication.LP_TAG, + String.format("Getting response from %s (%s): [%s]", server, + response_code, response_body)); + sendLongPollMessageToActivity(response_body); + Thread.sleep(5000); + } else { + Log.v(OvkApplication.LP_TAG, + String.format("Getting response from %s (%s): Invalid JSON data", server, + response_code)); + sendLongPollMessageToActivity(response_body); + Thread.sleep(60000); + } + } else if(response_code >= 400 && response_code <= 528) { + if(logging_enabled) Log.e(OvkApplication.LP_TAG, + String.format("Getting response from %s (%s)", server, + response_code)); + if(logging_enabled) Log.v(OvkApplication.LP_TAG, "Retrying in 60 seconds..."); + Thread.sleep(60000); } else { - if(logging_enabled) Log.v("OpenVK LPW", - String.format("Getting response from %s (%s)", server, response_code)); + if(logging_enabled) Log.e(OvkApplication.LP_TAG, + String.format("Getting response from %s (%s)", server, + response_code)); + Thread.sleep(5000); } - Thread.sleep(2000); + } } catch(ConnectException | SocketTimeoutException | UnknownHostException ex) { - if(logging_enabled) Log.v("OpenVK LPW", String.format("Connection error: %s", - ex.getMessage())); + if(logging_enabled) Log.v(OvkApplication.LP_TAG, String.format("Connection error: %s", ex.getMessage())); try { - if(logging_enabled) Log.v("OpenVK LPW", "Retrying in 60 seconds..."); + if(logging_enabled) Log.v(OvkApplication.LP_TAG, "Retrying in 60 seconds..."); Thread.sleep(60000); run(); } catch (InterruptedException e) { e.printStackTrace(); } } catch(SSLProtocolException ex) { - if(logging_enabled) Log.v("OpenVK LPW", String.format("Connection error: %s", + if(logging_enabled) Log.v(OvkApplication.LP_TAG, String.format("Connection error: %s", ex.getMessage())); isActivated = false; - if(logging_enabled) Log.v("OpenVK LPW", "LongPoll service stopped."); + if(logging_enabled) Log.v(OvkApplication.LP_TAG, "LongPoll service stopped."); } catch(SSLHandshakeException ex) { - if(logging_enabled) Log.v("OpenVK LPW", String.format("Connection error: %s", + if(logging_enabled) Log.v(OvkApplication.LP_TAG, String.format("Connection error: %s", ex.getMessage())); - if(logging_enabled) Log.v("OpenVK LPW", "LongPoll service stopped."); + if(logging_enabled) Log.v(OvkApplication.LP_TAG, "LongPoll service stopped."); isActivated = false; } catch(SSLException ex) { - if(logging_enabled) Log.v("OpenVK LPW", String.format("Connection error: %s", + if(logging_enabled) Log.v(OvkApplication.LP_TAG, String.format("Connection error: %s", ex.getMessage())); - Log.v("OpenVK LPW", "LongPoll service stopped."); + Log.v(OvkApplication.LP_TAG, "LongPoll service stopped."); isActivated = false; } catch (Exception ex) { isActivated = false; @@ -169,11 +193,10 @@ public void setProxyConnection(boolean useProxy, String address) { if(useProxy) { String[] address_array = address.split(":"); if (address_array.length == 2) { - httpClient = new OkHttpClient.Builder().connectTimeout(30, - TimeUnit.SECONDS).writeTimeout(15, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .retryOnConnectionFailure(false).proxy(new Proxy(Proxy.Type.HTTP, - new InetSocketAddress(address_array[0], + httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS). + writeTimeout(15, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS) + .retryOnConnectionFailure(false).proxy(new Proxy(Proxy.Type.HTTP, new + InetSocketAddress(address_array[0], Integer.parseInt(address_array[1])))).build(); } } @@ -185,30 +208,36 @@ public void setProxyConnection(boolean useProxy, String address) { private void sendLongPollMessageToActivity(final String response) { if(!looper_prepared) { Looper.prepare(); - handler = new Handler(); looper_prepared = true; + handler = new Handler(Looper.myLooper()) { + @Override + public void handleMessage(android.os.Message msg) { + super.handleMessage(msg); + if(msg.what == HandlerMessages.LONGPOLL) { + Intent intent = new Intent(); + intent.setAction("uk.openvk.android.refresh.LONGPOLL_RECEIVE"); + intent.putExtra("response", response); + ctx.sendBroadcast(intent); + } + } + }; } - Log.d("OK", "OK! LongPolling 1..."); - Runnable sendLongPoll = new Runnable() { - @Override - public void run() { - Intent intent = new Intent(); - intent.setAction("uk.openvk.android.refresh.LONGPOLL_RECEIVE"); - intent.putExtra("response", response); - ctx.sendBroadcast(intent); - Log.d("OK", "OK! LongPolling 2..."); - } - }; - handler.post(sendLongPoll); + Log.d(OvkApplication.LP_TAG, "OK! LongPolling 1..."); + android.os.Message msg = new android.os.Message(); + msg.what = HandlerMessages.LONGPOLL; + Bundle data = new Bundle(); + data.putString("response", response); + msg.setData(data); + handler.sendMessage(msg); } - public void updateCounters(final OvkAPIWrapper ovk) { + public void updateCounters(final OvkAPIWrapper wrapper) { Thread thread = null; - final Handler handler = new Handler(Looper.myLooper()); + final Handler handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { - ovk.sendAPIMethod("Account.getCounters"); + wrapper.sendAPIMethod("Account.getCounters"); try { if(error != null && error.description.length() > 0) { handler.postDelayed(this, 5000); @@ -223,12 +252,12 @@ public void run() { handler.postDelayed(runnable, 5000); } - public void keepUptime(final OvkAPIWrapper ovk) { + public void keepUptime(final OvkAPIWrapper wrapper) { handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { - ovk.sendAPIMethod("Account.setOnline"); + wrapper.sendAPIMethod("Account.setOnline"); try { if(error != null && error.description.length() > 0) { handler.postDelayed(this, 60000); diff --git a/app/src/main/java/uk/openvk/android/refresh/longpoll_api/receivers/LongPollReceiver.java b/app/src/main/java/uk/openvk/android/refresh/receivers/LongPollReceiver.java similarity index 90% rename from app/src/main/java/uk/openvk/android/refresh/longpoll_api/receivers/LongPollReceiver.java rename to app/src/main/java/uk/openvk/android/refresh/receivers/LongPollReceiver.java index 55a3c0b..8c2fce7 100644 --- a/app/src/main/java/uk/openvk/android/refresh/longpoll_api/receivers/LongPollReceiver.java +++ b/app/src/main/java/uk/openvk/android/refresh/receivers/LongPollReceiver.java @@ -1,9 +1,8 @@ -package uk.openvk.android.refresh.longpoll_api.receivers; +package uk.openvk.android.legacy.receivers; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.Build; import android.util.Log; public class LongPollReceiver extends BroadcastReceiver { diff --git a/app/src/main/java/uk/openvk/android/refresh/receivers/OvkAPIReceiver.java b/app/src/main/java/uk/openvk/android/refresh/receivers/OvkAPIReceiver.java new file mode 100644 index 0000000..c60ceb8 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/receivers/OvkAPIReceiver.java @@ -0,0 +1,440 @@ +package uk.openvk.android.refresh.receivers; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +import androidx.preference.PreferenceManager; +import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.api.OpenVKAPI; +import uk.openvk.android.refresh.api.enumerations.HandlerMessages; +import uk.openvk.android.refresh.api.wrappers.DownloadManager; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.AppActivity; +import uk.openvk.android.refresh.ui.core.activities.AuthActivity; +import uk.openvk.android.refresh.ui.core.activities.ConversationActivity; +import uk.openvk.android.refresh.ui.core.activities.FriendsIntentActivity; +import uk.openvk.android.refresh.ui.core.activities.GroupIntentActivity; +import uk.openvk.android.refresh.ui.core.activities.NewPostActivity; +import uk.openvk.android.refresh.ui.core.activities.ProfileIntentActivity; +import uk.openvk.android.refresh.ui.core.activities.QuickSearchActivity; +import uk.openvk.android.refresh.ui.core.activities.WallPostActivity; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; + +public class OvkAPIReceiver extends BroadcastReceiver { + private Activity activity; + public OvkAPIReceiver(Activity _activity) { + activity = _activity; + } + + public OvkAPIReceiver() { + + } + + public void setActivity(Activity activity) { + this.activity = activity; + } + + @Override + public void onReceive(Context context, Intent intent) { + if(activity instanceof final NetworkActivity netActivity) { + OpenVKAPI ovk_api = netActivity.ovk_api; + final Bundle data = intent.getExtras(); + final Message msg = parseJSONData(ovk_api.wrapper, netActivity.handler, data); + ovk_api.wrapper.handler.post(new Runnable() { + @Override + public void run() { + Log.d(OvkApplication.API_TAG, + String.format("Handling message %s in %s", msg.what, activity.getLocalClassName()) + ); + netActivity.receiveState(msg.what, data); + } + }); + } + } + + public Message parseJSONData(OvkAPIWrapper wrapper, Handler handler, Bundle data) { + Message msg = new Message(); + String method = data.getString("method"); + String args = data.getString("args"); + String where = data.getString("where"); + msg.setData(data); + SharedPreferences global_prefs = PreferenceManager.getDefaultSharedPreferences(activity); + DownloadManager downloadManager = new DownloadManager(activity, + global_prefs.getBoolean("useHTTPS", false), handler); + + downloadManager.setInstance(((OvkApplication) activity + .getApplicationContext()).getCurrentInstance()); + if (activity instanceof AuthActivity) { + assert method != null; + if ("Account.getProfileInfo".equals(method)) { + msg.what = HandlerMessages.ACCOUNT_PROFILE_INFO; + } + } else if (activity instanceof AppActivity app_a) { + downloadManager = app_a.ovk_api.dlman; + assert method != null; + switch (method) { + case "Account.getProfileInfo": + app_a.ovk_api.account.parse(data.getString("response"), wrapper); + msg.what = HandlerMessages.ACCOUNT_PROFILE_INFO; + break; + case "Account.getCounters": + app_a.ovk_api.account.parseCounters(data.getString("response")); + msg.what = HandlerMessages.ACCOUNT_COUNTERS; + break; + case "Newsfeed.get": + if (where != null && where.equals("more_news")) { + msg.what = HandlerMessages.NEWSFEED_GET_MORE; + app_a.ovk_api.newsfeed.parse(app_a, + downloadManager, data.getString("response"), + global_prefs.getString("photos_quality", ""), false); + } else { + msg.what = HandlerMessages.NEWSFEED_GET; + app_a.ovk_api.newsfeed.parse(app_a, + downloadManager, data.getString("response"), + global_prefs.getString("photos_quality", ""), true); + } + break; + case "Newsfeed.getGlobal": + if (where != null && where.equals("more_news")) { + msg.what = HandlerMessages.NEWSFEED_GET_MORE_GLOBAL; + app_a.ovk_api.newsfeed.parse(activity, + downloadManager, data.getString("response"), + global_prefs.getString("photos_quality", ""), false); + } else { + msg.what = HandlerMessages.NEWSFEED_GET_GLOBAL; + app_a.ovk_api.newsfeed.parse(activity, + downloadManager, data.getString("response"), + global_prefs.getString("photos_quality", ""), true); + } + break; + case "Messages.getLongPollServer": + app_a.longPollServer = app_a.ovk_api.messages + .parseLongPollServer(data.getString("response")); + msg.what = HandlerMessages.MESSAGES_GET_LONGPOLL_SERVER; + break; + case "Likes.add": + app_a.ovk_api.likes.parse(data.getString("response")); + msg.what = HandlerMessages.LIKES_ADD; + break; + case "Likes.delete": + app_a.ovk_api.likes.parse(data.getString("response")); + msg.what = HandlerMessages.LIKES_DELETE; + break; + case "Users.get": + app_a.ovk_api.users.parse(data.getString("response")); + msg.what = HandlerMessages.USERS_GET; + break; + case "Friends.get": + if (args != null && args.contains("offset")) { + msg.what = HandlerMessages.FRIENDS_GET_MORE; + app_a.ovk_api.friends.parse(data.getString("response"), + downloadManager, true, false); + } else { + assert where != null; + if(where.equals("profile_counter")) { + msg.what = HandlerMessages.FRIENDS_GET_ALT; + app_a.ovk_api.friends.parse(data.getString("response"), + downloadManager, false, true); + } else { + msg.what = HandlerMessages.FRIENDS_GET; + app_a.ovk_api.friends.parse(data.getString("response"), + downloadManager, true, true); + } + } + break; + case "Friends.getRequests": + msg.what = HandlerMessages.FRIENDS_REQUESTS; + app_a.ovk_api.friends.parseRequests(data.getString("response"), + downloadManager, true); + break; + case "Photos.getAlbums": + msg.what = HandlerMessages.PHOTOS_GETALBUMS; + if (args != null && args.contains("offset")) { + app_a.ovk_api.photos.parseAlbums(data.getString("response"), + downloadManager, false); + } else { + assert where != null; + app_a.ovk_api.photos.parseAlbums(data.getString("response"), + downloadManager, true); + } + break; + case "Wall.get": + if(where != null && where.equals("more_wall_posts")) { + app_a.ovk_api.wall.parse(activity, downloadManager, + global_prefs.getString("photos_quality", ""), + data.getString("response"), false, true); + msg.what = HandlerMessages.WALL_GET_MORE; + } else { + app_a.ovk_api.wall.parse(activity, downloadManager, + global_prefs.getString("photos_quality", ""), + data.getString("response"), true, true); + msg.what = HandlerMessages.WALL_GET; + } + break; + case "Messages.getConversations": + app_a.conversations = app_a.ovk_api.messages.parseConversationsList( + data.getString("response"), + downloadManager); + msg.what = HandlerMessages.MESSAGES_CONVERSATIONS; + break; + case "Groups.get": + if (args != null && args.contains("offset")) { + msg.what = HandlerMessages.GROUPS_GET_MORE; + app_a.old_friends_size = app_a.ovk_api.groups.getList().size(); + app_a.ovk_api.groups.parse(data.getString("response"), + downloadManager, + global_prefs.getString("photos_quality", ""), + true, false); + } else { + msg.what = HandlerMessages.GROUPS_GET; + app_a.ovk_api.groups.parse(data.getString("response"), + downloadManager, + global_prefs.getString("photos_quality", ""), + true, true); + } + break; + case "Ovk.version": + msg.what = HandlerMessages.OVK_VERSION; + app_a.ovk_api.ovk.parseVersion(data.getString("response")); + break; + case "Ovk.aboutInstance": + msg.what = HandlerMessages.OVK_ABOUTINSTANCE; + app_a.ovk_api.ovk.parseAboutInstance(data.getString("response")); + break; + case "Notes.get": + msg.what = HandlerMessages.NOTES_GET; + app_a.ovk_api.notes.parse(data.getString("response")); + break; + } + } else if (activity instanceof ConversationActivity conv_a) { + downloadManager = conv_a.ovk_api.dlman; + assert method != null; + switch (method) { + case "Messages.getHistory" -> { + conv_a.history = conv_a.conversation.parseHistory(activity, data.getString("response")); + msg.what = HandlerMessages.MESSAGES_GET_HISTORY; + } + case "Messages.send" -> msg.what = HandlerMessages.MESSAGES_SEND; + case "Messages.delete" -> msg.what = HandlerMessages.MESSAGES_DELETE; + } + } else if (activity instanceof FriendsIntentActivity friends_a) { + downloadManager = friends_a.ovk_api.dlman; + assert method != null; + switch (method) { + case "Account.getProfileInfo": + friends_a.ovk_api.account.parse(data.getString("response"), wrapper); + msg.what = HandlerMessages.ACCOUNT_PROFILE_INFO; + break; + case "Friends.get": + if (args != null && args.contains("offset")) { + msg.what = HandlerMessages.FRIENDS_GET_MORE; + friends_a.ovk_api.friends.parse(data.getString("response"), + downloadManager, true, false); + } else { + msg.what = HandlerMessages.FRIENDS_GET; + friends_a.ovk_api.friends.parse(data.getString("response"), + downloadManager, true, true); + } + break; + } + } else if (activity instanceof ProfileIntentActivity profile_a) { + downloadManager = profile_a.ovk_api.dlman; + if(method == null) { + method = ""; + } + switch (method) { + default: + Log.e(OvkApplication.API_TAG, String.format("[%s / %s] Method not found", method, + msg.what)); + break; + case "Account.getProfileInfo": + try { + profile_a.ovk_api.account.parse(data.getString("response"), wrapper); + msg.what = HandlerMessages.ACCOUNT_PROFILE_INFO; + } catch (Exception ex) { + msg.what = HandlerMessages.INTERNAL_ERROR; + } + break; + case "Account.getCounters": + profile_a.ovk_api.account.parseCounters(data.getString("response")); + msg.what = HandlerMessages.ACCOUNT_COUNTERS; + break; + case "Friends.get": + assert where != null; + if(where.equals("profile_counter")) { + msg.what = HandlerMessages.FRIENDS_GET_ALT; + profile_a.ovk_api.friends.parse(data.getString("response"), + downloadManager, false, true); + } + break; + case "Users.get": + profile_a.ovk_api.users.parse(data.getString("response")); + profile_a.user = profile_a.ovk_api.users.getList().get(0); + msg.what = HandlerMessages.USERS_GET; + break; + case "Users.search": + profile_a.ovk_api.users.parseSearch(data.getString("response"), + null); + msg.what = HandlerMessages.USERS_SEARCH; + break; + case "Wall.get": + if(where != null && where.equals("more_wall_posts")) { + profile_a.ovk_api.wall.parse(activity, downloadManager, + global_prefs.getString("photos_quality", ""), + data.getString("response"), false, true); + msg.what = HandlerMessages.WALL_GET_MORE; + } else { + profile_a.ovk_api.wall.parse(activity, downloadManager, + global_prefs.getString("photos_quality", ""), + data.getString("response"), true, true); + msg.what = HandlerMessages.WALL_GET; + } + break; + case "Likes.add": + profile_a.ovk_api.likes.parse(data.getString("response")); + msg.what = HandlerMessages.LIKES_ADD; + break; + case "Likes.delete": + profile_a.ovk_api.likes.parse(data.getString("response")); + msg.what = HandlerMessages.LIKES_DELETE; + break; + } + } else if(activity instanceof GroupIntentActivity group_a) { + downloadManager = group_a.ovk_api.dlman; + assert method != null; + switch (method) { + case "Account.getProfileInfo": + group_a.ovk_api.account.parse(data.getString("response"), wrapper); + msg.what = HandlerMessages.ACCOUNT_PROFILE_INFO; + break; + case "Groups.get": + group_a.ovk_api.groups.parse(data.getString("response")); + msg.what = HandlerMessages.USERS_GET; + break; + case "Groups.getById": + group_a.ovk_api.groups.parse(data.getString("response")); + msg.what = HandlerMessages.GROUPS_GET_BY_ID; + break; + case "Groups.search": + group_a.ovk_api.groups.parseSearch(data.getString("response"), + null); + msg.what = HandlerMessages.GROUPS_SEARCH; + break; + case "Wall.get": + if(where != null && where.equals("more_wall_posts")) { + group_a.ovk_api.wall.parse(activity, downloadManager, + global_prefs.getString("photos_quality", ""), + data.getString("response"), false, true); + msg.what = HandlerMessages.WALL_GET_MORE; + } else { + group_a.ovk_api.wall.parse(activity, downloadManager, + global_prefs.getString("photos_quality", ""), + data.getString("response"), true, true); + msg.what = HandlerMessages.WALL_GET; + } + break; + case "Likes.add": + group_a.ovk_api.likes.parse(data.getString("response")); + msg.what = HandlerMessages.LIKES_ADD; + break; + case "Likes.delete": + group_a.ovk_api.likes.parse(data.getString("response")); + msg.what = HandlerMessages.LIKES_DELETE; + break; + } + /* doesn't work yet + } else if(activity instanceof NotesIntentActivity) { + NotesIntentActivity notes_a = ((NotesIntentActivity) activity); + assert method != null; + if(method.equals("Notes.get")) { + msg.what = HandlerMessages.NOTES_GET; + notes_a.ovk_api.notes.parse(data.getString("response")); + } + */ + } else if(activity instanceof NewPostActivity newpost_a) { + assert method != null; + if(method.equals("Wall.post")) { + msg.what = HandlerMessages.WALL_POST; + } else if(method.startsWith("Photos.get") && method.endsWith("Server")) { + newpost_a.ovk_api.photos.parseUploadServer(data.getString("response"), method); + msg.what = HandlerMessages.PHOTOS_UPLOAD_SERVER; + } else if(method.startsWith("Photos.save")) { + msg.what = HandlerMessages.PHOTOS_SAVE; + newpost_a.ovk_api.photos.parseOnePhoto(data.getString("response")); + } + } else if(activity instanceof QuickSearchActivity quick_search_a) { + downloadManager = quick_search_a.ovk_api.dlman; + assert method != null; + switch (method) { + case "Groups.search": + quick_search_a.ovk_api.groups.parseSearch(data.getString("response"), + quick_search_a.ovk_api.dlman); + msg.what = HandlerMessages.GROUPS_SEARCH; + break; + case "Users.search": + quick_search_a.ovk_api.users.parseSearch(data.getString("response"), + quick_search_a.ovk_api.dlman); + msg.what = HandlerMessages.USERS_SEARCH; + break; + } + /* doesn't work yet + } else if(activity instanceof GroupMembersActivity) { + GroupMembersActivity group_members_a = ((GroupMembersActivity) activity); + downloadManager = group_members_a.ovk_api.dlman; + assert method != null; + switch (method) { + case "Groups.getMembers": + group_members_a.group.members = new ArrayList<>(); + group_members_a.group.parseMembers(data.getString("response"), + downloadManager, true); + msg.what = HandlerMessages.GROUP_MEMBERS; + break; + } + */ + } else if(activity instanceof WallPostActivity wall_post_a) { + downloadManager = wall_post_a.ovk_api.dlman; + assert method != null; + if ("Wall.getComments".equals(method)) { + wall_post_a.comments = wall_post_a.ovk_api.wall.parseComments(activity, downloadManager, + global_prefs.getString("photos_quality", ""), + data.getString("response")); + msg.what = HandlerMessages.WALL_ALL_COMMENTS; + } + /* doesn't work yet + } else if(activity instanceof PhotoAlbumIntentActivity) { + PhotoAlbumIntentActivity album_a = ((PhotoAlbumIntentActivity) activity); + downloadManager = album_a.ovk_api.dlman; + assert method != null; + switch (method) { + case "Photos.getAlbums": + msg.what = HandlerMessages.PHOTOS_GETALBUMS; + if (args != null && args.contains("offset")) { + album_a.ovk_api.photos.parseAlbums(data.getString("response"), + downloadManager, false); + } else { + assert where != null; + album_a.ovk_api.photos.parseAlbums(data.getString("response"), + downloadManager, true); + } + break; + case "Photos.get": + msg.what = HandlerMessages.PHOTOS_GET; + album_a.ovk_api.photos.parse( + data.getString("response"), + new PhotoAlbum(Long.parseLong(album_a.ids[1]), Long.parseLong(album_a.ids[0])), + downloadManager + ); + break; + } + */ + } + return msg; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/services/AuthenticatorService.java b/app/src/main/java/uk/openvk/android/refresh/services/AuthenticatorService.java new file mode 100644 index 0000000..71cbed5 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/services/AuthenticatorService.java @@ -0,0 +1,34 @@ +package uk.openvk.android.refresh.services; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +import androidx.annotation.Nullable; +import uk.openvk.android.refresh.utils.AccountAuthentificator; + +/** + * Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-legacy + */ + +public class AuthenticatorService extends Service { + @Nullable + @Override + public IBinder onBind(Intent intent) { + AccountAuthentificator authenticator = new AccountAuthentificator(this); + return authenticator.getIBinder(); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/longpoll_api/LongPollService.java b/app/src/main/java/uk/openvk/android/refresh/services/LongPollService.java similarity index 50% rename from app/src/main/java/uk/openvk/android/refresh/longpoll_api/LongPollService.java rename to app/src/main/java/uk/openvk/android/refresh/services/LongPollService.java index ffc0cb6..d2a7373 100644 --- a/app/src/main/java/uk/openvk/android/refresh/longpoll_api/LongPollService.java +++ b/app/src/main/java/uk/openvk/android/refresh/services/LongPollService.java @@ -1,56 +1,75 @@ -package uk.openvk.android.refresh.longpoll_api; +package uk.openvk.android.refresh.services; import android.app.Service; import android.content.Context; import android.content.Intent; -import android.os.Binder; -import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; import android.util.Log; import uk.openvk.android.refresh.BuildConfig; import uk.openvk.android.refresh.longpoll_api.wrappers.LongPollWrapper; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.longpoll_api.wrappers.LongPollWrapper; + +/** Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + **/ public class LongPollService extends Service { private String lp_server; private String key; private int ts; + private Handler handler; private OvkAPIWrapper ovk_api; private LongPollWrapper lpW; private Context ctx; private String access_token; private boolean use_https = false; - public class LongPollBinder extends Binder { - public LongPollService getService() { - return LongPollService.this; - } + public LongPollService() { + } + + public LongPollService(Context ctx, Handler handler, + String access_token, boolean use_https) { + this.handler = handler; + this.ctx = ctx; + this.access_token = access_token; + lpW = new LongPollWrapper(ctx, use_https); } @Override public void onCreate() { super.onCreate(); - Log.i("OpenVK", "Creating LongPoll Service..."); + Log.i("OpenVK Legacy", "Starting LongPoll Service..."); } @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.i("OpenVK", String.format("Getting LPS start ID: %d", startId)); - Bundle data = intent.getExtras(); - if (data != null) { - access_token = data.getString("access_token"); - } - return flags; + Log.i("OpenVK Legacy", String.format("Getting LPS start ID: %d", startId)); + return super.onStartCommand(intent, flags, startId); } - public void run(Context ctx, String instance, String lp_server, String key, int ts, boolean use_https) { - this.ctx = ctx; + public void run(String instance, String lp_server, String key, int ts, boolean use_https, + boolean legacy_client) { this.use_https = use_https; if(lpW == null) { lpW = new LongPollWrapper(ctx, use_https); } - ovk_api = new OvkAPIWrapper(ctx); + ovk_api = new OvkAPIWrapper(ctx, use_https, legacy_client, handler); ovk_api.setServer(instance); ovk_api.setAccessToken(access_token); if(BuildConfig.BUILD_TYPE.equals("release")) ovk_api.log(false); @@ -66,16 +85,12 @@ private void runLongPull(String lp_server, String key, int ts, boolean use_https } } - private final IBinder myBinder = new LongPollBinder(); - @Override public IBinder onBind(Intent intent) { - Log.d("OpenVK", "Service ONBIND"); - return mBinder; + // TODO: Return the communication channel to the service. + throw new UnsupportedOperationException("Not yet implemented"); } - private final IBinder mBinder = new LongPollBinder(); - @Override public void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/AppActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/AppActivity.java index cb7f266..2c8cf77 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/AppActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/AppActivity.java @@ -2,16 +2,11 @@ import android.annotation.SuppressLint; import android.app.AlarmManager; -import android.app.LocaleManager; -import android.app.Notification; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.graphics.Color; @@ -20,9 +15,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.util.Log; import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; @@ -31,23 +23,6 @@ import android.widget.ImageView; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBarDrawerToggle; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.appcompat.widget.AppCompatSpinner; -import androidx.appcompat.widget.Toolbar; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.core.os.LocaleListCompat; -import androidx.drawerlayout.widget.DrawerLayout; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; -import androidx.navigation.NavController; -import androidx.navigation.fragment.NavHostFragment; -import androidx.navigation.ui.AppBarConfiguration; -import androidx.navigation.ui.NavigationUI; -import androidx.preference.PreferenceManager; - import com.bumptech.glide.Glide; import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.bottomnavigation.BottomNavigationView; @@ -56,72 +31,64 @@ import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.navigation.NavigationBarView; import com.google.android.material.navigation.NavigationView; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.core.MonetCompat; import org.json.JSONObject; import java.util.ArrayList; -import java.util.List; import java.util.Locale; import java.util.Objects; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.AppCompatSpinner; +import androidx.appcompat.widget.Toolbar; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import androidx.navigation.NavController; +import androidx.navigation.fragment.NavHostFragment; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; +import androidx.preference.PreferenceManager; import dev.kdrag0n.monet.theme.ColorScheme; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.Friends; -import uk.openvk.android.refresh.api.Groups; -import uk.openvk.android.refresh.api.Likes; -import uk.openvk.android.refresh.api.Messages; -import uk.openvk.android.refresh.api.Newsfeed; -import uk.openvk.android.refresh.api.Ovk; -import uk.openvk.android.refresh.api.Users; -import uk.openvk.android.refresh.api.Wall; +import uk.openvk.android.refresh.api.entities.Conversation; +import uk.openvk.android.refresh.api.entities.Friend; +import uk.openvk.android.refresh.api.entities.Group; +import uk.openvk.android.refresh.api.entities.LongPollServer; +import uk.openvk.android.refresh.api.entities.User; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.Conversation; -import uk.openvk.android.refresh.api.models.Friend; -import uk.openvk.android.refresh.api.models.Group; -import uk.openvk.android.refresh.api.models.LongPollServer; -import uk.openvk.android.refresh.api.models.User; -import uk.openvk.android.refresh.api.models.WallPost; import uk.openvk.android.refresh.api.wrappers.DownloadManager; import uk.openvk.android.refresh.api.wrappers.JSONParser; import uk.openvk.android.refresh.api.wrappers.NotificationManager; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -import uk.openvk.android.refresh.longpoll_api.LongPollService; +import uk.openvk.android.refresh.services.LongPollService; import uk.openvk.android.refresh.ui.FragmentNavigator; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.core.enumerations.PublicPageCounters; import uk.openvk.android.refresh.ui.core.fragments.app.AboutApplicationFragment; import uk.openvk.android.refresh.ui.core.fragments.app.FriendsFragment; import uk.openvk.android.refresh.ui.core.fragments.app.GroupsFragment; -import uk.openvk.android.refresh.ui.core.fragments.app.settings.MainSettingsFragment; import uk.openvk.android.refresh.ui.core.fragments.app.MessagesFragment; import uk.openvk.android.refresh.ui.core.fragments.app.NewsfeedFragment; -import uk.openvk.android.refresh.ui.core.fragments.app.settings.PersonalizationFragment; import uk.openvk.android.refresh.ui.core.fragments.app.ProfileFragment; +import uk.openvk.android.refresh.ui.core.fragments.app.settings.MainSettingsFragment; +import uk.openvk.android.refresh.ui.core.fragments.app.settings.PersonalizationFragment; import uk.openvk.android.refresh.ui.core.fragments.app.settings.VideoSettingsFragment; import uk.openvk.android.refresh.ui.list.adapters.NewsfeedToolbarSpinnerAdapter; import uk.openvk.android.refresh.ui.list.items.ToolbarSpinnerItem; import uk.openvk.android.refresh.ui.wrappers.LocaleContextWrapper; -public class AppActivity extends MonetCompatActivity { +public class AppActivity extends NetworkActivity { public Handler handler; - public OvkAPIWrapper ovk_api; public Menu activity_menu; - private SharedPreferences instance_prefs; - private SharedPreferences global_prefs; + public int old_friends_size; private DownloadManager downloadManager; - public Account account; - private Newsfeed newsfeed; - private User user; - private Likes likes; - private Messages messages; - private Users users; - private Friends friends; - private Groups groups; - private Wall wall; public NewsfeedFragment newsfeedFragment; private DrawerLayout drawer; private ActionBarDrawerToggle toggle; @@ -130,7 +97,6 @@ public class AppActivity extends MonetCompatActivity { private ArrayList tbSpinnerItems; private NewsfeedToolbarSpinnerAdapter tbSpinnerAdapter; public MessagesFragment messagesFragment; - private ArrayList conversations; private MenuItem prevMenuItem; public MainSettingsFragment mainSettingsFragment; private PersonalizationFragment personalizationFragment; @@ -141,16 +107,17 @@ public class AppActivity extends MonetCompatActivity { private String current_fragment; private boolean isDarkTheme; public GroupsFragment groupsFragment; - private boolean mShouldUnbind; private LongPollService longPollService; - private LongPollServer longPollServer; + public LongPollServer longPollServer; private Intent longPollIntent; private VideoSettingsFragment videoSettingsFragment; private NotificationManager notifMan; private int screenOrientation; private int navBarHeight; public FragmentNavigator fn; + private User user; + public ArrayList conversations; @SuppressLint("ObsoleteSdkInt") @Override @@ -270,12 +237,14 @@ public boolean onOptionsItemSelected(MenuItem item) { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String url = ""; - if(account.user.screen_name != null && account.user.screen_name.length() > 0) { + if(ovk_api.account.user.screen_name != null && ovk_api.account.user.screen_name.length() > 0) { url = String.format("https://%s/%s", - instance_prefs.getString("server", ""), account.user.screen_name); + instance_prefs.getString("server", ""), + ovk_api.account.user.screen_name); } else { url = String.format("https://%s/id%s", - instance_prefs.getString("server", ""), account.user.id); + instance_prefs.getString("server", ""), + ovk_api.account.user.id); } android.content.ClipData clip = android.content.ClipData.newPlainText("Profile URL", url); @@ -283,12 +252,12 @@ public boolean onOptionsItemSelected(MenuItem item) { } } else if(item.getItemId() == R.id.open_in_browser) { String url = ""; - if(account.user.screen_name != null && account.user.screen_name.length() > 0) { + if(ovk_api.account.user.screen_name != null && ovk_api.account.user.screen_name.length() > 0) { url = String.format("https://%s/%s", - instance_prefs.getString("server", ""), account.user.screen_name); + instance_prefs.getString("server", ""), ovk_api.account.user.screen_name); } else { url = String.format("https://%s/id%s", - instance_prefs.getString("server", ""), account.user.id); + instance_prefs.getString("server", ""), ovk_api.account.user.id); } Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); @@ -373,8 +342,8 @@ public void setFloatingActionButton() { public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), NewPostActivity.class); try { - intent.putExtra("owner_id", account.user.id); - intent.putExtra("account_id", account.id); + intent.putExtra("owner_id", ovk_api.account.user.id); + intent.putExtra("account_id", ovk_api.account.id); startActivity(intent); } catch (Exception ex) { ex.printStackTrace(); @@ -458,7 +427,7 @@ public void onClick(View v) { startQuickSearchActivity(); } }); - if(account == null || account.user == null) { + if(ovk_api.account == null || ovk_api.account.user == null) { String profile_name = getResources().getString(R.string.loading); ((TextView) header.findViewById(R.id.profile_name)).setText(profile_name); header.findViewById(R.id.screen_name).setVisibility(View.GONE); @@ -584,7 +553,7 @@ public void switchNavItem(MenuItem item) { toolbar.setNavigationIcon(R.drawable.ic_menu); b_navView.getMenu().getItem(0).setChecked(true); navView.getMenu().getItem(1).setChecked(true); - if (newsfeed.getWallPosts() != null) { + if (ovk_api.newsfeed.getWallPosts() != null) { findViewById(R.id.fab_newpost).setVisibility(View.VISIBLE); } } else if (itemId == R.id.newsfeed) { @@ -598,7 +567,7 @@ public void switchNavItem(MenuItem item) { ((NewsfeedFragment) selectedFragment).refreshAdapter(); b_navView.getMenu().getItem(0).setChecked(true); navView.getMenu().getItem(1).setChecked(true); - if (newsfeed.getWallPosts() != null) { + if (ovk_api.newsfeed.getWallPosts() != null) { findViewById(R.id.fab_newpost).setVisibility(View.VISIBLE); } } else if (itemId == R.id.friends) { @@ -607,11 +576,13 @@ public void switchNavItem(MenuItem item) { fn.navigateTo(selectedFragment, "friends"); ((AppCompatSpinner) ((MaterialToolbar) findViewById(R.id.app_toolbar)) .findViewById(R.id.spinner)).setVisibility(View.GONE); - profileFragment.setData(account.user, friends, account, ovk_api); + profileFragment.setData(ovk_api.account.user, ovk_api.friends, + ovk_api.account, ovk_api.wrapper); setToolbarTitle(getResources().getString(R.string.nav_friends), ""); toolbar.setNavigationIcon(R.drawable.ic_menu); if (friendsFragment.getFriendsCount() == 0) { - friends.get(ovk_api, account.id, 25, "friends_list"); + ovk_api.friends.get(ovk_api.wrapper, + ovk_api.account.id, 25, "friends_list"); } b_navView.getMenu().getItem(1).setChecked(true); navView.getMenu().getItem(2).setChecked(true); @@ -622,11 +593,12 @@ public void switchNavItem(MenuItem item) { fn.navigateTo(selectedFragment, "groups"); ((AppCompatSpinner) ((MaterialToolbar) findViewById(R.id.app_toolbar)) .findViewById(R.id.spinner)).setVisibility(View.GONE); - profileFragment.setData(account.user, friends, account, ovk_api); + profileFragment.setData(ovk_api.account.user, + ovk_api.friends, ovk_api.account, ovk_api.wrapper); setToolbarTitle(getResources().getString(R.string.nav_groups), ""); toolbar.setNavigationIcon(R.drawable.ic_menu); - if (groups.getList() == null || groups.getList().size() == 0) { - groups.getGroups(ovk_api, account.id, 25); + if (ovk_api.groups.getList() == null || ovk_api.groups.getList().size() == 0) { + ovk_api.groups.getGroups(ovk_api.wrapper, ovk_api.account.id, 25); } b_navView.getMenu().getItem(3).setChecked(true); navView.getMenu().getItem(3).setChecked(true); @@ -637,11 +609,12 @@ public void switchNavItem(MenuItem item) { fn.navigateTo(selectedFragment, "messages"); ((AppCompatSpinner) ((MaterialToolbar) findViewById(R.id.app_toolbar)) .findViewById(R.id.spinner)).setVisibility(View.GONE); - profileFragment.setData(account.user, friends, account, ovk_api); + profileFragment.setData(ovk_api.account.user, ovk_api.friends, + ovk_api.account, ovk_api.wrapper); setToolbarTitle(getResources().getString(R.string.nav_messages), ""); toolbar.setNavigationIcon(R.drawable.ic_menu); if (conversations == null) { - messages.getConversations(ovk_api); + ovk_api.messages.getConversations(ovk_api.wrapper); } ((MessagesFragment) selectedFragment).refreshAdapter(); b_navView.getMenu().getItem(2).setChecked(true); @@ -652,18 +625,19 @@ public void switchNavItem(MenuItem item) { prevMenuItem = navView.getMenu().getItem(0); fn.navigateTo(selectedFragment, "profile"); ((AppCompatSpinner) toolbar.findViewById(R.id.spinner)).setVisibility(View.GONE); - profileFragment.setData(account.user,friends, account, ovk_api); + profileFragment.setData(ovk_api.account.user, ovk_api.friends, + ovk_api.account, ovk_api.wrapper); profileFragment.header.setCountersVisibility(PublicPageCounters.MEMBERS, false); profileFragment.header.setCountersVisibility(PublicPageCounters.FRIENDS, true); - if (wall.getWallItems() == null) { - wall.get(ovk_api, account.user.id, 50); + if (ovk_api.wall.getWallItems() == null) { + ovk_api.wall.get(ovk_api.wrapper, ovk_api.account.user.id, 50); } setToolbarTitle(getResources().getString(R.string.nav_profile), ""); toolbar.setNavigationIcon(R.drawable.ic_menu); b_navView.getMenu().getItem(4).setChecked(true); navView.getMenu().getItem(0).setChecked(true); findViewById(R.id.fab_newpost).setVisibility(View.GONE); - if(wall.getWallItems() != null) profileFragment.recreateWallAdapter(); + if(ovk_api.wall.getWallItems() != null) profileFragment.recreateWallAdapter(); if(profileFragment.aboutItems != null) profileFragment.recreateAboutAdapter(); } else if (itemId == R.id.settings) { fn.navigateTo(selectedFragment, "settings"); @@ -681,28 +655,7 @@ public void switchNavItem(MenuItem item) { } private void setAPIWrapper() { - ((OvkApplication) getApplicationContext()).ovk_api = new OvkAPIWrapper(this); - ovk_api = ((OvkApplication) getApplicationContext()).ovk_api; - downloadManager = new DownloadManager(this); - ovk_api.setServer(instance_prefs.getString("server", "")); - ovk_api.setAccessToken(instance_prefs.getString("access_token", "")); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - Log.d("OpenVK", String.format("Handling API message: %s", msg.what)); - receiveState(msg.what, msg.getData()); - } - }; - account = new Account(this); - account.getProfileInfo(ovk_api); - newsfeed = new Newsfeed(); user = new User(); - likes = new Likes(); - messages = new Messages(); - users = new Users(); - friends = new Friends(); - groups = new Groups(); - wall = new Wall(); } public Fragment getSelectedFragment() { @@ -710,17 +663,15 @@ public Fragment getSelectedFragment() { } @SuppressLint("NotifyDataSetChanged") - private void receiveState(int message, Bundle data) { + public void receiveState(int message, Bundle data) { // Handling OpenVK API and UI messages try { - if (message == HandlerMessages.OVKAPI_ACCOUNT_PROFILE_INFO) { - account.parse(data.getString("response"), ovk_api); - newsfeed.get(ovk_api, 25); - users.getAccountUser(ovk_api, account.id); - messages.getLongPollServer(ovk_api); - messages.getConversations(ovk_api); - } else if (message == HandlerMessages.OVKAPI_ACCOUNT_COUNTERS) { - account.parseCounters(data.getString("response")); + if (message == HandlerMessages.ACCOUNT_PROFILE_INFO) { + ovk_api.newsfeed.get(ovk_api.wrapper, 25); + ovk_api.users.getAccountUser(ovk_api.wrapper, ovk_api.account.id); + ovk_api.messages.getLongPollServer(ovk_api.wrapper); + ovk_api.messages.getConversations(ovk_api.wrapper); + } else if (message == HandlerMessages.ACCOUNT_COUNTERS) { BottomNavigationView b_navView = findViewById(R.id.bottom_nav_view); int accentColor; if(Global.checkMonet(this) && !OvkApplication.isTablet) { @@ -736,70 +687,61 @@ private void receiveState(int message, Bundle data) { .monetcompat.R.attr.colorAccent, getResources().getColor(R.color.accentColorRed)); } - if(account.counters.friends_requests > 0) { + if(ovk_api.account.counters.friends_requests > 0) { b_navView.getOrCreateBadge(R.id.friends) - .setNumber(account.counters.friends_requests); + .setNumber(ovk_api.account.counters.friends_requests); b_navView.getOrCreateBadge(R.id.friends) .setBackgroundColor(accentColor); } - if(account.counters.new_messages > 0) { + if(ovk_api.account.counters.new_messages > 0) { b_navView.getOrCreateBadge(R.id.messages) - .setNumber(account.counters.new_messages); + .setNumber(ovk_api.account.counters.new_messages); b_navView.getOrCreateBadge(R.id.messages) .setBackgroundColor(accentColor); } - } else if (message == HandlerMessages.OVKAPI_NEWSFEED_GET) { - newsfeed.parse(this, downloadManager, data.getString("response"), - "high", true); - newsfeedFragment.createAdapter(this, newsfeed.getWallPosts()); + } else if (message == HandlerMessages.NEWSFEED_GET) { + newsfeedFragment.createAdapter(this, ovk_api.newsfeed.getWallPosts()); newsfeedFragment.disableUpdateState(); if(selectedFragment == newsfeedFragment) { findViewById(R.id.fab_newpost).setVisibility(View.VISIBLE); } newsfeedFragment.setScrollingPositions(this, true); - } else if (message == HandlerMessages.OVKAPI_NEWSFEED_GET_GLOBAL) { - newsfeed.parse(this, downloadManager, data.getString("response"), - "high", true); - newsfeedFragment.createAdapter(this, newsfeed.getWallPosts()); + } else if (message == HandlerMessages.NEWSFEED_GET_GLOBAL) { + newsfeedFragment.createAdapter(this, ovk_api.newsfeed.getWallPosts()); newsfeedFragment.setScrollingPositions(this, true); newsfeedFragment.disableUpdateState(); - } else if (message == HandlerMessages.OVKAPI_NEWSFEED_GET_MORE) { - newsfeed.parse(this, downloadManager, data.getString("response"), - global_prefs.getString("photos_quality", ""), false); - newsfeedFragment.createAdapter(this, newsfeed.getWallPosts()); + } else if (message == HandlerMessages.NEWSFEED_GET_MORE) { + newsfeedFragment.createAdapter(this, ovk_api.newsfeed.getWallPosts()); newsfeedFragment.setScrollingPositions(this, true); - } else if (message == HandlerMessages.OVKAPI_NEWSFEED_GET_MORE_GLOBAL) { - newsfeed.parse(this, downloadManager, data.getString("response"), - global_prefs.getString("photos_quality", ""), false); - newsfeedFragment.createAdapter(this, newsfeed.getWallPosts()); + } else if (message == HandlerMessages.NEWSFEED_GET_MORE_GLOBAL) { + newsfeedFragment.createAdapter(this, ovk_api.newsfeed.getWallPosts()); newsfeedFragment.setScrollingPositions(this, true); - } else if(message == HandlerMessages.OVKAPI_LIKES_ADD) { - likes.parse(data.getString("response")); + } else if(message == HandlerMessages.LIKES_ADD) { if (global_prefs.getString("current_screen", "").equals("newsfeed")) { - newsfeedFragment.select(likes.position, "likes", 1); + newsfeedFragment.select(ovk_api.likes.position, "likes", 1); } else { global_prefs.getString("current_screen", ""); //((WallLayout) profileLayout.findViewById(R.id.wall_layout)).select(likes.position, "likes", 1); } - } else if(message == HandlerMessages.OVKAPI_LIKES_DELETE) { - likes.parse(data.getString("response")); + } else if(message == HandlerMessages.LIKES_DELETE) { if (selectedFragment == newsfeedFragment) { - newsfeedFragment.select(likes.position, "likes", 0); + newsfeedFragment.select(ovk_api.likes.position, "likes", 0); } else if (selectedFragment == profileFragment) { - newsfeedFragment.select(likes.position, "likes", 0); + newsfeedFragment.select(ovk_api.likes.position, "likes", 0); } - } else if (message == HandlerMessages.OVKAPI_USERS_GET_ALT) { - users.parse(data.getString("response")); - account.user = users.getList().get(0); - account.user.downloadAvatar(downloadManager, "high", "account_avatar"); - String profile_name = String.format("%s %s", account.first_name, account.last_name); + } else if (message == HandlerMessages.USERS_GET_ALT) { + ovk_api.account.user = ovk_api.users.getList().get(0); + ovk_api.account.user.downloadAvatar(downloadManager, "high", "account_avatar"); + String profile_name = String.format("%s %s", ovk_api.account.first_name, + ovk_api.account.last_name); ((TextView) ((NavigationView) findViewById(R.id.nav_view)).getHeaderView(0) .findViewById(R.id.profile_name)) .setText(profile_name); - if(account.user.screen_name != null && account.user.screen_name.length() > 0) { + if(ovk_api.account.user.screen_name != null && + ovk_api.account.user.screen_name.length() > 0) { ((TextView) ((NavigationView) findViewById(R.id.nav_view)).getHeaderView(0) .findViewById(R.id.screen_name)) - .setText(String.format("@%s", account.user.screen_name)); + .setText(String.format("@%s", ovk_api.account.user.screen_name)); ((TextView) ((NavigationView) findViewById(R.id.nav_view)).getHeaderView(0) .findViewById(R.id.screen_name)) .setVisibility(View.VISIBLE); @@ -808,14 +750,11 @@ private void receiveState(int message, Bundle data) { .findViewById(R.id.screen_name)) .setVisibility(View.GONE); } - friends.get(ovk_api, account.user.id, 25, "profile_counter"); - } else if(message == HandlerMessages.OVKAPI_MESSAGES_CONVERSATIONS) { - conversations = messages.parseConversationsList(data.getString("response"), - downloadManager); - messagesFragment.createAdapter(this, conversations, account); + ovk_api.friends.get(ovk_api.wrapper, ovk_api.account.user.id, 25, "profile_counter"); + } else if(message == HandlerMessages.MESSAGES_CONVERSATIONS) { + messagesFragment.createAdapter(this, conversations, ovk_api.account); messagesFragment.disableUpdateState(); - } else if (message == HandlerMessages.OVKAPI_MESSAGES_GET_LONGPOLL_SERVER) { - longPollServer = messages.parseLongPollServer(data.getString("response")); + } else if (message == HandlerMessages.MESSAGES_GET_LONGPOLL_SERVER) { AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); longPollIntent = new Intent(this, LongPollService.class); PendingIntent pendingIntent = null; @@ -841,61 +780,53 @@ private void receiveState(int message, Bundle data) { // Wake up service mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60 * 1000, pendingIntent); - } else if (message == HandlerMessages.OVKAPI_FRIENDS_GET_ALT) { - friends.parse(data.getString("response"), downloadManager, false, - true); - profileFragment.setFriendsCount(friends.count); - } else if (message == HandlerMessages.OVKAPI_FRIENDS_GET) { - friends.parse(data.getString("response"), downloadManager, true, - true); - ArrayList friendsList = friends.getFriends(); + } else if (message == HandlerMessages.FRIENDS_GET_ALT) { + profileFragment.setFriendsCount(ovk_api.friends.count); + } else if (message == HandlerMessages.FRIENDS_GET) { + ArrayList friendsList = ovk_api.friends.getFriends(); friendsFragment.createFriendsAdapter(this, friendsList); friendsFragment.disableUpdateState(); - friendsFragment.setScrollingPositions(this, friends.getFriends().size() > 0); - friends.getRequests(ovk_api); - } else if (message == HandlerMessages.OVKAPI_FRIENDS_GET_MORE) { - int old_friends_size = friends.getFriends().size(); - friends.parse(data.getString("response"), downloadManager, true, - false); - ArrayList friendsList = friends.getFriends(); + friendsFragment.setScrollingPositions(this, + ovk_api.friends.getFriends().size() > 0); + ovk_api.friends.getRequests(ovk_api.wrapper); + } else if (message == HandlerMessages.FRIENDS_GET_MORE) { + int old_friends_size = ovk_api.friends.getFriends().size(); + ArrayList friendsList = ovk_api.friends.getFriends(); friendsFragment.createFriendsAdapter(this, friendsList); friendsFragment.setScrollingPositions(this, old_friends_size != - friends.getFriends().size()); - } else if (message == HandlerMessages.OVKAPI_FRIENDS_REQUESTS) { - int old_friends_size = friends.getFriends().size(); - friends.parseRequests(data.getString("response"), downloadManager, true); - ArrayList friendsList = friends.requests; + ovk_api.friends.getFriends().size()); + } else if (message == HandlerMessages.FRIENDS_REQUESTS) { + int old_friends_size = ovk_api.friends.getFriends().size(); + ArrayList friendsList = ovk_api.friends.requests; friendsFragment.createRequestsAdapter(this, friendsList); friendsFragment.setScrollingPositions(this, old_friends_size != - friends.getFriends().size()); - } else if (message == HandlerMessages.OVKAPI_GROUPS_GET) { - groups.parse(data.getString("response"), downloadManager, - global_prefs.getString("photos_quality", ""), true, true); - ArrayList groupsList = groups.getList(); + ovk_api.friends.getFriends().size()); + } else if (message == HandlerMessages.GROUPS_GET) { + ArrayList groupsList = ovk_api.groups.getList(); if (selectedFragment == groupsFragment) { - groupsFragment.createAdapter(this, groups.getList(), "groups_list"); + groupsFragment.createAdapter(this, ovk_api.groups.getList(), + "groups_list"); } - } else if (message == HandlerMessages.OVKAPI_WALL_GET) { - wall.parse(this, downloadManager, "high", data.getString("response")); - profileFragment.createWallAdapter(this, wall.getWallItems()); - } else if (message == HandlerMessages.OVKAPI_OVK_ABOUTINSTANCE) { + } else if (message == HandlerMessages.WALL_GET) { + profileFragment.createWallAdapter(this, ovk_api.wall.getWallItems()); + } else if (message == HandlerMessages.OVK_ABOUTINSTANCE) { mainSettingsFragment.getInstanceInfo("stats", data.getString("response")); - } else if (message == HandlerMessages.OVKAPI_OVK_CHECK_HTTP || message == HandlerMessages.OVKAPI_OVK_CHECK_HTTPS) { + } else if (message == HandlerMessages.OVK_CHECK_HTTP || + message == HandlerMessages.OVK_CHECK_HTTPS) { mainSettingsFragment.getInstanceInfo("checkHTTP", data.getString("response")); - Ovk ovk = new Ovk(); - ovk.getVersion(ovk_api); - ovk.aboutInstance(ovk_api); - } else if (message == HandlerMessages.OVKAPI_OVK_VERSION) { + ovk_api.ovk.getVersion(ovk_api.wrapper); + ovk_api.ovk.aboutInstance(ovk_api.wrapper); + } else if (message == HandlerMessages.OVK_VERSION) { mainSettingsFragment.getInstanceInfo("instanceVersion", data.getString("response")); - } else if(message == HandlerMessages.DLM_CONVERSATIONS_AVATARS) { + } else if(message == HandlerMessages.CONVERSATIONS_AVATARS) { messagesFragment.loadAvatars(conversations); - } else if(message == HandlerMessages.DLM_NEWSFEED_AVATARS - || message == HandlerMessages.DLM_NEWSFEED_ATTACHMENTS - || message == HandlerMessages.DLM_WALL_AVATARS - || message == HandlerMessages.DLM_WALL_ATTACHMENTS) { + } else if(message == HandlerMessages.NEWSFEED_AVATARS + || message == HandlerMessages.NEWSFEED_ATTACHMENTS + || message == HandlerMessages.WALL_AVATARS + || message == HandlerMessages.WALL_ATTACHMENTS) { if(selectedFragment == newsfeedFragment) { if(newsfeedFragment.newsfeedAdapter != null) { - if (message == HandlerMessages.DLM_NEWSFEED_AVATARS) { + if (message == HandlerMessages.NEWSFEED_AVATARS) { newsfeedFragment.newsfeedAdapter.setAvatarLoadState(true); } else { newsfeedFragment.newsfeedAdapter.setPhotoLoadState(true); @@ -905,33 +836,33 @@ private void receiveState(int message, Bundle data) { } } else if(selectedFragment == profileFragment) { if(profileFragment.getWallAdapter() == null) { - profileFragment.createWallAdapter(this, wall.getWallItems()); + profileFragment.createWallAdapter(this, ovk_api.wall.getWallItems()); } - if (message == HandlerMessages.DLM_WALL_AVATARS) { + if (message == HandlerMessages.WALL_AVATARS) { profileFragment.getWallAdapter().setAvatarLoadState(true); } else { profileFragment.getWallAdapter().setPhotoLoadState(true); } profileFragment.refreshWallAdapter(); } - } else if(message == HandlerMessages.DLM_ACCOUNT_AVATAR) { + } else if(message == HandlerMessages.ACCOUNT_AVATAR) { Glide.with(this).load( String.format("%s/photos_cache/account_avatar/avatar_%s", - getCacheDir().getAbsolutePath(), account.user.id)) + getCacheDir().getAbsolutePath(), ovk_api.account.user.id)) .into((ImageView) ((NavigationView) findViewById(R.id.nav_view)) .getHeaderView(0).findViewById(R.id.profile_avatar)); - } else if (message == HandlerMessages.DLM_FRIEND_AVATARS) { + } else if (message == HandlerMessages.FRIEND_AVATARS) { friendsFragment.refreshAdapter(); - } else if (message == HandlerMessages.OVKAPI_FRIENDS_ADD) { - friends.requests.remove(friendsFragment.requests_cursor_index); - friendsFragment.createRequestsAdapter(this, friends.requests); - } else if(message == HandlerMessages.OVKAPI_FRIENDS_DELETE) { + } else if (message == HandlerMessages.FRIENDS_ADD) { + ovk_api.friends.requests.remove(friendsFragment.requests_cursor_index); + friendsFragment.createRequestsAdapter(this, ovk_api.friends.requests); + } else if(message == HandlerMessages.FRIENDS_DELETE) { JSONObject response = new JSONParser().parseJSON(data.getString("response")); int status = response.getInt("response"); if(status == 1) { user.friends_status = 0; } - profileFragment.setFriendStatus(account.user, user.friends_status); + profileFragment.setFriendStatus(ovk_api.account.user, user.friends_status); } else if(message < 0) { newsfeedFragment.setError(true, message, new View.OnClickListener() { @Override @@ -946,37 +877,27 @@ public void onClick(View v) { } private void retryConnection() { - if(account != null) { + if(ovk_api.account != null) { newsfeedFragment.setError(false, 0, null); - newsfeed.get(ovk_api, 25); - } else { - account = new Account(this); - if(selectedFragment == newsfeedFragment) - account.addQueue("Newsfeed.get", "count=25&extended=1"); - else if(selectedFragment == friendsFragment) - account.addQueue("Friends.get", "count=25&extended=1"); - else if(selectedFragment == profileFragment) - account.addQueue("Wall.get", String.format("owner_id=%s&count=50", - account.id)); - account.getProfileInfo(ovk_api); + ovk_api.newsfeed.get(ovk_api.wrapper, 25); } } @SuppressLint("NotifyDataSetChanged") public void refreshNewsfeed(boolean progress) { - if(newsfeed.getWallPosts() != null) { + if(ovk_api.newsfeed.getWallPosts() != null) { int pos = ((AppCompatSpinner) ((MaterialToolbar) findViewById(R.id.app_toolbar)) .findViewById(R.id.spinner)).getSelectedItemPosition(); - if(newsfeed != null) { - newsfeed.getWallPosts().clear(); + if(ovk_api.newsfeed != null) { + ovk_api.newsfeed.getWallPosts().clear(); newsfeedFragment.newsfeedAdapter.notifyDataSetChanged(); } - if (account != null) { - assert newsfeed != null; + if (ovk_api.account != null) { + assert ovk_api.newsfeed != null; if (pos == 0) { - newsfeed.get(ovk_api, 25); + ovk_api.newsfeed.get(ovk_api.wrapper, 25); } else { - newsfeed.getGlobal(ovk_api, 25); + ovk_api.newsfeed.getGlobal(ovk_api.wrapper, 25); } if (progress) { newsfeedFragment.showProgress(); @@ -986,9 +907,9 @@ public void refreshNewsfeed(boolean progress) { } public void refreshFriendsList(boolean progress) { - friends.get(ovk_api, account.id, 25, "friends_list"); - if(user.id == account.id) { - friends.getRequests(ovk_api); + ovk_api.friends.get(ovk_api.wrapper, ovk_api.account.id, 25, "friends_list"); + if(user.id == ovk_api.account.id) { + ovk_api.friends.getRequests(ovk_api.wrapper); } if (progress) { friendsFragment.showProgress(); @@ -996,21 +917,21 @@ public void refreshFriendsList(boolean progress) { } public void refreshGroupsList(boolean progress) { - groups.getGroups(ovk_api, account.id, 25); + ovk_api.groups.getGroups(ovk_api.wrapper, ovk_api.account.id, 25); if (progress) { groupsFragment.showProgress(); } } public void refreshConversations(boolean progress) { - messages.getConversations(ovk_api); + ovk_api.messages.getConversations(ovk_api.wrapper); if (progress) { messagesFragment.showProgress(); } } public void refreshMyWall(boolean progress) { - wall.get(ovk_api, account.user.id, 50); + ovk_api.wall.get(ovk_api.wrapper, ovk_api.account.user.id, 50); if (progress) { profileFragment.showProgress(); } @@ -1033,30 +954,6 @@ public void onBackPressed() { } } - public void addLike(int position, String post, View view) { - WallPost item; - if (selectedFragment == profileFragment) { - item = wall.getWallItems().get(position); - profileFragment.wallSelect(position, "likes", "add"); - } else { - item = newsfeed.getWallPosts().get(position); - newsfeedFragment.select(position, "likes", "add"); - } - likes.add(ovk_api, item.owner_id, item.post_id, position); - } - - public void deleteLike(int position, String post, View view) { - WallPost item; - if (selectedFragment == profileFragment) { - item = wall.getWallItems().get(position); - profileFragment.wallSelect(0, "likes", "delete"); - } else { - item = newsfeed.getWallPosts().get(position); - newsfeedFragment.select(0, "likes", "delete"); - } - likes.delete(ovk_api, item.owner_id, item.post_id, position); - } - public void setAvatarShape() { @SuppressLint("CutPasteId") ShapeableImageView avatar = ((ShapeableImageView) ((NavigationView) findViewById(R.id.nav_view)) @@ -1064,117 +961,8 @@ public void setAvatarShape() { Global.setAvatarShape(this, avatar); } - public void openConversation(int position) { - Conversation conversation = conversations.get(position); - Intent intent = new Intent(getApplicationContext(), ConversationActivity.class); - try { - intent.putExtra("peer_id", conversation.peer_id); - intent.putExtra("conv_title", conversation.title); - intent.putExtra("online", conversation.online); - startActivity(intent); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public void openProfileFromWall(int position) { - if(selectedFragment == newsfeedFragment) { - WallPost post = newsfeed.getWallPosts().get(position); - String url = ""; - if(post.author_id > 0) { - url = String.format("openvk://profile/id%s", post.author_id); - } else if(post.author_id < 0) { - url = String.format("openvk://group/club%s", post.author_id); - } - if(url.length() > 0) { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - final PackageManager pm = getPackageManager(); - @SuppressLint("QueryPermissionsNeeded") List - activityList = pm.queryIntentActivities(i, 0); - for (int index = 0; index < activityList.size(); index++) { - ResolveInfo app = activityList.get(index); - if (app.activityInfo.name.contains("uk.openvk.android.refresh")) { - i.setClassName(app.activityInfo.packageName, app.activityInfo.name); - } - } - startActivity(i); - } - } else { - WallPost post = wall.getWallItems().get(position); - String url = ""; - if(post.author_id > 0) { - url = String.format("openvk://profile/id%s", post.author_id); - } else if(post.author_id < 0) { - url = String.format("openvk://group/club%s", post.author_id); - } - if(url.length() > 0) { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - startActivity(i); - } - } - } - - public void openProfileFromFriends(int position, boolean isRequest) { - Intent i = new Intent(Intent.ACTION_VIEW); - String url = ""; - Friend friend; - if(isRequest) { - friend = friends.requests.get(position); - } else { - friend = friends.getFriends().get(position); - } - url = String.format("openvk://profile/id%s", friend.id); - if(url.length() > 0) { - i.setData(Uri.parse(url)); - final PackageManager pm = getPackageManager(); - @SuppressLint("QueryPermissionsNeeded") List - activityList = pm.queryIntentActivities(i, 0); - for (int index = 0; index < activityList.size(); index++) { - ResolveInfo app = activityList.get(index); - if (app.activityInfo.name.contains("uk.openvk.android.refresh")) { - i.setClassName(app.activityInfo.packageName, app.activityInfo.name); - } - } - startActivity(i); - } - } - - public void openCommunityPage(int position) { - Group group = groups.getList().get(position); - String url = ""; - url = String.format("openvk://group/club%s", group.id); - if(url.length() > 0) { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - final PackageManager pm = getPackageManager(); - @SuppressLint("QueryPermissionsNeeded") List - activityList = pm.queryIntentActivities(i, 0); - for (int index = 0; index < activityList.size(); index++) { - ResolveInfo app = activityList.get(index); - if (app.activityInfo.name.contains("uk.openvk.android.refresh")) { - i.setClassName(app.activityInfo.packageName, app.activityInfo.name); - } - } - startActivity(i); - } - } - private final ServiceConnection lpConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { - LongPollService.LongPollBinder binder = (LongPollService.LongPollBinder) service; - longPollService = binder.getService(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - AppActivity.this.startForegroundService(longPollIntent); - Notification notification = notifMan.createServiceNotification(AppActivity.this); - longPollService.startForeground(180, notification); - } - longPollService.run(AppActivity.this, instance_prefs.getString("server", ""), - longPollServer.address, longPollServer.key, longPollServer.ts, true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - AppActivity.this.unbindService(this); - } } @@ -1251,26 +1039,26 @@ protected void onDestroy() { } public void loadMoreFriends() { - if(friends != null) { - friends.get(ovk_api, account.id, 25, friends.offset); + if(ovk_api.friends != null) { + ovk_api.friends.get(ovk_api.wrapper, ovk_api.account.id, 25, ovk_api.friends.offset); } } public void loadMoreNews() { - if(newsfeed != null) { + if(ovk_api.newsfeed != null) { int pos = ((AppCompatSpinner) ((MaterialToolbar) findViewById(R.id.app_toolbar)) .findViewById(R.id.spinner)).getSelectedItemPosition(); if(pos == 0) { - newsfeed.get(ovk_api, 25, newsfeed.next_from); + ovk_api.newsfeed.get(ovk_api.wrapper, 25, ovk_api.newsfeed.next_from); } else { - newsfeed.getGlobal(ovk_api, 25, newsfeed.next_from); + ovk_api.newsfeed.getGlobal(ovk_api.wrapper, 25, ovk_api.newsfeed.next_from); } } } public void addToFriends(int user_id) { - if(user_id != account.id) { - friends.add(ovk_api, user_id); + if(user_id != ovk_api.account.id) { + ovk_api.friends.add(ovk_api.wrapper, user_id); } } diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/AuthActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/AuthActivity.java index b3dc44e..2d354cf 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/AuthActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/AuthActivity.java @@ -7,8 +7,6 @@ import android.graphics.Color; import android.os.Build; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; import android.os.Message; import android.preference.PreferenceManager; import android.text.Html; @@ -19,51 +17,45 @@ import android.widget.CompoundButton; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.appcompat.widget.Toolbar; -import androidx.core.view.WindowCompat; -import androidx.core.view.WindowInsetsControllerCompat; -import androidx.fragment.app.FragmentTransaction; - import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.checkbox.MaterialCheckBox; import com.google.android.material.color.MaterialColors; import com.google.android.material.snackbar.Snackbar; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.core.MonetCompat; import java.util.Locale; import java.util.Objects; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.Toolbar; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import androidx.fragment.app.FragmentTransaction; import dev.kdrag0n.monet.theme.ColorScheme; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Authorization; +import uk.openvk.android.refresh.api.entities.Authorization; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.core.enumerations.UiMessages; import uk.openvk.android.refresh.ui.core.fragments.auth.AuthFragment; import uk.openvk.android.refresh.ui.core.fragments.auth.AuthProgressFragment; import uk.openvk.android.refresh.ui.core.fragments.auth.AuthTwoFactorFragment; +import uk.openvk.android.refresh.ui.core.listeners.OnKeyboardStateListener; import uk.openvk.android.refresh.ui.util.OvkAlertDialogBuilder; import uk.openvk.android.refresh.ui.view.layouts.XConstraintLayout; -import uk.openvk.android.refresh.ui.core.listeners.OnKeyboardStateListener; import uk.openvk.android.refresh.ui.wrappers.LocaleContextWrapper; -public class AuthActivity extends MonetCompatActivity { - public Handler handler; - public OvkAPIWrapper ovk_api; +public class AuthActivity extends NetworkActivity { private FragmentTransaction ft; private XConstraintLayout auth_layout; private String instance; private String username; private String password; private AuthFragment authFragment; - private SharedPreferences instance_prefs; - private SharedPreferences global_prefs; private Snackbar snackbar; @SuppressLint("ObsoleteSdkInt") @@ -97,7 +89,6 @@ public void onKeyboardStateChanged(boolean state) { ft.commit(); global_prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); instance_prefs = getSharedPreferences("instance", 0); - setAPIWrapper(); showOvkWarning(); if(getResources().getColor(R.color.navbarColor) == getResources().getColor(android.R.color.white)) { try { @@ -156,17 +147,6 @@ protected void attachBaseContext(Context newBase) { super.attachBaseContext(LocaleContextWrapper.wrap(newBase, languageType)); } - private void setAPIWrapper() { - ovk_api = new OvkAPIWrapper(this); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - super.handleMessage(msg); - receiveState(msg.what, msg.getData()); - } - }; - } - public void signIn(String instance, String username, String password) { this.instance = instance; this.username = username; @@ -174,9 +154,6 @@ public void signIn(String instance, String username, String password) { ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.dynamic_fragment_layout, new AuthProgressFragment()); ft.commit(); - if(ovk_api == null) { - ovk_api = new OvkAPIWrapper(this); - } if(instance.equals("vk.com") || instance.equals("vk.ru") || instance.equals("vkontakte.ru")) { ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.dynamic_fragment_layout, new AuthFragment()); @@ -185,8 +162,8 @@ public void signIn(String instance, String username, String password) { authFragment.setAuthorizationData(instance, username, password); showOvkWarning(); } else { - ovk_api.setServer(instance); - ovk_api.authorize(username, password); + ovk_api.wrapper.setServer(instance); + ovk_api.wrapper.authorize(username, password); } } @@ -197,15 +174,12 @@ public void signIn(String twofactor_code) { if(snackbar != null) { snackbar.dismiss(); } - if(ovk_api == null) { - ovk_api = new OvkAPIWrapper(this); - ovk_api.setServer(instance); - } - ovk_api.authorize(username, password, twofactor_code); + ovk_api.wrapper.setServer(instance); + ovk_api.wrapper.authorize(username, password, twofactor_code); } - private void receiveState(int message, Bundle data) { - if (message == HandlerMessages.OVKAPI_AUTHORIZED) { + public void receiveState(int message, Bundle data) { + if (message == HandlerMessages.AUTHORIZED) { SharedPreferences.Editor editor = instance_prefs.edit(); Authorization auth = new Authorization(data.getString("response")); if(auth.getAccessToken() != null && auth.getAccessToken().length() > 0) { @@ -217,11 +191,11 @@ private void receiveState(int message, Bundle data) { startActivity(intent); finish(); } - } else if (message == HandlerMessages.OVKAPI_TWOFACTOR_CODE_REQUIRED) { + } else if (message == HandlerMessages.TWOFACTOR_CODE_REQUIRED) { ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.dynamic_fragment_layout, new AuthTwoFactorFragment()); ft.commit(); - } else if (message == HandlerMessages.OVKAPI_INVALID_USERNAME_OR_PASSWORD) { + } else if (message == HandlerMessages.INVALID_USERNAME_OR_PASSWORD) { ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.dynamic_fragment_layout, authFragment); authFragment.setAuthorizationData(instance, username, password); @@ -257,7 +231,7 @@ private void receiveState(int message, Bundle data) { com.google.android.material.R.id.snackbar_action); snackActionBtn.setLetterSpacing(0); snackbar.show(); - } else if(message == HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION) { + } else if(message == HandlerMessages.NO_INTERNET_CONNECTION) { ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.dynamic_fragment_layout, authFragment); authFragment.setAuthorizationData(instance, username, password); @@ -298,7 +272,7 @@ public void onClick(View view) { com.google.android.material.R.id.snackbar_action); snackActionBtn.setLetterSpacing(0); snackbar.show(); - } else if(message == HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE) { + } else if(message == HandlerMessages.INSTANCE_UNAVAILABLE) { ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.dynamic_fragment_layout, authFragment); authFragment.setAuthorizationData(instance, username, password); @@ -334,7 +308,7 @@ public void onClick(View view) { com.google.android.material.R.id.snackbar_action); snackActionBtn.setLetterSpacing(0); snackbar.show(); - } else if(message == HandlerMessages.OVKAPI_UNKNOWN_ERROR) { + } else if(message == HandlerMessages.UNKNOWN_ERROR) { ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.dynamic_fragment_layout, authFragment); authFragment.setAuthorizationData(instance, username, password); diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/ConversationActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/ConversationActivity.java index c0dc022..91db19d 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/ConversationActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/ConversationActivity.java @@ -17,51 +17,46 @@ import android.view.Window; import android.view.WindowManager; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.AppCompatImageButton; -import androidx.preference.PreferenceManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.color.MaterialColors; import com.google.android.material.textfield.TextInputEditText; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.core.MonetCompat; import java.util.ArrayList; import java.util.Locale; import java.util.Objects; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatImageButton; +import androidx.preference.PreferenceManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import dev.kdrag0n.monet.theme.ColorScheme; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; +import uk.openvk.android.refresh.api.entities.Conversation; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.Conversation; import uk.openvk.android.refresh.api.wrappers.DownloadManager; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; -import uk.openvk.android.refresh.ui.view.layouts.SendTextBottomPanel; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.list.adapters.MessagesAdapter; +import uk.openvk.android.refresh.ui.view.layouts.SendTextBottomPanel; import uk.openvk.android.refresh.ui.wrappers.LocaleContextWrapper; -public class ConversationActivity extends MonetCompatActivity { - public OvkAPIWrapper ovk_api; +public class ConversationActivity extends NetworkActivity { public Conversation conversation; - public Handler handler; public long peer_id; public String conv_title; public int peer_online; - private ArrayList history; + public ArrayList history; private MessagesAdapter conversation_adapter; private RecyclerView messagesView; private LinearLayoutManager llm; private DownloadManager downloadManager; - private SharedPreferences instance_prefs; private SendTextBottomPanel bottomPanel; - private uk.openvk.android.refresh.api.models.Message last_sended_message; - private SharedPreferences global_prefs; + private uk.openvk.android.refresh.api.entities.Message last_sended_message; private boolean isDarkTheme; @Override @@ -89,7 +84,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } setContentView(R.layout.activity_conversation); setMonetTheme(); - history = new ArrayList(); + history = new ArrayList(); setAPIWrapper(); setAppBar(); setBottomPanel(); @@ -145,13 +140,13 @@ private void setBottomPanel() { public void onClick(View v) { if(bottomPanel.getText().length() > 0) { try { - last_sended_message = new uk.openvk.android.refresh.api.models - .Message(1, 0, false, false, + last_sended_message = new uk.openvk.android.refresh.api.entities + .Message(1, false, false, (int)(System.currentTimeMillis() / 1000), bottomPanel.getText(), ConversationActivity.this); last_sended_message.sending = true; last_sended_message.isError = false; - conversation.sendMessage(ovk_api, bottomPanel.getText()); + conversation.sendMessage(ovk_api.wrapper, bottomPanel.getText()); if(history == null) { history = new ArrayList<>(); } @@ -235,24 +230,13 @@ public void onClick(View view) { } public void setAPIWrapper() { - ovk_api = new OvkAPIWrapper(this); - downloadManager = new DownloadManager(this); - ovk_api.setServer(instance_prefs.getString("server", "")); - ovk_api.setAccessToken(instance_prefs.getString("access_token", "")); conversation = new Conversation(); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - Log.d("OpenVK", String.format("Handling API message: %s", msg.what)); - receiveState(msg.what, msg.getData()); - } - }; - conversation.getHistory(ovk_api, peer_id); + conversation.getHistory(ovk_api.wrapper, peer_id); } @SuppressLint("NotifyDataSetChanged") - private void receiveState(int message, Bundle data) { - if (message == HandlerMessages.OVKAPI_MESSAGES_GET_HISTORY) { + public void receiveState(int message, Bundle data) { + if (message == HandlerMessages.MESSAGES_GET_HISTORY) { messagesView = findViewById(R.id.messages_view); history = conversation.parseHistory(this, data.getString("response")); conversation_adapter = new MessagesAdapter(this, history, peer_id); @@ -261,12 +245,12 @@ private void receiveState(int message, Bundle data) { llm.setStackFromEnd(true); messagesView.setLayoutManager(llm); messagesView.setAdapter(conversation_adapter); - } else if (message == HandlerMessages.OVKAPI_CHAT_DISABLED) { + } else if (message == HandlerMessages.CHAT_DISABLED) { last_sended_message.sending = false; last_sended_message.isError = true; history.set(history.size() - 1, last_sended_message); conversation_adapter.notifyDataSetChanged(); - } else if(message == HandlerMessages.OVKAPI_MESSAGES_SEND) { + } else if(message == HandlerMessages.MESSAGES_SEND) { last_sended_message.sending = false; last_sended_message.getSendedId(data.getString("response")); history.set(history.size() - 1, last_sended_message); diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/FriendsIntentActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/FriendsIntentActivity.java index 30041e5..5bea746 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/FriendsIntentActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/FriendsIntentActivity.java @@ -1,64 +1,40 @@ package uk.openvk.android.refresh.ui.core.activities; -import android.annotation.SuppressLint; import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.Log; import android.util.TypedValue; import android.view.View; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; -import androidx.preference.PreferenceManager; - import com.google.android.material.appbar.MaterialToolbar; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.core.MonetCompat; import java.util.ArrayList; -import java.util.List; import java.util.Locale; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import androidx.preference.PreferenceManager; import dev.kdrag0n.monet.theme.ColorScheme; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.Friends; -import uk.openvk.android.refresh.api.Users; +import uk.openvk.android.refresh.api.entities.Friend; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.Friend; -import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.core.fragments.app.FriendsFragment; import uk.openvk.android.refresh.ui.wrappers.LocaleContextWrapper; -public class FriendsIntentActivity extends MonetCompatActivity { - private SharedPreferences global_prefs; - private SharedPreferences instance_prefs; - public Handler handler; - private OvkAPIWrapper ovk_api; - private DownloadManager downloadManager; - public Account account; +public class FriendsIntentActivity extends NetworkActivity { private FragmentTransaction ft; private String args; private MaterialToolbar toolbar; - private Friends friends; private boolean isDarkTheme; private FriendsFragment friendsFragment; private long user_id; - private Users users; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -107,24 +83,8 @@ private void setMonetTheme() { } } - - private void setAPIWrapper() { - ovk_api = new OvkAPIWrapper(this); - downloadManager = new DownloadManager(this); - ovk_api.setServer(instance_prefs.getString("server", "")); - ovk_api.setAccessToken(instance_prefs.getString("access_token", "")); - friends = new Friends(); - users = new Users(); - account = new Account(this); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - Log.d("OpenVK", String.format("Handling API message: %s", msg.what)); - receiveState(msg.what, msg.getData()); - } - }; - account.getProfileInfo(ovk_api); + ovk_api.account.getProfileInfo(ovk_api.wrapper); } private void createFragment() { @@ -135,7 +95,7 @@ private void applyFragment() { friendsFragment = new FriendsFragment(); Bundle args = new Bundle(); args.putLong("user_id", user_id); - args.putLong("account_id", account.id); + args.putLong("account_id", ovk_api.account.id); friendsFragment.setArguments(args); FragmentManager fm = getSupportFragmentManager(); ft = getSupportFragmentManager().beginTransaction(); @@ -169,39 +129,36 @@ public void onClick(View view) { } } - private void receiveState(int message, Bundle data) { + public void receiveState(int message, Bundle data) { try { - if (message == HandlerMessages.OVKAPI_ACCOUNT_PROFILE_INFO) { - account.parse(data.getString("response"), ovk_api); + if (message == HandlerMessages.ACCOUNT_PROFILE_INFO) { if (args.startsWith("id")) { try { user_id = Integer.parseInt(args.substring(2)); - friends.get(ovk_api, Integer.parseInt(args.substring(2)), + ovk_api.friends.get(ovk_api.wrapper, Integer.parseInt(args.substring(2)), 25, "friends_list"); } catch (Exception ex) { - users.search(ovk_api, args); + ovk_api.users.search(ovk_api.wrapper, args); } } else { - users.search(ovk_api, args); + ovk_api.users.search(ovk_api.wrapper, args); } applyFragment(); - } else if (message == HandlerMessages.OVKAPI_FRIENDS_GET) { - friends.parse(data.getString("response"), downloadManager, + } else if (message == HandlerMessages.FRIENDS_GET) { + ovk_api.friends.parse(data.getString("response"), ovk_api.dlman, true, true); - ArrayList friendsList = friends.getFriends(); + ArrayList friendsList = ovk_api.friends.getFriends(); friendsFragment.createFriendsAdapter(this, friendsList); friendsFragment.disableUpdateState(); //friendsFragment.setScrollingPositions(this, friends.getFriends().size() > 0); - } else if (message == HandlerMessages.OVKAPI_FRIENDS_GET_MORE) { - int old_friends_size = friends.getFriends().size(); - friends.parse(data.getString("response"), downloadManager, + } else if (message == HandlerMessages.FRIENDS_GET_MORE) { + int old_friends_size = ovk_api.friends.getFriends().size(); + ovk_api.friends.parse(data.getString("response"), ovk_api.dlman, true, false); - ArrayList friendsList = friends.getFriends(); + ArrayList friendsList = ovk_api.friends.getFriends(); friendsFragment.createFriendsAdapter(this, friendsList); //friendsFragment.setScrollingPositions(this, old_friends_size != friends.getFriends().size()); - } if (message == HandlerMessages.DLM_FRIEND_AVATARS) { - //friendsFragment.refreshAdapter(); - } + } //friendsFragment.refreshAdapter(); } catch (Exception ex) { ex.printStackTrace(); finish(); @@ -209,32 +166,12 @@ private void receiveState(int message, Bundle data) { } public void refreshFriendsList(boolean progress) { - friends.get(ovk_api, account.id, 25, "friends_list"); + ovk_api.friends.get(ovk_api.wrapper, ovk_api.account.id, 25, "friends_list"); if (progress) { friendsFragment.showProgress(); } } - public void openProfileFromFriends(int position) { - Friend friend = friends.getFriends().get(position); - String url = ""; - url = String.format("openvk://profile/id%s", friend.id); - if(url.length() > 0) { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - final PackageManager pm = getPackageManager(); - @SuppressLint("QueryPermissionsNeeded") List activityList = - pm.queryIntentActivities(i, 0); - for (int index = 0; index < activityList.size(); index++) { - ResolveInfo app = activityList.get(index); - if (app.activityInfo.name.contains("uk.openvk.android.refresh")) { - i.setClassName(app.activityInfo.packageName, app.activityInfo.name); - } - } - startActivity(i); - } - } - @Override public void recreate() { @@ -248,8 +185,8 @@ public void onMonetColorsChanged(@NonNull MonetCompat monet, @NonNull ColorSchem } public void loadMoreFriends() { - if(friends != null) { - friends.get(ovk_api, user_id, 25, friends.offset); + if(ovk_api.friends != null) { + ovk_api.friends.get(ovk_api.wrapper, user_id, 25, ovk_api.friends.offset); } } } diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/GroupIntentActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/GroupIntentActivity.java index 77f5a73..81c2b10 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/GroupIntentActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/GroupIntentActivity.java @@ -2,61 +2,39 @@ import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.Log; import android.util.TypedValue; import android.view.MenuItem; import android.view.View; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; -import androidx.preference.PreferenceManager; - import com.google.android.material.appbar.MaterialToolbar; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.core.MonetCompat; import java.util.Locale; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import androidx.preference.PreferenceManager; import dev.kdrag0n.monet.theme.ColorScheme; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.Groups; -import uk.openvk.android.refresh.api.Likes; -import uk.openvk.android.refresh.api.Wall; +import uk.openvk.android.refresh.api.entities.Group; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.Group; -import uk.openvk.android.refresh.api.models.WallPost; -import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.core.enumerations.PublicPageCounters; import uk.openvk.android.refresh.ui.core.fragments.app.CommunityFragment; import uk.openvk.android.refresh.ui.wrappers.LocaleContextWrapper; -public class GroupIntentActivity extends MonetCompatActivity { - private SharedPreferences global_prefs; - private SharedPreferences instance_prefs; - public Handler handler; - private OvkAPIWrapper ovk_api; - private DownloadManager downloadManager; - private Wall wall; - public Account account; - private Likes likes; +public class GroupIntentActivity extends NetworkActivity { private CommunityFragment communityFragment; private FragmentTransaction ft; private String args; private MaterialToolbar toolbar; - private Groups groups; public Group group; private boolean isDarkTheme; @@ -99,15 +77,15 @@ protected void attachBaseContext(Context newBase) { public boolean onOptionsItemSelected(@NonNull MenuItem item) { if(item.getItemId() == R.id.leave_group) { if(group.is_member > 0) { - group.leave(ovk_api); + group.leave(ovk_api.wrapper); } else { - group.join(ovk_api); + group.join(ovk_api.wrapper); } } else if(item.getItemId() == R.id.copy_link) { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String url = ""; - if(account.user.screen_name != null && account.user.screen_name.length() > 0) { + if(ovk_api.account.user.screen_name != null && ovk_api.account.user.screen_name.length() > 0) { url = String.format("https://%s/%s", instance_prefs.getString("server", ""), group.screen_name); } else { @@ -119,7 +97,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { clipboard.setPrimaryClip(clip); } else if(item.getItemId() == R.id.open_in_browser) { String url = ""; - if(account.user.screen_name != null && account.user.screen_name.length() > 0) { + if(ovk_api.account.user.screen_name != null && ovk_api.account.user.screen_name.length() > 0) { url = String.format("https://%s/%s", instance_prefs.getString("server", ""), group.screen_name); } else { @@ -146,22 +124,7 @@ private void setMonetTheme() { } private void setAPIWrapper() { - ovk_api = new OvkAPIWrapper(this); - downloadManager = new DownloadManager(this); - ovk_api.setServer(instance_prefs.getString("server", "")); - ovk_api.setAccessToken(instance_prefs.getString("access_token", "")); - groups = new Groups(); - wall = new Wall(); - account = new Account(this); - likes = new Likes(); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - Log.d("OpenVK", String.format("Handling API message: %s", msg.what)); - receiveState(msg.what, msg.getData()); - } - }; - account.getProfileInfo(ovk_api); + ovk_api.account.getProfileInfo(ovk_api.wrapper); } private void createFragments() { @@ -202,25 +165,27 @@ public void onClick(View view) { } } - private void receiveState(int message, Bundle data) { + public void receiveState(int message, Bundle data) { try { - if (message == HandlerMessages.OVKAPI_ACCOUNT_PROFILE_INFO) { + if (message == HandlerMessages.ACCOUNT_PROFILE_INFO) { if (args.startsWith("club")) { try { - groups.getGroupByID(ovk_api, Integer.parseInt(args.substring(4))); + ovk_api.groups.getGroupByID( + ovk_api.wrapper, + Integer.parseInt(args.substring(4)) + ); } catch (Exception ex) { - groups.search(ovk_api, args); + ovk_api.groups.search(ovk_api.wrapper, args); } } else { - groups.search(ovk_api, args); + ovk_api.groups.search(ovk_api.wrapper, args); } communityFragment.header.hideSendMessageButton(); communityFragment.header.setCountersVisibility(PublicPageCounters.FRIENDS, false); communityFragment.header.setCountersVisibility(PublicPageCounters.MEMBERS, true); communityFragment.addGroupCollapseListener(); - } else if (message == HandlerMessages.OVKAPI_GROUPS_GET) { - groups.parseSearch(data.getString("response")); - group = groups.getList().get(0); + } else if (message == HandlerMessages.GROUPS_GET) { + group = ovk_api.groups.getList().get(0); MaterialToolbar appBar = findViewById(R.id.app_toolbar); appBar.getMenu().clear(); appBar.inflateMenu(R.menu.group); @@ -229,12 +194,11 @@ private void receiveState(int message, Bundle data) { appBar.getMenu().removeItem(R.id.leave_group); } } - communityFragment.setData(group, ovk_api); - group.downloadAvatar(downloadManager, "high"); - wall.get(ovk_api, -group.id, 50); - } else if (message == HandlerMessages.OVKAPI_GROUPS_GET_BY_ID) { - groups.parse(data.getString("response")); - group = groups.getList().get(0); + communityFragment.setData(group, ovk_api.wrapper); + group.downloadAvatar(ovk_api.dlman, "high"); + ovk_api.wall.get(ovk_api.wrapper, -group.id, 50); + } else if (message == HandlerMessages.GROUPS_GET_BY_ID) { + group = ovk_api.groups.getList().get(0); MaterialToolbar appBar = findViewById(R.id.app_toolbar); appBar.getMenu().clear(); appBar.inflateMenu(R.menu.group); @@ -243,27 +207,25 @@ private void receiveState(int message, Bundle data) { appBar.getMenu().removeItem(R.id.leave_group); } } - communityFragment.setData(group, ovk_api); - group.downloadAvatar(downloadManager, "high"); - wall.get(ovk_api, -group.id, 50); - } else if(message == HandlerMessages.OVKAPI_GROUPS_SEARCH) { - groups.parseSearch(data.getString("response")); - groups.getGroups(ovk_api, groups.getList().get(0).id, 1); - } else if (message == HandlerMessages.OVKAPI_WALL_GET) { - wall.parse(this, downloadManager, "high", data.getString("response")); - communityFragment.createWallAdapter(this, wall.getWallItems()); - } else if(message == HandlerMessages.DLM_WALL_AVATARS - || message == HandlerMessages.DLM_WALL_ATTACHMENTS) { - if(message == HandlerMessages.DLM_WALL_AVATARS) { + communityFragment.setData(group, ovk_api.wrapper); + group.downloadAvatar(ovk_api.dlman, "high"); + ovk_api.wall.get(ovk_api.wrapper, -group.id, 50); + } else if(message == HandlerMessages.GROUPS_SEARCH) { + ovk_api.groups.getGroups(ovk_api.wrapper, ovk_api.groups.getList().get(0).id, 1); + } else if (message == HandlerMessages.WALL_GET) { + communityFragment.createWallAdapter(this, ovk_api.wall.getWallItems()); + } else if(message == HandlerMessages.WALL_AVATARS + || message == HandlerMessages.WALL_ATTACHMENTS) { + if(message == HandlerMessages.WALL_AVATARS) { communityFragment.wallAdapter.setAvatarLoadState(true); } else { communityFragment.wallAdapter.setPhotoLoadState(true); } - } else if(message == HandlerMessages.DLM_GROUP_AVATARS) { - communityFragment.setData(group, ovk_api); - } else if (message == HandlerMessages.OVKAPI_GROUPS_JOIN) { + } else if(message == HandlerMessages.GROUP_AVATARS) { + communityFragment.setData(group, ovk_api.wrapper); + } else if (message == HandlerMessages.GROUPS_JOIN) { communityFragment.setJoinStatus(group, 1); - } else if (message == HandlerMessages.OVKAPI_GROUPS_LEAVE) { + } else if (message == HandlerMessages.GROUPS_LEAVE) { communityFragment.setJoinStatus(group, 0); } } catch (Exception ex) { @@ -271,24 +233,6 @@ private void receiveState(int message, Bundle data) { } } - public void openProfileFromWall(int position) { - WallPost post = wall.getWallItems().get(position); - String url = ""; - if(post.author_id != group.id) { - if (post.author_id > 0) { - url = String.format("openvk://profile/id%s", post.author_id); - } else if (post.author_id < 0) { - url = String.format("openvk://group/club%s", post.author_id); - } - - if (url.length() > 0) { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - startActivity(i); - } - } - } - @Override public void recreate() { diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/MainSettingsActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/MainSettingsActivity.java index 59e2f34..4af5a32 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/MainSettingsActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/MainSettingsActivity.java @@ -1,56 +1,40 @@ package uk.openvk.android.refresh.ui.core.activities; import android.content.Context; -import android.content.SharedPreferences; import android.content.res.Configuration; import android.os.Bundle; -import android.os.Handler; import android.util.TypedValue; import android.view.View; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; -import androidx.preference.PreferenceManager; - import com.google.android.material.appbar.MaterialToolbar; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.core.MonetCompat; import java.util.Locale; import java.util.Objects; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import androidx.preference.PreferenceManager; import dev.kdrag0n.monet.theme.ColorScheme; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.Likes; -import uk.openvk.android.refresh.api.Users; -import uk.openvk.android.refresh.api.Wall; -import uk.openvk.android.refresh.api.models.User; +import uk.openvk.android.refresh.api.entities.User; import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.core.fragments.app.AboutApplicationFragment; import uk.openvk.android.refresh.ui.core.fragments.app.settings.MainSettingsFragment; import uk.openvk.android.refresh.ui.core.fragments.app.settings.PersonalizationFragment; import uk.openvk.android.refresh.ui.wrappers.LocaleContextWrapper; -public class MainSettingsActivity extends MonetCompatActivity { - private SharedPreferences global_prefs; - private SharedPreferences instance_prefs; - public Handler handler; - private OvkAPIWrapper ovk_api; +public class MainSettingsActivity extends NetworkActivity { private DownloadManager downloadManager; - private Wall wall; - private Account account; - private Likes likes; private FragmentTransaction ft; private String args; private MaterialToolbar toolbar; - private Users users; private User user; private boolean isDarkTheme; private MainSettingsFragment mainSettingsFragment; diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/NewPostActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/NewPostActivity.java index 3d5a622..7a8b071 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/NewPostActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/NewPostActivity.java @@ -1,17 +1,12 @@ package uk.openvk.android.refresh.ui.core.activities; import android.content.Context; -import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.graphics.Color; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; import android.text.Editable; import android.text.TextWatcher; -import android.util.Log; import android.util.TypedValue; import android.view.MenuItem; import android.view.View; @@ -19,38 +14,28 @@ import android.view.WindowManager; import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.preference.PreferenceManager; - import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.color.MaterialColors; import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputLayout; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.core.MonetCompat; import java.util.Locale; import java.util.Objects; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.preference.PreferenceManager; import dev.kdrag0n.monet.theme.ColorScheme; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Wall; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.wrappers.LocaleContextWrapper; -public class NewPostActivity extends MonetCompatActivity { - private SharedPreferences global_prefs; - private SharedPreferences instance_prefs; - private OvkAPIWrapper ovk_api; - private DownloadManager downloadManager; - private Wall wall; - public Handler handler; +public class NewPostActivity extends NetworkActivity { private long owner_id; private long account_id; private String account_first_name; @@ -67,7 +52,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { Global.setInterfaceFont(this); instance_prefs = getSharedPreferences("instance", 0); setContentView(R.layout.activity_new_post); - setAPIWrapper(); setAppBar(); isDarkTheme = global_prefs.getBoolean("dark_theme", false); @@ -83,7 +67,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { account_id = extras.getLong("account_id"); account_first_name = extras.getString("account_first_name"); setAppBar(); - setAPIWrapper(); if (owner_id == 0) { finish(); } @@ -96,12 +79,9 @@ public void beforeTextChanged(CharSequence s, int start, int count, int after) { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { try { - if (Objects.requireNonNull(statusEditText.getText()) - .toString().length() > 0) { - toolbar.getMenu().getItem(0).setEnabled(true); - } else { - toolbar.getMenu().getItem(0).setEnabled(false); - } + toolbar.getMenu().getItem(0) + .setEnabled(Objects.requireNonNull(statusEditText.getText()) + .toString().length() > 0); } catch (Exception ex) { ex.printStackTrace(); } @@ -212,35 +192,21 @@ public boolean onMenuItemClick(MenuItem item) { private void sendPost() { if (Objects.requireNonNull(statusEditText.getText()).toString().length() > 0) { try { - wall.post(ovk_api, owner_id, statusEditText.getText().toString()); + ovk_api.wall.post(ovk_api.wrapper, owner_id, statusEditText.getText().toString(), + false, false); } catch (Exception e) { e.printStackTrace(); } } } - private void setAPIWrapper() { - ovk_api = new OvkAPIWrapper(this); - downloadManager = new DownloadManager(this); - ovk_api.setServer(instance_prefs.getString("server", "")); - ovk_api.setAccessToken(instance_prefs.getString("access_token", "")); - wall = new Wall(); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - Log.d("OpenVK", String.format("Handling API message: %s", msg.what)); - receiveState(msg.what, msg.getData()); - } - }; - } - - private void receiveState(int message, Bundle data) { + public void receiveState(int message, Bundle data) { try { - if(message == HandlerMessages.OVKAPI_WALL_POST) { + if(message == HandlerMessages.WALL_POST) { Toast.makeText(getApplicationContext(), getResources().getString(R.string.posted_successfully), Toast.LENGTH_LONG).show(); finish(); - } else if(message == HandlerMessages.OVKAPI_ACCESS_DENIED){ + } else if(message == HandlerMessages.ACCESS_DENIED){ Toast.makeText(getApplicationContext(), getResources().getString(R.string.posting_access_denied), Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/PhotoViewerActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/PhotoViewerActivity.java index 21e636c..6d79343 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/PhotoViewerActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/PhotoViewerActivity.java @@ -59,11 +59,12 @@ import uk.openvk.android.refresh.api.attachments.PhotoAttachment; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; import uk.openvk.android.refresh.api.wrappers.DownloadManager; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.core.enumerations.UiMessages; import uk.openvk.android.refresh.ui.util.glide.GlideApp; import uk.openvk.android.refresh.ui.view.ZoomableImageView; -public class PhotoViewerActivity extends MonetCompatActivity { +public class PhotoViewerActivity extends NetworkActivity { private SharedPreferences global_prefs; private PhotoAttachment photo; private DownloadManager downloadManager; @@ -159,7 +160,6 @@ private void loadPhoto() { findViewById(R.id.progress_layout).setVisibility(View.VISIBLE); Bundle data = getIntent().getExtras(); if(data != null) { - createDownloadManager(); cache_path = String.format("%s/photos_cache/original_photos/original_photo_a%s_%s", getCacheDir().getAbsolutePath(), data.getLong("author_id"), data.getLong("photo_id")); @@ -173,24 +173,11 @@ private void loadPhoto() { } } - private void createDownloadManager() { - downloadManager = new DownloadManager(this); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message message) { - Bundle data = message.getData(); - if(!BuildConfig.BUILD_TYPE.equals("release")) Log.d("OpenVK", - String.format("Handling API message: %s", message.what)); - receiveState(message.what, data); - } - }; - } - @SuppressLint("UseCompatLoadingForDrawables") - private void receiveState(int message, Bundle data) { - if(message == HandlerMessages.OVKAPI_ACCESS_DENIED_MARSHMALLOW) { + public void receiveState(int message, Bundle data) { + if(message == HandlerMessages.ACCESS_DENIED_MARSHMALLOW) { allowPermissionDialog(); - } else if(message == HandlerMessages.DLM_ORIGINAL_PHOTO) { + } else if(message == HandlerMessages.ORIGINAL_PHOTO) { try { findViewById(R.id.progress_layout).setVisibility(View.GONE); findViewById(R.id.image_view).setVisibility(View.VISIBLE); diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/ProfileIntentActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/ProfileIntentActivity.java index 66ffb6b..4d993b8 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/ProfileIntentActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/ProfileIntentActivity.java @@ -2,67 +2,40 @@ import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.Log; import android.util.TypedValue; import android.view.MenuItem; import android.view.View; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; -import androidx.preference.PreferenceManager; - import com.google.android.material.appbar.MaterialToolbar; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import com.kieronquinn.monetcompat.core.MonetCompat; -import org.json.JSONObject; - import java.util.Locale; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import androidx.preference.PreferenceManager; import dev.kdrag0n.monet.theme.ColorScheme; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.Friends; -import uk.openvk.android.refresh.api.Likes; -import uk.openvk.android.refresh.api.Users; -import uk.openvk.android.refresh.api.Wall; +import uk.openvk.android.refresh.api.entities.User; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.User; -import uk.openvk.android.refresh.api.models.WallPost; -import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.JSONParser; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.core.enumerations.PublicPageCounters; import uk.openvk.android.refresh.ui.core.fragments.app.ProfileFragment; import uk.openvk.android.refresh.ui.wrappers.LocaleContextWrapper; -public class ProfileIntentActivity extends MonetCompatActivity { - private SharedPreferences global_prefs; - private SharedPreferences instance_prefs; - public Handler handler; - private OvkAPIWrapper ovk_api; - private DownloadManager downloadManager; - private Wall wall; - public Account account; - private Likes likes; +public class ProfileIntentActivity extends NetworkActivity { private ProfileFragment profileFragment; private FragmentTransaction ft; private String args; private MaterialToolbar toolbar; - private Users users; - private Friends friends; - private User user; + public User user; private boolean isDarkTheme; @Override @@ -109,7 +82,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String url = ""; - if(account.user.screen_name != null && account.user.screen_name.length() > 0) { + if(ovk_api.account.user.screen_name != null && ovk_api.account.user.screen_name.length() > 0) { url = String.format("https://%s/%s", instance_prefs.getString("server", ""), user.screen_name); } else { @@ -121,7 +94,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { clipboard.setPrimaryClip(clip); } else if(item.getItemId() == R.id.open_in_browser) { String url = ""; - if(account.user.screen_name != null && account.user.screen_name.length() > 0) { + if(ovk_api.account.user.screen_name != null && ovk_api.account.user.screen_name.length() > 0) { url = String.format("https://%s/%s", instance_prefs.getString("server", ""), user.screen_name); } else { @@ -136,8 +109,8 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { } private void deleteFromFriends(long user_id) { - if(user_id != account.id) { - friends.delete(ovk_api, user_id); + if(user_id != ovk_api.account.id) { + ovk_api.friends.delete(ovk_api.wrapper, user_id); } } @@ -154,23 +127,7 @@ private void setMonetTheme() { } private void setAPIWrapper() { - ovk_api = new OvkAPIWrapper(this); - downloadManager = new DownloadManager(this); - ovk_api.setServer(instance_prefs.getString("server", "")); - ovk_api.setAccessToken(instance_prefs.getString("access_token", "")); - users = new Users(); - friends = new Friends(); - wall = new Wall(); - account = new Account(this); - likes = new Likes(); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - Log.d("OpenVK", String.format("Handling API message: %s", msg.what)); - receiveState(msg.what, msg.getData()); - } - }; - account.getProfileInfo(ovk_api); + ovk_api.account.getProfileInfo(ovk_api.wrapper); } private void createFragments() { @@ -211,61 +168,55 @@ public void onClick(View view) { } } - private void receiveState(int message, Bundle data) { + public void receiveState(int message, Bundle data) { try { - if (message == HandlerMessages.OVKAPI_ACCOUNT_PROFILE_INFO) { + if (message == HandlerMessages.ACCOUNT_PROFILE_INFO) { if (args.startsWith("id")) { - account.parse(data.getString("response"), ovk_api); MaterialToolbar appBar = findViewById(R.id.app_toolbar); appBar.getMenu().clear(); appBar.inflateMenu(R.menu.profile); if(appBar.getMenu().getItem(0).getItemId() == R.id.delete_friend) { - if (Integer.parseInt(args.substring(2)) == account.id) { + if (Integer.parseInt(args.substring(2)) == ovk_api.account.id) { appBar.getMenu().removeItem(R.id.delete_friend); } } try { - users.getUser(ovk_api, Integer.parseInt(args.substring(2))); + ovk_api.users.getUser(ovk_api.wrapper, Integer.parseInt(args.substring(2))); } catch (Exception ex) { - users.search(ovk_api, args); + ovk_api.users.search(ovk_api.wrapper, args); } } else { - users.search(ovk_api, args); + ovk_api.users.search(ovk_api.wrapper, args); } profileFragment.header.setCountersVisibility(PublicPageCounters.MEMBERS, false); profileFragment.header.setCountersVisibility(PublicPageCounters.FRIENDS, true); - } else if (message == HandlerMessages.OVKAPI_USERS_GET) { - users.parse(data.getString("response")); - user = users.getList().get(0); - profileFragment.setData(user, friends, account, ovk_api); + } else if (message == HandlerMessages.USERS_GET) { + user = ovk_api.users.getList().get(0); + profileFragment.setData(user, ovk_api.friends, ovk_api.account, ovk_api.wrapper); MaterialToolbar appBar = findViewById(R.id.app_toolbar); if(appBar.getMenu().getItem(0).getItemId() == R.id.delete_friend) { - if (user.id == account.id) { + if (user.id == ovk_api.account.id) { appBar.getMenu().removeItem(R.id.delete_friend); } else if (user.friends_status < 3) { appBar.getMenu().removeItem(R.id.delete_friend); } } - user.downloadAvatar(downloadManager, "high", "profile_avatars"); - wall.get(ovk_api, user.id, 50); - friends.get(ovk_api, user.id, 25, "profile_counter"); - } else if (message == HandlerMessages.OVKAPI_FRIENDS_GET_ALT) { - friends.parse(data.getString("response"), downloadManager, - false, true); - profileFragment.setFriendsCount(friends.count); - } else if(message == HandlerMessages.OVKAPI_USERS_SEARCH) { - users.parseSearch(data.getString("response")); - users.getUser(ovk_api, users.getList().get(0).id); - } else if (message == HandlerMessages.OVKAPI_WALL_GET) { - wall.parse(this, downloadManager, "high", data.getString("response")); - profileFragment.createWallAdapter(this, wall.getWallItems()); - } else if(message == HandlerMessages.DLM_WALL_AVATARS - || message == HandlerMessages.DLM_WALL_ATTACHMENTS) { + user.downloadAvatar(ovk_api.dlman, "high", "profile_avatars"); + ovk_api.wall.get(ovk_api.wrapper, user.id, 50); + ovk_api.friends.get(ovk_api.wrapper, user.id, 25, "profile_counter"); + } else if (message == HandlerMessages.FRIENDS_GET_ALT) { + profileFragment.setFriendsCount(ovk_api.friends.count); + } else if(message == HandlerMessages.USERS_SEARCH) { + ovk_api.users.getUser(ovk_api.wrapper, ovk_api.users.getList().get(0).id); + } else if (message == HandlerMessages.WALL_GET) { + profileFragment.createWallAdapter(this, ovk_api.wall.getWallItems()); + } else if(message == HandlerMessages.WALL_AVATARS + || message == HandlerMessages.WALL_ATTACHMENTS) { if (profileFragment.getWallAdapter() == null) { - profileFragment.createWallAdapter(this, wall.getWallItems()); + profileFragment.createWallAdapter(this, ovk_api.wall.getWallItems()); } try { - if (message == HandlerMessages.DLM_WALL_AVATARS) { + if (message == HandlerMessages.WALL_AVATARS) { profileFragment.getWallAdapter().setAvatarLoadState(true); } else { profileFragment.getWallAdapter().setPhotoLoadState(true); @@ -273,43 +224,18 @@ private void receiveState(int message, Bundle data) { } catch (Exception ignored) { } profileFragment.refreshWallAdapter(); - } else if(message == HandlerMessages.OVKAPI_FRIENDS_ADD) { - JSONObject response = new JSONParser().parseJSON(data.getString("response")); - user.friends_status = response.getInt("response"); - profileFragment.setFriendStatus(account.user, user.friends_status); - } else if(message == HandlerMessages.OVKAPI_FRIENDS_DELETE) { - JSONObject response = new JSONParser().parseJSON(data.getString("response")); - int status = response.getInt("response"); - if(status == 1) { - user.friends_status = 0; - } - profileFragment.setFriendStatus(account.user, user.friends_status); - } else if(message == HandlerMessages.DLM_PROFILE_AVATARS) { - profileFragment.setData(user, friends, account, ovk_api); + } else if(message == HandlerMessages.FRIENDS_ADD) { + profileFragment.setFriendStatus(ovk_api.account.user, user.friends_status); + } else if(message == HandlerMessages.FRIENDS_DELETE) { + profileFragment.setFriendStatus(ovk_api.account.user, user.friends_status); + } else if(message == HandlerMessages.PROFILE_AVATARS) { + profileFragment.setData(user, ovk_api.friends, ovk_api.account, ovk_api.wrapper); } } catch (Exception ex) { ex.printStackTrace(); } } - public void openProfileFromWall(int position) { - WallPost post = wall.getWallItems().get(position); - String url = ""; - if(post.author_id != user.id) { - if (post.author_id > 0) { - url = String.format("openvk://profile/id%s", post.author_id); - } else if (post.author_id < 0) { - url = String.format("openvk://group/club%s", post.author_id); - } - - if (url.length() > 0) { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - startActivity(i); - } - } - } - @Override public void onMonetColorsChanged(@NonNull MonetCompat monet, @NonNull ColorScheme monetColors, boolean isInitialChange) { diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/QuickSearchActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/QuickSearchActivity.java index 523bbc7..bff52fc 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/QuickSearchActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/QuickSearchActivity.java @@ -1,10 +1,7 @@ package uk.openvk.android.refresh.ui.core.activities; -import static java.security.AccessController.getContext; - import android.annotation.SuppressLint; import android.content.Intent; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; @@ -12,8 +9,10 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; -import android.os.Message; -import android.util.Log; + +import com.mancj.materialsearchbar.MaterialSearchBar; + +import java.util.List; import androidx.annotation.Nullable; import androidx.core.view.WindowCompat; @@ -21,38 +20,19 @@ import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - -import com.kieronquinn.monetcompat.app.MonetCompatActivity; -import com.mancj.materialsearchbar.MaterialSearchBar; - -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; - import io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Groups; -import uk.openvk.android.refresh.api.Users; +import uk.openvk.android.refresh.api.entities.Group; +import uk.openvk.android.refresh.api.entities.User; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.Group; -import uk.openvk.android.refresh.api.models.User; -import uk.openvk.android.refresh.api.models.WallPost; -import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.core.enumerations.UiMessages; import uk.openvk.android.refresh.ui.list.sections.CommunitiesSearchSection; import uk.openvk.android.refresh.ui.list.sections.PeopleSearchSection; -public class QuickSearchActivity extends MonetCompatActivity { - private SharedPreferences global_prefs; - private SharedPreferences instance_prefs; - public Handler handler; - private OvkAPIWrapper ovk_api; - private DownloadManager downloadManager; +public class QuickSearchActivity extends NetworkActivity { private boolean isDarkTheme; - private Users users; - private Groups groups; private MaterialSearchBar searchBar; private SectionedRecyclerViewAdapter sectionAdapter; private PeopleSearchSection peopleSection; @@ -98,15 +78,14 @@ public void onSearchConfirmed(CharSequence text) { peopleSection = null; commsSection = null; } - groups.search(ovk_api, query); - users.search(ovk_api, query); + ovk_api.groups.search(ovk_api.wrapper, query); + ovk_api.users.search(ovk_api.wrapper, query); } @Override public void onButtonClicked(int buttonCode) { } }); - setAPIWrapper(); } @SuppressLint("NotifyDataSetChanged") @@ -118,45 +97,27 @@ private void createSearchResultsAdapter(RecyclerView rv) { } if(commsSection == null) { commsSection = new CommunitiesSearchSection(QuickSearchActivity.this, - groups.getList()); + ovk_api.groups.getList()); sectionAdapter.addSection(commsSection); } else { commsSection = new CommunitiesSearchSection(QuickSearchActivity.this, - groups.getList()); + ovk_api.groups.getList()); } if(peopleSection == null) { peopleSection = new PeopleSearchSection(QuickSearchActivity.this, - users.getList()); + ovk_api.users.getList()); sectionAdapter.addSection(peopleSection); } else { peopleSection = new PeopleSearchSection(QuickSearchActivity.this, - users.getList()); + ovk_api.users.getList()); } } - private void setAPIWrapper() { - ovk_api = new OvkAPIWrapper(this); - downloadManager = new DownloadManager(this); - ovk_api.setServer(instance_prefs.getString("server", "")); - ovk_api.setAccessToken(instance_prefs.getString("access_token", "")); - users = new Users(); - groups = new Groups(); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - Log.d("OpenVK", String.format("Handling API message: %s", msg.what)); - receiveState(msg.what, msg.getData()); - } - }; - } - @SuppressLint("NotifyDataSetChanged") - private void receiveState(int message, Bundle data) { - if(message == HandlerMessages.OVKAPI_USERS_SEARCH) { - users.parseSearch(data.getString("response")); + public void receiveState(int message, Bundle data) { + if(message == HandlerMessages.USERS_SEARCH) { handler.sendEmptyMessage(UiMessages.UPTIME_QUICK_SEARCH); - } else if(message == HandlerMessages.OVKAPI_GROUPS_SEARCH) { - groups.parseSearch(data.getString("response")); + } else if(message == HandlerMessages.GROUPS_SEARCH) { handler.sendEmptyMessage(UiMessages.UPTIME_QUICK_SEARCH); } else if(message == UiMessages.UPTIME_QUICK_SEARCH) { final RecyclerView searchResultsView = findViewById(R.id.results_rv); @@ -169,7 +130,7 @@ private void setMonetTheme() { } public void openProfile(int position) { - User user = users.getList().get(position); + User user = ovk_api.users.getList().get(position); String url = ""; if(user.id > 0) { url = String.format("openvk://profile/id%s", user.id); @@ -191,7 +152,7 @@ public void openProfile(int position) { } public void openGroup(int position) { - Group group = groups.getList().get(position); + Group group = ovk_api.groups.getList().get(position); String url = ""; if(group.id > 0) { url = String.format("openvk://group/club%s", group.id); diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/VideoPlayerActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/VideoPlayerActivity.java index 6a213a9..bdffa34 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/VideoPlayerActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/VideoPlayerActivity.java @@ -33,9 +33,10 @@ import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; import uk.openvk.android.refresh.api.attachments.VideoAttachment; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.util.OvkAlertDialogBuilder; -public class VideoPlayerActivity extends MonetCompatActivity { +public class VideoPlayerActivity extends NetworkActivity { private VideoAttachment video; private String url; private LibVLC vlc; diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/WallPostActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/WallPostActivity.java index d18e42b..2a6400c 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/WallPostActivity.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/WallPostActivity.java @@ -1,83 +1,63 @@ package uk.openvk.android.refresh.ui.core.activities; import android.annotation.SuppressLint; -import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; import android.text.Editable; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; -import android.util.Log; import android.util.TypedValue; import android.view.View; import android.widget.TextView; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.appcompat.widget.AppCompatImageButton; -import androidx.appcompat.widget.Toolbar; -import androidx.preference.PreferenceManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.color.MaterialColors; import com.google.android.material.textfield.TextInputEditText; -import com.kieronquinn.monetcompat.app.MonetCompatActivity; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Objects; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.AppCompatImageButton; +import androidx.appcompat.widget.Toolbar; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.Wall; +import uk.openvk.android.refresh.api.entities.Comment; +import uk.openvk.android.refresh.api.entities.WallPost; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.Comment; -import uk.openvk.android.refresh.api.models.WallPost; -import uk.openvk.android.refresh.api.wrappers.DownloadManager; -import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; +import uk.openvk.android.refresh.ui.core.activities.base.NetworkActivity; import uk.openvk.android.refresh.ui.list.adapters.CommentsAdapter; import uk.openvk.android.refresh.ui.view.layouts.SendTextBottomPanel; -public class WallPostActivity extends MonetCompatActivity { - private SharedPreferences global_prefs; +public class WallPostActivity extends NetworkActivity { private boolean isDarkTheme; - private WallPost wallPost; private Toolbar toolbar; - private Wall wall; - private Account account; - private SharedPreferences instance_prefs; - private OvkAPIWrapper ovk_api; - private DownloadManager downloadManager; - public Handler handler; - private ArrayList comments; + public ArrayList comments; private CommentsAdapter commentsAdapter; private RecyclerView comments_rv; private LinearLayoutManager llm; private SendTextBottomPanel bottomPanel; private Comment last_sended_comment; + private WallPost wallPost; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - global_prefs = PreferenceManager.getDefaultSharedPreferences(this); try { if (global_prefs.getBoolean("dark_theme", false)) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); } - instance_prefs = getSharedPreferences("instance", 0); Global.setColorTheme(this, global_prefs.getString("theme_color", "blue"), getWindow()); Global.setInterfaceFont(this); @@ -88,7 +68,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { wallPost.counters = savedInstanceState.getParcelable("counters"); } else { if (getIntent().getExtras() != null) { - account = getIntent().getExtras().getParcelable("account"); + ovk_api.account = getIntent().getExtras().getParcelable("account"); wallPost = getIntent().getExtras().getParcelable("post"); wallPost.counters = getIntent().getExtras().getParcelable("counters"); } @@ -107,31 +87,17 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } private void setAPIWrapper() { - ovk_api = new OvkAPIWrapper(this); - downloadManager = new DownloadManager(this); - ovk_api.setServer(instance_prefs.getString("server", "")); - ovk_api.setAccessToken(instance_prefs.getString("access_token", "")); - handler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - Log.d("OpenVK", String.format("Handling API message: %s", msg.what)); - receiveState(msg.what, msg.getData()); - } - }; - account = new Account(this); - account.getProfileInfo(ovk_api); - wall = new Wall(); - wall.getComments(ovk_api, wallPost.owner_id, wallPost.post_id); + ovk_api.account.getProfileInfo(ovk_api.wrapper); + ovk_api.wall.getComments(ovk_api.wrapper, wallPost.owner_id, wallPost.post_id); } - private void receiveState(int message, Bundle data) { - if(message == HandlerMessages.OVKAPI_ACCOUNT_PROFILE_INFO) { - account.parse(data.getString("response"), ovk_api); + public void receiveState(int message, Bundle data) { + if(message == HandlerMessages.ACCOUNT_PROFILE_INFO) { + ovk_api.account.parse(data.getString("response"), ovk_api.wrapper); setBottomPanel(); - } else if (message == HandlerMessages.OVKAPI_WALL_ALL_COMMENTS) { - comments = wall.parseComments(this, downloadManager, data.getString("response")); + } else if (message == HandlerMessages.WALL_ALL_COMMENTS) { createCommentsAdapter(comments); - } else if (message == HandlerMessages.DLM_COMMENT_AVATARS) { + } else if (message == HandlerMessages.COMMENT_AVATARS) { loadCommentatorAvatars(); } } @@ -206,11 +172,8 @@ private void setBottomPanel() { public void onClick(View v) { if(bottomPanel.getText().length() > 0) { try { - last_sended_comment = new Comment(0, account.id, - String.format("%s %s", account.first_name, account.last_name), - (int) (System.currentTimeMillis() / 1000), - bottomPanel.getText()); - wall.createComment(ovk_api, wallPost.owner_id, + last_sended_comment = new Comment(); + ovk_api.wall.createComment(ovk_api.wrapper, wallPost.owner_id, wallPost.post_id, bottomPanel.getText()); if(comments == null) { comments = new ArrayList<>(); @@ -241,22 +204,18 @@ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { AppCompatImageButton send_btn = bottomPanel.findViewById(R.id.send_btn); - if(bottomPanel.getText().length() > 0) { - send_btn.setEnabled(true); - } else { - send_btn.setEnabled(false); - } + send_btn.setEnabled(bottomPanel.getText().length() > 0); } @Override public void afterTextChanged(Editable editable) { - if(((TextInputEditText) bottomPanel.findViewById(R.id.send_text)).getLineCount() > 4) { - ((TextInputEditText) bottomPanel.findViewById(R.id.send_text)).setLines(4); - } else { - ((TextInputEditText) bottomPanel.findViewById(R.id.send_text)).setLines( - ((TextInputEditText) bottomPanel.findViewById(R.id.send_text)). - getLineCount()); - } + ((TextInputEditText) bottomPanel.findViewById(R.id.send_text)) + .setLines( + Math.min( + ((TextInputEditText) bottomPanel.findViewById(R.id.send_text)) + .getLineCount(), 4 + ) + ); } }); } diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/base/NetworkActivity.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/base/NetworkActivity.java new file mode 100644 index 0000000..2eff3a4 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/activities/base/NetworkActivity.java @@ -0,0 +1,123 @@ +package uk.openvk.android.refresh.ui.core.activities.base; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; + +import com.kieronquinn.monetcompat.app.MonetCompatActivity; + +import androidx.annotation.Nullable; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import androidx.preference.PreferenceManager; +import uk.openvk.android.refresh.BuildConfig; +import uk.openvk.android.refresh.OvkApplication; +import uk.openvk.android.refresh.api.OpenVKAPI; +import uk.openvk.android.refresh.api.enumerations.HandlerMessages; +import uk.openvk.android.refresh.api.interfaces.OvkAPIListeners; +import uk.openvk.android.refresh.receivers.OvkAPIReceiver; + +public class NetworkActivity extends MonetCompatActivity { + public OpenVKAPI ovk_api; + public SharedPreferences global_prefs; + public SharedPreferences instance_prefs; + public SharedPreferences.Editor global_prefs_editor; + public SharedPreferences.Editor instance_prefs_editor; + public Handler handler; + private OvkAPIReceiver receiver; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + global_prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + instance_prefs = ((OvkApplication) getApplicationContext()).getAccountPreferences(); + global_prefs_editor = global_prefs.edit(); + instance_prefs_editor = instance_prefs.edit(); + handler = new Handler(Looper.myLooper()); + ovk_api = new OpenVKAPI(this, global_prefs, instance_prefs, handler); + OvkAPIListeners apiListeners = new OvkAPIListeners(); + setAPIListeners(apiListeners); + registerAPIDataReceiver(); + } + + public void registerAPIDataReceiver() { + receiver = new OvkAPIReceiver(this); + LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter( + "uk.openvk.android.legacy.API_DATA_RECEIVE")); + } + + private void setAPIListeners(final OvkAPIListeners listeners) { + listeners.from = getLocalClassName(); + listeners.successListener = new OvkAPIListeners.OnAPISuccessListener() { + @Override + public void onAPISuccess(final Context ctx, int msg_code, final Bundle data) { + if(!BuildConfig.BUILD_TYPE.equals("release")) + Log.d(OvkApplication.APP_TAG, + String.format( + "Handling API message %s in %s", + msg_code, + getLocalClassName() + ) + ); + if(msg_code == HandlerMessages.PARSE_JSON) { + new Thread(new Runnable() { + @Override + public void run() { + Intent intent = new Intent(); + intent.setAction("uk.openvk.android.legacy.API_DATA_RECEIVE"); + data.putString("address", listeners.from); + intent.putExtras(data); + LocalBroadcastManager.getInstance(ctx).sendBroadcast(intent); + } + }).start(); + } else { + receiveState(msg_code, data); + } + } + }; + listeners.failListener = new OvkAPIListeners.OnAPIFailListener() { + @Override + public void onAPIFailed(Context ctx, int msg_code, final Bundle data) { + if(!BuildConfig.BUILD_TYPE.equals("release")) + Log.d(OvkApplication.APP_TAG, + String.format( + "Handling API message %s in %s", + msg_code, + getLocalClassName() + ) + ); + receiveState(msg_code, data); + } + }; + listeners.processListener = new OvkAPIListeners.OnAPIProcessListener() { + @Override + public void onAPIProcess(Context ctx, Bundle data, long value, long length) { + if(!BuildConfig.BUILD_TYPE.equals("release")) + Log.d(OvkApplication.APP_TAG, + String.format( + "Handling API message %s in %s", + HandlerMessages.UPLOAD_PROGRESS, + getLocalClassName() + ) + ); + receiveState(HandlerMessages.UPLOAD_PROGRESS, data); + } + }; + ovk_api.wrapper.setAPIListeners(listeners); + ovk_api.dlman.setAPIListeners(listeners); + ovk_api.ulman.setAPIListeners(listeners); + } + + public void receiveState(int message, Bundle data) { + } + + @Override + protected void onDestroy() { + LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver); + super.onDestroy(); + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/CommunityFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/CommunityFragment.java index 9de1a84..6cda76a 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/CommunityFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/CommunityFragment.java @@ -12,41 +12,38 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toolbar; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.preference.PreferenceManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import androidx.viewpager2.widget.ViewPager2; import com.bumptech.glide.Glide; import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; import java.util.ArrayList; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.preference.PreferenceManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.viewpager2.widget.ViewPager2; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; +import uk.openvk.android.refresh.api.entities.Group; +import uk.openvk.android.refresh.api.entities.WallPost; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.Group; -import uk.openvk.android.refresh.api.models.WallPost; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; import uk.openvk.android.refresh.ui.core.activities.AppActivity; import uk.openvk.android.refresh.ui.core.activities.GroupIntentActivity; import uk.openvk.android.refresh.ui.core.fragments.app.pub_pages.AboutFragment; import uk.openvk.android.refresh.ui.core.fragments.app.pub_pages.WallFragment; import uk.openvk.android.refresh.ui.core.listeners.AppBarStateChangeListener; +import uk.openvk.android.refresh.ui.list.adapters.NewsfeedAdapter; import uk.openvk.android.refresh.ui.list.adapters.PublicPageAboutAdapter; import uk.openvk.android.refresh.ui.list.items.PublicPageAboutItem; import uk.openvk.android.refresh.ui.view.layouts.ErrorLayout; import uk.openvk.android.refresh.ui.view.layouts.ProfileHeader; import uk.openvk.android.refresh.ui.view.layouts.ProgressLayout; -import uk.openvk.android.refresh.ui.list.adapters.NewsfeedAdapter; import uk.openvk.android.refresh.ui.view.pager.adapters.PublicPagerAdapter; public class CommunityFragment extends Fragment implements AppBarLayout.OnOffsetChangedListener { @@ -208,17 +205,17 @@ public void setError(boolean visible, int message, View.OnClickListener listener ((ProgressLayout) view.findViewById(R.id.progress_layout)).setVisibility(View.GONE); errorLayout.setVisibility(View.VISIBLE); errorLayout.setRetryButtonClickListener(listener); - if(message == HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION) { + if(message == HandlerMessages.NO_INTERNET_CONNECTION) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_no_internet); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) .setText(R.string.error_subtitle); - } else if(message == HandlerMessages.OVKAPI_INTERNAL_ERROR || message == HandlerMessages.OVKAPI_UNKNOWN_ERROR) { + } else if(message == HandlerMessages.INTERNAL_ERROR || message == HandlerMessages.UNKNOWN_ERROR) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_instance_failure); ((TextView) errorLayout.findViewById(R.id.error_subtitle)). setText(R.string.error_subtitle_instance); - } else if(message == HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE) { + } else if(message == HandlerMessages.INSTANCE_UNAVAILABLE) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_instance); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/FriendsFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/FriendsFragment.java index 7d0de1e..e445163 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/FriendsFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/FriendsFragment.java @@ -6,12 +6,18 @@ import android.graphics.Color; import android.os.Bundle; import android.os.Handler; -import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import com.google.android.material.color.MaterialColors; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import com.kieronquinn.monetcompat.core.MonetCompat; + +import java.util.ArrayList; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -20,28 +26,18 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.viewpager2.widget.ViewPager2; - -import com.google.android.material.color.MaterialColors; -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; -import com.kieronquinn.monetcompat.core.MonetCompat; - -import java.util.ArrayList; -import java.util.Objects; - import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Conversation; -import uk.openvk.android.refresh.api.models.Friend; +import uk.openvk.android.refresh.api.entities.Conversation; +import uk.openvk.android.refresh.api.entities.Friend; import uk.openvk.android.refresh.ui.core.activities.AppActivity; import uk.openvk.android.refresh.ui.core.activities.FriendsIntentActivity; import uk.openvk.android.refresh.ui.core.fragments.app.friends.FriendRequestsFragment; import uk.openvk.android.refresh.ui.core.fragments.app.friends.FriendsListFragment; -import uk.openvk.android.refresh.ui.core.listeners.OnRecyclerScrollListener; import uk.openvk.android.refresh.ui.list.adapters.FriendRequestsAdapter; +import uk.openvk.android.refresh.ui.list.adapters.FriendsAdapter; import uk.openvk.android.refresh.ui.view.InfinityRecyclerView; import uk.openvk.android.refresh.ui.view.layouts.ProgressLayout; -import uk.openvk.android.refresh.ui.list.adapters.FriendsAdapter; import uk.openvk.android.refresh.ui.view.pager.adapters.FriendsPagerAdapter; public class FriendsFragment extends Fragment { diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/GroupsFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/GroupsFragment.java index f3b69fa..f52ec85 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/GroupsFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/GroupsFragment.java @@ -9,6 +9,10 @@ import android.view.View; import android.view.ViewGroup; +import com.kieronquinn.monetcompat.core.MonetCompat; + +import java.util.ArrayList; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -18,21 +22,15 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.kieronquinn.monetcompat.core.MonetCompat; - -import java.util.ArrayList; -import java.util.Objects; - import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Conversation; -import uk.openvk.android.refresh.api.models.Group; +import uk.openvk.android.refresh.api.entities.Conversation; +import uk.openvk.android.refresh.api.entities.Group; import uk.openvk.android.refresh.ui.core.activities.AppActivity; +import uk.openvk.android.refresh.ui.list.adapters.GroupsAdapter; import uk.openvk.android.refresh.ui.view.layouts.ErrorLayout; import uk.openvk.android.refresh.ui.view.layouts.ProgressLayout; -import uk.openvk.android.refresh.ui.list.adapters.GroupsAdapter; public class GroupsFragment extends Fragment { private View view; diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/MessagesFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/MessagesFragment.java index 8253d9f..341ec1a 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/MessagesFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/MessagesFragment.java @@ -9,6 +9,10 @@ import android.view.View; import android.view.ViewGroup; +import com.kieronquinn.monetcompat.core.MonetCompat; + +import java.util.ArrayList; + import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.preference.PreferenceManager; @@ -16,21 +20,15 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.kieronquinn.monetcompat.core.MonetCompat; - -import java.util.ArrayList; -import java.util.Objects; - import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.models.Conversation; +import uk.openvk.android.refresh.api.entities.Account; +import uk.openvk.android.refresh.api.entities.Conversation; import uk.openvk.android.refresh.ui.core.activities.AppActivity; +import uk.openvk.android.refresh.ui.list.adapters.ConversationsAdapter; import uk.openvk.android.refresh.ui.view.layouts.ErrorLayout; import uk.openvk.android.refresh.ui.view.layouts.ProgressLayout; -import uk.openvk.android.refresh.ui.list.adapters.ConversationsAdapter; public class MessagesFragment extends Fragment { private View view; diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/NewsfeedFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/NewsfeedFragment.java index 981641c..5c6e2c1 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/NewsfeedFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/NewsfeedFragment.java @@ -3,7 +3,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; -import android.content.res.ColorStateList; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -11,34 +10,30 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; import android.widget.TextView; +import com.kieronquinn.monetcompat.core.MonetCompat; + +import java.util.ArrayList; + import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.google.android.material.button.MaterialButton; -import com.kieronquinn.monetcompat.core.MonetCompat; - -import java.util.ArrayList; -import java.util.Objects; - import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; +import uk.openvk.android.refresh.api.entities.WallPost; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.WallPost; import uk.openvk.android.refresh.ui.core.activities.AppActivity; import uk.openvk.android.refresh.ui.core.activities.GroupIntentActivity; import uk.openvk.android.refresh.ui.core.activities.ProfileIntentActivity; +import uk.openvk.android.refresh.ui.list.adapters.NewsfeedAdapter; import uk.openvk.android.refresh.ui.view.InfinityRecyclerView; import uk.openvk.android.refresh.ui.view.layouts.ErrorLayout; import uk.openvk.android.refresh.ui.view.layouts.ProgressLayout; -import uk.openvk.android.refresh.ui.list.adapters.NewsfeedAdapter; public class NewsfeedFragment extends Fragment { private LinearLayoutManager layoutManager; @@ -116,13 +111,13 @@ public void createAdapter(Context ctx, ArrayList wallPosts) { if(newsfeedAdapter == null) { if(ctx instanceof AppActivity) { newsfeedAdapter = new NewsfeedAdapter(getActivity(), this.wallPosts, - ((AppActivity) ctx).account); + ((AppActivity) ctx).ovk_api.account); } else if(ctx instanceof ProfileIntentActivity) { newsfeedAdapter = new NewsfeedAdapter(getActivity(), this.wallPosts, - ((ProfileIntentActivity) ctx).account); + ((ProfileIntentActivity) ctx).ovk_api.account); } else if(ctx instanceof GroupIntentActivity) { newsfeedAdapter = new NewsfeedAdapter(getActivity(), this.wallPosts, - ((GroupIntentActivity) ctx).account); + ((GroupIntentActivity) ctx).ovk_api.account); } llm = new LinearLayoutManager(ctx); llm.setOrientation(LinearLayoutManager.VERTICAL); @@ -161,23 +156,23 @@ public void setError(boolean visible, int message, View.OnClickListener listener ((ProgressLayout) view.findViewById(R.id.progress_layout)).setVisibility(View.GONE); errorLayout.setVisibility(View.VISIBLE); errorLayout.setRetryButtonClickListener(listener); - if(message == HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION) { + if(message == HandlerMessages.NO_INTERNET_CONNECTION) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_no_internet); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) .setText(R.string.error_subtitle); - } else if(message == HandlerMessages.OVKAPI_CONNECTION_TIMEOUT) { + } else if(message == HandlerMessages.CONNECTION_TIMEOUT) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_instance_nrps); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) .setText(R.string.error_subtitle_instance); - } else if(message == HandlerMessages.OVKAPI_INTERNAL_ERROR - || message == HandlerMessages.OVKAPI_UNKNOWN_ERROR) { + } else if(message == HandlerMessages.INTERNAL_ERROR + || message == HandlerMessages.UNKNOWN_ERROR) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_instance_failure); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) .setText(R.string.error_subtitle_instance); - } else if(message == HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE) { + } else if(message == HandlerMessages.INSTANCE_UNAVAILABLE) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_instance); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/ProfileFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/ProfileFragment.java index aefa452..1589eaf 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/ProfileFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/ProfileFragment.java @@ -18,20 +18,10 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toolbar; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.preference.PreferenceManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import androidx.viewpager2.widget.ViewPager2; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.button.MaterialButton; import com.google.android.material.color.MaterialColors; import com.google.android.material.tabs.TabLayout; @@ -40,29 +30,34 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.preference.PreferenceManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.viewpager2.widget.ViewPager2; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.Friends; +import uk.openvk.android.refresh.api.entities.Account; +import uk.openvk.android.refresh.api.entities.User; +import uk.openvk.android.refresh.api.entities.WallPost; import uk.openvk.android.refresh.api.enumerations.HandlerMessages; -import uk.openvk.android.refresh.api.models.User; -import uk.openvk.android.refresh.api.models.WallPost; +import uk.openvk.android.refresh.api.models.Friends; import uk.openvk.android.refresh.api.wrappers.OvkAPIWrapper; import uk.openvk.android.refresh.ui.core.activities.AppActivity; import uk.openvk.android.refresh.ui.core.activities.ConversationActivity; -import uk.openvk.android.refresh.ui.core.activities.GroupIntentActivity; import uk.openvk.android.refresh.ui.core.activities.ProfileIntentActivity; import uk.openvk.android.refresh.ui.core.fragments.app.pub_pages.AboutFragment; import uk.openvk.android.refresh.ui.core.fragments.app.pub_pages.WallFragment; import uk.openvk.android.refresh.ui.core.listeners.AppBarStateChangeListener; +import uk.openvk.android.refresh.ui.list.adapters.NewsfeedAdapter; import uk.openvk.android.refresh.ui.list.adapters.PublicPageAboutAdapter; import uk.openvk.android.refresh.ui.list.items.PublicPageAboutItem; import uk.openvk.android.refresh.ui.view.layouts.ErrorLayout; import uk.openvk.android.refresh.ui.view.layouts.ProfileHeader; import uk.openvk.android.refresh.ui.view.layouts.ProgressLayout; -import uk.openvk.android.refresh.ui.list.adapters.NewsfeedAdapter; import uk.openvk.android.refresh.ui.view.pager.adapters.PublicPagerAdapter; public class ProfileFragment extends Fragment implements AppBarLayout.OnOffsetChangedListener { @@ -369,17 +364,17 @@ public void setError(boolean visible, int message, View.OnClickListener listener ((ProgressLayout) view.findViewById(R.id.progress_layout)).setVisibility(View.GONE); errorLayout.setVisibility(View.VISIBLE); errorLayout.setRetryButtonClickListener(listener); - if(message == HandlerMessages.OVKAPI_NO_INTERNET_CONNECTION) { + if(message == HandlerMessages.NO_INTERNET_CONNECTION) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_no_internet); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) .setText(R.string.error_subtitle); - } else if(message == HandlerMessages.OVKAPI_INTERNAL_ERROR || message == HandlerMessages.OVKAPI_UNKNOWN_ERROR) { + } else if(message == HandlerMessages.INTERNAL_ERROR || message == HandlerMessages.UNKNOWN_ERROR) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_instance_failure); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) .setText(R.string.error_subtitle_instance); - } else if(message == HandlerMessages.OVKAPI_INSTANCE_UNAVAILABLE) { + } else if(message == HandlerMessages.INSTANCE_UNAVAILABLE) { ((TextView) errorLayout.findViewById(R.id.error_title)) .setText(R.string.error_instance); ((TextView) errorLayout.findViewById(R.id.error_subtitle)) diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/friends/FriendRequestsFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/friends/FriendRequestsFragment.java index 38f5cfe..1c353dd 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/friends/FriendRequestsFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/friends/FriendRequestsFragment.java @@ -4,12 +4,13 @@ import android.content.Context; import android.os.Bundle; import android.os.Handler; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; +import java.util.ArrayList; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -17,12 +18,9 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import java.util.ArrayList; - import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Friend; +import uk.openvk.android.refresh.api.entities.Friend; import uk.openvk.android.refresh.ui.list.adapters.FriendRequestsAdapter; import uk.openvk.android.refresh.ui.list.items.PublicPageAboutItem; diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/friends/FriendsListFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/friends/FriendsListFragment.java index 0fbe31c..f24ed2c 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/friends/FriendsListFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/friends/FriendsListFragment.java @@ -3,12 +3,13 @@ import android.annotation.SuppressLint; import android.content.Context; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; +import java.util.ArrayList; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -16,14 +17,10 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import java.util.ArrayList; - import uk.openvk.android.refresh.OvkApplication; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Friend; +import uk.openvk.android.refresh.api.entities.Friend; import uk.openvk.android.refresh.ui.list.adapters.FriendsAdapter; -import uk.openvk.android.refresh.ui.list.adapters.PublicPageAboutAdapter; public class FriendsListFragment extends Fragment { public View view; diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/pub_pages/WallFragment.java b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/pub_pages/WallFragment.java index d506107..f264db3 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/pub_pages/WallFragment.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/core/fragments/app/pub_pages/WallFragment.java @@ -9,16 +9,15 @@ import android.view.ViewGroup; import android.widget.LinearLayout; +import java.util.ArrayList; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - -import java.util.ArrayList; - import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.WallPost; +import uk.openvk.android.refresh.api.entities.WallPost; import uk.openvk.android.refresh.ui.core.activities.AppActivity; import uk.openvk.android.refresh.ui.core.activities.GroupIntentActivity; import uk.openvk.android.refresh.ui.core.activities.ProfileIntentActivity; @@ -69,13 +68,13 @@ public void createWallAdapter(Context ctx, ArrayList posts) { wallView.setLayoutManager(llm); if(ctx instanceof AppActivity) { wallAdapter = new NewsfeedAdapter(ctx, this.wallPosts, - ((AppActivity) ctx).account); + ((AppActivity) ctx).ovk_api.account); } else if(ctx instanceof ProfileIntentActivity) { wallAdapter = new NewsfeedAdapter(ctx, this.wallPosts, - ((ProfileIntentActivity) ctx).account); + ((ProfileIntentActivity) ctx).ovk_api.account); } else if(ctx instanceof GroupIntentActivity) { wallAdapter = new NewsfeedAdapter(ctx, this.wallPosts, - ((GroupIntentActivity) ctx).account); + ((GroupIntentActivity) ctx).ovk_api.account); } wallView.setAdapter(wallAdapter); } else { diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/CommentsAdapter.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/CommentsAdapter.java index e863169..2f98e96 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/CommentsAdapter.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/CommentsAdapter.java @@ -10,17 +10,16 @@ import android.widget.TextView; import android.widget.Toast; -import androidx.collection.LruCache; -import androidx.recyclerview.widget.RecyclerView; - import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.concurrent.TimeUnit; +import androidx.collection.LruCache; +import androidx.recyclerview.widget.RecyclerView; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Comment; +import uk.openvk.android.refresh.api.entities.Comment; public class CommentsAdapter extends RecyclerView.Adapter { diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/ConversationsAdapter.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/ConversationsAdapter.java index bb32888..4743a32 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/ConversationsAdapter.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/ConversationsAdapter.java @@ -2,25 +2,25 @@ import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - import com.bumptech.glide.load.engine.DiskCacheStrategy; import java.util.ArrayList; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; -import uk.openvk.android.refresh.api.models.Conversation; +import uk.openvk.android.refresh.api.entities.Account; +import uk.openvk.android.refresh.api.entities.Conversation; +import uk.openvk.android.refresh.ui.core.activities.ConversationActivity; import uk.openvk.android.refresh.ui.util.glide.GlideApp; -import uk.openvk.android.refresh.ui.core.activities.AppActivity; public class ConversationsAdapter extends RecyclerView.Adapter { private final Account account; @@ -78,7 +78,8 @@ void bind(final int position) { Global.setAvatarShape(ctx, convertView.findViewById(R.id.conv_avatar)); ((ImageView) convertView.findViewById(R.id.conv_avatar)).setImageTintList(null); GlideApp.with(ctx) - .load(String.format("%s/photos_cache/conversations_avatars/avatar_%s", ctx.getCacheDir().getAbsolutePath(), item.peer_id)) + .load(String.format("%s/photos_cache/conversations_avatars/avatar_%s", + ctx.getCacheDir().getAbsolutePath(), item.peer_id)) .error(ctx.getResources().getDrawable(R.drawable.circular_avatar)) .diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true) .dontAnimate().centerCrop() @@ -88,13 +89,25 @@ void bind(final int position) { @Override public void onClick(View v) { if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).openConversation(position); + openConversation(item); } } }); } } + public void openConversation(Conversation conv) { + Intent intent = new Intent(ctx, ConversationActivity.class); + try { + intent.putExtra("peer_id", conv.peer_id); + intent.putExtra("conv_title", conv.title); + intent.putExtra("online", conv.online); + ctx.startActivity(intent); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + @Override public int getItemViewType(int position) { return position; diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/FriendRequestsAdapter.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/FriendRequestsAdapter.java index a41a518..3bd6b28 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/FriendRequestsAdapter.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/FriendRequestsAdapter.java @@ -2,26 +2,29 @@ import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.RecyclerView; - import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.google.android.material.button.MaterialButton; import java.util.ArrayList; +import java.util.List; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Friend; +import uk.openvk.android.refresh.api.entities.Friend; import uk.openvk.android.refresh.ui.core.activities.AppActivity; -import uk.openvk.android.refresh.ui.core.activities.FriendsIntentActivity; import uk.openvk.android.refresh.ui.core.fragments.app.FriendsFragment; import uk.openvk.android.refresh.ui.util.glide.GlideApp; @@ -86,11 +89,7 @@ void bind(final int position) { View.OnClickListener openProfileListener = new View.OnClickListener() { @Override public void onClick(View v) { - if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).openProfileFromFriends(position, true); - } else if(ctx.getClass().getSimpleName().equals("FriendsIntentActivity")) { - ((FriendsIntentActivity) ctx).openProfileFromFriends(position); - } + openProfile(item); } }; add_btn.setOnClickListener(new View.OnClickListener() { @@ -118,4 +117,23 @@ public int getItemViewType(int position) { private Friend getItem(int position) { return items.get(position); } + + public void openProfile(Friend friend) { + String url = ""; + url = String.format("openvk://profile/id%s", friend.id); + if(url.length() > 0) { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + final PackageManager pm = ctx.getPackageManager(); + @SuppressLint("QueryPermissionsNeeded") List activityList = + pm.queryIntentActivities(i, 0); + for (int index = 0; index < activityList.size(); index++) { + ResolveInfo app = activityList.get(index); + if (app.activityInfo.name.contains("uk.openvk.android.refresh")) { + i.setClassName(app.activityInfo.packageName, app.activityInfo.name); + } + } + ctx.startActivity(i); + } + } } diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/FriendsAdapter.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/FriendsAdapter.java index 3cce90b..2c95b12 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/FriendsAdapter.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/FriendsAdapter.java @@ -2,31 +2,33 @@ import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.graphics.Color; +import android.net.Uri; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.preference.PreferenceManager; -import androidx.recyclerview.widget.RecyclerView; - import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.google.android.material.color.MaterialColors; import com.kieronquinn.monetcompat.core.MonetCompat; import java.util.ArrayList; +import java.util.List; import java.util.Objects; +import androidx.annotation.NonNull; +import androidx.preference.PreferenceManager; +import androidx.recyclerview.widget.RecyclerView; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Friend; -import uk.openvk.android.refresh.ui.core.activities.FriendsIntentActivity; +import uk.openvk.android.refresh.api.entities.Friend; import uk.openvk.android.refresh.ui.util.glide.GlideApp; -import uk.openvk.android.refresh.ui.core.activities.AppActivity; public class FriendsAdapter extends RecyclerView.Adapter { private Context ctx; @@ -90,11 +92,7 @@ void bind(final int position) { View.OnClickListener openProfileListener = new View.OnClickListener() { @Override public void onClick(View v) { - if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).openProfileFromFriends(position, false); - } else if(ctx.getClass().getSimpleName().equals("FriendsIntentActivity")) { - ((FriendsIntentActivity) ctx).openProfileFromFriends(position); - } + openProfile(item); } }; setTheme(convertView); @@ -131,4 +129,23 @@ public int getItemViewType(int position) { private Friend getItem(int position) { return items.get(position); } + + public void openProfile(Friend friend) { + String url = ""; + url = String.format("openvk://profile/id%s", friend.id); + if(url.length() > 0) { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + final PackageManager pm = ctx.getPackageManager(); + @SuppressLint("QueryPermissionsNeeded") List activityList = + pm.queryIntentActivities(i, 0); + for (int index = 0; index < activityList.size(); index++) { + ResolveInfo app = activityList.get(index); + if (app.activityInfo.name.contains("uk.openvk.android.refresh")) { + i.setClassName(app.activityInfo.packageName, app.activityInfo.name); + } + } + ctx.startActivity(i); + } + } } diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/GroupsAdapter.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/GroupsAdapter.java index 199bf04..9cb0f49 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/GroupsAdapter.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/GroupsAdapter.java @@ -2,24 +2,27 @@ import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - import com.bumptech.glide.load.engine.DiskCacheStrategy; import java.util.ArrayList; +import java.util.List; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Group; +import uk.openvk.android.refresh.api.entities.Group; import uk.openvk.android.refresh.ui.util.glide.GlideApp; -import uk.openvk.android.refresh.ui.core.activities.AppActivity; public class GroupsAdapter extends RecyclerView.Adapter { private Context ctx; @@ -84,9 +87,7 @@ void bind(final int position) { convertView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).openCommunityPage(position); - } + openCommunityPage(item); } }); } @@ -100,4 +101,23 @@ public int getItemViewType(int position) { private Group getItem(int position) { return items.get(position); } + + public void openCommunityPage(Group group) { + String url = ""; + url = String.format("openvk://group/club%s", group.id); + if(url.length() > 0) { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + final PackageManager pm = ctx.getPackageManager(); + @SuppressLint("QueryPermissionsNeeded") List + activityList = pm.queryIntentActivities(i, 0); + for (int index = 0; index < activityList.size(); index++) { + ResolveInfo app = activityList.get(index); + if (app.activityInfo.name.contains("uk.openvk.android.refresh")) { + i.setClassName(app.activityInfo.packageName, app.activityInfo.name); + } + } + ctx.startActivity(i); + } + } } diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/MessagesAdapter.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/MessagesAdapter.java index d285f18..02e1c8e 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/MessagesAdapter.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/MessagesAdapter.java @@ -11,11 +11,6 @@ import android.widget.ProgressBar; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.cardview.widget.CardView; -import androidx.preference.PreferenceManager; -import androidx.recyclerview.widget.RecyclerView; - import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.google.android.material.color.MaterialColors; import com.kieronquinn.monetcompat.core.MonetCompat; @@ -23,9 +18,13 @@ import java.util.ArrayList; import java.util.Objects; +import androidx.annotation.NonNull; +import androidx.cardview.widget.CardView; +import androidx.preference.PreferenceManager; +import androidx.recyclerview.widget.RecyclerView; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Message; +import uk.openvk.android.refresh.api.entities.Message; import uk.openvk.android.refresh.ui.util.glide.GlideApp; public class MessagesAdapter extends RecyclerView.Adapter { diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/NewsfeedAdapter.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/NewsfeedAdapter.java index 55cf171..e0a715c 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/NewsfeedAdapter.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/adapters/NewsfeedAdapter.java @@ -3,13 +3,15 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.text.method.LinkMovementMethod; -import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; @@ -18,34 +20,30 @@ import android.widget.ImageView; import android.widget.TextView; -import androidx.fragment.app.FragmentManager; -import androidx.preference.PreferenceManager; -import androidx.recyclerview.widget.RecyclerView; - import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.google.android.material.color.MaterialColors; import com.google.android.material.imageview.ShapeableImageView; import com.kieronquinn.monetcompat.core.MonetCompat; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.concurrent.TimeUnit; +import java.util.List; +import androidx.fragment.app.FragmentManager; +import androidx.preference.PreferenceManager; +import androidx.recyclerview.widget.RecyclerView; import uk.openvk.android.refresh.Global; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.Account; +import uk.openvk.android.refresh.api.OpenVKAPI; import uk.openvk.android.refresh.api.attachments.Attachment; import uk.openvk.android.refresh.api.attachments.PhotoAttachment; import uk.openvk.android.refresh.api.attachments.VideoAttachment; -import uk.openvk.android.refresh.api.models.WallPost; +import uk.openvk.android.refresh.api.entities.Account; +import uk.openvk.android.refresh.api.entities.WallPost; import uk.openvk.android.refresh.ui.core.activities.AppActivity; -import uk.openvk.android.refresh.ui.core.activities.GroupIntentActivity; import uk.openvk.android.refresh.ui.core.activities.PhotoViewerActivity; -import uk.openvk.android.refresh.ui.core.activities.ProfileIntentActivity; import uk.openvk.android.refresh.ui.core.activities.VideoPlayerActivity; +import uk.openvk.android.refresh.ui.core.activities.WallPostActivity; import uk.openvk.android.refresh.ui.view.layouts.PhotoAttachmentLayout; import uk.openvk.android.refresh.ui.view.layouts.VideoAttachmentLayout; @@ -121,31 +119,6 @@ public Holder(View view) { void bind(final int position) { final WallPost item = getItem(position); poster_name.setText(item.name); - Date dt = new Date(TimeUnit.SECONDS.toMillis(item.dt_sec)); - Date dt_midnight = new Date(System.currentTimeMillis() + 86400000); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(dt_midnight); - calendar.set(Calendar.HOUR_OF_DAY, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - if((calendar.getTimeInMillis() - (TimeUnit.SECONDS.toMillis(item.dt_sec))) < 86400000) { - item.info = String.format(ctx.getResources().getStringArray(R.array.date_differences)[1], - new SimpleDateFormat("HH:mm").format(dt)); - } else if((calendar.getTimeInMillis() - (TimeUnit.SECONDS.toMillis(item.dt_sec))) < (86400000 * 2)) { - item.info = String.format(ctx.getResources().getStringArray(R.array.date_differences)[2], - new SimpleDateFormat("HH:mm").format(dt)); - } else if((calendar.getTimeInMillis() - (TimeUnit.SECONDS.toMillis(item.dt_sec))) - < 31536000000L) { - item.info = String.format(ctx.getResources().getStringArray(R.array.date_differences)[3], - new SimpleDateFormat("d MMMM").format(dt), - new SimpleDateFormat("HH:mm").format(dt)); - } else { - item.info = String.format(ctx.getResources().getStringArray(R.array.date_differences) - [3], - new SimpleDateFormat("d MMMM yyyy").format(dt), - new SimpleDateFormat("HH:mm").format(dt)); - } post_info.setText(item.info); if(item.verified_author) { @@ -196,7 +169,7 @@ public void onClick(View view) { } else if (ctx.getClass().getSimpleName().equals("GroupIntentActivity")) { //((GroupIntentActivity) ctx).deleteLike(position, "post", view); } else if (ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).deleteLike(position, "post", view); + deleteLike(item, position, "post", view); } } else { if(!likeDeleted) { @@ -207,7 +180,7 @@ public void onClick(View view) { } else if (ctx.getClass().getSimpleName().equals("GroupIntentActivity")) { //((GroupIntentActivity) ctx).addLike(position, "post", view); } else if (ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).addLike(position, "post", view); + addLike(item, position, "post", view); } } } @@ -216,7 +189,7 @@ public void onClick(View view) { post_comments.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Global.openPostComments(account, item, ctx); + openPostComments(item, ctx); } }); @@ -272,13 +245,7 @@ public void onClick(View v) { View.OnClickListener openProfileListener = new View.OnClickListener() { @Override public void onClick(View v) { - if(ctx.getClass().getSimpleName().equals("AppActivity")) { - ((AppActivity) ctx).openProfileFromWall(position); - } else if(ctx.getClass().getSimpleName().equals("ProfileIntentActivity")) { - ((ProfileIntentActivity) ctx).openProfileFromWall(position); - } else if(ctx.getClass().getSimpleName().equals("GroupIntentActivity")) { - ((GroupIntentActivity) ctx).openProfileFromWall(position); - } + openProfile(item); } }; (convertView.findViewById(R.id.profile_avatar)) @@ -396,6 +363,29 @@ private void setTheme(WallPost item) { } } + public void openProfile(WallPost post) { + String url = ""; + if(post.author_id > 0) { + url = String.format("openvk://profile/id%s", post.author_id); + } else if(post.author_id < 0) { + url = String.format("openvk://group/club%s", post.author_id); + } + if(url.length() > 0) { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + final PackageManager pm = ctx.getPackageManager(); + @SuppressLint("QueryPermissionsNeeded") List + activityList = pm.queryIntentActivities(i, 0); + for (int index = 0; index < activityList.size(); index++) { + ResolveInfo app = activityList.get(index); + if (app.activityInfo.name.contains("uk.openvk.android.refresh")) { + i.setClassName(app.activityInfo.packageName, app.activityInfo.name); + } + } + ctx.startActivity(i); + } + } + private void setTextViewDrawableColor(TextView textView, int color) { for (Drawable drawable : textView.getCompoundDrawablesRelative()) { if (drawable != null) { @@ -404,6 +394,13 @@ private void setTextViewDrawableColor(TextView textView, int color) { } } + public void openPostComments(WallPost post, Context ctx) { + Intent intent = new Intent(ctx, WallPostActivity.class); + intent.putExtra("post", post); + intent.putExtra("counters", post.counters); + ctx.startActivity(intent); + } + @Override public int getItemViewType(int position) { return position; @@ -420,4 +417,28 @@ public void setAvatarLoadState(boolean value) { this.avatar_loaded = value; //notifyDataSetChanged(); } + + public void addLike(WallPost item, int position, String post, View view) { + if(ctx instanceof AppActivity app_a) { + OpenVKAPI ovk_api = app_a.ovk_api; + if (app_a.selectedFragment == ((AppActivity) ctx).profileFragment) { + app_a.profileFragment.wallSelect(position, "likes", "add"); + } else { + app_a.newsfeedFragment.select(position, "likes", "add"); + } + ovk_api.likes.add(ovk_api.wrapper, item.owner_id, item.post_id, position); + } + } + + public void deleteLike(WallPost item, int position, String post, View view) { + if(ctx instanceof AppActivity app_a) { + OpenVKAPI ovk_api = app_a.ovk_api; + if (app_a.selectedFragment == ((AppActivity) ctx).profileFragment) { + app_a.profileFragment.wallSelect(position, "likes", "delete"); + } else { + app_a.newsfeedFragment.select(position, "likes", "delete"); + } + ovk_api.likes.delete(ovk_api.wrapper, item.owner_id, item.post_id, position); + } + } } \ No newline at end of file diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/sections/CommunitiesSearchSection.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/sections/CommunitiesSearchSection.java index b039787..76c1202 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/sections/CommunitiesSearchSection.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/sections/CommunitiesSearchSection.java @@ -4,16 +4,14 @@ import android.view.View; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - import java.util.ArrayList; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import io.github.luizgrp.sectionedrecyclerviewadapter.Section; import io.github.luizgrp.sectionedrecyclerviewadapter.SectionParameters; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.Group; -import uk.openvk.android.refresh.api.models.User; +import uk.openvk.android.refresh.api.entities.Group; import uk.openvk.android.refresh.ui.core.activities.QuickSearchActivity; public class CommunitiesSearchSection extends Section { diff --git a/app/src/main/java/uk/openvk/android/refresh/ui/list/sections/PeopleSearchSection.java b/app/src/main/java/uk/openvk/android/refresh/ui/list/sections/PeopleSearchSection.java index 28afc8b..98950f6 100644 --- a/app/src/main/java/uk/openvk/android/refresh/ui/list/sections/PeopleSearchSection.java +++ b/app/src/main/java/uk/openvk/android/refresh/ui/list/sections/PeopleSearchSection.java @@ -1,21 +1,17 @@ package uk.openvk.android.refresh.ui.list.sections; import android.content.Context; -import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import java.text.BreakIterator; import java.util.ArrayList; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import io.github.luizgrp.sectionedrecyclerviewadapter.Section; import io.github.luizgrp.sectionedrecyclerviewadapter.SectionParameters; import uk.openvk.android.refresh.R; -import uk.openvk.android.refresh.api.models.User; +import uk.openvk.android.refresh.api.entities.User; import uk.openvk.android.refresh.ui.core.activities.QuickSearchActivity; public class PeopleSearchSection extends Section { diff --git a/app/src/main/java/uk/openvk/android/refresh/utils/AccountAuthentificator.java b/app/src/main/java/uk/openvk/android/refresh/utils/AccountAuthentificator.java new file mode 100644 index 0000000..bc99352 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/utils/AccountAuthentificator.java @@ -0,0 +1,87 @@ +package uk.openvk.android.refresh.utils; + +import android.accounts.AbstractAccountAuthenticator; +import android.accounts.Account; +import android.accounts.AccountAuthenticatorResponse; +import android.accounts.AccountManager; +import android.accounts.NetworkErrorException; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.widget.Toast; + +import uk.openvk.android.refresh.ui.core.activities.AuthActivity; + +/** + * Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + *

+ * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + *

+ * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + *

+ * Source code: https://github.com/openvk/mobile-android-refresh + */ + +public class AccountAuthentificator extends AbstractAccountAuthenticator { + + private final Context ctx; + + public AccountAuthentificator(Context ctx) { + super(ctx); + this.ctx = ctx; + } + + @Override + public Bundle addAccount(AccountAuthenticatorResponse accountAuthenticatorResponse, + String s, String s2, String[] strings, Bundle bundle) + throws NetworkErrorException { + Intent i = new Intent(this.ctx, AuthActivity.class); + i.putExtra("accountAuthenticatorResponse", accountAuthenticatorResponse); + bundle.putParcelable("intent", i); + return bundle; + } + + @Override + public Bundle editProperties(AccountAuthenticatorResponse accountAuthenticatorResponse, String s) { + return null; + } + + @Override + public Bundle confirmCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, + Account account, Bundle bundle) + throws NetworkErrorException { + return null; + } + + @Override + public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse, + Account account, String s, Bundle bundle) + throws NetworkErrorException { + return null; + } + + @Override + public String getAuthTokenLabel(String s) { + return null; + } + + @Override + public Bundle updateCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, + Account account, String s, Bundle bundle) + throws NetworkErrorException { + return null; + } + + @Override + public Bundle hasFeatures(AccountAuthenticatorResponse accountAuthenticatorResponse, + Account account, String[] strings) throws NetworkErrorException { + return null; + } +} diff --git a/app/src/main/java/uk/openvk/android/refresh/utils/LibraryLoader.java b/app/src/main/java/uk/openvk/android/refresh/utils/LibraryLoader.java new file mode 100644 index 0000000..92313b2 --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/utils/LibraryLoader.java @@ -0,0 +1,24 @@ +package uk.openvk.android.refresh.utils; + +import android.content.Context; + +/** + * Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + */ + +public interface LibraryLoader { + void loadSharedLibrary(Context ctx, String library_name) throws UnsatisfiedLinkError, SecurityException, Exception; +} diff --git a/app/src/main/java/uk/openvk/android/refresh/utils/RealPathUtil.java b/app/src/main/java/uk/openvk/android/refresh/utils/RealPathUtil.java new file mode 100644 index 0000000..ab63c8d --- /dev/null +++ b/app/src/main/java/uk/openvk/android/refresh/utils/RealPathUtil.java @@ -0,0 +1,107 @@ +package uk.openvk.android.refresh.utils; + +import android.annotation.SuppressLint; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.util.Log; + +import uk.openvk.android.refresh.OvkApplication; + +/** + * Copyleft © 2022, 2023 OpenVK Team + * Copyleft © 2022, 2023 Dmitry Tretyakov (aka. Tinelix) + * + * This program is free software: you can redistribute it and/or modify it under the terms of + * the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this + * program. If not, see https://www.gnu.org/licenses/. + * + * Source code: https://github.com/openvk/mobile-android-refresh + */ + +@SuppressLint("Recycle") +public class RealPathUtil { + public static String getRealPathFromURI(Context context, Uri uri) { + String selection = null; + String[] selectionArgs = null; + // Uri is different in versions after KITKAT (Android 4.4), we need to + if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) { + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + uri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + } else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + if ("image".equals(type)) { + uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + selection = "_id=?"; + selectionArgs = new String[]{ + split[1] + }; + } + } + if ("content".equalsIgnoreCase(uri.getScheme())) { + + + if (isGooglePhotosUri(uri)) { + return uri.getLastPathSegment(); + } + + String[] projection = { + MediaStore.Images.Media.DATA + }; + Cursor cursor = null; + try { + cursor = context.getContentResolver() + .query(uri, projection, selection, selectionArgs, null); + int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + if (cursor.moveToFirst()) { + return cursor.getString(column_index); + } + } catch (Exception e) { + e.printStackTrace(); + } + } else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + return null; + } + + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + public static boolean isGooglePhotosUri(Uri uri) { + return "com.google.android.apps.photos.content".equals(uri.getAuthority()); + } +}