From 99b8b2c297dc35c9c023d6843f8b7fa2d80028d1 Mon Sep 17 00:00:00 2001 From: oogee Date: Mon, 21 Jan 2019 22:08:31 +0200 Subject: [PATCH 01/19] externalize editor with subject input field --- app/src/main/AndroidManifest.xml | 2 +- .../activities/board/BoardActivity.java | 6 ++-- .../CreateTopicActivity.java} | 4 +-- .../NewTopicTask.java | 2 +- .../res/layout/activity_create_content.xml | 28 +++------------- app/src/main/res/layout/full_post_editor.xml | 32 +++++++++++++++++++ 6 files changed, 43 insertions(+), 31 deletions(-) rename app/src/main/java/gr/thmmy/mthmmy/activities/{create_content/CreateContentActivity.java => create_topic/CreateTopicActivity.java} (96%) rename app/src/main/java/gr/thmmy/mthmmy/activities/{create_content => create_topic}/NewTopicTask.java (98%) create mode 100644 app/src/main/res/layout/full_post_editor.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7620bcf7..1640d0d2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -161,7 +161,7 @@ diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java index 61fc45e6..41b92813 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java @@ -23,7 +23,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; -import gr.thmmy.mthmmy.activities.create_content.CreateContentActivity; +import gr.thmmy.mthmmy.activities.create_topic.CreateTopicActivity; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Board; import gr.thmmy.mthmmy.model.Bookmark; @@ -105,8 +105,8 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo newTopicFAB.setOnClickListener(view -> { if (sessionManager.isLoggedIn()) { if (newTopicUrl != null) { - Intent intent = new Intent(this, CreateContentActivity.class); - intent.putExtra(CreateContentActivity.EXTRA_NEW_TOPIC_URL, newTopicUrl); + Intent intent = new Intent(this, CreateTopicActivity.class); + intent.putExtra(CreateTopicActivity.EXTRA_NEW_TOPIC_URL, newTopicUrl); startActivity(intent); } } else { diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/CreateTopicActivity.java similarity index 96% rename from app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java rename to app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/CreateTopicActivity.java index 920a03b9..4bc6efe3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/CreateTopicActivity.java @@ -1,4 +1,4 @@ -package gr.thmmy.mthmmy.activities.create_content; +package gr.thmmy.mthmmy.activities.create_topic; import android.content.Intent; import android.content.SharedPreferences; @@ -21,7 +21,7 @@ import gr.thmmy.mthmmy.session.SessionManager; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import timber.log.Timber; -public class CreateContentActivity extends BaseActivity implements NewTopicTask.NewTopicTaskCallbacks { +public class CreateTopicActivity extends BaseActivity implements NewTopicTask.NewTopicTaskCallbacks { public final static String EXTRA_NEW_TOPIC_URL = "new-topic-extra"; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/NewTopicTask.java similarity index 98% rename from app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java rename to app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/NewTopicTask.java index 985e0930..5495d50a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/NewTopicTask.java @@ -1,4 +1,4 @@ -package gr.thmmy.mthmmy.activities.create_content; +package gr.thmmy.mthmmy.activities.create_topic; import android.os.AsyncTask; diff --git a/app/src/main/res/layout/activity_create_content.xml b/app/src/main/res/layout/activity_create_content.xml index 7e6a9b40..e7f65e47 100644 --- a/app/src/main/res/layout/activity_create_content.xml +++ b/app/src/main/res/layout/activity_create_content.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" - tools:context=".activities.create_content.CreateContentActivity" + tools:context=".activities.create_topic.CreateTopicActivity" android:layout_height="match_parent" android:layout_width="match_parent" android:fitsSystemWindows="true"> @@ -29,31 +29,11 @@ - - - - - - + android:layout_width="match_parent"/> + + + + + + + + + + \ No newline at end of file From fd41917ec049cd01148428c42bcbaf1f7c7a8189 Mon Sep 17 00:00:00 2001 From: oogee Date: Mon, 21 Jan 2019 22:30:19 +0200 Subject: [PATCH 02/19] init pm activity --- app/build.gradle | 3 +- app/src/main/AndroidManifest.xml | 1 + .../create_pm/CreatePMActivity.java | 63 +++++++++++++++++++ .../create_topic/CreateTopicActivity.java | 2 +- .../main/res/layout/activity_create_pm.xml | 56 +++++++++++++++++ ..._content.xml => activity_create_topic.xml} | 0 6 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java create mode 100644 app/src/main/res/layout/activity_create_pm.xml rename app/src/main/res/layout/{activity_create_content.xml => activity_create_topic.xml} (100%) diff --git a/app/build.gradle b/app/build.gradle index 12853e57..f5dd36bd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -89,7 +89,8 @@ dependencies { implementation 'ru.noties:markwon:2.0.0' implementation 'net.gotev:uploadservice:3.4.2' implementation 'net.gotev:uploadservice-okhttp:3.4.2' - implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.4' //Plugin: https://plugins.jetbrains.com/plugin/11249-okhttp-profiler + implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.4' + //Plugin: https://plugins.jetbrains.com/plugin/11249-okhttp-profiler } apply plugin: 'com.google.gms.google-services' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1640d0d2..28662173 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -173,6 +173,7 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activities.main.MainActivity" /> + \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java new file mode 100644 index 00000000..54eec9ea --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java @@ -0,0 +1,63 @@ +package gr.thmmy.mthmmy.activities.create_pm; + +import android.os.Bundle; +import android.text.InputType; +import android.view.View; +import android.view.inputmethod.EditorInfo; + +import com.google.android.material.textfield.TextInputLayout; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.base.BaseActivity; +import gr.thmmy.mthmmy.editorview.EditorView; +import gr.thmmy.mthmmy.editorview.EmojiKeyboard; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; + +public class CreatePMActivity extends BaseActivity { + + private MaterialProgressBar progressBar; + private EditorView contentEditor; + private TextInputLayout subjectInput; + private EmojiKeyboard emojiKeyboard; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_create_pm); + + //Initialize toolbar + toolbar = findViewById(R.id.toolbar); + toolbar.setTitle("Create topic"); + setSupportActionBar(toolbar); + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + } + + progressBar = findViewById(R.id.progressBar); + + emojiKeyboard = findViewById(R.id.emoji_keyboard); + + subjectInput = findViewById(R.id.subject_input); + subjectInput.getEditText().setRawInputType(InputType.TYPE_CLASS_TEXT); + subjectInput.getEditText().setImeOptions(EditorInfo.IME_ACTION_DONE); + + contentEditor = findViewById(R.id.main_content_editorview); + contentEditor.setEmojiKeyboard(emojiKeyboard); + emojiKeyboard.registerEmojiInputField(contentEditor); + contentEditor.setOnSubmitListener(v -> { + // TODO: send pm + }); + } + + @Override + public void onBackPressed() { + if (emojiKeyboard.getVisibility() == View.VISIBLE) { + emojiKeyboard.setVisibility(View.GONE); + } else { + super.onBackPressed(); + } + } + + +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/CreateTopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/CreateTopicActivity.java index 4bc6efe3..ec661962 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/CreateTopicActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_topic/CreateTopicActivity.java @@ -33,7 +33,7 @@ public class CreateTopicActivity extends BaseActivity implements NewTopicTask.Ne @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_create_content); + setContentView(R.layout.activity_create_topic); //Initialize toolbar toolbar = findViewById(R.id.toolbar); diff --git a/app/src/main/res/layout/activity_create_pm.xml b/app/src/main/res/layout/activity_create_pm.xml new file mode 100644 index 00000000..f0405463 --- /dev/null +++ b/app/src/main/res/layout/activity_create_pm.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_create_content.xml b/app/src/main/res/layout/activity_create_topic.xml similarity index 100% rename from app/src/main/res/layout/activity_create_content.xml rename to app/src/main/res/layout/activity_create_topic.xml From 27b2a04809ad6d3dce114f078af4d57b1cc4e654 Mon Sep 17 00:00:00 2001 From: oogee Date: Wed, 23 Jan 2019 11:50:17 +0200 Subject: [PATCH 03/19] complete task for sending PMs --- app/src/main/AndroidManifest.xml | 4 +- .../create_pm/CreatePMActivity.java | 57 +++++++++++- .../activities/create_pm/SendPMTask.java | 87 +++++++++++++++++++ .../activities/profile/ProfileActivity.java | 65 +++++++------- 4 files changed, 180 insertions(+), 33 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/SendPMTask.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 28662173..80f6e4b8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -173,7 +173,9 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activities.main.MainActivity" /> - + \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java index 54eec9ea..e690023b 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java @@ -1,30 +1,45 @@ package gr.thmmy.mthmmy.activities.create_pm; +import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.PreferenceManager; import android.text.InputType; +import android.text.TextUtils; import android.view.View; import android.view.inputmethod.EditorInfo; +import android.widget.Toast; import com.google.android.material.textfield.TextInputLayout; import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.activities.profile.ProfileActivity; +import gr.thmmy.mthmmy.activities.settings.SettingsActivity; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.editorview.EditorView; import gr.thmmy.mthmmy.editorview.EmojiKeyboard; +import gr.thmmy.mthmmy.session.SessionManager; +import gr.thmmy.mthmmy.utils.ExternalAsyncTask; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; +import timber.log.Timber; -public class CreatePMActivity extends BaseActivity { +public class CreatePMActivity extends BaseActivity implements ExternalAsyncTask.OnTaskStartedListener, ExternalAsyncTask.OnTaskFinishedListener { private MaterialProgressBar progressBar; private EditorView contentEditor; private TextInputLayout subjectInput; private EmojiKeyboard emojiKeyboard; + private String username, sendPmUrl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_create_pm); + Intent callingIntent = getIntent(); + username = callingIntent.getStringExtra(ProfileActivity.BUNDLE_PROFILE_USERNAME); + sendPmUrl = callingIntent.getStringExtra(ProfileActivity.BUNDLE_SEND_PM_URL); + //Initialize toolbar toolbar = findViewById(R.id.toolbar); toolbar.setTitle("Create topic"); @@ -46,7 +61,27 @@ public class CreatePMActivity extends BaseActivity { contentEditor.setEmojiKeyboard(emojiKeyboard); emojiKeyboard.registerEmojiInputField(contentEditor); contentEditor.setOnSubmitListener(v -> { - // TODO: send pm + if (TextUtils.isEmpty(subjectInput.getEditText().getText())) { + subjectInput.setError("Required"); + return; + } + if (TextUtils.isEmpty(contentEditor.getText())) { + contentEditor.setError("Required"); + return; + } + + boolean includeAppSignature = true; + SessionManager sessionManager = BaseActivity.getSessionManager(); + if (sessionManager.isLoggedIn()) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + includeAppSignature = prefs.getBoolean(SettingsActivity.POSTING_APP_SIGNATURE_ENABLE_KEY, true); + } + + SendPMTask sendPMTask = new SendPMTask(includeAppSignature); + sendPMTask.setOnTaskStartedListener(this); + sendPMTask.setOnTaskFinishedListener(this); + sendPMTask.execute(sendPmUrl, username, subjectInput.getEditText().getText().toString(), + contentEditor.getText().toString()); }); } @@ -60,4 +95,22 @@ public class CreatePMActivity extends BaseActivity { } + @Override + public void onTaskStarted() { + Timber.i("New pm started being sent"); + progressBar.setVisibility(View.VISIBLE); + } + + @Override + public void onTaskFinished(Boolean success) { + progressBar.setVisibility(View.INVISIBLE); + if (success) { + Timber.i("New pm sent successfully"); + Toast.makeText(this, "Personal message sent successfully", Toast.LENGTH_SHORT).show(); + finish(); + } else { + Timber.w("Failed to send pm"); + Toast.makeText(getBaseContext(), "Failed to send PM. Check your connection", Toast.LENGTH_LONG).show(); + } + } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/SendPMTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/SendPMTask.java new file mode 100644 index 00000000..875504dc --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/SendPMTask.java @@ -0,0 +1,87 @@ +package gr.thmmy.mthmmy.activities.create_pm; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +import java.io.IOException; + +import gr.thmmy.mthmmy.base.BaseApplication; +import gr.thmmy.mthmmy.utils.ExternalAsyncTask; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import timber.log.Timber; + +import static gr.thmmy.mthmmy.activities.topic.Posting.replyStatus; + +public class SendPMTask extends ExternalAsyncTask { + + private boolean includeAppSignature; + + public SendPMTask(boolean includeAppSignature) { + this.includeAppSignature = includeAppSignature; + } + + @Override + protected Boolean doInBackground(String... strings) { + Request request = new Request.Builder() + .url(strings[0] + ";wap2") + .build(); + + OkHttpClient client = BaseApplication.getInstance().getClient(); + + Document document; + String seqnum, sc, outbox, createTopicUrl, replied_to, folder; + try { + Response response = client.newCall(request).execute(); + document = Jsoup.parse(response.body().string()); + + seqnum = document.select("input[name=seqnum]").first().attr("value"); + sc = document.select("input[name=sc]").first().attr("value"); + outbox = document.select("input[name=outbox]").first().attr("value"); + replied_to = document.select("input[name=replied_to]").first().attr("value"); + folder = document.select("input[name=folder]").first().attr("value"); + createTopicUrl = document.select("form").first().attr("action"); + + final String appSignature = "\n[right][size=7pt][i]sent from [url=https://play.google.com/store/apps/" + + "details?id=gr.thmmy.mthmmy]mTHMMY[/url] [/i][/size][/right]"; + + RequestBody postBody = new MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("message", strings[3] + (includeAppSignature ? appSignature : "")) + .addFormDataPart("seqnum", seqnum) + .addFormDataPart("sc", sc) + .addFormDataPart("u", strings[1]) // recipient + .addFormDataPart("subject", strings[2]) + .addFormDataPart("outbox", outbox) + .addFormDataPart("replied_to", replied_to) + .addFormDataPart("folder", folder) + .build(); + + Request pmRequest = new Request.Builder() + .url(createTopicUrl) + .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36") + .post(postBody) + .build(); + + try { + client.newCall(pmRequest).execute(); + Response response2 = client.newCall(pmRequest).execute(); + switch (replyStatus(response2)) { + case SUCCESSFUL: + BaseApplication.getInstance().logFirebaseAnalyticsEvent("new_topic_creation", null); + return true; + default: + Timber.e("Malformed pmRequest. Request string: %s", pmRequest.toString()); + return false; + } + } catch (IOException e) { + return false; + } + } catch (IOException e) { + return false; + } + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java index 247365c8..b54f9484 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java @@ -1,5 +1,6 @@ package gr.thmmy.mthmmy.activities.profile; +import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.graphics.Typeface; @@ -31,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatDelegate; import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.Fragment; @@ -38,6 +40,8 @@ import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; import androidx.viewpager.widget.ViewPager; import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.activities.LoginActivity; +import gr.thmmy.mthmmy.activities.create_pm.CreatePMActivity; import gr.thmmy.mthmmy.activities.profile.latestPosts.LatestPostsFragment; import gr.thmmy.mthmmy.activities.profile.stats.StatsFragment; import gr.thmmy.mthmmy.activities.profile.summary.SummaryFragment; @@ -79,6 +83,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment * If username is not available put an empty string or leave it null. */ public static final String BUNDLE_PROFILE_USERNAME = "USERNAME"; + public static final String BUNDLE_SEND_PM_URL = "send-pm-url"; private TextView usernameView; private ImageView avatarView; @@ -92,6 +97,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment private String profileUrl; private String avatarUrl; private String username; + private String sendPmUrl; private int tabSelect; //Fix for vector drawables on android <21 @@ -140,37 +146,29 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment viewPager = findViewById(R.id.profile_tab_container); pmFAB = findViewById(R.id.profile_fab); - pmFAB.setEnabled(false); - pmFAB.hide(); - /*if (!sessionManager.isLoggedIn()) pmFAB.hide(); + if (!sessionManager.isLoggedIn()) pmFAB.hide(); else { - pmFAB.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (sessionManager.isLoggedIn()) { - //TODO PM - } else { - new AlertDialog.Builder(ProfileActivity.this) - .setMessage("You need to be logged in to sent a personal message!") - .setPositiveButton("Login", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - Intent intent = new Intent(ProfileActivity.this, LoginActivity.class); - startActivity(intent); - finish(); - overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out); - } - }) - .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - } - }) - .show(); - } + pmFAB.setOnClickListener(view -> { + if (sessionManager.isLoggedIn()) { + Intent sendPMIntent = new Intent(ProfileActivity.this, CreatePMActivity.class); + sendPMIntent.putExtra(BUNDLE_PROFILE_USERNAME, username); + sendPMIntent.putExtra(BUNDLE_SEND_PM_URL, sendPmUrl); + startActivity(sendPMIntent); + } else { + new AlertDialog.Builder(ProfileActivity.this) + .setMessage("You need to be logged in to sent a personal message!") + .setPositiveButton("Login", (dialogInterface, i) -> { + Intent intent = new Intent(ProfileActivity.this, LoginActivity.class); + startActivity(intent); + finish(); + overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out); + }) + .setNegativeButton("Cancel", (dialogInterface, i) -> { + }) + .show(); } }); - }*/ + } ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory(Uri.parse(profileUrl)); if (!target.is(ThmmyPage.PageCategory.PROFILE)) { @@ -211,7 +209,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment if (pmFAB.getVisibility() != View.GONE) pmFAB.setEnabled(false); } - private void loadAvatar(){ + private void loadAvatar() { Picasso.with(this) .load(avatarUrl) .fit() @@ -224,7 +222,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment .into(avatarView); } - private void loadDefaultAvatar(){ + private void loadDefaultAvatar() { Picasso.with(this) .load(R.drawable.ic_default_user_avatar) .fit() @@ -296,6 +294,13 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment usernameSpan.setSpan(new ForegroundColorSpan(Color.parseColor("#26A69A")) , 2, usernameSpan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } + // Url needed to send to send pm + Elements urllinks; + urllinks = profilePage.select("a:contains(Send this member a personal message.)"); + if (urllinks.size() == 0) { + urllinks = profilePage.select("a:contains(Αποστολή προσωπικού μηνύματος σε αυτό το μέλος.)"); + } + sendPmUrl = urllinks.first().attr("href"); return null; } From 327f84e83f0cd60b6b707225f0833613a8c90134 Mon Sep 17 00:00:00 2001 From: oogee Date: Wed, 23 Jan 2019 12:14:55 +0200 Subject: [PATCH 04/19] send correct user arguement --- .../mthmmy/activities/create_pm/CreatePMActivity.java | 2 +- .../thmmy/mthmmy/activities/create_pm/SendPMTask.java | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java index e690023b..b6925fba 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/CreatePMActivity.java @@ -80,7 +80,7 @@ public class CreatePMActivity extends BaseActivity implements ExternalAsyncTask. SendPMTask sendPMTask = new SendPMTask(includeAppSignature); sendPMTask.setOnTaskStartedListener(this); sendPMTask.setOnTaskFinishedListener(this); - sendPMTask.execute(sendPmUrl, username, subjectInput.getEditText().getText().toString(), + sendPMTask.execute(sendPmUrl, subjectInput.getEditText().getText().toString(), contentEditor.getText().toString()); }); } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/SendPMTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/SendPMTask.java index 875504dc..703e47b9 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/SendPMTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_pm/SendPMTask.java @@ -33,7 +33,7 @@ public class SendPMTask extends ExternalAsyncTask { OkHttpClient client = BaseApplication.getInstance().getClient(); Document document; - String seqnum, sc, outbox, createTopicUrl, replied_to, folder; + String seqnum, sc, outbox, createTopicUrl, replied_to, folder, u; try { Response response = client.newCall(request).execute(); document = Jsoup.parse(response.body().string()); @@ -43,6 +43,7 @@ public class SendPMTask extends ExternalAsyncTask { outbox = document.select("input[name=outbox]").first().attr("value"); replied_to = document.select("input[name=replied_to]").first().attr("value"); folder = document.select("input[name=folder]").first().attr("value"); + u = document.select("input[name=u]").first().attr("value"); createTopicUrl = document.select("form").first().attr("action"); final String appSignature = "\n[right][size=7pt][i]sent from [url=https://play.google.com/store/apps/" + @@ -50,11 +51,11 @@ public class SendPMTask extends ExternalAsyncTask { RequestBody postBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) - .addFormDataPart("message", strings[3] + (includeAppSignature ? appSignature : "")) + .addFormDataPart("message", strings[2] + (includeAppSignature ? appSignature : "")) .addFormDataPart("seqnum", seqnum) .addFormDataPart("sc", sc) - .addFormDataPart("u", strings[1]) // recipient - .addFormDataPart("subject", strings[2]) + .addFormDataPart("u", u) // recipient id + .addFormDataPart("subject", strings[1]) .addFormDataPart("outbox", outbox) .addFormDataPart("replied_to", replied_to) .addFormDataPart("folder", folder) @@ -71,7 +72,7 @@ public class SendPMTask extends ExternalAsyncTask { Response response2 = client.newCall(pmRequest).execute(); switch (replyStatus(response2)) { case SUCCESSFUL: - BaseApplication.getInstance().logFirebaseAnalyticsEvent("new_topic_creation", null); + BaseApplication.getInstance().logFirebaseAnalyticsEvent("new_pm_sent", null); return true; default: Timber.e("Malformed pmRequest. Request string: %s", pmRequest.toString()); From ace845f55b13f4ef9d0049564cf94f2719c70248 Mon Sep 17 00:00:00 2001 From: oogee Date: Sat, 9 Feb 2019 13:08:45 +0200 Subject: [PATCH 05/19] inbox activity init, up gradle plugin --- app/src/main/AndroidManifest.xml | 10 ++++++- .../activities/inbox/InboxActivity.java | 27 +++++++++++++++++++ .../gr/thmmy/mthmmy/base/BaseActivity.java | 26 +++++++++++++++--- .../res/drawable/ic_message_white_24dp.xml | 5 ++++ app/src/main/res/layout/activity_inbox.xml | 25 +++++++++++++++++ app/src/main/res/values/strings.xml | 3 ++- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +-- 8 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxActivity.java create mode 100644 app/src/main/res/drawable/ic_message_white_24dp.xml create mode 100644 app/src/main/res/layout/activity_inbox.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 80f6e4b8..e5aa6809 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,6 +17,7 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> + @@ -173,9 +174,16 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activities.main.MainActivity" /> - + + + \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxActivity.java new file mode 100644 index 00000000..57952965 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxActivity.java @@ -0,0 +1,27 @@ +package gr.thmmy.mthmmy.activities.inbox; + +import android.os.Bundle; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.base.BaseActivity; + +public class InboxActivity extends BaseActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_inbox); + + //Initialize toolbar + toolbar = findViewById(R.id.toolbar); + toolbar.setTitle("Inbox"); + setSupportActionBar(toolbar); + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + } + + createDrawer(); + drawer.setSelection(INBOX_ID); + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index d8019545..61c39969 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -48,6 +48,7 @@ import gr.thmmy.mthmmy.activities.AboutActivity; import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.activities.bookmarks.BookmarksActivity; import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity; +import gr.thmmy.mthmmy.activities.inbox.InboxActivity; import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.settings.SettingsActivity; @@ -161,6 +162,7 @@ public abstract class BaseActivity extends AppCompatActivity { protected static final int ABOUT_ID = 5; protected static final int SETTINGS_ID = 6; protected static final int SHOUTBOX_ID = 7; + protected static final int INBOX_ID = 8; private AccountHeader accountHeader; private ProfileDrawerItem profileDrawerItem; @@ -175,8 +177,9 @@ public abstract class BaseActivity extends AppCompatActivity { final int selectedPrimaryColor = ContextCompat.getColor(this, R.color.primary_dark); final int selectedSecondaryColor = ContextCompat.getColor(this, R.color.accent); - PrimaryDrawerItem homeItem, bookmarksItem, settingsItem, aboutItem, shoutboxItem; - IconicsDrawable homeIcon, homeIconSelected, downloadsIcon, downloadsIconSelected, uploadIcon, uploadIconSelected, settingsIcon, + PrimaryDrawerItem homeItem, bookmarksItem, settingsItem, aboutItem, shoutboxItem, inboxItem; + IconicsDrawable homeIcon, homeIconSelected, downloadsIcon, downloadsIconSelected, uploadIcon, + uploadIconSelected, settingsIcon, settingsIconSelected, bookmarksIcon, bookmarksIconSelected, aboutIcon, aboutIconSelected; //Drawer Icons @@ -274,6 +277,18 @@ public abstract class BaseActivity extends AppCompatActivity { .withSelectedIconColor(selectedSecondaryColor) .withIconTintingEnabled(true); + inboxItem = new PrimaryDrawerItem() + .withTextColor(primaryColor) + .withSelectedColor(selectedPrimaryColor) + .withSelectedTextColor(selectedSecondaryColor) + .withIdentifier(INBOX_ID) + .withName(R.string.inbox) + .withIcon(R.drawable.ic_message_white_24dp) + .withIconColor(primaryColor) + .withSelectedIconColor(selectedSecondaryColor) + .withIconTintingEnabled(true); + + if (sessionManager.isLoggedIn()) //When logged in { loginLogoutItem = new PrimaryDrawerItem() @@ -368,6 +383,11 @@ public abstract class BaseActivity extends AppCompatActivity { Intent intent = new Intent(BaseActivity.this, ShoutboxActivity.class); startActivity(intent); } + } else if (drawerItem.equals(INBOX_ID)) { + if (!(BaseActivity.this instanceof InboxActivity)) { + Intent intent = new Intent(BaseActivity.this, InboxActivity.class); + startActivity(intent); + } } else if (drawerItem.equals(DOWNLOADS_ID)) { if (!(BaseActivity.this instanceof DownloadsActivity)) { Intent intent = new Intent(BaseActivity.this, DownloadsActivity.class); @@ -412,7 +432,7 @@ public abstract class BaseActivity extends AppCompatActivity { }); if (sessionManager.isLoggedIn()) - drawerBuilder.addDrawerItems(homeItem, bookmarksItem, shoutboxItem, downloadsItem, settingsItem, loginLogoutItem, aboutItem); + drawerBuilder.addDrawerItems(homeItem, bookmarksItem, shoutboxItem, inboxItem, downloadsItem, settingsItem, loginLogoutItem, aboutItem); else drawerBuilder.addDrawerItems(homeItem, bookmarksItem, shoutboxItem, settingsItem, loginLogoutItem, aboutItem); diff --git a/app/src/main/res/drawable/ic_message_white_24dp.xml b/app/src/main/res/drawable/ic_message_white_24dp.xml new file mode 100644 index 00000000..a935c9d5 --- /dev/null +++ b/app/src/main/res/drawable/ic_message_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_inbox.xml b/app/src/main/res/layout/activity_inbox.xml new file mode 100644 index 00000000..79b8b848 --- /dev/null +++ b/app/src/main/res/layout/activity_inbox.xml @@ -0,0 +1,25 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bf3d9e5f..f306a815 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -11,6 +11,8 @@ About Home Bookmarks + Shoutbox + Inbox Info OK Cancel @@ -21,7 +23,6 @@ Recent Forum Unread - Shoutbox Refresh diff --git a/build.gradle b/build.gradle index 463af701..7b07a1e4 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.0' classpath 'com.google.gms:google-services:4.2.0' classpath 'io.fabric.tools:gradle:1.26.1' classpath 'org.ajoberstar.grgit:grgit-core:3.0.0' // Also change in app/gradle/grgit.gradle diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 07d9d5c1..9758fbe6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Sep 28 13:21:54 EEST 2018 +#Sat Feb 09 12:35:50 EET 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip From 37c9c1e7991984f98ab9b1a00fc7470240a96aaa Mon Sep 17 00:00:00 2001 From: oogee Date: Wed, 10 Jul 2019 12:10:04 +0300 Subject: [PATCH 06/19] create inbox task --- .../activities/inbox/tasks/InboxTask.java | 22 +++++++++++++++++++ .../java/gr/thmmy/mthmmy/model/Inbox.java | 4 ++++ .../main/java/gr/thmmy/mthmmy/model/PM.java | 4 ++++ 3 files changed, 30 insertions(+) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/inbox/tasks/InboxTask.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/model/Inbox.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/model/PM.java diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/tasks/InboxTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/tasks/InboxTask.java new file mode 100644 index 00000000..50c72745 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/tasks/InboxTask.java @@ -0,0 +1,22 @@ +package gr.thmmy.mthmmy.activities.inbox.tasks; + +import org.jsoup.nodes.Document; + +import gr.thmmy.mthmmy.model.Inbox; +import gr.thmmy.mthmmy.utils.parsing.NewParseTask; +import gr.thmmy.mthmmy.utils.parsing.ParseException; +import okhttp3.Response; + +public class InboxTask extends NewParseTask { + @Override + protected Inbox parse(Document document, Response response) throws ParseException { + return null; + } + + @Override + protected int getResultCode(Response response, Inbox data) { + return 0; + } +} + + diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Inbox.java b/app/src/main/java/gr/thmmy/mthmmy/model/Inbox.java new file mode 100644 index 00000000..d84af7cc --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Inbox.java @@ -0,0 +1,4 @@ +package gr.thmmy.mthmmy.model; + +public class Inbox { +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/PM.java b/app/src/main/java/gr/thmmy/mthmmy/model/PM.java new file mode 100644 index 00000000..3739180a --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/model/PM.java @@ -0,0 +1,4 @@ +package gr.thmmy.mthmmy.model; + +public class PM { +} From fd6ada0af68aac54f3918eb0b24559dcfadcca21 Mon Sep 17 00:00:00 2001 From: Thodoris1999 Date: Wed, 10 Jul 2019 12:54:02 +0300 Subject: [PATCH 07/19] create inbox viewmodel and bind the inbox task to Inbox Activity --- .../activities/inbox/InboxActivity.java | 14 ++++++++ .../activities/topic/TopicActivity.java | 2 +- .../mthmmy/viewmodel/InboxViewModel.java | 36 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/viewmodel/InboxViewModel.java diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxActivity.java index 57952965..fba3b5fd 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxActivity.java @@ -2,11 +2,16 @@ package gr.thmmy.mthmmy.activities.inbox; import android.os.Bundle; +import androidx.lifecycle.ViewModelProviders; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; +import gr.thmmy.mthmmy.viewmodel.InboxViewModel; public class InboxActivity extends BaseActivity { + InboxViewModel inboxViewModel; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -23,5 +28,14 @@ public class InboxActivity extends BaseActivity { createDrawer(); drawer.setSelection(INBOX_ID); + + inboxViewModel = ViewModelProviders.of(this).get(InboxViewModel.class); + subscribeUI(); + } + + private void subscribeUI() { + inboxViewModel.setOnInboxTaskFinishedListener((resultCode, data) -> { + + }); } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java index 639ab3c7..64c04437 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java @@ -652,7 +652,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo Toast.makeText(this, "Failed to remove vote", Toast.LENGTH_LONG).show(); } }); - // observe the chages in data + // observe the changes in data viewModel.getPageIndicatorIndex().observe(this, pageIndicatorIndex -> { if (pageIndicatorIndex == null) return; pageIndicator.setText(String.valueOf(pageIndicatorIndex) + "/" + diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/InboxViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/InboxViewModel.java new file mode 100644 index 00000000..18b33919 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/InboxViewModel.java @@ -0,0 +1,36 @@ +package gr.thmmy.mthmmy.viewmodel; + +import androidx.lifecycle.ViewModel; + +import gr.thmmy.mthmmy.activities.inbox.tasks.InboxTask; +import gr.thmmy.mthmmy.model.Inbox; + +public class InboxViewModel extends ViewModel implements InboxTask.OnNetworkTaskFinishedListener { + private static final String INBOX_URL = "https://www.thmmy.gr/smf/index.php?action=pm"; + + private InboxTask currentInboxTask; + + private Inbox inbox; + private InboxTask.OnNetworkTaskFinishedListener onInboxTaskFinishedListener; + + private void loadInbox() { + currentInboxTask = new InboxTask(); + currentInboxTask.setOnNetworkTaskFinishedListener(this); + currentInboxTask.execute(INBOX_URL); + } + + public void setOnInboxTaskFinishedListener(InboxTask.OnNetworkTaskFinishedListener onInboxTaskFinishedListener) { + this.onInboxTaskFinishedListener = onInboxTaskFinishedListener; + } + + @Override + public void onNetworkTaskFinished(int resultCode, Inbox inbox) { + this.inbox = inbox; + onInboxTaskFinishedListener.onNetworkTaskFinished(resultCode, inbox); + } + + public Inbox getInbox() { + if (inbox == null) throw new NullPointerException("Inbox has not been loaded yet"); + return inbox; + } +} From ed712e1369e542c479d5cc07874c3f50af106899 Mon Sep 17 00:00:00 2001 From: Thodoris1999 Date: Wed, 10 Jul 2019 13:24:13 +0300 Subject: [PATCH 08/19] create personal message adapter item layout --- .../main/res/layout/activity_inbox_pm_row.xml | 241 ++++++++++++++++++ app/src/main/res/values/strings.xml | 6 + 2 files changed, 247 insertions(+) create mode 100644 app/src/main/res/layout/activity_inbox_pm_row.xml diff --git a/app/src/main/res/layout/activity_inbox_pm_row.xml b/app/src/main/res/layout/activity_inbox_pm_row.xml new file mode 100644 index 00000000..71dcd877 --- /dev/null +++ b/app/src/main/res/layout/activity_inbox_pm_row.xml @@ -0,0 +1,241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f306a815..22f77e5f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -209,4 +209,10 @@ New topic Create topic + + + Personal message author thumbnail + PM author + PM subject + PM content From 193a79c78ac91eba79c68b0a4cd85b6455dea453 Mon Sep 17 00:00:00 2001 From: Thodoris1999 Date: Wed, 10 Jul 2019 18:23:51 +0300 Subject: [PATCH 09/19] create inbox recyclerview and adapter --- .../mthmmy/activities/inbox/InboxAdapter.java | 201 ++++++++++++++++++ .../java/gr/thmmy/mthmmy/model/Inbox.java | 11 + .../main/java/gr/thmmy/mthmmy/model/PM.java | 25 +++ app/src/main/res/layout/activity_inbox.xml | 115 +++++++++- .../main/res/layout/activity_inbox_pm_row.xml | 31 +-- 5 files changed, 342 insertions(+), 41 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java new file mode 100644 index 00000000..b52a3c25 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java @@ -0,0 +1,201 @@ +package gr.thmmy.mthmmy.activities.inbox; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebResourceRequest; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.content.res.ResourcesCompat; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.RecyclerView; + +import com.squareup.picasso.Picasso; + +import java.util.ArrayList; +import java.util.Objects; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.activities.board.BoardActivity; +import gr.thmmy.mthmmy.activities.profile.ProfileActivity; +import gr.thmmy.mthmmy.activities.topic.TopicActivity; +import gr.thmmy.mthmmy.model.PM; +import gr.thmmy.mthmmy.model.ThmmyPage; +import gr.thmmy.mthmmy.utils.CircleTransform; +import gr.thmmy.mthmmy.viewmodel.InboxViewModel; + +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE; +import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; +import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; +import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; + +public class InboxAdapter extends RecyclerView.Adapter { + + private Context context; + private InboxViewModel inboxViewModel; + + public InboxAdapter(InboxActivity context) { + inboxViewModel = ViewModelProviders.of(context).get(InboxViewModel.class); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.activity_inbox_pm_row, parent, false); + return new InboxAdapter.PMViewHolder(itemView); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { + InboxAdapter.PMViewHolder holder = (PMViewHolder) viewHolder; + PM currentPM = pms().get(position); + + //Post's WebView parameters + holder.pm.setClickable(true); + holder.pm.setWebViewClient(new LinkLauncher()); + + Picasso.with(context) + .load(currentPM.getThumbnailUrl()) + .fit() + .centerCrop() + .error(Objects.requireNonNull(ResourcesCompat.getDrawable(context.getResources() + , R.drawable.ic_default_user_avatar_darker, null))) + .placeholder(Objects.requireNonNull(ResourcesCompat.getDrawable(context.getResources() + , R.drawable.ic_default_user_avatar_darker, null))) + .transform(new CircleTransform()) + .into(holder.thumbnail); + + //Sets username,submit date, index number, subject, post's and attached files texts + holder.username.setText(currentPM.getAuthor()); + holder.pmDate.setText(currentPM.getPostDate()); + holder.subject.setText(currentPM.getSubject()); + holder.pm.loadDataWithBaseURL("file:///android_asset/", currentPM.getContent(), + "text/html", "UTF-8", null); + } + + @Override + public int getItemCount() { + return pms().size(); + } + + private ArrayList pms() { + return inboxViewModel.getInbox().getPms(); + } + + static class PMViewHolder extends RecyclerView.ViewHolder { + final LinearLayout cardChildLinear; + final TextView pmDate, username, subject; + final ImageView thumbnail; + final public WebView pm; + final ImageButton overflowButton; + final RelativeLayout header; + final LinearLayout userExtraInfo; + + final TextView specialRank, rank, gender, numberOfPosts, personalText, stars; + + PMViewHolder(@NonNull View view) { + super(view); + cardChildLinear = view.findViewById(R.id.card_child_linear); + pmDate = view.findViewById(R.id.pm_date); + thumbnail = view.findViewById(R.id.thumbnail); + username = view.findViewById(R.id.username); + subject = view.findViewById(R.id.subject); + pm = view.findViewById(R.id.pm); + pm.setBackgroundColor(Color.argb(1, 255, 255, 255)); + overflowButton = view.findViewById(R.id.pm_overflow_menu); + + //User's extra info + header = view.findViewById(R.id.header); + userExtraInfo = view.findViewById(R.id.user_extra_info); + specialRank = view.findViewById(R.id.special_rank); + rank = view.findViewById(R.id.rank); + gender = view.findViewById(R.id.gender); + numberOfPosts = view.findViewById(R.id.number_of_posts); + personalText = view.findViewById(R.id.personal_text); + stars = view.findViewById(R.id.stars); + } + } + + /** + * This class is used to handle link clicks in WebViews. When link url is one that the app can + * handle internally, it does. Otherwise user is prompt to open the link in a browser. + */ + @SuppressWarnings("unchecked") + private class LinkLauncher extends WebViewClient { + @SuppressWarnings("deprecation") + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + final Uri uri = Uri.parse(url); + return handleUri(uri); + } + + @TargetApi(Build.VERSION_CODES.N) + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + final Uri uri = request.getUrl(); + return handleUri(uri); + } + + @SuppressWarnings("SameReturnValue") + private boolean handleUri(final Uri uri) { + final String uriString = uri.toString(); + + ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory(uri); + if (target.is(ThmmyPage.PageCategory.TOPIC)) { + //This url points to a topic + Intent intent = new Intent(context, TopicActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_TOPIC_URL, uriString); + intent.putExtras(extras); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + return true; + } else if (target.is(ThmmyPage.PageCategory.BOARD)) { + Intent intent = new Intent(context, BoardActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_BOARD_URL, uriString); + extras.putString(BUNDLE_BOARD_TITLE, ""); + intent.putExtras(extras); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + return true; + } else if (target.is(ThmmyPage.PageCategory.PROFILE)) { + Intent intent = new Intent(context, ProfileActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_PROFILE_URL, uriString); + extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); + extras.putString(BUNDLE_PROFILE_USERNAME, ""); + intent.putExtras(extras); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + return true; + } + + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + + //Method always returns true as no url should be loaded in the WebViews + return true; + } + + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Inbox.java b/app/src/main/java/gr/thmmy/mthmmy/model/Inbox.java index d84af7cc..f428e95b 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/Inbox.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Inbox.java @@ -1,4 +1,15 @@ package gr.thmmy.mthmmy.model; +import java.util.ArrayList; + public class Inbox { + private ArrayList pms; + + public ArrayList getPms() { + return pms; + } + + public void setPms(ArrayList pms) { + this.pms = pms; + } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/PM.java b/app/src/main/java/gr/thmmy/mthmmy/model/PM.java index 3739180a..eef06033 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/PM.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/PM.java @@ -1,4 +1,29 @@ package gr.thmmy.mthmmy.model; public class PM { + private String thumbnailUrl; + private String author; + private String subject; + private String content; + private String postDate; + + public String getAuthor() { + return author; + } + + public String getContent() { + return content; + } + + public String getSubject() { + return subject; + } + + public String getThumbnailUrl() { + return thumbnailUrl; + } + + public String getPostDate() { + return postDate; + } } diff --git a/app/src/main/res/layout/activity_inbox.xml b/app/src/main/res/layout/activity_inbox.xml index 79b8b848..6d39dee0 100644 --- a/app/src/main/res/layout/activity_inbox.xml +++ b/app/src/main/res/layout/activity_inbox.xml @@ -1,5 +1,5 @@ - - + android:layout_height="@dimen/progress_bar_height" + android:indeterminate="true" + android:visibility="invisible" + app:layout_anchor="@id/appbar" + app:layout_anchorGravity="bottom|center" + app:mpb_indeterminateTint="@color/accent" + app:mpb_progressStyle="horizontal" /> + + + + - + + + + + + + + + + + + - + android:hint="@string/button_page" + android:maxLines="1" + android:textColor="@color/white" + android:textSize="22sp" /> - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_inbox_pm_row.xml b/app/src/main/res/layout/activity_inbox_pm_row.xml index 71dcd877..c4bdced2 100644 --- a/app/src/main/res/layout/activity_inbox_pm_row.xml +++ b/app/src/main/res/layout/activity_inbox_pm_row.xml @@ -162,7 +162,7 @@ - - @@ -216,26 +207,6 @@ android:focusable="true" tools:text="@string/pm_content" /> - - - - \ No newline at end of file From ba4e40b0040eccf38298f72839411a0e4e239336 Mon Sep 17 00:00:00 2001 From: Thodoris1999 Date: Thu, 11 Jul 2019 14:47:25 +0300 Subject: [PATCH 10/19] Parse pms. Also move methods that use similar code with TopicParser to ParseHelpers and reuse code --- .../mthmmy/activities/inbox/InboxAdapter.java | 2 +- .../activities/inbox/tasks/InboxTask.java | 180 ++++++++++++++++++ .../mthmmy/activities/topic/TopicAdapter.java | 6 +- .../mthmmy/activities/topic/TopicParser.java | 125 +----------- .../activities/topic/tasks/TopicTask.java | 4 +- .../java/gr/thmmy/mthmmy/model/Inbox.java | 17 ++ .../main/java/gr/thmmy/mthmmy/model/PM.java | 131 ++++++++++++- .../mthmmy/utils/parsing/ParseHelpers.java | 115 ++++++++++- 8 files changed, 451 insertions(+), 129 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java index b52a3c25..ed5a1419 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/InboxAdapter.java @@ -85,7 +85,7 @@ public class InboxAdapter extends RecyclerView.Adapter //Sets username,submit date, index number, subject, post's and attached files texts holder.username.setText(currentPM.getAuthor()); - holder.pmDate.setText(currentPM.getPostDate()); + holder.pmDate.setText(currentPM.getPmDate()); holder.subject.setText(currentPM.getSubject()); holder.pm.loadDataWithBaseURL("file:///android_asset/", currentPM.getContent(), "text/html", "UTF-8", null); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/tasks/InboxTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/tasks/InboxTask.java index 50c72745..252e5b72 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/tasks/InboxTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/inbox/tasks/InboxTask.java @@ -1,15 +1,37 @@ package gr.thmmy.mthmmy.activities.inbox.tasks; +import org.jsoup.Jsoup; import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Inbox; +import gr.thmmy.mthmmy.model.PM; import gr.thmmy.mthmmy.utils.parsing.NewParseTask; import gr.thmmy.mthmmy.utils.parsing.ParseException; +import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import okhttp3.Response; public class InboxTask extends NewParseTask { @Override protected Inbox parse(Document document, Response response) throws ParseException { + Inbox inbox = new Inbox(); + ParseHelpers.deobfuscateElements(document.select("span.__cf_email__,a.__cf_email__"), true); + + ParseHelpers.Language language = ParseHelpers.Language.getLanguage(document); + + inbox.setCurrentPageIndex(ParseHelpers.parseCurrentPageIndex(document, language)); + inbox.setNumberOfPages(ParseHelpers.parseNumberOfPages(document, inbox.getCurrentPageIndex(), language)); + + ArrayList pmList = parsePMs(document, language); + + return null; } @@ -17,6 +39,164 @@ public class InboxTask extends NewParseTask { protected int getResultCode(Response response, Inbox data) { return 0; } + + private ArrayList parsePMs(Document document, ParseHelpers.Language language) { + ArrayList pms = new ArrayList<>(); + Elements pmContainerContainers = document.select("td[style=padding: 1px 1px 0 1px;]"); + for (Element pmContainerContainer : pmContainerContainers) { + PM pm = new PM(); + boolean isAuthorDeleted; + Element pmContainer = pmContainerContainer.select("table[style=table-layout: fixed;]").first().child(0); + + Element thumbnail = pmContainer.select("img.avatar").first(); + pm.setThumbnailUrl(thumbnail.attr("src")); + + Element subjectAndDateContainer = pmContainer.select("td[align=left]").first(); + pm.setSubject(subjectAndDateContainer.select("b").first().text()); + Element dateContainer = subjectAndDateContainer.select("div").first(); + pm.setPmDate(subjectAndDateContainer.select("div").first().text()); + + String content = ParseHelpers.youtubeEmbeddedFix(pmContainer.select("div.personalmessage").first()); + //Adds stuff to make it work in WebView + //style.css + content = "" + content; + pm.setContent(content); + + pm.setQuoteUrl(pmContainer.select("img[src=https://www.thmmy.gr/smf/Themes/scribbles2_114/images/buttons/quote.gif]") + .first().parent().attr("href")); + pm.setReplyUrl(pmContainer.select("img[src=https://www.thmmy.gr/smf/Themes/scribbles2_114/images/buttons/im_reply.gif]") + .first().parent().attr("href")); + pm.setDeleteUrl(pmContainer.select("img[src=https://www.thmmy.gr/smf/index.php?actio" + + "n=pm;sa=pmactions;pm_actions[321639]=delete;f=inbox;start=45;;sesc=07776660021fecb42ad23f8c5dba6aff]") + .first().parent().attr("href")); + + // language specific parsing + Element username; + if (language == ParseHelpers.Language.GREEK) { + //Finds username and profile's url + username = pmContainer.select("a[title^=Εμφάνιση προφίλ του μέλους]").first(); + if (username == null) { //Deleted profile + isAuthorDeleted = true; + String authorName = pmContainer.select("td:has(div.smalltext:containsOwn(Επισκέπτης))[style^=overflow]") + .first().text(); + authorName = authorName.substring(0, authorName.indexOf(" Επισκέπτης")); + pm.setAuthor(authorName); + pm.setAuthorColor(ParseHelpers.USER_COLOR_YELLOW); + } else { + isAuthorDeleted = false; + pm.setAuthor(username.html()); + pm.setAuthor(username.attr("href")); + } + + String date = dateContainer.text(); + date = date.substring(date.indexOf("στις:") + 6, date.indexOf(" »")); + pm.setPmDate(date); + } else { + //Finds username + username = pmContainer.select("a[title^=View the profile of]").first(); + if (username == null) { //Deleted profile + isAuthorDeleted = true; + String authorName = pmContainer + .select("td:has(div.smalltext:containsOwn(Guest))[style^=overflow]") + .first().text(); + authorName = authorName.substring(0, authorName.indexOf(" Guest")); + pm.setAuthor(authorName); + pm.setAuthorColor(ParseHelpers.USER_COLOR_YELLOW); + } else { + isAuthorDeleted = false; + pm.setAuthor(username.html()); + pm.setAuthor(username.attr("href")); + } + + String date = dateContainer.text(); + date = date.substring(date.indexOf("on:") + 4, date.indexOf(" »")); + pm.setPmDate(date); + } + + if (!isAuthorDeleted) { + int postsLineIndex = -1; + int starsLineIndex = -1; + + Element authorInfoContainer = pmContainer.select("div.smalltext").first(); + List infoList = Arrays.asList(authorInfoContainer.html().split("
")); + + if (language == ParseHelpers.Language.GREEK) { + for (String line : infoList) { + if (line.contains("Μηνύματα:")) { + postsLineIndex = infoList.indexOf(line); + //Remove any line breaks and spaces on the start and end + pm.setAuthorNumberOfPosts(line.replace("\n", "").replace("\r", "").trim()); + } + if (line.contains("Φύλο:")) { + if (line.contains("alt=\"Άντρας\"")) + pm.setAuthorGender("Φύλο: Άντρας"); + else + pm.setAuthorGender("Φύλο: Γυναίκα"); + } + if (line.contains("alt=\"*\"")) { + starsLineIndex = infoList.indexOf(line); + Document starsHtml = Jsoup.parse(line); + pm.setAuthorNumberOfStars(starsHtml.select("img[alt]").size()); + pm.setAuthorColor(ParseHelpers.colorPicker(starsHtml.select("img[alt]").first() + .attr("abs:src"))); + } + } + } else { + for (String line : infoList) { + if (line.contains("Posts:")) { + postsLineIndex = infoList.indexOf(line); + //Remove any line breaks and spaces on the start and end + pm.setAuthorNumberOfPosts(line.replace("\n", "").replace("\r", "").trim()); + } + if (line.contains("Gender:")) { + if (line.contains("alt=\"Male\"")) + pm.setAuthorGender("Gender: Male"); + else + pm.setAuthorGender("Gender: Female"); + } + if (line.contains("alt=\"*\"")) { + starsLineIndex = infoList.indexOf(line); + Document starsHtml = Jsoup.parse(line); + pm.setAuthorNumberOfStars(starsHtml.select("img[alt]").size()); + pm.setAuthorColor(ParseHelpers.colorPicker(starsHtml.select("img[alt]").first() + .attr("abs:src"))); + } + } + } + + //If this member has no stars yet ==> New member, + //or is just a member + if (starsLineIndex == -1 || starsLineIndex == 1) { + pm.setAuthorRank(infoList.get(0).trim()); //First line has the rank + //They don't have a special rank + } else if (starsLineIndex == 2) { //This member has a special rank + pm.setAuthorSpecialRank(infoList.get(0).trim());//First line has the special rank + pm.setAuthorRank(infoList.get(1).trim());//Second line has the rank + } + for (int i = postsLineIndex + 1; i < infoList.size() - 1; ++i) { + //Searches under "Posts:" + //and above "Personal Message", "View Profile" etc buttons + String thisLine = infoList.get(i); + if (!Objects.equals(thisLine, "") && thisLine != null + && !Objects.equals(thisLine, " \n") + && !thisLine.contains("avatar") + && !thisLine.contains(" { } else //noinspection deprecation holder.cardChildLinear.setBackground(context.getResources(). getDrawable(R.drawable.mention_card)); - } else if (mUserColor == TopicParser.USER_COLOR_PINK) { + } else if (mUserColor == ParseHelpers.USER_COLOR_PINK) { //Special card for special member of the month! if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { holder.cardChildLinear.setBackground(context.getResources(). diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java index 1a7922ff..bd8dfab2 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java @@ -1,7 +1,5 @@ package gr.thmmy.mthmmy.activities.topic; -import android.graphics.Color; - import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -30,23 +28,9 @@ import timber.log.Timber; * Singleton used for parsing a topic. *

Class contains the methods: