Browse Source

Merge branch 'develop' into editor_view

pull/45/head
oogee 6 years ago
committed by GitHub
parent
commit
a67221563b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      README.md
  2. 6
      app/build.gradle
  3. 2
      app/src/main/AndroidManifest.xml
  4. 4
      app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java
  5. 4
      app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java
  6. 1
      app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java
  7. 1
      app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java
  8. 22
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  9. 6
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java
  10. 1
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java
  11. 1
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/EditTask.java
  12. 1
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditTask.java
  13. 1
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/ReplyTask.java
  14. 3
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
  15. 3
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTaskResult.java
  16. 293
      app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java
  17. 501
      app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java
  18. 34
      app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java
  19. 3
      app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
  20. 47
      app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
  21. 1
      app/src/main/java/gr/thmmy/mthmmy/services/DownloadHelper.java
  22. 42
      app/src/main/java/gr/thmmy/mthmmy/utils/CrashReporter.java
  23. 11
      app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
  24. 4
      app/src/main/res/drawable/ic_attach_file_white_24dp.xml
  25. 5
      app/src/main/res/drawable/ic_photo_camera_white_24dp.xml
  26. 113
      app/src/main/res/layout/activity_upload.xml
  27. 1
      app/src/main/res/layout/activity_upload_fields_builder.xml
  28. 14
      app/src/main/res/layout/spinner_dropdown_item.xml
  29. 14
      app/src/main/res/layout/spinner_item.xml
  30. 4
      app/src/main/res/values-v21/styles.xml
  31. 1
      app/src/main/res/values-w820dp/dimens.xml
  32. 1
      app/src/main/res/values/dimens.xml
  33. 11
      app/src/main/res/values/strings.xml
  34. 4
      app/src/main/res/values/styles.xml
  35. 2
      build.gradle

2
README.md

@ -22,7 +22,7 @@ Please refer to [CONTRIBUTING.md](/CONTRIBUTING.md) for details.
## Contact ## Contact
Do not hesitate to contact us for any matter, either by sending an email to `thmmynolife@gmail.com`, or by joining our [Discord server][discord-server]. Do not hesitate to contact us for any matter, either by sending an email to [thmmynolife@gmail.com](mailto:thmmynolife@gmail.com), or by joining our [Discord server][discord-server].
**Legal attribution: Google Play and the Google Play logo are trademarks of Google Inc.* **Legal attribution: Google Play and the Google Play logo are trademarks of Google Inc.*

6
app/build.gradle

@ -41,9 +41,9 @@ dependencies {
implementation 'com.android.support:support-v4:27.1.1' implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1' implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1' implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.google.firebase:firebase-core:16.0.1' implementation 'com.google.firebase:firebase-core:16.0.3'
implementation 'com.google.firebase:firebase-messaging:17.1.0' implementation 'com.google.firebase:firebase-messaging:17.3.0'
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.4' implementation 'com.crashlytics.sdk.android:crashlytics:2.9.5'
implementation 'com.squareup.okhttp3:okhttp:3.10.0' implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.picasso:picasso:2.5.2' implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'

2
app/src/main/AndroidManifest.xml

@ -121,7 +121,7 @@
<activity <activity
android:name=".activities.settings.SettingsActivity" android:name=".activities.settings.SettingsActivity"
android:parentActivityName=".activities.main.MainActivity" android:parentActivityName=".activities.main.MainActivity"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.PreferenceTheme">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity" /> android:value=".activities.main.MainActivity" />

4
app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java

@ -12,9 +12,12 @@ import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.Toast; import android.widget.Toast;
import com.google.firebase.analytics.FirebaseAnalytics;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.main.MainActivity;
import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.base.BaseApplication;
import timber.log.Timber; import timber.log.Timber;
import static gr.thmmy.mthmmy.session.SessionManager.BANNED_USER; import static gr.thmmy.mthmmy.session.SessionManager.BANNED_USER;
@ -163,6 +166,7 @@ public class LoginActivity extends BaseActivity {
Toast.makeText(getApplicationContext(), Toast.makeText(getApplicationContext(),
"Welcome, " + sessionManager.getUsername() + "!", Toast.LENGTH_LONG) "Welcome, " + sessionManager.getUsername() + "!", Toast.LENGTH_LONG)
.show(); .show();
BaseApplication.getInstance().logFirebaseAnalyticsEvent(FirebaseAnalytics.Event.LOGIN, null);
//Go to main //Go to main
Intent intent = new Intent(LoginActivity.this, MainActivity.class); Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent); startActivity(intent);

4
app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java

@ -286,9 +286,11 @@ public class BoardActivity extends BaseActivity implements BoardAdapter.OnLoadMo
if (pLastPost.contains("by")) { if (pLastPost.contains("by")) {
pLastPost = pLastPost.substring(0, pLastPost.indexOf("by")) + pLastPost = pLastPost.substring(0, pLastPost.indexOf("by")) +
"\n" + pLastPost.substring(pLastPost.indexOf("by")); "\n" + pLastPost.substring(pLastPost.indexOf("by"));
} else { } else if (pLastPost.contains("από")) {
pLastPost = pLastPost.substring(0, pLastPost.indexOf("από")) + pLastPost = pLastPost.substring(0, pLastPost.indexOf("από")) +
"\n" + pLastPost.substring(pLastPost.indexOf("από")); "\n" + pLastPost.substring(pLastPost.indexOf("από"));
} else {
Timber.wtf("Board parsing about to fail. pLastPost came with: %s", pLastPost);
} }
pLastPostUrl = topicColumns.last().select("a:has(img)").first().attr("href"); pLastPostUrl = topicColumns.last().select("a:has(img)").first().attr("href");
parsedTopics.add(new Topic(pTopicUrl, pSubject, pStartedBy, pLastPost, pLastPostUrl, parsedTopics.add(new Topic(pTopicUrl, pSubject, pStartedBy, pLastPost, pLastPostUrl,

1
app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java

@ -6,7 +6,6 @@ import android.support.annotation.NonNull;
import android.support.v4.widget.SwipeRefreshLayout; import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

1
app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java

@ -1,7 +1,6 @@
package gr.thmmy.mthmmy.activities.settings; package gr.thmmy.mthmmy.activities.settings;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;

22
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java

@ -201,6 +201,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
paginationEnabled(false); paginationEnabled(false);
Timber.i("Starting initial topic load");
viewModel.loadUrl(topicPageUrl); viewModel.loadUrl(topicPageUrl);
} }
@ -501,10 +502,13 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
public void onDeleteTaskFinished(boolean result) { public void onDeleteTaskFinished(boolean result) {
progressBar.setVisibility(ProgressBar.GONE); progressBar.setVisibility(ProgressBar.GONE);
if (result) if (result) {
Timber.i("Post deleted successfully");
viewModel.reloadPage(); viewModel.reloadPage();
else } else {
Timber.w("Failed to delete post");
Toast.makeText(getBaseContext(), "Delete failed!", Toast.LENGTH_SHORT).show(); Toast.makeText(getBaseContext(), "Delete failed!", Toast.LENGTH_SHORT).show();
}
} }
}); });
viewModel.setReplyFinishListener(new ReplyTask.ReplyTaskCallbacks() { viewModel.setReplyFinishListener(new ReplyTask.ReplyTaskCallbacks() {
@ -524,15 +528,18 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
progressBar.setVisibility(ProgressBar.GONE); progressBar.setVisibility(ProgressBar.GONE);
if (success) { if (success) {
Timber.i("Post reply successful");
replyFAB.show(); replyFAB.show();
bottomNavBar.setVisibility(View.VISIBLE); bottomNavBar.setVisibility(View.VISIBLE);
viewModel.setWritingReply(false); viewModel.setWritingReply(false);
if ((postsList.get(postsList.size() - 1).getPostNumber() + 1) % 15 == 0) { if ((postsList.get(postsList.size() - 1).getPostNumber() + 1) % 15 == 0) {
Timber.i("Reply was posted in new page. Switching to last page.");
viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647); viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
} else { } else {
viewModel.reloadPage(); viewModel.reloadPage();
} }
} else { } else {
Timber.w("Post reply unsuccessful");
Toast.makeText(getBaseContext(), "Post failed!", Toast.LENGTH_SHORT).show(); Toast.makeText(getBaseContext(), "Post failed!", Toast.LENGTH_SHORT).show();
recyclerView.getChildAt(postsList.size() - 1).setAlpha(1); recyclerView.getChildAt(postsList.size() - 1).setAlpha(1);
recyclerView.getChildAt(postsList.size() - 1).setEnabled(true); recyclerView.getChildAt(postsList.size() - 1).setEnabled(true);
@ -567,6 +574,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
progressBar.setVisibility(ProgressBar.GONE); progressBar.setVisibility(ProgressBar.GONE);
if (result) { if (result) {
Timber.i("Post edit successful");
postsList.get(position).setPostType(Post.TYPE_POST); postsList.get(position).setPostType(Post.TYPE_POST);
topicAdapter.notifyItemChanged(position); topicAdapter.notifyItemChanged(position);
replyFAB.show(); replyFAB.show();
@ -574,6 +582,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
viewModel.setEditingPost(false); viewModel.setEditingPost(false);
viewModel.reloadPage(); viewModel.reloadPage();
} else { } else {
Timber.i("Post edit unsuccessful");
Toast.makeText(getBaseContext(), "Edit failed!", Toast.LENGTH_SHORT).show(); Toast.makeText(getBaseContext(), "Edit failed!", Toast.LENGTH_SHORT).show();
recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setAlpha(1); recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setAlpha(1);
recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setEnabled(true); recyclerView.getChildAt(viewModel.getPostBeingEditedPosition()).setEnabled(true);
@ -632,9 +641,11 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
progressBar.setVisibility(ProgressBar.GONE); progressBar.setVisibility(ProgressBar.GONE);
switch (resultCode) { switch (resultCode) {
case SUCCESS: case SUCCESS:
Timber.i("Successfully loaded topic with URL %s", viewModel.getTopicUrl());
paginationEnabled(true); paginationEnabled(true);
break; break;
case NETWORK_ERROR: case NETWORK_ERROR:
Timber.w("Network error on loaded page");
if (viewModel.getPostsList().getValue() == null) { if (viewModel.getPostsList().getValue() == null) {
// no page has been loaded yet. Give user the ability to refresh // no page has been loaded yet. Give user the ability to refresh
recyclerView.setVisibility(View.GONE); recyclerView.setVisibility(View.GONE);
@ -656,6 +667,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
} }
break; break;
case UNAUTHORIZED: case UNAUTHORIZED:
Timber.w("Requested topic was unauthorized");
recyclerView.setVisibility(View.GONE); recyclerView.setVisibility(View.GONE);
TextView errorTextview = findViewById(R.id.error_textview); TextView errorTextview = findViewById(R.id.error_textview);
errorTextview.setText(getString(R.string.unauthorized_topic_error)); errorTextview.setText(getString(R.string.unauthorized_topic_error));
@ -663,7 +675,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
break; break;
default: default:
//Parse failed - should never happen //Parse failed - should never happen
Timber.d("Parse failed!"); //TODO report ParseException!!! Timber.wtf("Parse failed!"); //TODO report ParseException!!!
Toast.makeText(getBaseContext(), "Fatal Error", Toast.LENGTH_SHORT).show(); Toast.makeText(getBaseContext(), "Fatal Error", Toast.LENGTH_SHORT).show();
finish(); finish();
break; break;
@ -672,6 +684,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
viewModel.getPrepareForReplyResult().observe(this, prepareForReplyResult -> { viewModel.getPrepareForReplyResult().observe(this, prepareForReplyResult -> {
progressBar.setVisibility(ProgressBar.GONE); progressBar.setVisibility(ProgressBar.GONE);
if (prepareForReplyResult != null && prepareForReplyResult.isSuccessful()) { if (prepareForReplyResult != null && prepareForReplyResult.isSuccessful()) {
Timber.i("Prepare for reply successful");
//prepare for a reply //prepare for a reply
viewModel.setWritingReply(true); viewModel.setWritingReply(true);
postsList.add(Post.newQuickReply()); postsList.add(Post.newQuickReply());
@ -680,12 +693,14 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
replyFAB.hide(); replyFAB.hide();
bottomNavBar.setVisibility(View.GONE); bottomNavBar.setVisibility(View.GONE);
} else { } else {
Timber.i("Prepare for reply unsuccessful");
Snackbar.make(findViewById(R.id.main_content), getString(R.string.generic_network_error), Snackbar.LENGTH_SHORT).show(); Snackbar.make(findViewById(R.id.main_content), getString(R.string.generic_network_error), Snackbar.LENGTH_SHORT).show();
} }
}); });
viewModel.getPrepareForEditResult().observe(this, result -> { viewModel.getPrepareForEditResult().observe(this, result -> {
progressBar.setVisibility(ProgressBar.GONE); progressBar.setVisibility(ProgressBar.GONE);
if (result != null && result.isSuccessful()) { if (result != null && result.isSuccessful()) {
Timber.i("Prepare for edit successful");
viewModel.setEditingPost(true); viewModel.setEditingPost(true);
postsList.get(result.getPosition()).setPostType(Post.TYPE_EDIT); postsList.get(result.getPosition()).setPostType(Post.TYPE_EDIT);
topicAdapter.notifyItemChanged(result.getPosition()); topicAdapter.notifyItemChanged(result.getPosition());
@ -693,6 +708,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
replyFAB.hide(); replyFAB.hide();
bottomNavBar.setVisibility(View.GONE); bottomNavBar.setVisibility(View.GONE);
} else { } else {
Timber.i("Prepare for edit unsuccessful");
Snackbar.make(findViewById(R.id.main_content), getString(R.string.generic_network_error), Snackbar.LENGTH_SHORT).show(); Snackbar.make(findViewById(R.id.main_content), getString(R.string.generic_network_error), Snackbar.LENGTH_SHORT).show();
} }
}); });

6
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java

@ -1,9 +1,7 @@
package gr.thmmy.mthmmy.activities.topic; package gr.thmmy.mthmmy.activities.topic;
import android.graphics.Color; import android.graphics.Color;
import android.util.Log;
import org.jsoup.Connection;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
@ -249,6 +247,10 @@ public class TopicParser {
p_deletePostURL = postDelete.attr("href"); p_deletePostURL = postDelete.attr("href");
} }
Element postEdit = thisRow.select("a:has(img[alt='Αλλαγή'])").first();
if (postEdit != null)
p_editPostURL = postEdit.attr("href");
//Finds post's submit date //Finds post's submit date
Element postDate = thisRow.select("div.smalltext:matches(στις:)").first(); Element postDate = thisRow.select("div.smalltext:matches(στις:)").first();
p_postDate = postDate.text(); p_postDate = postDate.text();

1
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/DeleteTask.java

@ -38,6 +38,7 @@ public class DeleteTask extends AsyncTask<String, Void, Boolean> {
//Response response = client.newCall(delete).execute(); //Response response = client.newCall(delete).execute();
switch (Posting.replyStatus(response)) { switch (Posting.replyStatus(response)) {
case SUCCESSFUL: case SUCCESSFUL:
BaseApplication.getInstance().logFirebaseAnalyticsEvent("post_deletion", null);
return true; return true;
default: default:
Timber.e("Something went wrong. Request string: %s", delete.toString()); Timber.e("Something went wrong. Request string: %s", delete.toString());

1
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/EditTask.java

@ -51,6 +51,7 @@ public class EditTask extends AsyncTask<String, Void, Boolean> {
Response response = client.newCall(post).execute(); Response response = client.newCall(post).execute();
switch (replyStatus(response)) { switch (replyStatus(response)) {
case SUCCESSFUL: case SUCCESSFUL:
BaseApplication.getInstance().logFirebaseAnalyticsEvent("post_editing", null);
return true; return true;
case NEW_REPLY_WHILE_POSTING: case NEW_REPLY_WHILE_POSTING:
//TODO this... //TODO this...

1
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditTask.java

@ -9,7 +9,6 @@ import org.jsoup.select.Selector;
import java.io.IOException; import java.io.IOException;
import gr.thmmy.mthmmy.activities.topic.tasks.PrepareForEditResult;
import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.base.BaseApplication;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;

1
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/ReplyTask.java

@ -54,6 +54,7 @@ public class ReplyTask extends AsyncTask<String, Void, Boolean> {
Response response = client.newCall(post).execute(); Response response = client.newCall(post).execute();
switch (replyStatus(response)) { switch (replyStatus(response)) {
case SUCCESSFUL: case SUCCESSFUL:
BaseApplication.getInstance().logFirebaseAnalyticsEvent("post_creation", null);
return true; return true;
case NEW_REPLY_WHILE_POSTING: case NEW_REPLY_WHILE_POSTING:
//TODO this... //TODO this...

3
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java

@ -107,7 +107,6 @@ public class TopicTask extends AsyncTask<String, Void, TopicTaskResult> {
return new TopicTaskResult(ResultCode.SUCCESS, topicTitle, replyPageUrl, newPostsList, loadedPageTopicId, return new TopicTaskResult(ResultCode.SUCCESS, topicTitle, replyPageUrl, newPostsList, loadedPageTopicId,
currentPageIndex, pageCount, focusedPostIndex, topicTreeAndMods, topicViewers); currentPageIndex, pageCount, focusedPostIndex, topicTreeAndMods, topicViewers);
} catch (IOException e) { } catch (IOException e) {
Timber.i(e, "IO Exception");
return new TopicTaskResult(ResultCode.NETWORK_ERROR, null, null, null, return new TopicTaskResult(ResultCode.NETWORK_ERROR, null, null, null,
0, 0, 0, 0, null, null); 0, 0, 0, 0, null, null);
} catch (Exception e) { } catch (Exception e) {
@ -115,7 +114,7 @@ public class TopicTask extends AsyncTask<String, Void, TopicTaskResult> {
return new TopicTaskResult(ResultCode.UNAUTHORIZED, null, null, null, return new TopicTaskResult(ResultCode.UNAUTHORIZED, null, null, null,
0, 0, 0, 0, null, null); 0, 0, 0, 0, null, null);
} else { } else {
Timber.e(e, "Parsing Error"); Timber.e(e, "Topic parse failed");
return new TopicTaskResult(ResultCode.PARSING_ERROR, null, null, null, return new TopicTaskResult(ResultCode.PARSING_ERROR, null, null, null,
0, 0, 0, 0, null, null); 0, 0, 0, 0, null, null);
} }

3
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTaskResult.java

@ -1,10 +1,7 @@
package gr.thmmy.mthmmy.activities.topic.tasks; package gr.thmmy.mthmmy.activities.topic.tasks;
import android.util.SparseArray;
import java.util.ArrayList; import java.util.ArrayList;
import gr.thmmy.mthmmy.activities.topic.tasks.TopicTask;
import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.Post;
public class TopicTaskResult { public class TopicTaskResult {

293
app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java

@ -5,20 +5,17 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.provider.OpenableColumns; import android.support.design.widget.FloatingActionButton;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.content.res.AppCompatResources; import android.support.v7.content.res.AppCompatResources;
import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceManager;
import android.support.v7.widget.AppCompatButton; import android.support.v7.widget.AppCompatButton;
import android.support.v7.widget.AppCompatTextView;
import android.view.View; import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
@ -37,12 +34,8 @@ import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -73,12 +66,15 @@ public class UploadActivity extends BaseActivity {
*/ */
public static final String BUNDLE_UPLOAD_CATEGORY = "UPLOAD_CATEGORY"; public static final String BUNDLE_UPLOAD_CATEGORY = "UPLOAD_CATEGORY";
private static final String uploadIndexUrl = "https://www.thmmy.gr/smf/index.php?action=tpmod;dl=upload"; private static final String uploadIndexUrl = "https://www.thmmy.gr/smf/index.php?action=tpmod;dl=upload";
private static final String uploadedFrommThmmyPromptHtml = "<br /><div style=\"text-align: right;\"><span style=\"font-style: italic;\">uploaded from <a href=\"https://play.google.com/store/apps/details?id=gr.thmmy.mthmmy\">mTHMMY</a></span>"; private static final String uploadedFromThmmyPromptHtml = "<br /><div style=\"text-align: right;\"><span style=\"font-style: italic;\">uploaded from <a href=\"https://play.google.com/store/apps/details?id=gr.thmmy.mthmmy\">mTHMMY</a></span>";
private static final int REQUEST_CODE_CHOOSE_FILE = 8; /**
private static final int REQUEST_CODE_CAMERA = 4; * Request codes used in activities for result (AFR) calls
private static final int REQUEST_CODE_FIELDS_BUILDER = 74; */
private static final int AFR_REQUEST_CODE_CHOOSE_FILE = 8;
private static final int AFR_REQUEST_CODE_CAMERA = 4;
private static final int AFR_REQUEST_CODE_FIELDS_BUILDER = 74;
private static ArrayList<UploadCategory> uploadRootCategories = new ArrayList<>(); private ArrayList<UploadCategory> uploadRootCategories = new ArrayList<>();
private ParseUploadPageTask parseUploadPageTask; private ParseUploadPageTask parseUploadPageTask;
private ArrayList<String> bundleCategory; private ArrayList<String> bundleCategory;
private String categorySelected = "-1"; private String categorySelected = "-1";
@ -94,8 +90,7 @@ public class UploadActivity extends BaseActivity {
private EditText uploadTitle; private EditText uploadTitle;
private EditText uploadDescription; private EditText uploadDescription;
private AppCompatButton titleDescriptionBuilderButton; private AppCompatButton titleDescriptionBuilderButton;
private AppCompatButton selectFileButton; private AppCompatTextView filenameHolder;
//private static AppCompatButton titleDescriptionBuilderButton;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -141,7 +136,7 @@ public class UploadActivity extends BaseActivity {
titleDescriptionBuilderButton = findViewById(R.id.upload_title_description_builder); titleDescriptionBuilderButton = findViewById(R.id.upload_title_description_builder);
titleDescriptionBuilderButton.setOnClickListener(view -> { titleDescriptionBuilderButton.setOnClickListener(view -> {
if (categorySelected.equals("-1")) { if (categorySelected.equals("-1")) {
Toast.makeText(view.getContext(), "Please choose category first", Toast.LENGTH_SHORT).show(); Toast.makeText(view.getContext(), "Please choose a category first", Toast.LENGTH_SHORT).show();
return; return;
} }
@ -186,65 +181,62 @@ public class UploadActivity extends BaseActivity {
} }
//Fixes course and semester //Fixes course and semester
maybeCourse = maybeCourse.replaceAll("-", "").replace("(ΝΠΣ)", "").trim(); String course = maybeCourse.replaceAll("-", "").replace("(ΝΠΣ)", "").trim();
maybeSemester = maybeSemester.replaceAll("-", "").trim().substring(0, 1); String semester = maybeSemester.replaceAll("-", "").trim().substring(0, 1);
Intent intent = new Intent(UploadActivity.this, UploadFieldsBuilderActivity.class); Intent intent = new Intent(UploadActivity.this, UploadFieldsBuilderActivity.class);
Bundle builderExtras = new Bundle(); Bundle builderExtras = new Bundle();
builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE, maybeCourse); builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE, course);
builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER, maybeSemester); builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER, semester);
intent.putExtras(builderExtras); intent.putExtras(builderExtras);
startActivityForResult(intent, REQUEST_CODE_FIELDS_BUILDER); startActivityForResult(intent, AFR_REQUEST_CODE_FIELDS_BUILDER);
}); });
titleDescriptionBuilderButton.setEnabled(false); titleDescriptionBuilderButton.setEnabled(false);
uploadTitle = findViewById(R.id.upload_title); uploadTitle = findViewById(R.id.upload_title);
uploadDescription = findViewById(R.id.upload_description); uploadDescription = findViewById(R.id.upload_description);
selectFileButton = findViewById(R.id.upload_select_file_button); filenameHolder = findViewById(R.id.upload_filename);
Drawable filenameDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_attach_file_white_24dp);
filenameHolder.setCompoundDrawablesRelativeWithIntrinsicBounds(filenameDrawable, null, null, null);
AppCompatButton selectFileButton = findViewById(R.id.upload_select_file_button);
Drawable selectStartDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_insert_drive_file_white_24dp); Drawable selectStartDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_insert_drive_file_white_24dp);
selectFileButton.setCompoundDrawablesRelativeWithIntrinsicBounds(selectStartDrawable, null, null, null); selectFileButton.setCompoundDrawablesRelativeWithIntrinsicBounds(selectStartDrawable, null, null, null);
selectFileButton.setOnClickListener(v -> { selectFileButton.setOnClickListener(v -> {
final CharSequence[] options = {"Take photo", "Choose file", String[] mimeTypes = {"image/jpeg", "text/html", "image/png", "image/jpg", "image/gif",
"Cancel"}; "application/pdf", "application/rar", "application/x-tar", "application/zip",
AlertDialog.Builder builder = new AlertDialog.Builder(UploadActivity.this); "application/msword", "image/vnd.djvu", "application/gz", "application/tar.gz"};
builder.setTitle("Upload file");
builder.setItems(options, (dialog, item) -> {
if (options[item].equals("Take photo")) {
/*Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CODE_CAMERA);*/
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra("return-data", true);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(UploadsHelper.getTempFile(this)));
Intent targetedIntent = new Intent(takePhotoIntent);
List<ResolveInfo> resInfo = this.getPackageManager().queryIntentActivities(takePhotoIntent, 0);
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
targetedIntent.setPackage(packageName);
}
startActivityForResult(takePhotoIntent, REQUEST_CODE_CAMERA);
} else if (options[item].equals("Choose file")) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT)
String[] mimeTypes = {"image/jpeg", "text/html", "image/png", "image/jpg", "image/gif", //.setType("*/*")
"application/pdf", "application/rar", "application/x-tar", "application/zip", .setType("image/jpeg")
"application/msword", "image/vnd.djvu", "application/gz", "application/tar.gz"}; .putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT) startActivityForResult(intent, AFR_REQUEST_CODE_CHOOSE_FILE);
//.setType("*/*") });
.setType("image/jpeg")
.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
startActivityForResult(intent, REQUEST_CODE_CHOOSE_FILE); AppCompatButton takePhotoButton = findViewById(R.id.upload_take_photo_button);
} else if (options[item].equals("Cancel")) { Drawable takePhotoDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_photo_camera_white_24dp);
dialog.dismiss(); takePhotoButton.setCompoundDrawablesRelativeWithIntrinsicBounds(takePhotoDrawable, null, null, null);
} takePhotoButton.setOnClickListener(v -> {
}); Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
builder.show(); takePhotoIntent.putExtra("return-data", true);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(UploadsHelper.getCacheFile(this)));
Intent targetedIntent = new Intent(takePhotoIntent);
List<ResolveInfo> resInfo = this.getPackageManager().queryIntentActivities(takePhotoIntent, 0);
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
targetedIntent.setPackage(packageName);
}
startActivityForResult(takePhotoIntent, AFR_REQUEST_CODE_CAMERA);
}); });
findViewById(R.id.upload_upload_button).setOnClickListener(view -> { FloatingActionButton uploadFAB = findViewById(R.id.upload_fab);
uploadFAB.setOnClickListener(view -> {
progressBar.setVisibility(View.VISIBLE);
String uploadTitleText = uploadTitle.getText().toString(); String uploadTitleText = uploadTitle.getText().toString();
String uploadDescriptionText = uploadDescription.getText().toString(); String uploadDescriptionText = uploadDescription.getText().toString();
@ -252,39 +244,40 @@ public class UploadActivity extends BaseActivity {
uploadTitle.setError("Required"); uploadTitle.setError("Required");
} }
if (fileUri == null) { if (fileUri == null) {
selectFileButton.setError("Required"); Toast.makeText(view.getContext(), "Please choose a file to upload or take a photo", Toast.LENGTH_LONG).show();
} }
if (categorySelected.equals("-1")) { if (categorySelected.equals("-1")) {
Toast.makeText(view.getContext(), "Please choose category first", Toast.LENGTH_SHORT).show(); Toast.makeText(view.getContext(), "Please choose category first", Toast.LENGTH_SHORT).show();
} }
if (categorySelected.equals("-1") || uploadTitleText.equals("") || fileUri == null) { if (categorySelected.equals("-1") || uploadTitleText.equals("") || fileUri == null) {
progressBar.setVisibility(View.GONE);
return; return;
} }
String tmpDescriptionText = uploadDescriptionText;
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(view.getContext()); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(view.getContext());
if (sharedPrefs.getBoolean(UPLOADING_APP_SIGNATURE_ENABLE_KEY, true)) { if (sharedPrefs.getBoolean(UPLOADING_APP_SIGNATURE_ENABLE_KEY, true)) {
tmpDescriptionText += uploadedFrommThmmyPromptHtml; uploadDescriptionText += uploadedFromThmmyPromptHtml;
} }
String tempFilePath = null; String tempFilePath = null;
if (uploadFilename != null) { if (uploadFilename != null) {
//File should be uploaded with a certain name. Temporarily copies the file and renames it
tempFilePath = UploadsHelper.createTempFile(this, fileUri, uploadFilename); tempFilePath = UploadsHelper.createTempFile(this, fileUri, uploadFilename);
if (tempFilePath == null) { if (tempFilePath == null) {
//Something went wrong, abort //Something went wrong, abort
Toast.makeText(this, "Could not create temporary file for renaming", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
return; return;
} }
} }
try { try {
final String finalTempFilePath = tempFilePath;
new MultipartUploadRequest(view.getContext(), uploadIndexUrl) new MultipartUploadRequest(view.getContext(), uploadIndexUrl)
.setUtf8Charset() .setUtf8Charset()
.addParameter("tp-dluploadtitle", uploadTitleText) .addParameter("tp-dluploadtitle", uploadTitleText)
.addParameter("tp-dluploadcat", categorySelected) .addParameter("tp-dluploadcat", categorySelected)
.addParameter("tp-dluploadtext", tmpDescriptionText) .addParameter("tp-dluploadtext", uploadDescriptionText)
.addFileToUpload(tempFilePath == null .addFileToUpload(tempFilePath == null
? fileUri.toString() ? fileUri.toString()
: tempFilePath : tempFilePath
@ -302,68 +295,46 @@ public class UploadActivity extends BaseActivity {
public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse, public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse,
Exception exception) { Exception exception) {
Toast.makeText(context, "Upload failed", Toast.LENGTH_SHORT).show(); Toast.makeText(context, "Upload failed", Toast.LENGTH_SHORT).show();
if (finalTempFilePath != null) { UploadsHelper.deleteTempFiles();
if (!UploadsHelper.deleteTempFile(finalTempFilePath)) { progressBar.setVisibility(View.GONE);
Toast.makeText(context, "Failed to delete temporary file", Toast.LENGTH_SHORT).show();
}
}
} }
@Override @Override
public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) { public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) {
if (finalTempFilePath != null) { Toast.makeText(context, "Upload completed successfully", Toast.LENGTH_SHORT).show();
if (!UploadsHelper.deleteTempFile(finalTempFilePath)) { UploadsHelper.deleteTempFiles();
Toast.makeText(context, "Failed to delete temporary file", Toast.LENGTH_SHORT).show(); BaseApplication.getInstance().logFirebaseAnalyticsEvent("file_upload", null);
}
} uploadTitle.setText(null);
uploadDescription.setText(null);
fileUri = null;
filenameHolder.setText(null);
filenameHolder.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
} }
@Override @Override
public void onCancelled(Context context, UploadInfo uploadInfo) { public void onCancelled(Context context, UploadInfo uploadInfo) {
if (finalTempFilePath != null) { Toast.makeText(context, "Upload canceled", Toast.LENGTH_SHORT).show();
if (!UploadsHelper.deleteTempFile(finalTempFilePath)) {
Toast.makeText(context, "Failed to delete temporary file", Toast.LENGTH_SHORT).show(); UploadsHelper.deleteTempFiles();
} progressBar.setVisibility(View.GONE);
}
} }
}) })
.startUpload(); .startUpload();
} catch (Exception exception) { } catch (Exception exception) {
Timber.e(exception, "AndroidUploadService: %s", exception.getMessage()); Timber.e(exception, "AndroidUploadService: %s", exception.getMessage());
progressBar.setVisibility(View.GONE);
} }
}); });
if (uploadRootCategories.isEmpty()) { if (uploadRootCategories.isEmpty()) {
//Parses the uploads page
parseUploadPageTask = new ParseUploadPageTask(); parseUploadPageTask = new ParseUploadPageTask();
parseUploadPageTask.execute(uploadIndexUrl); parseUploadPageTask.execute(uploadIndexUrl);
} else { } else {
String[] tmpSpinnerArray = new String[uploadRootCategories.size()]; //Renders the already parsed data
for (int i = 0; i < uploadRootCategories.size(); ++i) { updateUIElements();
tmpSpinnerArray[i] = uploadRootCategories.get(i).getCategoryTitle();
}
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(BaseApplication.getInstance().getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item, tmpSpinnerArray);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
rootCategorySpinner.setAdapter(spinnerArrayAdapter);
//Sets bundle selection
if (bundleCategory != null) {
int bundleSelectionIndex = -1, currentIndex = 0;
for (UploadCategory category : uploadRootCategories) {
if (bundleCategory.get(0).contains(category.getCategoryTitle())) {
bundleSelectionIndex = currentIndex;
break;
}
++currentIndex;
}
if (bundleSelectionIndex != -1) {
rootCategorySpinner.setSelection(bundleSelectionIndex, true);
bundleCategory.remove(0);
}
}
titleDescriptionBuilderButton.setEnabled(true); titleDescriptionBuilderButton.setEnabled(true);
} }
} }
@ -392,15 +363,16 @@ public class UploadActivity extends BaseActivity {
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_CHOOSE_FILE && data != null) { if (requestCode == AFR_REQUEST_CODE_CHOOSE_FILE) {
if (resultCode == Activity.RESULT_CANCELED) { if (resultCode == Activity.RESULT_CANCELED || data == null) {
return; return;
} }
fileUri = data.getData(); fileUri = data.getData();
if (fileUri != null) { if (fileUri != null) {
String filename = UploadsHelper.filenameFromUri(this, fileUri); String filename = UploadsHelper.filenameFromUri(this, fileUri);
selectFileButton.setText(filename); filenameHolder.setText(filename);
filenameHolder.setVisibility(View.VISIBLE);
filename = filename.toLowerCase(); filename = filename.toLowerCase();
if (filename.endsWith(".jpg")) { if (filename.endsWith(".jpg")) {
@ -422,38 +394,40 @@ public class UploadActivity extends BaseActivity {
fileIcon = "blank.gif"; fileIcon = "blank.gif";
} }
} }
} else if (requestCode == REQUEST_CODE_CAMERA) { } else if (requestCode == AFR_REQUEST_CODE_CAMERA) {
if (resultCode == Activity.RESULT_CANCELED) { if (resultCode == Activity.RESULT_CANCELED) {
return; return;
} }
Bitmap bitmap; Bitmap bitmap;
File cacheImageFile = UploadsHelper.getTempFile(this); File cacheImageFile = UploadsHelper.getCacheFile(this);
if (resultCode == Activity.RESULT_OK) {
fileUri = Uri.fromFile(cacheImageFile);
fileIcon = "jpg_image.gif";
bitmap = UploadsHelper.getImageResized(this, fileUri);
int rotation = UploadsHelper.getRotation(this, fileUri);
bitmap = UploadsHelper.rotate(bitmap, rotation);
try {
FileOutputStream out = new FileOutputStream(cacheImageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
String newFilename = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE). Uri cacheFileUri = Uri.fromFile(cacheImageFile);
format(new Date()); fileIcon = "jpg_image.gif";
fileUri = Uri.parse(UploadsHelper.createTempFile(this, fileUri, newFilename));
newFilename += ".jpg"; bitmap = UploadsHelper.getImageResized(this, cacheFileUri);
selectFileButton.setText(newFilename); int rotation = UploadsHelper.getRotation(this, cacheFileUri);
bitmap = UploadsHelper.rotate(bitmap, rotation);
try {
FileOutputStream out = new FileOutputStream(cacheImageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
} }
} else if (requestCode == REQUEST_CODE_FIELDS_BUILDER) {
String newFilename = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).
format(new Date());
fileUri = Uri.parse(UploadsHelper.createTempFile(this, cacheFileUri, newFilename));
newFilename += ".jpg";
filenameHolder.setText(newFilename);
filenameHolder.setVisibility(View.VISIBLE);
UploadsHelper.deleteCacheFiles(this);
} else if (requestCode == AFR_REQUEST_CODE_FIELDS_BUILDER) {
if (resultCode == Activity.RESULT_CANCELED) { if (resultCode == Activity.RESULT_CANCELED) {
return; return;
} }
@ -499,8 +473,8 @@ public class UploadActivity extends BaseActivity {
} }
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(getApplicationContext(), ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item, tmpSpinnerArray); R.layout.spinner_item, tmpSpinnerArray);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerArrayAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
AppCompatSpinnerWithoutDefault subSpinner = new AppCompatSpinnerWithoutDefault(categoriesSpinners.getContext()); AppCompatSpinnerWithoutDefault subSpinner = new AppCompatSpinnerWithoutDefault(categoriesSpinners.getContext());
subSpinner.setPromptId(R.string.upload_spinners_hint); subSpinner.setPromptId(R.string.upload_spinners_hint);
@ -578,7 +552,7 @@ public class UploadActivity extends BaseActivity {
UploadCategory secondLevelCategory = firstLevelCategory.getSubCategories().get(firstLevelCategory.getSubCategories().size() - 1); UploadCategory secondLevelCategory = firstLevelCategory.getSubCategories().get(firstLevelCategory.getSubCategories().size() - 1);
secondLevelCategory.addSubCategory(categoryValue, categoryText); secondLevelCategory.addSubCategory(categoryValue, categoryText);
} else if (categoryText.startsWith("---- ")) { } else if (categoryText.startsWith("---- ")) {
//This is a level three subcategory //This is a level four subcategory
UploadCategory rootLevelCategory = uploadRootCategories.get(uploadRootCategories.size() - 1); UploadCategory rootLevelCategory = uploadRootCategories.get(uploadRootCategories.size() - 1);
UploadCategory firstLevelCategory = rootLevelCategory.getSubCategories().get(rootLevelCategory.getSubCategories().size() - 1); UploadCategory firstLevelCategory = rootLevelCategory.getSubCategories().get(rootLevelCategory.getSubCategories().size() - 1);
UploadCategory secondLevelCategory = firstLevelCategory.getSubCategories().get(firstLevelCategory.getSubCategories().size() - 1); UploadCategory secondLevelCategory = firstLevelCategory.getSubCategories().get(firstLevelCategory.getSubCategories().size() - 1);
@ -593,36 +567,39 @@ public class UploadActivity extends BaseActivity {
@Override @Override
protected void postExecution(ResultCode result) { protected void postExecution(ResultCode result) {
String[] tmpSpinnerArray = new String[uploadRootCategories.size()]; updateUIElements();
for (int i = 0; i < uploadRootCategories.size(); ++i) { titleDescriptionBuilderButton.setEnabled(true);
tmpSpinnerArray[i] = uploadRootCategories.get(i).getCategoryTitle(); progressBar.setVisibility(ProgressBar.GONE);
} }
}
private void updateUIElements() {
String[] tmpSpinnerArray = new String[uploadRootCategories.size()];
for (int i = 0; i < uploadRootCategories.size(); ++i) {
tmpSpinnerArray[i] = uploadRootCategories.get(i).getCategoryTitle();
}
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(BaseApplication.getInstance().getApplicationContext(), ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(BaseApplication.getInstance().getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item, tmpSpinnerArray); R.layout.spinner_item, tmpSpinnerArray);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerArrayAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
rootCategorySpinner.setAdapter(spinnerArrayAdapter); rootCategorySpinner.setAdapter(spinnerArrayAdapter);
//Sets bundle selection //Sets bundle selection
if (bundleCategory != null) { if (bundleCategory != null) {
int bundleSelectionIndex = -1, currentIndex = 0; int bundleSelectionIndex = -1, currentIndex = 0;
for (UploadCategory category : uploadRootCategories) { for (UploadCategory category : uploadRootCategories) {
if (bundleCategory.get(0).contains(category.getCategoryTitle())) { if (bundleCategory.get(0).contains(category.getCategoryTitle())) {
bundleSelectionIndex = currentIndex; bundleSelectionIndex = currentIndex;
break; break;
}
++currentIndex;
}
if (bundleSelectionIndex != -1) {
rootCategorySpinner.setSelection(bundleSelectionIndex, true);
bundleCategory.remove(0);
} }
++currentIndex;
} }
titleDescriptionBuilderButton.setEnabled(true); if (bundleSelectionIndex != -1) {
progressBar.setVisibility(ProgressBar.GONE); rootCategorySpinner.setSelection(bundleSelectionIndex, true);
bundleCategory.remove(0);
}
} }
} }
} }

501
app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java

@ -87,7 +87,7 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity {
//Initialize toolbar //Initialize toolbar
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle("Upload fields builder"); toolbar.setTitle(R.string.upload_fields_builder_toolbar_title);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
if (getSupportActionBar() != null) { if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@ -215,263 +215,300 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity {
@Nullable @Nullable
private String getGreeklishOrMinifiedCourseName(boolean greeklish) { private String getGreeklishOrMinifiedCourseName(boolean greeklish) {
//TODO fill missing values if (course.contains("Ψηφιακή Επεξεργασία Σήματος")) {
if (course.contains("Συστήματα Υπολογιστών (Υπολογιστικά Συστήματα)")) { return greeklish ? "PSES" : "ΨΕΣ";
return greeklish ? "sys_ypologistwn" : "Συσ. Υπολογιστών"; } else if (course.contains("Ψηφιακή Επεξεργασία Εικόνας")) {
} else if (course.contains("Τεχνική Μηχανική")) { return greeklish ? "psee" : "ΨΕΕ";
return greeklish ? "texn_mhxan" : "Τεχν. Μηχαν."; } else if (course.contains("Ψηφιακές Τηλεπικοινωνίες ΙΙ")) {
} else if (course.contains("Διαφορικές Εξισώσεις")) { return greeklish ? "pshf_thlep_II" : "Ψηφιακές Τηλεπ. 2";
return greeklish ? "diaforikes" : "Διαφορικές"; } else if (course.contains("Ψηφιακές Τηλεπικοινωνίες Ι")) {
} else if (course.contains("Θεωρία Πιθανοτήτων και Στατιστική")) { return greeklish ? "pshf_thlep_I" : "Ψηφιακές Τηλεπ. 1";
return greeklish ? "pithanothtes" : "Πιθανότητες"; } else if (course.contains("Ψηφιακά Φίλτρα")) {
} else if (course.contains("Εφαρμοσμένα Μαθηματικά Ι")) { return greeklish ? "filtra" : "Φίλτρα";
return greeklish ? "efarmosmena_math_I" : "Εφαρμοσμένα 1"; } else if (course.contains("Ψηφιακά Συστήματα ΙΙΙ")) {
} else if (course.contains("Ηλεκτρικά Κυκλώματα ΙΙ")) { return greeklish ? "pshfiaka_III" : "Ψηφιακά 3";
return greeklish ? "kyklwmata_II" : "Κυκλώματα 2"; } else if (course.contains("Ψηφιακά Συστήματα ΙΙ")) {
} else if (course.contains("Ηλεκτρολογικά Υλικά")) { return greeklish ? "pshfiaka_II" : "Ψηφιακά 2";
return greeklish ? "ylika" : "Ηλεκτρ. Υλικά";
} else if (course.contains("Ηλεκτρομαγνητικό Πεδίο Ι")) {
return greeklish ? "pedio_I" : "Πεδίο 1";
} else if (course.contains("Θεωρία Σημάτων και Γραμμικών Συστημάτων")) {
return greeklish ? "analog_shma" : "Σύματα & Συστήματα";
} else if (course.contains("Προγραμματιστικές Τεχνικές")) {
return greeklish ? "cpp" : "Προγραμματ. Τεχν.";
} else if (course.contains("Αριθμητική Ανάλυση")) {
return greeklish ? "arith_anal" : "Αριθμ. Ανάλυση";
} else if (course.contains("Αρχιτεκτονική Υπολογιστών")) {
return greeklish ? "arx_ypologistwn" : "Αρχ. Υπολογιστών";
} else if (course.contains("Εισαγωγή στην Ενεργειακή Τεχνολογία Ι")) {
return greeklish ? "EET_I" : "ΕΕΤ 1";
} else if (course.contains("Ηλεκτρικά Κυκλώματα ΙΙΙ")) {
return greeklish ? "kyklwmata_I" : "Κυκλώματα 3";
} else if (course.contains("Ηλεκτρομαγνητικό Πεδίο ΙΙ")) {
return greeklish ? "pedio_II" : "Πεδίο 2";
} else if (course.contains("Στοχαστικό Σήμα")) {
return greeklish ? "stox_shma" : "Στοχ. Σήμα";
} else if (course.contains("Ψηφιακά Συστήματα Ι")) { } else if (course.contains("Ψηφιακά Συστήματα Ι")) {
return greeklish ? "pshfiaka_I" : "Ψηφιακά 1"; return greeklish ? "pshfiaka_I" : "Ψηφιακά 1";
} else if (course.contains("Αναλογικές Τηλεπικοινωνίες (πρώην Τηλεπικοινωνιακά Συστήματα Ι)")) { } else if (course.contains("Φωτονική Τεχνολογία")) {
return greeklish ? "anal_thlep" : "Αναλογικές Τηλεπ."; return greeklish ? "fwtonikh" : "Φωτονική";
} else if (course.contains("Διάδοση Ηλεκτρομαγνητικού Κύματος Ι (πρώην Πεδίο ΙΙΙ)")) {
return greeklish ? "diadosi_1" : "Διάδοση 1";
} else if (course.contains("Δομές Δεδομένων")) {
return greeklish ? "dom_dedomenwn" : "Δομ. Δεδομ.";
} else if (course.contains("Εισαγωγή στην Ενεργειακή Τεχνολογία ΙΙ")) {
return greeklish ? "EET_2" : "ΕΕΤ2";
} else if (course.contains("Ηλεκτρικές Μετρήσεις Ι")) {
return greeklish ? "metrhseis_1" : "Μετρήσεις 1";
} else if (course.contains("Ηλεκτρονική ΙΙ")) {
return greeklish ? "hlektronikh_2" : "Ηλεκτρονική 2";
} else if (course.contains("Συστήματα Αυτομάτου Ελέγχου Ι")) {
return greeklish ? "SAE_1" : "ΣΑΕ 1";
} else if (course.contains("Γραμμική Άλγεβρα")) {
return greeklish ? "grammikh_algebra" : "Γραμμ. Άλγεβρ.";
} else if (course.contains("Δομημένος Προγραμματισμός")) {
return greeklish ? "C" : "Δομ. Προγραμμ.";
} else if (course.contains("Λογική Σχεδίαση")) {
return greeklish ? "logiki_sxediash" : "Λογική Σχεδίαση";
} else if (course.contains("Λογισμός Ι")) {
return greeklish ? "logismos_I" : "Λογισμός 1";
} else if (course.contains("Τεχνικές Σχεδίασης με Η/Υ")) {
return greeklish ? "sxedio" : "Σχέδιο";
} else if (course.contains("Φυσική Ι")) { } else if (course.contains("Φυσική Ι")) {
return greeklish ? "fysikh_I" : "Φυσική 1"; return greeklish ? "fysikh_I" : "Φυσική 1";
} else if (course.contains("Αντικειμενοστραφής Προγραμματισμός")) { } else if (course.contains("Υψηλές Τάσεις ΙΙΙ")) {
return greeklish ? "OOP" : "Αντικειμενοστραφής"; return greeklish ? "ypshles_III" : "Υψηλές 3";
} else if (course.contains("Εφαρμοσμένη Θερμοδυναμική")) { } else if (course.contains("Υψηλές Τάσεις ΙΙ")) {
return greeklish ? "thermodynamikh" : "Θερμοδυναμική"; return greeklish ? "ypshles_II" : "Υψηλές 2";
} else if (course.contains("Ηλεκτρικά Κυκλώματα Ι")) {
return greeklish ? "kyklwmata_I" : "Κυκλώματα 1";
} else if (course.contains("Λογισμός ΙΙ")) {
return greeklish ? "logismos_II" : "Λογισμός 2";
} else if (course.contains("Οργάνωση Υπολογιστών")) {
return greeklish ? "org_ypol" : "Οργάνωση Υπολ.";
} else if (course.contains("Ηλεκτρονική Ι")) {
return greeklish ? "hlektronikh_1" : "Ηλεκτρονική 1";
} else if (course.contains("Διακριτά μαθηματικά")) {
return greeklish ? "diakrita" : "Διακριτά Μαθηματικά";
} else if (course.contains("Σήματα και Συστήματα")) {
return greeklish ? "analog_shma" : "Σύματα & Συστήματα";
} else if (course.contains("Εισαγωγή στις εφαρμογές Πυρηνικής Τεχνολογίας")) {
return greeklish ? "Intro_Purhnikh_Texn" : "Εισ. Πυρηνικη Τεχν.";
} else if (course.contains("Επιχειρησιακή Έρευνα")) {
return greeklish ? "epixeirisiaki" : "Επιχειρησιακή Έρευνα";
} else if (course.contains("Ημιαγωγά Υλικά: Θεωρία-Διατάξεις")) {
return greeklish ? "Hmiagwga_Ylika" : "Ημιαγωγά Υλικά";
} else if (course.contains("Μετάδοση Θερμότητας")) {
return greeklish ? "metadosi_therm" : "Μετάδοση Θερμ.";
} else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας Ι")) {
return greeklish ? "SHE_I" : "ΣΗΕ 1";
} else if (course.contains("Υψηλές Τάσεις Ι")) { } else if (course.contains("Υψηλές Τάσεις Ι")) {
return greeklish ? "ypshles_I" : "Υψηλές 1"; return greeklish ? "ypshles_I" : "Υψηλές 1";
} else if (course.contains("Θεωρία και Τεχνολογία Πυρηνικών Αντιδραστήρων")) { } else if (course.contains("Υψηλές Τάσεις 4")) {
return greeklish ? "texn_antidrasthrwn" : "Τεχνολογία Αντιδραστήρων"; return greeklish ? "ypshles_IV" : "Υψηλές 4";
} else if (course.contains("Υπολογιστικός Ηλεκτρομαγνητισμός")) {
return greeklish ? "ypologistikos_HM" : "Υπολογιστικός Η/Μ";
} else if (course.contains("Υπολογιστικές Μέθοδοι στα Ενεργειακά Συστήματα")) {
return greeklish ? "ymes" : "ΥΜΕΣ";
} else if (course.contains("Τηλεπικοινωνιακή Ηλεκτρονική")) {
return greeklish ? "tilep_ilektr" : "Τηλεπ. Ηλεκτρ.";
} else if (course.contains("Τηλεοπτικά Συστήματα")) {
return greeklish ? "tileoptika" : "Τηλεοπτικά";
} else if (course.contains("Τεχνολογία Λογισμικού")) {
return greeklish ? "SE" : "Τεχνολογία Λογισμικού";
} else if (course.contains("Τεχνολογία Ηλεκτροτεχνικών Υλικών")) { } else if (course.contains("Τεχνολογία Ηλεκτροτεχνικών Υλικών")) {
return greeklish ? "Hlektrotexnika_Ylika" : "Ηλεκτροτεχνικά Υλικά"; return greeklish ? "Hlektrotexnika_Ylika" : "Ηλεκτροτεχνικά Υλικά";
} else if (course.contains("Ηλεκτρικές Μηχανές Α'")) { } else if (course.contains("Τεχνολογία Ήχου και Εικόνας")) {
return greeklish ? "mhxanes_A" : "Μηχανές Α"; return greeklish ? "texn_hxoy_eikonas" : "Τεχνολογία Ήχου και Εικόνας";
} else if (course.contains("Σταθμοί Παραγωγής Ηλεκτρικής Ενέργειας")) { } else if (course.contains("Τεχνική Μηχανική")) {
return greeklish ? "SPHE" : "ΣΠΗΕ"; return greeklish ? "texn_mhxan" : "Τεχν. Μηχαν.";
} else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας ΙΙ")) { } else if (course.contains("Τεχνικές μη Καταστρεπτικών Δοκιμών")) {
return greeklish ? "SHE_II" : "ΣΗΕ 2"; return greeklish ? "non_destructive_tests" : "Μη Καταστρεπτικές Δοκιμές";
} else if (course.contains("Υψηλές Τάσεις ΙΙ")) { } else if (course.contains("Τεχνικές Σχεδίασης με Η/Υ")) {
return greeklish ? "ypshles_II" : "Υψηλές 2"; return greeklish ? "sxedio" : "Σχέδιο";
} else if (course.contains("Αρχές Οικονομίας")) { } else if (course.contains("Τεχνικές Κωδικοποίησης")) {
return greeklish ? "arx_oikonomias" : "Αρχές Οικονομίας"; return greeklish ? "texn_kwdikopoihshs" : "Τεχνικές Κωδικοποίησης";
} else if (course.contains("Διανεμημένη Παραγωγή")) { } else if (course.contains("Τεχνικές Βελτιστοποίησης")) {
return greeklish ? "dian_paragwgh" : "Διανεμημένη Παραγωγή"; return greeklish ? "veltistopoihsh" : "Βελτιστοποίηση";
} else if (course.contains("Διαχείριση Συστημάτων Ηλεκτρικής Ενέργειας")) { } else if (course.contains("Σύνθεση Τηλεπικοινωνιακών Διατάξεων")) {
return greeklish ? "dshe" : "ΔΣΗΕ"; return greeklish ? "synth_thlep_diataksewn" : "Σύνθεση Τηλεπ. Διατάξεων";
} else if (course.contains("Υψηλές Τάσεις ΙΙΙ")) { } else if (course.contains("Σύνθεση Ενεργών και Παθητικών Κυκλωμάτων")) {
return greeklish ? "ypshles_III" : "Υψηλές 3"; return greeklish ? "synthesh" : "Σύνθεση";
} else if (course.contains("Ανάλυση Συστημάτων Ηλεκτρικής Ενέργειας")) { } else if (course.contains("Σχεδίαση Συστημάτων VLSI")) {
return greeklish ? "ASHE" : "ΑΣΗΕ"; return greeklish ? "VLSI" : "VLSI";
} else if (course.contains("Ηλεκτρικές Μηχανές Β'")) { } else if (course.contains("Συστήματα Υπολογιστών (Υπολογιστικά Συστήματα)")) {
return greeklish ? "mhxanes_B" : "Μηχανές Β"; return greeklish ? "sys_ypologistwn" : "Συσ. Υπολογιστών";
} else if (course.contains("Ηλεκτρονικά Ισχύος Ι")) { } else if (course.contains("Συστήματα Πολυμέσων και Εικονική Πραγματικότητα")) {
return greeklish ? "isxyos_I" : "Ισχύος 1"; return greeklish ? "polymesa" : "Πολυμέσα";
} else if (course.contains("Συστήματα Μικροϋπολογιστών")) {
return greeklish ? "mikro_I" : "Μίκρο 1";
} else if (course.contains("Συστήματα Ηλεκτροκίνησης")) {
return greeklish ? "hlektrokinhsh" : "Ηλεκτροκίνηση";
} else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας ΙΙΙ")) { } else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας ΙΙΙ")) {
return greeklish ? "SHE_III" : "ΣΗΕ 3"; return greeklish ? "SHE_III" : "ΣΗΕ 3";
} else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας ΙΙ")) {
return greeklish ? "SHE_II" : "ΣΗΕ 2";
} else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας Ι")) {
return greeklish ? "SHE_I" : "ΣΗΕ 1";
} else if (course.contains("Συστήματα Αυτομάτου Ελέγχου ΙΙI")) {
return greeklish ? "SAE_III" : "ΣΑΕ 3";
} else if (course.contains("Συστήματα Αυτομάτου Ελέγχου ΙΙ")) {
return greeklish ? "SAE_II" : "ΣΑΕ 2";
} else if (course.contains("Συστήματα Αυτομάτου Ελέγχου Ι")) {
return greeklish ? "SAE_1" : "ΣΑΕ 1";
} else if (course.contains("Στοχαστικό Σήμα")) {
return greeklish ? "stox_shma" : "Στοχ. Σήμα";
} else if (course.contains("Σταθμοί Παραγωγής Ηλεκτρικής Ενέργειας")) {
return greeklish ? "SPHE" : "ΣΠΗΕ";
} else if (course.contains("Σερβοκινητήρια Συστήματα")) { } else if (course.contains("Σερβοκινητήρια Συστήματα")) {
return greeklish ? "servo" : "Σέρβο"; return greeklish ? "servo" : "Σέρβο";
} else if (course.contains("Συστήματα Ηλεκτροκίνησης")) { } else if (course.contains("Σήματα και Συστήματα")) {
return greeklish ? "hlektrokinhsh" : "Ηλεκτροκίνηση"; return greeklish ? "analog_shma" : "Σύματα & Συστήματα";
} else if (course.contains("Υπολογιστικές Μέθοδοι στα Ενεργειακά Συστήματα")) {
return greeklish ? "ymes" : "ΥΜΕΣ";
} else if (course.contains("Υψηλές Τάσεις 4")) {
return greeklish ? "ypshles_IV" : "Υψηλές 4";
} else if (course.contains("Ηλεκτρικές Μηχανές Γ'")) {
return greeklish ? "mhxanes_C" : "Μηχανές Γ";
} else if (course.contains("Ηλεκτρική Οικονομία")) {
return greeklish ? "hlektr_oikonomia" : "Ηλεκτρική Οικονομία";
} else if (course.contains("Ηλεκτρονικά Ισχύος ΙΙ")) {
return greeklish ? "isxyos_II" : "Ισχύος 2";
} else if (course.contains("Ανάλυση και Σχεδίαση Αλγορίθμων")) {
return greeklish ? "algorithms" : "Αλγόριθμοι";
} else if (course.contains("Διακριτά Μαθηματικά")) {
return greeklish ? "diakrita" : "Διακριτά Μαθηματικά";
} else if (course.contains("Κβαντική Φυσική")) {
return greeklish ? "kvantikh" : "Κβαντική";
} else if (course.contains("Ρομποτική")) { } else if (course.contains("Ρομποτική")) {
return greeklish ? "rompotikh" : "Ρομποτική"; return greeklish ? "rompotikh" : "Ρομποτική";
} else if (course.contains("Τεχνικές Βελτιστοποίησης")) {
return greeklish ? "veltistopoihsh" : "Βελτιστοποίηση";
} else if (course.contains("Ηλεκτρικές Μετρήσεις ΙΙ")) {
return greeklish ? "metrhseis_II" : "Μετρήσεις 2";
} else if (course.contains("Ηλεκτρονική ΙΙΙ")) {
return greeklish ? "hlektronikh_III" : "Ηλεκτρονική 3";
} else if (course.contains("Συστήματα Αυτομάτου Ελέγχου ΙΙ")) {
return greeklish ? "SAE_II" : "ΣΑΕ 2";
} else if (course.contains("Ψηφιακά Συστήματα ΙΙ")) {
return greeklish ? "pshfiaka_II" : "Ψηφιακά 2";
} else if (course.contains("Ανάλυση Χρονοσειρών")) {
return greeklish ? "xronoseires" : "Χρονοσειρές";
} else if (course.contains("Θεωρία Υπολογισμών και Αλγορίθμων")) {
return greeklish ? "thya" : "ΘΥΑ";
} else if (course.contains("Παράλληλα και Κατανεμημένα Συστήματα")) {
return greeklish ? "parallhla" : "Παράλληλα";
} else if (course.contains("Προγραμματιζόμενα Κυκλώματα ASIC")) {
return greeklish ? "asic" : "ASIC";
} else if (course.contains("Προσομοίωση και Μοντελοποίηση Συστημάτων")) { } else if (course.contains("Προσομοίωση και Μοντελοποίηση Συστημάτων")) {
return greeklish ? "montelopoihsh" : "Μοντελοποίηση"; return greeklish ? "montelopoihsh" : "Μοντελοποίηση";
} else if (course.contains("Συστήματα Αυτομάτου Ελέγχου ΙΙI")) { } else if (course.contains("Προηγμένες Τεχνικές Επεξεργασίας Σήματος")) {
return greeklish ? "SAE_III" : "ΣΑΕ 3"; return greeklish ? "ptes" : "ΠΤΕΣ";
} else if (course.contains("Σύνθεση Ενεργών και Παθητικών Κυκλωμάτων")) { } else if (course.contains("Προγραμματιστικές Τεχνικές")) {
return greeklish ? "synthesh" : "Σύνθεση"; return greeklish ? "cpp" : "Προγραμματ. Τεχν.";
} else if (course.contains("Δίκτυα Υπολογιστών Ι")) { } else if (course.contains("Προγραμματιζόμενα Κυκλώματα ASIC")) {
return greeklish ? "diktya_I" : "Δίκτυα 1"; return greeklish ? "asic" : "ASIC";
} else if (course.contains("Λειτουργικά Συστήματα")) { } else if (course.contains("Παράλληλα και Κατανεμημένα Συστήματα")) {
return greeklish ? "OS" : "Λειτουργικά"; return greeklish ? "parallhla" : "Παράλληλα";
} else if (course.contains("Συστήματα Μικροϋπολογιστών")) { } else if (course.contains("Οργάνωση και Διοίκηση Εργοστασίων")) {
return greeklish ? "mikro_I" : "Μίκρο 1"; return greeklish ? "organ_dioik_ergostasiwn" : "Οργάνωση και Διοίκηση Εργοστασίων";
} else if (course.contains("Ασαφή Συστήματα")) { } else if (course.contains("Οργάνωση Υπολογιστών")) {
return greeklish ? "asafh" : "Ασαφή"; return greeklish ? "org_ypol" : "Οργάνωση Υπολ.";
} else if (course.contains("Γραφική με Υπολογιστές")) {
return greeklish ? "grafikh" : "Γραφική";
} else if (course.contains("Ενσωματωμένα Συστήματα Πραγματικού Χρόνου")) {
return greeklish ? "enswmatwmena" : "Ενσωματωμένα";
} else if (course.contains("Τηλεπικοινωνιακή Ηλεκτρονική")) {
return greeklish ? "tilep_ilektr" : "Τηλεπ. Ηλεκτρ.";
} else if (course.contains("Ψηφιακά Συστήματα ΙΙΙ")) {
return greeklish ? "pshfiaka_III" : "Ψηφιακά 3";
} else if (course.contains("Ψηφιακή Επεξεργασία Εικόνας")) {
return greeklish ? "psee" : "ΨΕΕ";
} else if (course.contains("Δίκτυα Υπολογιστών ΙΙ")) {
return greeklish ? "diktya_II" : "Δίκτυα 2";
} else if (course.contains("Μικροεπεξεργαστές και Περιφερειακά")) {
return greeklish ? "mikro_II" : "Μίκρο 2";
} else if (course.contains("Τεχνολογία Λογισμικού")) {
return greeklish ? "SE" : "Τεχνολογία Λογισμικού";
} else if (course.contains("Ψηφιακά Φίλτρα")) {
return greeklish ? "filtra" : "Φίλτρα";
} else if (course.contains("Αναγνώριση Προτύπων")) {
return greeklish ? "protipa" : "Αναγνώριση Προτύπων";
} else if (course.contains("Ασφάλεια Πληροφοριακών Συστημάτων")) {
return greeklish ? "asfaleia" : "Ασφάλεια";
} else if (course.contains("Βάσεις Δεδομένων")) {
return greeklish ? "vaseis" : "Βάσεις";
} else if (course.contains("Βιομηχανική Πληροφορική")) {
return greeklish ? "viomix_plir" : "Βιομηχανική Πληρ";
} else if (course.contains("Ευφυή Συστήματα Ρομπότ")) {
return greeklish ? "eufuh" : "Ευφυή";
} else if (course.contains("Συστήματα Πολυμέσων και Εικονική Πραγματικότητα")) {
return greeklish ? "polymesa" : "Πολυμέσα";
} else if (course.contains("Σχεδίαση Συστημάτων VLSI")) {
return greeklish ? "VLSI" : "VLSI";
} else if (course.contains("Ακουστική Ι")) {
return greeklish ? "akoystikh_I" : "Ακουστική 1";
} else if (course.contains("Εφαρμοσμένα Μαθηματικά ΙΙ")) {
return greeklish ? "efarmosmena_math_II" : "Εφαρμοσμένα 2";
} else if (course.contains("Ηλεκτρακουστική Ι")) {
return greeklish ? "hlektroakoystikh_I" : "Ηλεκτροακουστική 1";
} else if (course.contains("Οπτική Ι")) {
return greeklish ? "optikh_I" : "Οπτική 1";
} else if (course.contains("Διάδοση Η/Μ Κύματος ΙΙ")) {
return greeklish ? "diadosi_II" : "Διάδοση 2";
} else if (course.contains("Ψηφιακές Τηλεπικοινωνίες Ι")) {
return greeklish ? "pshf_thlep_I" : "Ψηφιακές Τηλεπ. 1";
} else if (course.contains("Ακουστική ΙΙ")) {
return greeklish ? "akoystikh_II" : "Ακουστική 2";
} else if (course.contains("Βιοϊατρική Τεχνολογία")) {
return greeklish ? "vioiatriki" : "Βιοιατρική";
} else if (course.contains("Ηλεκτρακουστική ΙΙ")) {
return greeklish ? "hlektroakoystikh_II" : "Ηλεκτροακουστική 2";
} else if (course.contains("Οπτική ΙΙ")) { } else if (course.contains("Οπτική ΙΙ")) {
return greeklish ? "optikh_II" : "Οπτική 2"; return greeklish ? "optikh_II" : "Οπτική 2";
} else if (course.contains("Ασύρματος Τηλεπικοινωνία Ι")) { } else if (course.contains("Οπτική Ι")) {
return greeklish ? "asyrmatos_I" : "Ασύρματος 1"; return greeklish ? "optikh_I" : "Οπτική 1";
} else if (course.contains("Οπτικές Επικοινωνίες")) {
return greeklish ? "optikes_thlep" : "Οπτικές Τηλεπ.";
} else if (course.contains("Μικροκύματα II")) {
return greeklish ? "mikrokymata_II" : "Μικροκύματα 2";
} else if (course.contains("Μικροκύματα I")) { } else if (course.contains("Μικροκύματα I")) {
return greeklish ? "mikrokymata_I" : "Μικροκύματα 1"; return greeklish ? "mikrokymata_I" : "Μικροκύματα 1";
} else if (course.contains("Ψηφιακές Τηλεπικοινωνίες ΙΙ")) { } else if (course.contains("Μικροκυματική Τηλεπισκόπηση")) {
return greeklish ? "pshf_thlep_II" : "Ψηφιακές Τηλεπ. 2"; return greeklish ? "thlepiskophsh" : "Τηλεπισκόπηση";
} else if (course.contains("Ψηφιακή Επεξεργασία Σήματος")) { } else if (course.contains("Μικροεπεξεργαστές και Περιφερειακά")) {
return greeklish ? "PSES" : "ΨΕΣ"; return greeklish ? "mikro_II" : "Μίκρο 2";
} else if (course.contains("Εισαγωγή στην Πολιτική Οικονομία")) { } else if (course.contains("Μετάδοση Θερμότητας")) {
return greeklish ? "polit_oik" : "Πολιτική Οικονομία"; return greeklish ? "metadosi_therm" : "Μετάδοση Θερμ.";
} else if (course.contains("Λογισμός ΙΙ")) {
return greeklish ? "logismos_II" : "Λογισμός 2";
} else if (course.contains("Λογισμός Ι")) {
return greeklish ? "logismos_I" : "Λογισμός 1";
} else if (course.contains("Λογική Σχεδίαση")) {
return greeklish ? "logiki_sxediash" : "Λογική Σχεδίαση";
} else if (course.contains("Λειτουργικά Συστήματα")) {
return greeklish ? "OS" : "Λειτουργικά";
} else if (course.contains("Κινητές και Δορυφορικές Επικοινωνίες")) {
return greeklish ? "kinhtes_doryforikes_epik" : "Κινητές & Δορυφορικές Επικοινωνίες";
} else if (course.contains("Κβαντική Φυσική")) {
return greeklish ? "kvantikh" : "Κβαντική";
} else if (course.contains("Θεωρία και Τεχνολογία Πυρηνικών Αντιδραστήρων")) {
return greeklish ? "texn_antidrasthrwn" : "Τεχνολογία Αντιδραστήρων";
} else if (course.contains("Θεωρία Υπολογισμών και Αλγορίθμων")) {
return greeklish ? "thya" : "ΘΥΑ";
} else if (course.contains("Θεωρία Σκέδασης")) { } else if (course.contains("Θεωρία Σκέδασης")) {
return greeklish ? "skedash" : "Σκέδαση"; return greeklish ? "skedash" : "Σκέδαση";
} else if (course.contains("Προηγμένες Τεχνικές Επεξεργασίας Σήματος")) { } else if (course.contains("Θεωρία Σημάτων και Γραμμικών Συστημάτων")) {
return greeklish ? "ptes" : "ΠΤΕΣ"; return greeklish ? "analog_shma" : "Σύματα & Συστήματα";
} else if (course.contains("Τηλεοπτικά Συστήματα")) {
return greeklish ? "tileoptika" : "Τηλεοπτικά";
} else if (course.contains("Ασύρματος Τηλεπικοινωνία ΙΙ")) {
return greeklish ? "asyrmatos_II" : "Ασύρματος 2";
} else if (course.contains("Δίκτυα Τηλεπικοινωνιών")) {
return greeklish ? "diktya_thlep" : "Δίκτυα Τηλέπ.";
} else if (course.contains("Θεωρία Πληροφοριών")) { } else if (course.contains("Θεωρία Πληροφοριών")) {
return greeklish ? "theoria_plir" : "Θεωρία Πληρ."; return greeklish ? "theoria_plir" : "Θεωρία Πληρ.";
} else if (course.contains("Οπτικές Επικοινωνίες")) { } else if (course.contains("Θεωρία Πιθανοτήτων και Στατιστική")) {
return greeklish ? "optikes_thlep" : "Οπτικές Τηλεπ."; return greeklish ? "pithanothtes" : "Πιθανότητες";
} else if (course.contains("Ημιαγωγά Υλικά: Θεωρία-Διατάξεις")) {
return greeklish ? "Hmiagwga_Ylika" : "Ημιαγωγά Υλικά";
} else if (course.contains("Ηλεκτρονική ΙΙΙ")) {
return greeklish ? "hlektronikh_III" : "Ηλεκτρονική 3";
} else if (course.contains("Ηλεκτρονική ΙΙ")) {
return greeklish ? "hlektronikh_2" : "Ηλεκτρονική 2";
} else if (course.contains("Ηλεκτρονική Ι")) {
return greeklish ? "hlektronikh_1" : "Ηλεκτρονική 1";
} else if (course.contains("Ηλεκτρονικές Διατάξεις και Μετρήσεις")) {
return greeklish ? "hlektron_diatakseis_metrhseis" : "Ηλεκτρονικές Διατάξεις και Μετρήσεις";
} else if (course.contains("Ηλεκτρονικά Ισχύος ΙΙ")) {
return greeklish ? "isxyos_II" : "Ισχύος 2";
} else if (course.contains("Ηλεκτρονικά Ισχύος Ι")) {
return greeklish ? "isxyos_I" : "Ισχύος 1";
} else if (course.contains("Ηλεκτρομαγνητικό Πεδίο ΙΙ")) {
return greeklish ? "pedio_II" : "Πεδίο 2";
} else if (course.contains("Ηλεκτρομαγνητικό Πεδίο Ι")) {
return greeklish ? "pedio_I" : "Πεδίο 1";
} else if (course.contains("Ηλεκτρομαγνητική Συμβατότητα")) {
return greeklish ? "HM_symvatothta" : "H/M Συμβατότητα";
} else if (course.contains("Ηλεκτρολογικά Υλικά")) {
return greeklish ? "ylika" : "Ηλεκτρ. Υλικά";
} else if (course.contains("Ηλεκτρική Οικονομία")) {
return greeklish ? "hlektr_oikonomia" : "Ηλεκτρική Οικονομία";
} else if (course.contains("Ηλεκτρικές Μηχανές Γ'")) {
return greeklish ? "mhxanes_C" : "Μηχανές Γ";
} else if (course.contains("Ηλεκτρικές Μηχανές Β'")) {
return greeklish ? "mhxanes_B" : "Μηχανές Β";
} else if (course.contains("Ηλεκτρικές Μηχανές Α'")) {
return greeklish ? "mhxanes_A" : "Μηχανές Α";
} else if (course.contains("Ηλεκτρικές Μετρήσεις ΙΙ")) {
return greeklish ? "metrhseis_II" : "Μετρήσεις 2";
} else if (course.contains("Ηλεκτρικές Μετρήσεις Ι")) {
return greeklish ? "metrhseis_1" : "Μετρήσεις 1";
} else if (course.contains("Ηλεκτρικά Κυκλώματα ΙΙΙ")) {
return greeklish ? "kyklwmata_I" : "Κυκλώματα 3";
} else if (course.contains("Ηλεκτρικά Κυκλώματα ΙΙ")) {
return greeklish ? "kyklwmata_II" : "Κυκλώματα 2";
} else if (course.contains("Ηλεκτρικά Κυκλώματα Ι")) {
return greeklish ? "kyklwmata_I" : "Κυκλώματα 1";
} else if (course.contains("Ηλεκτρακουστική ΙΙ")) {
return greeklish ? "hlektroakoystikh_II" : "Ηλεκτροακουστική 2";
} else if (course.contains("Ηλεκτρακουστική Ι")) {
return greeklish ? "hlektroakoystikh_I" : "Ηλεκτροακουστική 1";
} else if (course.contains("Εφαρμοσμένη Θερμοδυναμική")) {
return greeklish ? "thermodynamikh" : "Θερμοδυναμική";
} else if (course.contains("Εφαρμοσμένα Μαθηματικά ΙΙ")) {
return greeklish ? "efarmosmena_math_II" : "Εφαρμοσμένα 2";
} else if (course.contains("Εφαρμοσμένα Μαθηματικά Ι")) {
return greeklish ? "efarmosmena_math_I" : "Εφαρμοσμένα 1";
} else if (course.contains("Εφαρμογές Τηλεπικοινωνιακών Διατάξεων")) {
return greeklish ? "efarm_thlep_diataksewn" : "Εφαρμογές Τηλεπ. Διατάξεων";
} else if (course.contains("Ευφυή Συστήματα Ρομπότ")) {
return greeklish ? "eufuh" : "Ευφυή";
} else if (course.contains("Ευρυζωνικά Δίκτυα")) { } else if (course.contains("Ευρυζωνικά Δίκτυα")) {
return greeklish ? "eyryzwnika" : "Ευρυζωνικά"; return greeklish ? "eyryzwnika" : "Ευρυζωνικά";
} else if (course.contains("Τεχνικές μη Καταστρεπτικών Δοκιμών")) { } else if (course.contains("Επιχειρησιακή Έρευνα")) {
return greeklish ? "non_destructive_tests" : "Μη Καταστρεπτικές Δοκιμές"; return greeklish ? "epixeirisiaki" : "Επιχειρησιακή Έρευνα";
} else if (course.contains("Φωτονική Τεχνολογία")) { } else if (course.contains("Ενσωματωμένα Συστήματα Πραγματικού Χρόνου")) {
return greeklish ? "fwtonikh" : "Φωτονική"; return greeklish ? "enswmatwmena" : "Ενσωματωμένα";
} else if (course.contains("Μικροκυματική Τηλεπισκόπηση")) { } else if (course.contains("Εισαγωγή στις εφαρμογές Πυρηνικής Τεχνολογίας")) {
return greeklish ? "thlepiskophsh" : "Τηλεπισκόπηση"; return greeklish ? "Intro_Purhnikh_Texn" : "Εισ. Πυρηνικη Τεχν.";
} else if (course.contains("Μικροκύματα II")) { } else if (course.contains("Εισαγωγή στην Πολιτική Οικονομία")) {
return greeklish ? "mikrokymata_II" : "Μικροκύματα 2"; return greeklish ? "polit_oik" : "Πολιτική Οικονομία";
} else if (course.contains("Εισαγωγή στην Ενεργειακή Τεχνολογία ΙΙ")) {
return greeklish ? "EET_2" : "ΕΕΤ2";
} else if (course.contains("Εισαγωγή στην Ενεργειακή Τεχνολογία Ι")) {
return greeklish ? "EET_I" : "ΕΕΤ 1";
} else if (course.contains("Ειδικές Κεραίες, Σύνθεση Κεραιών")) {
return greeklish ? "eidikes_keraies" : "Ειδικές Κεραίες, Σύνθεση Κεραιών";
} else if (course.contains("Ειδικές Αρχιτεκτονικές Υπολογιστών")) {
return greeklish ? "eidikes_arx_ypolog" : "Ειδικές Αρχιτεκτονικές Υπολογιστών";
} else if (course.contains("Ειδικά Κεφάλαια Συστημάτων Ηλεκτρικής Ενέργειας")) {
return greeklish ? "ekshe" : "ΕΚΣΗΕ";
} else if (course.contains("Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου Ι")) {
return greeklish ? "eidika_kef_HM_pedioy_I" : "Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου Ι";
} else if (course.contains("Ειδικά Κεφάλαια Διαφορικών Εξισώσεων")) {
return greeklish ? "eidika_kef_diaf_eksis" : "Ειδικά Κεφάλαια Διαφορικών Εξισώσεων";
} else if (course.contains("Δομημένος Προγραμματισμός")) {
return greeklish ? "C" : "Δομ. Προγραμμ.";
} else if (course.contains("Δομές Δεδομένων")) {
return greeklish ? "dom_dedomenwn" : "Δομ. Δεδομ.";
} else if (course.contains("Διαχείριση Συστημάτων Ηλεκτρικής Ενέργειας")) {
return greeklish ? "dshe" : "ΔΣΗΕ";
} else if (course.contains("Διαφορικές Εξισώσεις")) {
return greeklish ? "diaforikes" : "Διαφορικές";
} else if (course.contains("Διανεμημένη Παραγωγή")) {
return greeklish ? "dian_paragwgh" : "Διανεμημένη Παραγωγή";
} else if (course.contains("Διακριτά μαθηματικά")) {
return greeklish ? "diakrita" : "Διακριτά Μαθηματικά";
} else if (course.contains("Διακριτά Μαθηματικά")) {
return greeklish ? "diakrita" : "Διακριτά Μαθηματικά";
} else if (course.contains("Διάδοση Ηλεκτρομαγνητικού Κύματος Ι (πρώην Πεδίο ΙΙΙ)")) {
return greeklish ? "diadosi_1" : "Διάδοση 1";
} else if (course.contains("Διάδοση Η/Μ Κύματος ΙΙ")) {
return greeklish ? "diadosi_II" : "Διάδοση 2";
} else if (course.contains("Δίκτυα Υπολογιστών ΙΙ")) {
return greeklish ? "diktya_II" : "Δίκτυα 2";
} else if (course.contains("Δίκτυα Υπολογιστών Ι")) {
return greeklish ? "diktya_I" : "Δίκτυα 1";
} else if (course.contains("Δίκτυα Τηλεπικοινωνιών")) {
return greeklish ? "diktya_thlep" : "Δίκτυα Τηλέπ.";
} else if (course.contains("Γραφική με Υπολογιστές")) {
return greeklish ? "grafikh" : "Γραφική";
} else if (course.contains("Γραμμική Άλγεβρα")) {
return greeklish ? "grammikh_algebra" : "Γραμμ. Άλγεβρ.";
} else if (course.contains("Γεωηλεκτρομαγνητισμός")) {
return greeklish ? "geohlektromagnitismos" : "Γεωηλεκτρομαγνητισμός";
} else if (course.contains("Βιοϊατρική Τεχνολογία")) {
return greeklish ? "vioiatriki" : "Βιοιατρική";
} else if (course.contains("Βιομηχανική Πληροφορική")) {
return greeklish ? "viomix_plir" : "Βιομηχανική Πληρ";
} else if (course.contains("Βιομηχανικά Ηλεκτρονικά")) {
return greeklish ? "bhomix_hlektronika" : "Βιομηχανικά Ηλεκτρονικά";
} else if (course.contains("Βάσεις Δεδομένων")) {
return greeklish ? "vaseis" : "Βάσεις";
} else if (course.contains("Ασύρματος Τηλεπικοινωνία ΙΙ")) {
return greeklish ? "asyrmatos_II" : "Ασύρματος 2";
} else if (course.contains("Ασύρματος Τηλεπικοινωνία Ι")) {
return greeklish ? "asyrmatos_I" : "Ασύρματος 1";
} else if (course.contains("Ασφάλεια Πληροφοριακών Συστημάτων")) {
return greeklish ? "asfaleia" : "Ασφάλεια";
} else if (course.contains("Ασαφή Συστήματα")) {
return greeklish ? "asafh" : "Ασαφή";
} else if (course.contains("Αρχιτεκτονική Υπολογιστών")) {
return greeklish ? "arx_ypologistwn" : "Αρχ. Υπολογιστών";
} else if (course.contains("Αρχές Παράλληλης Επεξεργασίας")) {
return greeklish ? "arxes_parall_epeksergasias" : "Αρχές Παράλληλης Επεξεργασίας";
} else if (course.contains("Αρχές Οικονομίας")) {
return greeklish ? "arx_oikonomias" : "Αρχές Οικονομίας";
} else if (course.contains("Αριθμητική Ανάλυση")) {
return greeklish ? "arith_anal" : "Αριθμ. Ανάλυση";
} else if (course.contains("Αξιοπιστία Συστημάτων")) {
return greeklish ? "aksiopistia_systhmatwn" : "Αξιοπιστία Συστημάτων";
} else if (course.contains("Αντικειμενοστραφής Προγραμματισμός")) {
return greeklish ? "OOP" : "Αντικειμενοστραφής";
} else if (course.contains("Αναλογικές Τηλεπικοινωνίες (πρώην Τηλεπικοινωνιακά Συστήματα Ι)")) {
return greeklish ? "anal_thlep" : "Αναλογικές Τηλεπ.";
} else if (course.contains("Αναγνώριση Προτύπων")) {
return greeklish ? "protipa" : "Αναγνώριση Προτύπων";
} else if (course.contains("Ανάλυση και Σχεδίαση Αλγορίθμων")) {
return greeklish ? "algorithms" : "Αλγόριθμοι";
} else if (course.contains("Ανάλυση Χρονοσειρών")) {
return greeklish ? "xronoseires" : "Χρονοσειρές";
} else if (course.contains("Ανάλυση Συστημάτων Ηλεκτρικής Ενέργειας")) {
return greeklish ? "ASHE" : "ΑΣΗΕ";
} else if (course.contains("Ανάλυση Ηλεκτρικών Κυκλωμάτων με Υπολογιστή")) {
return greeklish ? "analysh_hlektr_kykl" : "Ανάλυση Ηλεκτρικ. Κυκλ. με Υπολογιστή";
} else if (course.contains("Ακουστική ΙΙ")) {
return greeklish ? "akoystikh_II" : "Ακουστική 2";
} else if (course.contains("Ακουστική Ι")) {
return greeklish ? "akoystikh_I" : "Ακουστική 1";
} else { } else {
return null; return null;
} }

34
app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java

@ -8,6 +8,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.media.ExifInterface; import android.media.ExifInterface;
import android.net.Uri; import android.net.Uri;
import android.os.Environment;
import android.provider.OpenableColumns; import android.provider.OpenableColumns;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@ -25,7 +26,7 @@ import timber.log.Timber;
class UploadsHelper { class UploadsHelper {
private static final int DEFAULT_MIN_WIDTH_QUALITY = 400; private static final int DEFAULT_MIN_WIDTH_QUALITY = 400;
private static final String TEMP_IMAGE_NAME = "tempUploadFile.jpg"; private static final String CACHE_IMAGE_NAME = "tempUploadFile.jpg";
@NonNull @NonNull
static String filenameFromUri(Context context, Uri uri) { static String filenameFromUri(Context context, Uri uri) {
@ -53,7 +54,7 @@ class UploadsHelper {
static String createTempFile(Context context, Uri fileUri, String newFilename) { static String createTempFile(Context context, Uri fileUri, String newFilename) {
String oldFilename = filenameFromUri(context, fileUri); String oldFilename = filenameFromUri(context, fileUri);
String fileExtension = oldFilename.substring(oldFilename.indexOf(".")); String fileExtension = oldFilename.substring(oldFilename.indexOf("."));
String destinationFilename = android.os.Environment.getExternalStorageDirectory().getPath() + String destinationFilename = Environment.getExternalStorageDirectory().getPath() +
File.separatorChar + "~tmp_mThmmy_uploads" + File.separatorChar + newFilename + fileExtension; File.separatorChar + "~tmp_mThmmy_uploads" + File.separatorChar + newFilename + fileExtension;
File tempDirectory = new File(android.os.Environment.getExternalStorageDirectory().getPath() + File tempDirectory = new File(android.os.Environment.getExternalStorageDirectory().getPath() +
@ -99,16 +100,35 @@ class UploadsHelper {
return destinationFilename; return destinationFilename;
} }
static File getTempFile(Context context) { static File getCacheFile(Context context) {
File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME); File imageFile = new File(context.getExternalCacheDir(), CACHE_IMAGE_NAME);
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
imageFile.getParentFile().mkdirs(); imageFile.getParentFile().mkdirs();
return imageFile; return imageFile;
} }
static boolean deleteTempFile(String destinationFilename) { @SuppressWarnings("ResultOfMethodCallIgnored")
File file = new File(destinationFilename); static void deleteTempFiles() {
return file.delete(); File tempFilesDirectory = new File(Environment.getExternalStorageDirectory().getPath() +
File.separatorChar + "~tmp_mThmmy_uploads");
if (tempFilesDirectory.isDirectory()) {
String[] tempFilesArray = tempFilesDirectory.list();
for (String tempFile : tempFilesArray) {
new File(tempFilesDirectory, tempFile).delete();
}
tempFilesDirectory.delete();
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
static void deleteCacheFiles(Context context) {
File cacheFilesDirectory = context.getExternalCacheDir();
assert cacheFilesDirectory != null;
String[] tempFilesArray = cacheFilesDirectory.list();
for (String tempFile : tempFilesArray) {
new File(cacheFilesDirectory, tempFile).delete();
}
} }
/** /**

3
app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java

@ -7,7 +7,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
@ -45,12 +44,12 @@ import java.util.ArrayList;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.AboutActivity; import gr.thmmy.mthmmy.activities.AboutActivity;
import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.upload.UploadActivity;
import gr.thmmy.mthmmy.activities.bookmarks.BookmarkActivity; import gr.thmmy.mthmmy.activities.bookmarks.BookmarkActivity;
import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity; import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity;
import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.main.MainActivity;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
import gr.thmmy.mthmmy.activities.settings.SettingsActivity; import gr.thmmy.mthmmy.activities.settings.SettingsActivity;
import gr.thmmy.mthmmy.activities.upload.UploadActivity;
import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.model.Bookmark;
import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.model.ThmmyFile;
import gr.thmmy.mthmmy.services.DownloadHelper; import gr.thmmy.mthmmy.services.DownloadHelper;

47
app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java

@ -5,6 +5,7 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.widget.ImageView; import android.widget.ImageView;
@ -12,6 +13,7 @@ import android.widget.ImageView;
import com.franmontiel.persistentcookiejar.PersistentCookieJar; import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache; import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor; import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.jakewharton.picasso.OkHttp3Downloader; import com.jakewharton.picasso.OkHttp3Downloader;
import com.mikepenz.fontawesome_typeface_library.FontAwesome; import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsDrawable;
@ -22,7 +24,6 @@ import com.squareup.picasso.Picasso;
import net.gotev.uploadservice.UploadService; import net.gotev.uploadservice.UploadService;
import net.gotev.uploadservice.okhttp.OkHttpStack; import net.gotev.uploadservice.okhttp.OkHttpStack;
import java.io.IOException;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -31,16 +32,17 @@ import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.CrashReportingTree; import gr.thmmy.mthmmy.utils.CrashReportingTree;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response;
import timber.log.Timber; import timber.log.Timber;
public class BaseApplication extends Application { public class BaseApplication extends Application {
private static BaseApplication baseApplication; //BaseApplication singleton private static BaseApplication baseApplication; //BaseApplication singleton
// Client & SessionManager //FirebaseAnalytics
private FirebaseAnalytics firebaseAnalytics;
//Client & SessionManager
private OkHttpClient client; private OkHttpClient client;
private SessionManager sessionManager; private SessionManager sessionManager;
@ -59,32 +61,31 @@ public class BaseApplication extends Application {
super.onCreate(); super.onCreate();
baseApplication = this; //init singleton baseApplication = this; //init singleton
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG)
Timber.plant(new Timber.DebugTree()); Timber.plant(new Timber.DebugTree());
} else { else
Timber.plant(new CrashReportingTree()); Timber.plant(new CrashReportingTree());
}
// Analytics init
firebaseAnalytics = FirebaseAnalytics.getInstance(this);
SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE); SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
SharedPrefsCookiePersistor sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(getApplicationContext()); SharedPrefsCookiePersistor sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(getApplicationContext());
PersistentCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor); PersistentCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor);
client = new OkHttpClient.Builder() client = new OkHttpClient.Builder()
.cookieJar(cookieJar) .cookieJar(cookieJar)
.addInterceptor(new Interceptor() { .addInterceptor(chain -> {
@Override Request request = chain.request();
public Response intercept(Chain chain) throws IOException { HttpUrl oldUrl = chain.request().url();
Request request = chain.request(); if (Objects.equals(chain.request().url().host(), "www.thmmy.gr")) {
HttpUrl oldUrl = chain.request().url(); if (!oldUrl.toString().contains("theme=4")) {
if (Objects.equals(chain.request().url().host(), "www.thmmy.gr")) { //Probably works but needs more testing:
if (!oldUrl.toString().contains("theme=4")) { HttpUrl newUrl = oldUrl.newBuilder().addQueryParameter("theme", "4").build();
//Probably works but needs more testing: request = request.newBuilder().url(newUrl).build();
HttpUrl newUrl = oldUrl.newBuilder().addQueryParameter("theme", "4").build();
request = request.newBuilder().url(newUrl).build();
}
} }
return chain.proceed(request);
} }
return chain.proceed(request);
}) })
.connectTimeout(30, TimeUnit.SECONDS) .connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS)
@ -130,6 +131,12 @@ public class BaseApplication extends Application {
dpWidth = displayMetrics.widthPixels / displayMetrics.density; dpWidth = displayMetrics.widthPixels / displayMetrics.density;
} }
public void logFirebaseAnalyticsEvent(String event, Bundle params) {
firebaseAnalytics.logEvent(event, params);
}
//Getters
public OkHttpClient getClient() { public OkHttpClient getClient() {
return client; return client;
} }

1
app/src/main/java/gr/thmmy/mthmmy/services/DownloadHelper.java

@ -41,6 +41,7 @@ public class DownloadHelper {
request.setDestinationInExternalPublicDir(SAVE_DIR.getName(), fileName); request.setDestinationInExternalPublicDir(SAVE_DIR.getName(), fileName);
request.allowScanningByMediaScanner(); request.allowScanningByMediaScanner();
BaseApplication.getInstance().logFirebaseAnalyticsEvent("file_download", null);
downloadManager.enqueue(request); downloadManager.enqueue(request);
} catch (Exception e) { } catch (Exception e) {
Toast.makeText(applicationContext, "Download failed...", Toast.LENGTH_SHORT).show(); Toast.makeText(applicationContext, "Download failed...", Toast.LENGTH_SHORT).show();

42
app/src/main/java/gr/thmmy/mthmmy/utils/CrashReporter.java

@ -0,0 +1,42 @@
package gr.thmmy.mthmmy.utils;
import com.crashlytics.android.Crashlytics;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
public class CrashReporter {
private static final int STRING_BATCH_LENGTH = 250;
private CrashReporter() {}
public static void reportDocument(Document document, String key) {
String documentString = document.toString();
ParseHelpers.Language language = ParseHelpers.Language.getLanguage(document);
Elements postRows;
if (language.is(ParseHelpers.Language.GREEK))
postRows = document.select("form[id=quickModForm]>table>tbody>tr:matches(στις)");
else
postRows = document.select("form[id=quickModForm]>table>tbody>tr:matches(on)");
for (Element thisRow : postRows) {
String subject = thisRow.select("div[id^=subject_]").first().select("a").first().text();
documentString = documentString.replace(subject, "subject");
String post = thisRow.select("div").select(".post").first().text();
documentString = documentString.replace(post, "post");
}
int batchCount = documentString.length() / STRING_BATCH_LENGTH;
for (int i = 0; i < batchCount; i++) {
String batch;
if (i != batchCount - 1)
batch = documentString.substring(i * STRING_BATCH_LENGTH, (i + 1) * STRING_BATCH_LENGTH);
else
batch = documentString.substring(i * STRING_BATCH_LENGTH);
Crashlytics.setString(key + "_" + i + 1, batch);
}
}
}

11
app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java

@ -22,6 +22,7 @@ import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import timber.log.Timber;
public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTaskCompleted, public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTaskCompleted,
PrepareForReply.OnPrepareForReplyFinished, PrepareForEditTask.OnPrepareEditFinished { PrepareForReply.OnPrepareForReplyFinished, PrepareForEditTask.OnPrepareEditFinished {
@ -85,6 +86,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
public void reloadPage() { public void reloadPage() {
if (topicUrl == null) throw new NullPointerException("No topic task has been requested yet!"); if (topicUrl == null) throw new NullPointerException("No topic task has been requested yet!");
Timber.i("Reloading page");
loadUrl(topicUrl); loadUrl(topicUrl);
} }
@ -93,6 +95,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
throw new NullPointerException("No page has been loaded yet!"); throw new NullPointerException("No page has been loaded yet!");
int pageRequested = pageIndicatorIndex.getValue() - 1; int pageRequested = pageIndicatorIndex.getValue() - 1;
if (pageRequested != currentPageIndex - 1) { if (pageRequested != currentPageIndex - 1) {
Timber.i("Changing to page " + pageRequested + 1);
loadUrl(ParseHelpers.getBaseURL(topicUrl) + "." + String.valueOf(pageRequested * 15)); loadUrl(ParseHelpers.getBaseURL(topicUrl) + "." + String.valueOf(pageRequested * 15));
pageIndicatorIndex.setValue(pageRequested + 1); pageIndicatorIndex.setValue(pageRequested + 1);
} else { } else {
@ -105,6 +108,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
throw new NullPointerException("Topic task has not finished yet!"); throw new NullPointerException("Topic task has not finished yet!");
stopLoading(); stopLoading();
setPageIndicatorIndex(pageCount, true); setPageIndicatorIndex(pageCount, true);
Timber.i("Preparing for reply");
currentPrepareForReplyTask = new PrepareForReply(prepareForReplyCallbacks, this, currentPrepareForReplyTask = new PrepareForReply(prepareForReplyCallbacks, this,
replyPageUrl.getValue()); replyPageUrl.getValue());
currentPrepareForReplyTask.execute(toQuoteList.toArray(new Integer[0])); currentPrepareForReplyTask.execute(toQuoteList.toArray(new Integer[0]));
@ -122,11 +126,13 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
includeAppSignature = prefs.getBoolean(SettingsActivity.POSTING_APP_SIGNATURE_ENABLE_KEY, true); includeAppSignature = prefs.getBoolean(SettingsActivity.POSTING_APP_SIGNATURE_ENABLE_KEY, true);
} }
toQuoteList.clear(); toQuoteList.clear();
Timber.i("Posting reply");
new ReplyTask(replyFinishListener, includeAppSignature).execute(subject, reply, new ReplyTask(replyFinishListener, includeAppSignature).execute(subject, reply,
replyForm.getNumReplies(), replyForm.getSeqnum(), replyForm.getSc(), replyForm.getTopic()); replyForm.getNumReplies(), replyForm.getSeqnum(), replyForm.getSc(), replyForm.getTopic());
} }
public void deletePost(String postDeleteUrl) { public void deletePost(String postDeleteUrl) {
Timber.i("Deleting post");
new DeleteTask(deleteTaskCallbacks).execute(postDeleteUrl); new DeleteTask(deleteTaskCallbacks).execute(postDeleteUrl);
} }
@ -134,6 +140,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
if (replyPageUrl.getValue() == null) if (replyPageUrl.getValue() == null)
throw new NullPointerException("Topic task has not finished yet!"); throw new NullPointerException("Topic task has not finished yet!");
stopLoading(); stopLoading();
Timber.i("Preparing for edit");
currentPrepareForEditTask = new PrepareForEditTask(prepareForEditCallbacks, this, position, currentPrepareForEditTask = new PrepareForEditTask(prepareForEditCallbacks, this, position,
replyPageUrl.getValue()); replyPageUrl.getValue());
currentPrepareForEditTask.execute(postEditURL); currentPrepareForEditTask.execute(postEditURL);
@ -143,6 +150,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
if (prepareForEditResult.getValue() == null) if (prepareForEditResult.getValue() == null)
throw new NullPointerException("Edit preparation was not found!"); throw new NullPointerException("Edit preparation was not found!");
PrepareForEditResult editResult = prepareForEditResult.getValue(); PrepareForEditResult editResult = prepareForEditResult.getValue();
Timber.i("Editing post");
new EditTask(editTaskCallbacks, position).execute(editResult.getCommitEditUrl(), message, new EditTask(editTaskCallbacks, position).execute(editResult.getCommitEditUrl(), message,
editResult.getNumReplies(), editResult.getSeqnum(), editResult.getSc(), subject, editResult.getTopic()); editResult.getNumReplies(), editResult.getSeqnum(), editResult.getSc(), subject, editResult.getTopic());
} }
@ -154,15 +162,18 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
*/ */
public void stopLoading() { public void stopLoading() {
if (currentTopicTask != null && currentTopicTask.getStatus() == AsyncTask.Status.RUNNING) { if (currentTopicTask != null && currentTopicTask.getStatus() == AsyncTask.Status.RUNNING) {
Timber.i("Canceling topic task");
currentTopicTask.cancel(true); currentTopicTask.cancel(true);
pageIndicatorIndex.setValue(currentPageIndex); pageIndicatorIndex.setValue(currentPageIndex);
topicTaskObserver.onTopicTaskCancelled(); topicTaskObserver.onTopicTaskCancelled();
} }
if (currentPrepareForEditTask != null && currentPrepareForEditTask.getStatus() == AsyncTask.Status.RUNNING) { if (currentPrepareForEditTask != null && currentPrepareForEditTask.getStatus() == AsyncTask.Status.RUNNING) {
Timber.i("Canceling prepare for edit task");
currentPrepareForEditTask.cancel(true); currentPrepareForEditTask.cancel(true);
prepareForEditCallbacks.onPrepareEditCancelled(); prepareForEditCallbacks.onPrepareEditCancelled();
} }
if (currentPrepareForReplyTask != null && currentPrepareForReplyTask.getStatus() == AsyncTask.Status.RUNNING) { if (currentPrepareForReplyTask != null && currentPrepareForReplyTask.getStatus() == AsyncTask.Status.RUNNING) {
Timber.i("Canceling prepare for reply task");
currentPrepareForReplyTask.cancel(true); currentPrepareForReplyTask.cancel(true);
prepareForReplyCallbacks.onPrepareForReplyCancelled(); prepareForReplyCallbacks.onPrepareForReplyCancelled();
} }

4
app/src/main/res/drawable/ic_attach_file_white_24dp.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp">
<path android:fillColor="#FFFFFF" android:pathData="M16.5,6v11.5c0,2.21 -1.79,4 -4,4s-4,-1.79 -4,-4V5c0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5v10.5c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V6H10v9.5c0,1.38 1.12,2.5 2.5,2.5s2.5,-1.12 2.5,-2.5V5c0,-2.21 -1.79,-4 -4,-4S7,2.79 7,5v12.5c0,3.04 2.46,5.5 5.5,5.5s5.5,-2.46 5.5,-5.5V6h-1.5z"/>
</vector>

5
app/src/main/res/drawable/ic_photo_camera_white_24dp.xml

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp">
<path android:fillColor="#FFFFFF" android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
<path android:fillColor="#FFFFFF" android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
</vector>

113
app/src/main/res/layout/activity_upload.xml

@ -23,7 +23,7 @@
app:popupTheme="@style/ToolbarTheme" /> app:popupTheme="@style/ToolbarTheme" />
</android.support.design.widget.AppBarLayout> </android.support.design.widget.AppBarLayout>
<ScrollView <android.support.v4.widget.NestedScrollView
android:id="@+id/upload_outer_scrollview" android:id="@+id/upload_outer_scrollview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -41,16 +41,6 @@
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:orientation="vertical"> android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:gravity="center"
android:text="@string/upload_category_pre_text"
android:textAlignment="center"
android:textColor="@color/accent" />
<LinearLayout <LinearLayout
android:id="@+id/upload_spinners" android:id="@+id/upload_spinners"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -68,25 +58,6 @@
android:prompt="@string/upload_spinners_hint" /> android:prompt="@string/upload_spinners_hint" />
</LinearLayout> </LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:gravity="center"
android:text="@string/upload_title_description_pre_text"
android:textAlignment="center"
android:textColor="@color/accent" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/upload_title_description_builder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:gravity="center"
android:text="@string/upload_title_description_builder"
android:textAlignment="center"
android:textColor="@color/accent" />
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -113,32 +84,69 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/upload_description_hint" android:hint="@string/upload_description_hint"
android:inputType="textMultiLine" android:inputType="textMultiLine" />
android:maxLines="3" />
</android.support.design.widget.TextInputLayout> </android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatButton <android.support.v7.widget.AppCompatButton
android:id="@+id/upload_select_file_button" android:id="@+id/upload_title_description_builder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:text="@string/upload_select_file"
android:textColor="@color/primary_text" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/upload_upload_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_marginBottom="6dp"
android:gravity="center_vertical" android:gravity="center"
android:text="@string/upload_upload_button" android:text="@string/upload_title_description_builder"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/accent" /> android:textColor="@color/accent" />
<android.support.v7.widget.AppCompatTextView
android:id="@+id/upload_filename"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:drawablePadding="5dp"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/primary_text"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/upload_select_file_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="16dp"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:text="@string/upload_select_file"
android:textColor="@color/primary_text" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/upload_take_photo_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="16dp"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:text="@string/upload_take_photo"
android:textColor="@color/primary_text" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </android.support.v4.widget.NestedScrollView>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar <me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"
@ -151,6 +159,15 @@
app:layout_anchorGravity="bottom|center" app:layout_anchorGravity="bottom|center"
app:mpb_indeterminateTint="@color/accent" app:mpb_indeterminateTint="@color/accent"
app:mpb_progressStyle="horizontal" /> app:mpb_progressStyle="horizontal" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/upload_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="@dimen/fab_margins"
android:layout_marginEnd="@dimen/fab_margins"
app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareFABBehavior"
app:srcCompat="@drawable/ic_file_upload_white_24dp" />
</android.support.design.widget.CoordinatorLayout>

1
app/src/main/res/layout/activity_upload_fields_builder.xml

@ -37,6 +37,7 @@
android:id="@+id/upload_fields_builder_content_linear" android:id="@+id/upload_fields_builder_content_linear"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView

14
app/src/main/res/layout/spinner_dropdown_item.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:paddingBottom="6dp"
android:paddingEnd="7dp"
android:paddingStart="7dp"
android:paddingTop="6dp"
android:singleLine="true"
android:textColor="@color/primary_text"
android:textSize="@dimen/medium_text" />

14
app/src/main/res/layout/spinner_item.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:paddingBottom="6dp"
android:paddingEnd="7dp"
android:paddingStart="7dp"
android:paddingTop="6dp"
android:singleLine="true"
android:textColor="@color/primary_text"
android:textSize="@dimen/medium_text" />

4
app/src/main/res/values-v21/styles.xml

@ -24,6 +24,10 @@
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item> <item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppTheme.PreferenceTheme" parent="AppTheme.NoActionBar">
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="colorControlActivated">@color/accent</item>
</style> </style>
</resources> </resources>

1
app/src/main/res/values-w820dp/dimens.xml

@ -9,5 +9,6 @@
<dimen name="post_image_button">144dp</dimen> <dimen name="post_image_button">144dp</dimen>
<dimen name="fab_margins">64dp</dimen> <dimen name="fab_margins">64dp</dimen>
<dimen name="progress_bar_height">40dp</dimen> <dimen name="progress_bar_height">40dp</dimen>
<dimen name="medium_text">16sp</dimen>
<dimen name="big_text">24sp</dimen> <dimen name="big_text">24sp</dimen>
</resources> </resources>

1
app/src/main/res/values/dimens.xml

@ -7,6 +7,7 @@
<dimen name="post_image_button">36dp</dimen> <dimen name="post_image_button">36dp</dimen>
<dimen name="fab_margins">16dp</dimen> <dimen name="fab_margins">16dp</dimen>
<dimen name="progress_bar_height">10dp</dimen> <dimen name="progress_bar_height">10dp</dimen>
<dimen name="medium_text">16sp</dimen>
<dimen name="big_text">24sp</dimen> <dimen name="big_text">24sp</dimen>
<dimen name="editor_format_button_size">24dp</dimen> <dimen name="editor_format_button_size">24dp</dimen>
<dimen name="editor_format_button_margin_between">4dp</dimen> <dimen name="editor_format_button_margin_between">4dp</dimen>

11
app/src/main/res/values/strings.xml

@ -114,13 +114,11 @@
<string name="upload_button">Upload</string> <string name="upload_button">Upload</string>
<!--Upload Activity--> <!--Upload Activity-->
<string name="upload_category_pre_text">Select the correct category for the file</string> <string name="upload_title_description_builder">Generate title and description</string>
<string name="upload_title_description_pre_text">Fill in the title and description\nor</string>
<string name="upload_title_description_builder">build them automatically</string>
<string name="upload_title_hint">Title</string> <string name="upload_title_hint">Title</string>
<string name="upload_description_hint">Description</string> <string name="upload_description_hint">Description</string>
<string name="upload_select_file">Select file to upload</string> <string name="upload_select_file">Select file</string>
<string name="upload_upload_button">Upload</string> <string name="upload_take_photo">Take photo</string>
<string name="upload_spinners_hint">Select a category</string> <string name="upload_spinners_hint">Select a category</string>
<!--Upload Fields Builder Activity--> <!--Upload Fields Builder Activity-->
@ -134,7 +132,8 @@
<string name="upload_fields_builder_radio_button_sept">September</string> <string name="upload_fields_builder_radio_button_sept">September</string>
<string name="upload_fields_builder_select_year_title">Select year</string> <string name="upload_fields_builder_select_year_title">Select year</string>
<string name="upload_fields_builder_year_hint">Year</string> <string name="upload_fields_builder_year_hint">Year</string>
<string name="upload_fields_builder_submit">Build</string> <string name="upload_fields_builder_submit">Generate</string>
<string name="upload_fields_builder_toolbar_title">Upload fields generator</string>
<!--Settings Activity--> <!--Settings Activity-->
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>

4
app/src/main/res/values/styles.xml

@ -24,7 +24,11 @@
<style name="AppTheme.NoActionBar"> <style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.PreferenceTheme" parent="AppTheme.NoActionBar">
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="colorControlActivated">@color/accent</item>
</style> </style>
<style name="PopupMenuStyle"> <style name="PopupMenuStyle">

2
build.gradle

@ -8,7 +8,7 @@ buildscript {
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.1.3' classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.google.gms:google-services:4.0.1' classpath 'com.google.gms:google-services:4.0.1'
classpath 'io.fabric.tools:gradle:1.25.4' classpath 'io.fabric.tools:gradle:1.25.4'
} }

Loading…
Cancel
Save