From 6fffe4777c468fe38feb9113c91a0090fc59bf5a Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 23 May 2019 15:26:15 +0300 Subject: [PATCH 01/18] Add last commit badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1dfb2197..0eb2123e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![API](https://img.shields.io/badge/API-19%2B-blue.svg?style=flat)](https://android-arsenal.com/api?level=19) [![Discord Channel](https://img.shields.io/badge/discord-public@mTHMMY-738bd7.svg?style=flat)][discord-server] +![Last Commit](https://img.shields.io/github/last-commit/ThmmyNoLife/mTHMMY/develop.svg?style=flat) ![mTHMMY logo](app/src/main/res/mipmap-xhdpi/ic_launcher.png) From 33a10747eb300dc9240453a1054fc0ca6fffcd24 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sun, 13 Jan 2019 12:08:40 +0200 Subject: [PATCH 02/18] Up version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4a4812ea..c2b07d75 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "gr.thmmy.mthmmy" minSdkVersion 19 targetSdkVersion 28 - versionCode 17 - versionName "1.6.2" + versionCode 18 + versionName "1.6.3" archivesBaseName = "mTHMMY-v$versionName" buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\"" buildConfigField "String", "COMMIT_HASH", "\"" + getCommitHash() + "\"" From 4709796b8afd7cd98426e2f3abd7ab63a0064766 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sun, 16 Jun 2019 12:56:55 +0300 Subject: [PATCH 03/18] Update uploads to androidx, comment out retry stuff, Fix FAB disappearing --- app/build.gradle | 3 +- app/src/main/AndroidManifest.xml | 8 + .../activities/board/BoardActivity.java | 1 + .../downloads/DownloadsActivity.java | 68 +- .../mthmmy/activities/topic/TopicAdapter.java | 36 +- .../activities/upload/UploadActivity.java | 791 ++++++++++++++---- .../upload/UploadFieldsBuilderActivity.java | 342 ++++---- .../activities/upload/UploadsHelper.java | 182 ++-- .../gr/thmmy/mthmmy/base/BaseActivity.java | 192 ++++- .../gr/thmmy/mthmmy/model/UploadFile.java | 44 + .../mthmmy/services/UploadsReceiver.java | 223 +++++ .../java/gr/thmmy/mthmmy/utils/FileUtils.java | 97 ++- .../mthmmy/utils/ScrollAwareFABBehavior.java | 18 +- .../java/gr/thmmy/mthmmy/utils/TakePhoto.java | 174 ++++ .../drawable/ic_attach_file_white_24dp.xml | 4 - .../res/drawable/ic_cached_accent_24dp.xml | 4 + .../res/drawable/ic_cancel_accent_24dp.xml | 4 + .../drawable/ic_info_outline_warning_24dp.xml | 4 + app/src/main/res/layout/activity_board.xml | 15 +- .../main/res/layout/activity_downloads.xml | 4 +- app/src/main/res/layout/activity_topic.xml | 4 +- app/src/main/res/layout/activity_upload.xml | 72 +- .../layout/activity_upload_fields_builder.xml | 2 +- .../layout/activity_upload_file_list_row.xml | 24 + .../activity_upload_filename_info_popup.xml | 10 + .../res/layout/dialog_upload_progress.xml | 43 + .../res/layout/editor_view_color_picker.xml | 37 +- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 12 +- app/src/main/res/xml/app_preferences_user.xml | 4 +- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 32 files changed, 1799 insertions(+), 630 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/model/UploadFile.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java delete mode 100644 app/src/main/res/drawable/ic_attach_file_white_24dp.xml create mode 100644 app/src/main/res/drawable/ic_cached_accent_24dp.xml create mode 100644 app/src/main/res/drawable/ic_cancel_accent_24dp.xml create mode 100644 app/src/main/res/drawable/ic_info_outline_warning_24dp.xml create mode 100644 app/src/main/res/layout/activity_upload_file_list_row.xml create mode 100644 app/src/main/res/layout/activity_upload_filename_info_popup.xml create mode 100644 app/src/main/res/layout/dialog_upload_progress.xml diff --git a/app/build.gradle b/app/build.gradle index c2b07d75..337120bc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,7 +44,7 @@ android { tasks.whenTaskAdded { task -> if (task.name.contains("assembleRelease")) { task.getDependsOn().add({ - def inputFile = new File("app/google-services.json") + def inputFile = new File("google-services.json") def json = new JsonSlurper().parseText(inputFile.text) if (json.project_info.project_id != "mthmmy-release-3aef0") throw new GradleException('Please supply the correct google-services.json for release (or manually change the id above)!') @@ -73,6 +73,7 @@ dependencies { implementation 'com.google.firebase:firebase-core:16.0.6' implementation 'com.google.firebase:firebase-messaging:17.3.4' implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8' + implementation 'com.snatik:storage:2.1.0' implementation 'com.squareup.okhttp3:okhttp:3.12.0' implementation 'com.squareup.picasso:picasso:2.5.2' implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7620bcf7..1e8bf257 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -160,6 +160,14 @@ + + + + + + { diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java index addccf35..e4c3676c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java @@ -1,8 +1,12 @@ package gr.thmmy.mthmmy.activities.downloads; +import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; @@ -16,7 +20,11 @@ import java.util.Objects; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.activities.upload.UploadActivity; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.model.Download; @@ -29,6 +37,8 @@ import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; +import static gr.thmmy.mthmmy.activities.upload.UploadActivity.BUNDLE_UPLOAD_CATEGORY; + public class DownloadsActivity extends BaseActivity implements DownloadsAdapter.OnLoadMoreListener { /** * The key to use when putting download's url String to {@link DownloadsActivity}'s Bundle. @@ -47,7 +57,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. private MaterialProgressBar progressBar; private RecyclerView recyclerView; private DownloadsAdapter downloadsAdapter; - //private FloatingActionButton uploadFAB; + private FloatingActionButton uploadFAB; private ParseDownloadPageTask parseDownloadPageTask; private int numberOfPages = -1; @@ -113,37 +123,37 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. } }); -// uploadFAB = findViewById(R.id.upload_fab); -// uploadFAB.setEnabled(false); -// uploadFAB.hide(); + uploadFAB = findViewById(R.id.upload_fab); + uploadFAB.setEnabled(false); + uploadFAB.hide(); parseDownloadPageTask = new ParseDownloadPageTask(); parseDownloadPageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, downloadsUrl); } -// @Override -// public boolean onCreateOptionsMenu(Menu menu) { -// // Inflates the menu; this adds items to the action bar if it is present. -// getMenuInflater().inflate(R.menu.downloads_menu, menu); -// super.onCreateOptionsMenu(menu); -// return true; -// } -// -// @Override -// public boolean onOptionsItemSelected(MenuItem item) { -// // Handle presses on the action bar items -// switch (item.getItemId()) { -// case R.id.menu_upload: -// Intent intent = new Intent(DownloadsActivity.this, UploadActivity.class); -// Bundle extras = new Bundle(); -// extras.putString(BUNDLE_UPLOAD_CATEGORY, downloadsNav); -// intent.putExtras(extras); -// startActivity(intent); -// return true; -// default: -// return super.onOptionsItemSelected(item); -// } -// } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflates the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.downloads_menu, menu); + super.onCreateOptionsMenu(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle presses on the action bar items + switch (item.getItemId()) { + case R.id.menu_upload: + Intent intent = new Intent(DownloadsActivity.this, UploadActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_UPLOAD_CATEGORY, downloadsNav); + intent.putExtras(extras); + startActivity(intent); + return true; + default: + return super.onOptionsItemSelected(item); + } + } @Override public void onLoadMore() { @@ -198,7 +208,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. @Override protected void onPreExecute() { if (!isLoadingMore) progressBar.setVisibility(ProgressBar.VISIBLE); - //if (uploadFAB.getVisibility() != View.GONE) uploadFAB.setEnabled(false); + if (uploadFAB.getVisibility() != View.GONE) uploadFAB.setEnabled(false); } @Override @@ -296,7 +306,7 @@ public class DownloadsActivity extends BaseActivity implements DownloadsAdapter. toolbar.setTitle(downloadsTitle); ++pagesLoaded; - //if (uploadFAB.getVisibility() != View.GONE) uploadFAB.setEnabled(true); + if (uploadFAB.getVisibility() != View.GONE) uploadFAB.setEnabled(true); progressBar.setVisibility(ProgressBar.INVISIBLE); downloadsAdapter.notifyDataSetChanged(); isLoadingMore = false; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java index dba15a45..5472a742 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java @@ -87,6 +87,7 @@ import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; import static gr.thmmy.mthmmy.activities.topic.TopicParser.USER_COLOR_WHITE; import static gr.thmmy.mthmmy.activities.topic.TopicParser.USER_COLOR_YELLOW; import static gr.thmmy.mthmmy.base.BaseActivity.getSessionManager; +import static gr.thmmy.mthmmy.utils.FileUtils.faIconFromFilename; /** * Custom {@link RecyclerView.Adapter} used for topics. @@ -392,7 +393,7 @@ class TopicAdapter extends RecyclerView.Adapter { attached.setClickable(true); attached.setTypeface(Typeface.createFromAsset(context.getAssets() , "fonts/fontawesome-webfont.ttf")); - attached.setText(faIconFromFilename(attachedFile.getFilename()) + " " + attached.setText(faIconFromFilename(context, attachedFile.getFilename()) + " " + attachedFile.getFilename() + attachedFile.getFileInfo()); attached.setTextColor(filesTextColor); attached.setPadding(0, 3, 0, 3); @@ -1035,37 +1036,4 @@ class TopicAdapter extends RecyclerView.Adapter { public interface OnPostFocusChangeListener { void onPostFocusChange(int position); } - - /** - * Returns a String with a single FontAwesome typeface character corresponding to this file's - * extension. - * - * @param filename String with filename containing file's extension - * @return FontAwesome character according to file's type - * @see FontAwesome - */ - @NonNull - private String faIconFromFilename(String filename) { - filename = filename.toLowerCase(); - - if (filename.contains("jpg") || filename.contains("gif") || filename.contains("jpeg") - || filename.contains("png")) - return context.getResources().getString(R.string.fa_file_image_o); - else if (filename.contains("pdf")) - return context.getResources().getString(R.string.fa_file_pdf_o); - else if (filename.contains("zip") || filename.contains("rar") || filename.contains("tar.gz")) - return context.getResources().getString(R.string.fa_file_zip_o); - else if (filename.contains("txt")) - return context.getResources().getString(R.string.fa_file_text_o); - else if (filename.contains("doc") || filename.contains("docx")) - return context.getResources().getString(R.string.fa_file_word_o); - else if (filename.contains("xls") || filename.contains("xlsx")) - return context.getResources().getString(R.string.fa_file_excel_o); - else if (filename.contains("pps")) - return context.getResources().getString(R.string.fa_file_powerpoint_o); - else if (filename.contains("mpg")) - return context.getResources().getString(R.string.fa_file_video_o); - - return context.getResources().getString(R.string.fa_file); - } } \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java index 974b8b20..20fea00f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java @@ -1,54 +1,68 @@ package gr.thmmy.mthmmy.activities.upload; import android.app.Activity; +import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.ResolveInfo; -import android.graphics.Bitmap; +import android.content.pm.PackageManager; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; -import android.provider.MediaStore; +import androidx.annotation.NonNull; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import androidx.core.content.FileProvider; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.preference.PreferenceManager; +import androidx.appcompat.widget.AppCompatButton; +import androidx.appcompat.widget.AppCompatImageButton; +import android.text.Editable; +import android.text.Spannable; +import android.text.TextWatcher; +import android.text.method.LinkMovementMethod; +import android.text.style.ForegroundColorSpan; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.LinearLayout; +import android.widget.PopupWindow; import android.widget.ProgressBar; +import android.widget.TextView; import android.widget.Toast; -import com.google.android.material.floatingactionbutton.FloatingActionButton; - import net.gotev.uploadservice.MultipartUploadRequest; -import net.gotev.uploadservice.ServerResponse; -import net.gotev.uploadservice.UploadInfo; +import net.gotev.uploadservice.UploadNotificationAction; import net.gotev.uploadservice.UploadNotificationConfig; -import net.gotev.uploadservice.UploadStatusDelegate; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.File; -import java.io.FileOutputStream; +import java.lang.ref.WeakReference; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; -import java.util.List; import java.util.Locale; +import java.util.UUID; -import androidx.appcompat.content.res.AppCompatResources; -import androidx.appcompat.widget.AppCompatButton; -import androidx.appcompat.widget.AppCompatTextView; -import androidx.preference.PreferenceManager; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.model.UploadCategory; +import gr.thmmy.mthmmy.model.UploadFile; +import gr.thmmy.mthmmy.services.UploadsReceiver; import gr.thmmy.mthmmy.utils.AppCompatSpinnerWithoutDefault; +import gr.thmmy.mthmmy.utils.FileUtils; +import gr.thmmy.mthmmy.utils.TakePhoto; import gr.thmmy.mthmmy.utils.parsing.ParseException; import gr.thmmy.mthmmy.utils.parsing.ParseTask; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; @@ -60,6 +74,7 @@ import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.BUND import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.RESULT_DESCRIPTION; import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.RESULT_FILENAME; import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.RESULT_TITLE; +import static gr.thmmy.mthmmy.utils.FileUtils.faIconFromFilename; public class UploadActivity extends BaseActivity { /** @@ -71,27 +86,40 @@ public class UploadActivity extends BaseActivity { /** * Request codes used in activities for result (AFR) calls */ - 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 final int AFR_REQUEST_CODE_CHOOSE_FILE = 8; //Arbitrary, application specific + private static final int AFR_REQUEST_CODE_CAMERA = 4; //Arbitrary, application specific + private static final int AFR_REQUEST_CODE_FIELDS_BUILDER = 74; //Arbitrary, application specific + + /** + * Request code to gain read/write permission + */ + private static final int UPLOAD_REQUEST_CODE = 42; //Arbitrary, application specific + + private static final int MAX_FILE_SIZE_SUPPORTED = 45000000; + //private UploadsReceiver uploadsReceiver = new UploadsReceiver(); private ArrayList uploadRootCategories = new ArrayList<>(); private ParseUploadPageTask parseUploadPageTask; private ArrayList bundleCategory; private String categorySelected = "-1"; private String uploaderProfileIndex = "1"; - private String uploadFilename; - private Uri fileUri; + + private ArrayList filesList = new ArrayList<>(); + private File photoFileCreated = null; private String fileIcon; + private AppCompatImageButton uploadFilenameInfo; + private CustomTextWatcher textWatcher; + private boolean hasModifiedFilename = false; //UI elements private MaterialProgressBar progressBar; private LinearLayout categoriesSpinners; private AppCompatSpinnerWithoutDefault rootCategorySpinner; private EditText uploadTitle; + private EditText uploadFilename; private EditText uploadDescription; private AppCompatButton titleDescriptionBuilderButton; - private AppCompatTextView filenameHolder; + private LinearLayout filesListView; @Override protected void onCreate(Bundle savedInstanceState) { @@ -197,9 +225,36 @@ public class UploadActivity extends BaseActivity { uploadTitle = findViewById(R.id.upload_title); uploadDescription = findViewById(R.id.upload_description); - filenameHolder = findViewById(R.id.upload_filename); - Drawable filenameDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_attach_file_white_24dp); - filenameHolder.setCompoundDrawablesRelativeWithIntrinsicBounds(filenameDrawable, null, null, null); + uploadFilenameInfo = findViewById(R.id.upload_filename_info); + uploadFilenameInfo.setOnClickListener(view -> { + //Inflates the popup menu content + LayoutInflater layoutInflater = (LayoutInflater) view.getContext(). + getSystemService(Context.LAYOUT_INFLATER_SERVICE); + if (layoutInflater == null) { + return; + } + + Context wrapper = new ContextThemeWrapper(this, R.style.PopupWindow); + View popUpContent = layoutInflater.inflate(R.layout.activity_upload_filename_info_popup, null); + + //Creates the PopupWindow + PopupWindow popUp = new PopupWindow(wrapper); + popUp.setContentView(popUpContent); + popUp.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT); + popUp.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); + popUp.setFocusable(true); + + ((TextView) popUpContent.findViewById(R.id.upload_filename_info_text)). + setMovementMethod(LinkMovementMethod.getInstance()); + //Displays the popup + popUp.showAsDropDown(view); + }); + + uploadFilename = findViewById(R.id.upload_filename); + textWatcher = new CustomTextWatcher(); + uploadFilename.addTextChangedListener(textWatcher); + + filesListView = findViewById(R.id.upload_files_list); AppCompatButton selectFileButton = findViewById(R.id.upload_select_file_button); Drawable selectStartDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_insert_drive_file_white_24dp); @@ -212,7 +267,8 @@ public class UploadActivity extends BaseActivity { Intent intent = new Intent(Intent.ACTION_GET_CONTENT) //.setType("*/*") .setType("image/jpeg") - .putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes); + .putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes) + .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); startActivityForResult(intent, AFR_REQUEST_CODE_CHOOSE_FILE); }); @@ -221,118 +277,153 @@ public class UploadActivity extends BaseActivity { Drawable takePhotoDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_photo_camera_white_24dp); takePhotoButton.setCompoundDrawablesRelativeWithIntrinsicBounds(takePhotoDrawable, null, null, null); takePhotoButton.setOnClickListener(v -> { - Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - takePhotoIntent.putExtra("return-data", true); - takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(UploadsHelper.getCacheFile(this))); - - Intent targetedIntent = new Intent(takePhotoIntent); - List resInfo = this.getPackageManager().queryIntentActivities(takePhotoIntent, 0); - for (ResolveInfo resolveInfo : resInfo) { - String packageName = resolveInfo.activityInfo.packageName; - targetedIntent.setPackage(packageName); - } - startActivityForResult(takePhotoIntent, AFR_REQUEST_CODE_CAMERA); + if (checkPerms()) + takePhoto(); + else + requestPerms(UPLOAD_REQUEST_CODE); }); FloatingActionButton uploadFAB = findViewById(R.id.upload_fab); + uploadFAB.setTag(true); uploadFAB.setOnClickListener(view -> { + //Attempts upload progressBar.setVisibility(View.VISIBLE); String uploadTitleText = uploadTitle.getText().toString(); - String uploadDescriptionText = uploadDescription.getText().toString(); - - if (uploadTitleText.equals("")) { - uploadTitle.setError("Required"); - } - if (fileUri == null) { - Toast.makeText(view.getContext(), "Please choose a file to upload or take a photo", Toast.LENGTH_LONG).show(); - } - if (categorySelected.equals("-1")) { - Toast.makeText(view.getContext(), "Please choose category first", Toast.LENGTH_SHORT).show(); - } - - if (categorySelected.equals("-1") || uploadTitleText.equals("") || fileUri == null) { - progressBar.setVisibility(View.GONE); - return; - } - - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(view.getContext()); - if (sharedPrefs.getBoolean(UPLOADING_APP_SIGNATURE_ENABLE_KEY, true)) { - uploadDescriptionText += uploadedFromThmmyPromptHtml; - } + String editTextFilename = uploadFilename.getText().toString(); + final String[] uploadDescriptionText = {uploadDescription.getText().toString()}; + + //Checks if all required fields are filled + { + boolean shouldReturn = false; + if (uploadTitleText.equals("")) { + uploadTitle.setError("Required"); + shouldReturn = true; + } + if (filesList.isEmpty()) { + Toast.makeText(view.getContext(), "Please choose a file to upload or take a photo", Toast.LENGTH_LONG).show(); + shouldReturn = true; + } + if (categorySelected.equals("-1")) { + Toast.makeText(view.getContext(), "Please choose category first", Toast.LENGTH_SHORT).show(); + shouldReturn = true; + } + if (!filesList.isEmpty()) { + long totalFilesSize = 0; + for (UploadFile file : filesList) { + totalFilesSize += FileUtils.sizeFromUri(this, file.getFileUri()); + } - String tempFilePath = 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); - if (tempFilePath == null) { - //Something went wrong, abort - Toast.makeText(this, "Could not create temporary file for renaming", Toast.LENGTH_SHORT).show(); + if (totalFilesSize > MAX_FILE_SIZE_SUPPORTED) { + Toast.makeText(view.getContext(), "Your files are too powerful for thmmy. Reduce size or split!", Toast.LENGTH_LONG).show(); + shouldReturn = true; + } + } + if (!editTextFilename.matches("(.+\\.)+.+") || + !FileUtils.getFilenameWithoutExtension(editTextFilename). + matches("[0-9a-zA-Zα-ωΑ-Ω~!@#$%^&()_+=\\-`\\[\\]{};',.]+")) { + uploadFilename.setError("Invalid filename"); + shouldReturn = true; + } + if (shouldReturn) { progressBar.setVisibility(View.GONE); return; } } - try { - new MultipartUploadRequest(view.getContext(), uploadIndexUrl) - .setUtf8Charset() - .addParameter("tp-dluploadtitle", uploadTitleText) - .addParameter("tp-dluploadcat", categorySelected) - .addParameter("tp-dluploadtext", uploadDescriptionText) - .addFileToUpload(tempFilePath == null - ? fileUri.toString() - : tempFilePath - , "tp-dluploadfile") - .addParameter("tp_dluploadicon", fileIcon) - .addParameter("tp-uploaduser", uploaderProfileIndex) - .setNotificationConfig(new UploadNotificationConfig()) - .setMaxRetries(2) - .setDelegate(new UploadStatusDelegate() { - @Override - public void onProgress(Context context, UploadInfo uploadInfo) { - } + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Upload to thmmy"); + builder.setMessage("Are you sure?"); + builder.setPositiveButton("YES, FIRE AWAY", (dialog, which) -> { + //Checks settings and possibly adds "Uploaded from mTHMMY" string to description + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(view.getContext()); + if (sharedPrefs.getBoolean(UPLOADING_APP_SIGNATURE_ENABLE_KEY, true)) { + uploadDescriptionText[0] += uploadedFromThmmyPromptHtml; + } - @Override - public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse, - Exception exception) { - Toast.makeText(context, "Upload failed", Toast.LENGTH_SHORT).show(); - UploadsHelper.deleteTempFiles(); - progressBar.setVisibility(View.GONE); - } + for (UploadFile file : filesList) { + if (file.isCameraPhoto()) { + TakePhoto.galleryAddPic(this, file.getPhotoFile()); + } + } - @Override - public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) { - Toast.makeText(context, "Upload completed successfully", Toast.LENGTH_SHORT).show(); - UploadsHelper.deleteTempFiles(); - BaseApplication.getInstance().logFirebaseAnalyticsEvent("file_upload", null); - - uploadTitle.setText(null); - uploadDescription.setText(null); - fileUri = null; - filenameHolder.setText(null); - filenameHolder.setVisibility(View.GONE); + Uri tempFileUri = null; + if (filesList.size() == 1) { + //Checks if the file needs renaming + UploadFile uploadFile = filesList.get(0); + String selectedFileFilename = FileUtils.filenameFromUri(this, uploadFile.getFileUri()); + + if (!editTextFilename.equals(selectedFileFilename)) { + //File should be uploaded with a different name + if (!uploadFile.isCameraPhoto()) { + //Temporarily copies the file to a another location and renames it + tempFileUri = UploadsHelper.createTempFile(this, storage, + uploadFile.getFileUri(), + FileUtils.getFilenameWithoutExtension(editTextFilename)); + } else { + //Renames the photo taken + String photoPath = uploadFile.getPhotoFile().getPath(); + photoPath = photoPath.substring(0, photoPath.lastIndexOf(File.separator)); + String destinationFilename = photoPath + File.separator + + FileUtils.getFilenameWithoutExtension(editTextFilename) + ".jpg"; + + if (!storage.rename(uploadFile.getPhotoFile().getAbsolutePath(), destinationFilename)) { + //Something went wrong, abort + Toast.makeText(this, "Could not create temporary file for renaming", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); + return; } - @Override - public void onCancelled(Context context, UploadInfo uploadInfo) { - Toast.makeText(context, "Upload canceled", Toast.LENGTH_SHORT).show(); + //Points photoFile and fileUri to the new copied and renamed file + uploadFile.setPhotoFile(storage.getFile(destinationFilename)); + uploadFile.setFileUri(FileProvider.getUriForFile(this, getPackageName() + + ".provider", uploadFile.getPhotoFile())); + } + } + } else { + Uri[] filesListArray = new Uri[filesList.size()]; + for (int i = 0; i < filesList.size(); ++i) { + filesListArray[i] = filesList.get(i).getFileUri(); + } + + new ZipTask(this, editTextFilename, categorySelected, + uploadTitleText, uploadDescriptionText[0], fileIcon, + uploaderProfileIndex).execute(filesListArray); + finish(); + return; + } - UploadsHelper.deleteTempFiles(); - progressBar.setVisibility(View.GONE); - } - }) - .startUpload(); - } catch (Exception exception) { - Timber.e(exception, "AndroidUploadService: %s", exception.getMessage()); + String uploadID = UUID.randomUUID().toString(); + if (uploadFile(this, uploadID, getConfigForUpload(this, uploadID, + editTextFilename), + categorySelected, uploadTitleText, + uploadDescriptionText[0], fileIcon, uploaderProfileIndex, + tempFileUri == null + ? filesList.get(0).getFileUri() + : tempFileUri)) { + finish(); + } else { + Toast.makeText(this, "Couldn't initiate upload.", Toast.LENGTH_SHORT).show(); + } + }); + + builder.setNegativeButton("NOPE", (dialog, which) -> { progressBar.setVisibility(View.GONE); - } + dialog.dismiss(); + }); + + AlertDialog alert = builder.create(); + alert.setOnCancelListener(dialog -> { + progressBar.setVisibility(View.GONE); + dialog.dismiss(); + }); + alert.show(); }); if (uploadRootCategories.isEmpty()) { //Parses the uploads page parseUploadPageTask = new ParseUploadPageTask(); - parseUploadPageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, uploadIndexUrl); + parseUploadPageTask.execute(uploadIndexUrl); } else { //Renders the already parsed data updateUIElements(); @@ -355,11 +446,17 @@ public class UploadActivity extends BaseActivity { super.onResume(); } + @Override + protected void onPause() { + super.onPause(); + } + @Override protected void onDestroy() { super.onDestroy(); - if (parseUploadPageTask != null && parseUploadPageTask.getStatus() != AsyncTask.Status.RUNNING) + if (parseUploadPageTask != null && parseUploadPageTask.getStatus() != AsyncTask.Status.RUNNING) { parseUploadPageTask.cancel(true); + } } @Override @@ -369,71 +466,119 @@ public class UploadActivity extends BaseActivity { return; } - fileUri = data.getData(); - if (fileUri != null) { - String filename = UploadsHelper.filenameFromUri(this, fileUri); - filenameHolder.setText(filename); - filenameHolder.setVisibility(View.VISIBLE); - - filename = filename.toLowerCase(); - if (filename.endsWith(".jpg")) { - fileIcon = "jpg_image.gif"; - } else if (filename.endsWith(".gif")) { - fileIcon = "gif_image.gif"; - } else if (filename.endsWith(".png")) { - fileIcon = "png_image.gif"; - } else if (filename.endsWith(".html") || filename.endsWith(".htm")) { - fileIcon = "html_file.gif"; - } else if (filename.endsWith(".pdf") || filename.endsWith(".doc") || - filename.endsWith("djvu")) { - fileIcon = "text_file.gif"; - } else if (filename.endsWith(".zip") || filename.endsWith(".rar") || - filename.endsWith(".tar") || filename.endsWith(".tar.gz") || - filename.endsWith(".gz")) { - fileIcon = "archive.gif"; - } else { - fileIcon = "blank.gif"; + if (data.getClipData() != null) { + fileIcon = "archive.gif"; + textWatcher.setFileExtension(".zip"); + + if (!hasModifiedFilename) { + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); + String zipFilename = "mThmmy_" + timeStamp + ".zip"; + uploadFilename.setText(zipFilename); + hasModifiedFilename = false; + } + + for (int fileIndex = 0; fileIndex < data.getClipData().getItemCount(); ++fileIndex) { + Uri newFileUri = data.getClipData().getItemAt(fileIndex).getUri(); + String filename = FileUtils.filenameFromUri(this, newFileUri); + addFileViewToList(filename); + filesList.add(new UploadFile(false, newFileUri, null)); + } + } else { + Uri newFileUri = data.getData(); + if (newFileUri != null) { + String filename = FileUtils.filenameFromUri(this, newFileUri); + + if (filesList.isEmpty()) { + textWatcher.setFileExtension(FileUtils.getFileExtension(filename)); + + if (!hasModifiedFilename) { + uploadFilename.setText(filename); + hasModifiedFilename = false; + } + + filename = filename.toLowerCase(); + if (filename.endsWith(".jpg")) { + fileIcon = "jpg_image.gif"; + } else if (filename.endsWith(".gif")) { + fileIcon = "gif_image.gif"; + } else if (filename.endsWith(".png")) { + fileIcon = "png_image.gif"; + } else if (filename.endsWith(".html") || filename.endsWith(".htm")) { + fileIcon = "html_file.gif"; + } else if (filename.endsWith(".pdf") || filename.endsWith(".doc") || + filename.endsWith("djvu")) { + fileIcon = "text_file.gif"; + } else if (filename.endsWith(".zip") || filename.endsWith(".rar") || + filename.endsWith(".tar") || filename.endsWith(".tar.gz") || + filename.endsWith(".gz")) { + fileIcon = "archive.gif"; + } else { + fileIcon = "blank.gif"; + } + } else { + fileIcon = "archive.gif"; + textWatcher.setFileExtension(".zip"); + + if (!hasModifiedFilename) { + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); + String zipFilename = "mThmmy_" + timeStamp + ".zip"; + uploadFilename.setText(zipFilename); + hasModifiedFilename = false; + } + } + + addFileViewToList(filename); + filesList.add(new UploadFile(false, newFileUri, null)); } } } else if (requestCode == AFR_REQUEST_CODE_CAMERA) { if (resultCode == Activity.RESULT_CANCELED) { + //Deletes image file + storage.deleteFile(photoFileCreated.getAbsolutePath()); return; } - Bitmap bitmap; - File cacheImageFile = UploadsHelper.getCacheFile(this); + if (filesList.isEmpty()) { + textWatcher.setFileExtension(FileUtils.getFileExtension(photoFileCreated.getName())); - Uri cacheFileUri = Uri.fromFile(cacheImageFile); - fileIcon = "jpg_image.gif"; - - bitmap = UploadsHelper.getImageResized(this, cacheFileUri); - int rotation = UploadsHelper.getRotation(this, cacheFileUri); - bitmap = UploadsHelper.rotate(bitmap, rotation); + if (!hasModifiedFilename) { + uploadFilename.setText(photoFileCreated.getName()); + hasModifiedFilename = false; + } - try { - FileOutputStream out = new FileOutputStream(cacheImageFile); - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); - out.flush(); - out.close(); - } catch (Exception e) { - e.printStackTrace(); + fileIcon = "jpg_image.gif"; + } else { + fileIcon = "archive.gif"; + textWatcher.setFileExtension(".zip"); + + if (!hasModifiedFilename) { + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); + String zipFilename = "mThmmy_" + timeStamp + ".zip"; + uploadFilename.setText(zipFilename); + hasModifiedFilename = false; + } } - 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); + UploadFile newFile = new UploadFile(true, TakePhoto.processResult(this, + photoFileCreated), photoFileCreated); + addFileViewToList(FileUtils.getFilenameWithoutExtension(FileUtils. + filenameFromUri(this, newFile.getFileUri()))); + filesList.add(newFile); } else if (requestCode == AFR_REQUEST_CODE_FIELDS_BUILDER) { if (resultCode == Activity.RESULT_CANCELED) { return; } - uploadFilename = data.getStringExtra(RESULT_FILENAME); + String previousName = uploadFilename.getText().toString(); + if (previousName.isEmpty()) { + uploadFilename.setText(data.getStringExtra(RESULT_FILENAME)); + } else { + String filenameWithExtension = data.getStringExtra(RESULT_FILENAME) + + FileUtils.getFileExtension(previousName); + uploadFilename.setText(filenameWithExtension); + } + hasModifiedFilename = true; + uploadTitle.setText(data.getStringExtra(RESULT_TITLE)); uploadDescription.setText(data.getStringExtra(RESULT_DESCRIPTION)); } else { @@ -441,6 +586,243 @@ public class UploadActivity extends BaseActivity { } } + @Override + public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions + , @NonNull int[] grantResults) { + switch (permsRequestCode) { + case UPLOAD_REQUEST_CODE: + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) + takePhoto(); + break; + } + } + + // Should only be called after making sure permissions are granted + private void takePhoto() { + // Create the File where the photo should go + photoFileCreated = TakePhoto.createImageFile(this); + + // Continue only if the File was successfully created + if (photoFileCreated != null) { + startActivityForResult(TakePhoto.getIntent(this, photoFileCreated), + AFR_REQUEST_CODE_CAMERA); + } + } + + private void updateUIElements() { + String[] tmpSpinnerArray = new String[uploadRootCategories.size()]; + for (int i = 0; i < uploadRootCategories.size(); ++i) { + tmpSpinnerArray[i] = uploadRootCategories.get(i).getCategoryTitle(); + } + + ArrayAdapter spinnerArrayAdapter = new ArrayAdapter<>(BaseApplication.getInstance().getApplicationContext(), + R.layout.spinner_item, tmpSpinnerArray); + spinnerArrayAdapter.setDropDownViewResource(R.layout.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); + } + } + } + + private void addFileViewToList(String filename) { + LayoutInflater layoutInflater = getLayoutInflater(); + LinearLayout newFileRow = (LinearLayout) layoutInflater. + inflate(R.layout.activity_upload_file_list_row, null); + + TextView itemText = newFileRow.findViewById(R.id.upload_file_item_text); + itemText.setTypeface(Typeface.createFromAsset(this.getAssets() + , "fonts/fontawesome-webfont.ttf")); + String filenameWithIcon = faIconFromFilename(this, filename) + " " + filename; + itemText.setText(filenameWithIcon); + + newFileRow.findViewById(R.id.upload_file_item_remove).setOnClickListener(view -> { + int fileIndex = filesListView.indexOfChild(newFileRow); + filesListView.removeViewAt(fileIndex); + + if (filesList.get(fileIndex).isCameraPhoto()) { + storage.deleteFile(filesList.get(fileIndex).getPhotoFile().getAbsolutePath()); + } + filesList.remove(fileIndex); + if (filesList.isEmpty()) { + filesListView.setVisibility(View.GONE); + } else if (filesList.size() == 1) { + textWatcher.setFileExtension(FileUtils.getFileExtension(FileUtils. + filenameFromUri(this, filesList.get(0).getFileUri()))); + } + }); + + filesListView.addView(newFileRow); + filesListView.setVisibility(View.VISIBLE); + } + + public static UploadNotificationConfig getConfigForUpload(Context context, String uploadID, + String filename) { + UploadNotificationConfig uploadNotificationConfig = new UploadNotificationConfig(); + uploadNotificationConfig.setIconForAllStatuses(android.R.drawable.stat_sys_upload); + uploadNotificationConfig.setTitleForAllStatuses("Uploading " + filename); + + uploadNotificationConfig.getProgress().iconResourceID = android.R.drawable.stat_sys_upload; + uploadNotificationConfig.getCompleted().iconResourceID = android.R.drawable.stat_sys_upload_done; + uploadNotificationConfig.getError().iconResourceID = android.R.drawable.stat_sys_upload_done; + uploadNotificationConfig.getError().iconColorResourceID = R.color.error_red; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + uploadNotificationConfig.getError().message = "Error during upload. Click for options"; + } + uploadNotificationConfig.getCancelled().iconColorResourceID = android.R.drawable.stat_sys_upload_done; + uploadNotificationConfig.getCancelled().autoClear = true; + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + Intent combinedActionsIntent = new Intent(UploadsReceiver.ACTION_COMBINED_UPLOAD); + combinedActionsIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadID); + + /*combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_RETRY_FILENAME, filename); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_RETRY_CATEGORY, retryCategory); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_RETRY_TITLE, retryTitleText); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_RETRY_DESCRIPTION, retryDescription); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_RETRY_ICON, retryIcon); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_RETRY_UPLOADER, retryUploaderProfile); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_RETRY_FILE_URI, retryFileUri);*/ + + uploadNotificationConfig.setClickIntentForAllStatuses(PendingIntent.getBroadcast(context, + 1, combinedActionsIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Intent retryIntent = new Intent(context, UploadsReceiver.class); + retryIntent.setAction(UploadsReceiver.ACTION_RETRY_UPLOAD); + retryIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadID); + + Intent cancelIntent = new Intent(context, UploadsReceiver.class); + cancelIntent.setAction(UploadsReceiver.ACTION_CANCEL_UPLOAD); + cancelIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadID); + + uploadNotificationConfig.getProgress().actions.add(new UploadNotificationAction( + R.drawable.ic_cancel_accent_24dp, + context.getString(R.string.upload_notification_cancel), + PendingIntent.getBroadcast(context, 0, cancelIntent, + PendingIntent.FLAG_UPDATE_CURRENT) + )); + uploadNotificationConfig.getError().actions.add(new UploadNotificationAction( + R.drawable.ic_notification, + context.getString(R.string.upload_notification_retry), + PendingIntent.getBroadcast(context, 0, retryIntent, + PendingIntent.FLAG_UPDATE_CURRENT) + )); + } + + return uploadNotificationConfig; + } + + public static boolean uploadFile(Context context, String uploadID, + UploadNotificationConfig uploadNotificationConfig, + String categorySelected, String uploadTitleText, + String uploadDescriptionText, String fileIcon, + String uploaderProfileIndex, Uri fileUri) { + try { + new MultipartUploadRequest(context, uploadID, uploadIndexUrl) + .setUtf8Charset() + .setNotificationConfig(uploadNotificationConfig) + .addParameter("tp-dluploadtitle", uploadTitleText) + .addParameter("tp-dluploadcat", categorySelected) + .addParameter("tp-dluploadtext", uploadDescriptionText) + .addFileToUpload(fileUri.toString() + , "tp-dluploadfile") + .addParameter("tp_dluploadicon", fileIcon) + .addParameter("tp-uploaduser", uploaderProfileIndex) + .setNotificationConfig(uploadNotificationConfig) + .setMaxRetries(2) + .startUpload(); + + Toast.makeText(context, "Uploading files in the background.", Toast.LENGTH_SHORT).show(); + return true; + } catch (Exception exception) { + Timber.e(exception, "AndroidUploadService: %s", exception.getMessage()); + return false; + } + } + + private class CustomTextWatcher implements TextWatcher { + String oldFilename, fileExtension; + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + //Saves an instance of the filename before changing + oldFilename = s.toString(); + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + //Warns user for bad filenames + String filenameWithoutExtension = FileUtils.getFilenameWithoutExtension(s.toString()); + if (filenameWithoutExtension != null && !filenameWithoutExtension.isEmpty() && + !filenameWithoutExtension.matches("[0-9a-zA-Z~!@#$%^&()_+=\\-`\\[\\]{};',.]+")) { + uploadFilenameInfo.setImageResource(R.drawable.ic_info_outline_warning_24dp); + } else { + uploadFilenameInfo.setImageResource(R.drawable.ic_info_outline_white_24dp); + } + + if (fileExtension == null) { + hasModifiedFilename = !s.toString().isEmpty(); + return; + } + + if (!s.toString().endsWith(fileExtension)) { + //User tried to alter the extension + //Prevents the change + uploadFilename.setText(oldFilename); + return; + } + + //User has modified the filename + hasModifiedFilename = true; + if (s.toString().isEmpty() || (filesList.size() == 1 && s.toString().equals(FileUtils. + filenameFromUri(getApplicationContext(), filesList.get(0).getFileUri())))) { + //After modification the filename falls back to the original + hasModifiedFilename = false; + } + + //Adds the grey colored span to the extension + s.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.secondary_text)), + s.length() - fileExtension.length(), s.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + + void setFileExtension(String extension) { + boolean oldHasModifiedFilename = hasModifiedFilename; + oldFilename = uploadFilename.getText().toString(); + fileExtension = extension; + String newFilename; + + if (!oldFilename.isEmpty()) { + newFilename = FileUtils.getFilenameWithoutExtension(oldFilename) + extension; + } else { + newFilename = extension; + } + + uploadFilename.setText(newFilename); + hasModifiedFilename = oldHasModifiedFilename; + } + } + private class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener { private ArrayList parentCategories, childCategories; @@ -574,32 +956,79 @@ public class UploadActivity extends BaseActivity { } } - private void updateUIElements() { - String[] tmpSpinnerArray = new String[uploadRootCategories.size()]; - for (int i = 0; i < uploadRootCategories.size(); ++i) { - tmpSpinnerArray[i] = uploadRootCategories.get(i).getCategoryTitle(); + public static class ZipTask extends AsyncTask { + // Weak references will still allow the Activity to be garbage-collected + private final WeakReference weakActivity; + final String zipFilename, categorySelected, uploadTitleText, uploadDescriptionText, + fileIcon, uploaderProfileIndex; + Uri zipFileUri; + + // Suppresses default constructor + @SuppressWarnings("unused") + private ZipTask() { + weakActivity = null; + this.zipFilename = null; + this.categorySelected = null; + this.uploadTitleText = null; + this.uploadDescriptionText = null; + this.fileIcon = null; + this.uploaderProfileIndex = null; } - ArrayAdapter spinnerArrayAdapter = new ArrayAdapter<>(BaseApplication.getInstance().getApplicationContext(), - R.layout.spinner_item, tmpSpinnerArray); - spinnerArrayAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item); - rootCategorySpinner.setAdapter(spinnerArrayAdapter); + ZipTask(Activity uploadsActivity, @NonNull String zipFilename, + @NonNull String categorySelected, @NonNull String uploadTitleText, + @NonNull String uploadDescriptionText, @NonNull String fileIcon, + @NonNull String uploaderProfileIndex) { + weakActivity = new WeakReference<>(uploadsActivity); + this.zipFilename = zipFilename; + this.categorySelected = categorySelected; + this.uploadTitleText = uploadTitleText; + this.uploadDescriptionText = uploadDescriptionText; + this.fileIcon = fileIcon; + this.uploaderProfileIndex = uploaderProfileIndex; + } - //Sets bundle selection - if (bundleCategory != null) { - int bundleSelectionIndex = -1, currentIndex = 0; + @Override + protected void onPreExecute() { + assert weakActivity != null; + Toast.makeText(weakActivity.get(), "Zipping files", Toast.LENGTH_SHORT).show(); + } - for (UploadCategory category : uploadRootCategories) { - if (bundleCategory.get(0).contains(category.getCategoryTitle())) { - bundleSelectionIndex = currentIndex; - break; - } - ++currentIndex; + @Override + protected Boolean doInBackground(Uri... filesToZip) { + if (weakActivity == null || zipFilename == null) { + return false; } + File zipFile = UploadsHelper.createZipFile(zipFilename); - if (bundleSelectionIndex != -1) { - rootCategorySpinner.setSelection(bundleSelectionIndex, true); - bundleCategory.remove(0); + if (zipFile == null) { + return false; + } + zipFileUri = FileProvider.getUriForFile(weakActivity.get(), + weakActivity.get().getPackageName() + + ".provider", zipFile); + + UploadsHelper.zip(weakActivity.get(), filesToZip, zipFileUri); + return true; + } + + @Override + protected void onPostExecute(Boolean result) { + if (weakActivity == null) { + return; + } + + if (!result) { + Toast.makeText(weakActivity.get(), "Couldn't create zip!", Toast.LENGTH_SHORT).show(); + return; + } + + String uploadID = UUID.randomUUID().toString(); + if (!uploadFile(weakActivity.get(), uploadID, + getConfigForUpload(weakActivity.get(), uploadID, zipFilename), categorySelected, + uploadTitleText, uploadDescriptionText, fileIcon, uploaderProfileIndex, + zipFileUri)) { + Toast.makeText(weakActivity.get(), "Couldn't initiate upload.", Toast.LENGTH_SHORT).show(); } } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java index f9fd9407..e89fda41 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java @@ -3,6 +3,7 @@ package gr.thmmy.mthmmy.activities.upload; import android.app.Activity; import android.content.Intent; import android.os.Bundle; +import androidx.annotation.Nullable; import android.text.Editable; import android.text.TextWatcher; import android.view.View; @@ -12,14 +13,14 @@ import android.widget.RadioGroup; import android.widget.Toast; import java.util.Calendar; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.base.BaseActivity; import timber.log.Timber; -public class UploadFieldsBuilderActivity extends AppCompatActivity { +public class UploadFieldsBuilderActivity extends BaseActivity { static final String BUNDLE_UPLOAD_FIELD_BUILDER_COURSE = "UPLOAD_FIELD_BUILDER_COURSE"; static final String BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER = "UPLOAD_FIELD_BUILDER_SEMESTER"; @@ -28,6 +29,7 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity { static final String RESULT_DESCRIPTION = "RESULT_DESCRIPTION"; private String course, semester; + private boolean isValidYear; private LinearLayout semesterChooserLinear; private RadioGroup typeRadio, semesterRadio; @@ -38,18 +40,17 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { String working = s.toString(); - boolean isValid; if (working.length() == 4) { int currentYear = Calendar.getInstance().get(Calendar.YEAR); int inputYear = Integer.parseInt(working); - isValid = inputYear <= currentYear && inputYear > 2000; + isValidYear = inputYear <= currentYear && inputYear > 1980; } else { - isValid = false; + isValidYear = false; } - if (!isValid) { + if (!isValidYear) { year.setError("Please enter a valid year"); } else { year.setError(null); @@ -86,7 +87,7 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity { } //Initialize toolbar - Toolbar toolbar = findViewById(R.id.toolbar); + toolbar = findViewById(R.id.toolbar); toolbar.setTitle(R.string.upload_fields_builder_toolbar_title); setSupportActionBar(toolbar); if (getSupportActionBar() != null) { @@ -94,6 +95,9 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity { getSupportActionBar().setDisplayShowHomeEnabled(true); } + createDrawer(); + drawer.setSelection(UPLOAD_ID, false); + semesterChooserLinear = findViewById(R.id.upload_fields_builder_choose_semester); semesterRadio = findViewById(R.id.upload_fields_builder_semester_radio_group); semesterRadio.check(Integer.parseInt(semester) % 2 == 0 @@ -121,8 +125,8 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity { } else if (semesterChooserLinear.getVisibility() == View.VISIBLE && semesterId == -1) { Toast.makeText(view.getContext(), "Please choose a semester for the upload", Toast.LENGTH_SHORT).show(); return; - } else if (year.getText().toString().isEmpty()) { - Toast.makeText(view.getContext(), "Please choose a year for the upload", Toast.LENGTH_SHORT).show(); + } else if (year.getText().toString().isEmpty() || !isValidYear) { + Toast.makeText(view.getContext(), "Please choose a valid year for the upload", Toast.LENGTH_SHORT).show(); return; } @@ -212,304 +216,324 @@ public class UploadFieldsBuilderActivity extends AppCompatActivity { return getGreeklishOrMinifiedCourseName(false); } + private String normalizeLatinNumbers(String stringWithLatinNumbers) { + String greekLatinOne = "Ι", englishLatinOne = "I"; + String normalisedString; + + //Separates the latin number suffix from the course name + final String regex = "(.+)\\ ([IΙ]+)"; + final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); + final Matcher matcher = pattern.matcher(stringWithLatinNumbers); + + if (matcher.matches() && matcher.groupCount() == 2) { + normalisedString = matcher.group(1) + " " + matcher.group(2).replaceAll(greekLatinOne, englishLatinOne); + } else { + normalisedString = stringWithLatinNumbers; + } + + return normalisedString; + } @Nullable private String getGreeklishOrMinifiedCourseName(boolean greeklish) { - if (course.contains("Ψηφιακή Επεξεργασία Σήματος")) { + String normalisedCourse = normalizeLatinNumbers(course); + + if (normalisedCourse.contains(("Ψηφιακή Επεξεργασία Σήματος"))) { return greeklish ? "PSES" : "ΨΕΣ"; - } else if (course.contains("Ψηφιακή Επεξεργασία Εικόνας")) { + } else if (normalisedCourse.contains(("Ψηφιακή Επεξεργασία Εικόνας"))) { return greeklish ? "psee" : "ΨΕΕ"; - } else if (course.contains("Ψηφιακές Τηλεπικοινωνίες ΙΙ")) { + } else if (normalisedCourse.contains(("Ψηφιακές Τηλεπικοινωνίες II"))) { return greeklish ? "pshf_thlep_II" : "Ψηφιακές Τηλεπ. 2"; - } else if (course.contains("Ψηφιακές Τηλεπικοινωνίες Ι")) { + } else if (normalisedCourse.contains(("Ψηφιακές Τηλεπικοινωνίες I"))) { return greeklish ? "pshf_thlep_I" : "Ψηφιακές Τηλεπ. 1"; - } else if (course.contains("Ψηφιακά Φίλτρα")) { + } else if (normalisedCourse.contains(("Ψηφιακά Φίλτρα"))) { return greeklish ? "filtra" : "Φίλτρα"; - } else if (course.contains("Ψηφιακά Συστήματα ΙΙΙ")) { + } else if (normalisedCourse.contains(("Ψηφιακά Συστήματα III"))) { return greeklish ? "pshfiaka_III" : "Ψηφιακά 3"; - } else if (course.contains("Ψηφιακά Συστήματα ΙΙ")) { + } else if (normalisedCourse.contains(("Ψηφιακά Συστήματα II"))) { return greeklish ? "pshfiaka_II" : "Ψηφιακά 2"; - } else if (course.contains("Ψηφιακά Συστήματα Ι")) { + } else if (normalisedCourse.contains(("Ψηφιακά Συστήματα I"))) { return greeklish ? "pshfiaka_I" : "Ψηφιακά 1"; - } else if (course.contains("Φωτονική Τεχνολογία")) { + } else if (normalisedCourse.contains(("Φωτονική Τεχνολογία"))) { return greeklish ? "fwtonikh" : "Φωτονική"; - } else if (course.contains("Φυσική Ι")) { + } else if (normalisedCourse.contains(("Φυσική I"))) { return greeklish ? "fysikh_I" : "Φυσική 1"; - } else if (course.contains("Υψηλές Τάσεις ΙΙΙ")) { + } else if (normalisedCourse.contains(("Υψηλές Τάσεις III"))) { return greeklish ? "ypshles_III" : "Υψηλές 3"; - } else if (course.contains("Υψηλές Τάσεις ΙΙ")) { + } else if (normalisedCourse.contains(("Υψηλές Τάσεις II"))) { return greeklish ? "ypshles_II" : "Υψηλές 2"; - } else if (course.contains("Υψηλές Τάσεις Ι")) { + } else if (normalisedCourse.contains(("Υψηλές Τάσεις I"))) { return greeklish ? "ypshles_I" : "Υψηλές 1"; - } else if (course.contains("Υψηλές Τάσεις 4")) { + } else if (normalisedCourse.contains(("Υψηλές Τάσεις 4"))) { return greeklish ? "ypshles_IV" : "Υψηλές 4"; - } else if (course.contains("Υπολογιστικός Ηλεκτρομαγνητισμός")) { + } else if (normalisedCourse.contains(("Υπολογιστικός Ηλεκτρομαγνητισμός"))) { return greeklish ? "ypologistikos_HM" : "Υπολογιστικός Η/Μ"; - } else if (course.contains("Υπολογιστικές Μέθοδοι στα Ενεργειακά Συστήματα")) { + } else if (normalisedCourse.contains(("Υπολογιστικές Μέθοδοι στα Ενεργειακά Συστήματα"))) { return greeklish ? "ymes" : "ΥΜΕΣ"; - } else if (course.contains("Τηλεπικοινωνιακή Ηλεκτρονική")) { + } else if (normalisedCourse.contains(("Τηλεπικοινωνιακή Ηλεκτρονική"))) { return greeklish ? "tilep_ilektr" : "Τηλεπ. Ηλεκτρ."; - } else if (course.contains("Τηλεοπτικά Συστήματα")) { + } else if (normalisedCourse.contains(("Τηλεοπτικά Συστήματα"))) { return greeklish ? "tileoptika" : "Τηλεοπτικά"; - } else if (course.contains("Τεχνολογία Λογισμικού")) { + } else if (normalisedCourse.contains(("Τεχνολογία Λογισμικού"))) { return greeklish ? "SE" : "Τεχνολογία Λογισμικού"; - } else if (course.contains("Τεχνολογία Ηλεκτροτεχνικών Υλικών")) { + } else if (normalisedCourse.contains(("Τεχνολογία Ηλεκτροτεχνικών Υλικών"))) { return greeklish ? "Hlektrotexnika_Ylika" : "Ηλεκτροτεχνικά Υλικά"; - } else if (course.contains("Τεχνολογία Ήχου και Εικόνας")) { + } else if (normalisedCourse.contains(("Τεχνολογία Ήχου και Εικόνας"))) { return greeklish ? "texn_hxoy_eikonas" : "Τεχνολογία Ήχου και Εικόνας"; - } else if (course.contains("Τεχνική Μηχανική")) { + } else if (normalisedCourse.contains(("Τεχνική Μηχανική"))) { return greeklish ? "texn_mhxan" : "Τεχν. Μηχαν."; - } else if (course.contains("Τεχνικές μη Καταστρεπτικών Δοκιμών")) { + } else if (normalisedCourse.contains(("Τεχνικές μη Καταστρεπτικών Δοκιμών"))) { return greeklish ? "non_destructive_tests" : "Μη Καταστρεπτικές Δοκιμές"; - } else if (course.contains("Τεχνικές Σχεδίασης με Η/Υ")) { + } else if (normalisedCourse.contains(("Τεχνικές Σχεδίασης με Η/Υ"))) { return greeklish ? "sxedio" : "Σχέδιο"; - } else if (course.contains("Τεχνικές Κωδικοποίησης")) { + } else if (normalisedCourse.contains(("Τεχνικές Κωδικοποίησης"))) { return greeklish ? "texn_kwdikopoihshs" : "Τεχνικές Κωδικοποίησης"; - } else if (course.contains("Τεχνικές Βελτιστοποίησης")) { + } else if (normalisedCourse.contains(("Τεχνικές Βελτιστοποίησης"))) { return greeklish ? "veltistopoihsh" : "Βελτιστοποίηση"; - } else if (course.contains("Σύνθεση Τηλεπικοινωνιακών Διατάξεων")) { + } else if (normalisedCourse.contains(("Σύνθεση Τηλεπικοινωνιακών Διατάξεων"))) { return greeklish ? "synth_thlep_diataksewn" : "Σύνθεση Τηλεπ. Διατάξεων"; - } else if (course.contains("Σύνθεση Ενεργών και Παθητικών Κυκλωμάτων")) { + } else if (normalisedCourse.contains(("Σύνθεση Ενεργών και Παθητικών Κυκλωμάτων"))) { return greeklish ? "synthesh" : "Σύνθεση"; - } else if (course.contains("Σχεδίαση Συστημάτων VLSI")) { + } else if (normalisedCourse.contains(("Σχεδίαση Συστημάτων VLSI"))) { return greeklish ? "VLSI" : "VLSI"; - } else if (course.contains("Συστήματα Υπολογιστών (Υπολογιστικά Συστήματα)")) { + } else if (normalisedCourse.contains(("Συστήματα Υπολογιστών (Υπολογιστικά Συστήματα)"))) { return greeklish ? "sys_ypologistwn" : "Συσ. Υπολογιστών"; - } else if (course.contains("Συστήματα Πολυμέσων και Εικονική Πραγματικότητα")) { + } else if (normalisedCourse.contains(("Συστήματα Πολυμέσων και Εικονική Πραγματικότητα"))) { return greeklish ? "polymesa" : "Πολυμέσα"; - } else if (course.contains("Συστήματα Μικροϋπολογιστών")) { + } else if (normalisedCourse.contains(("Συστήματα Μικροϋπολογιστών"))) { return greeklish ? "mikro_I" : "Μίκρο 1"; - } else if (course.contains("Συστήματα Ηλεκτροκίνησης")) { + } else if (normalisedCourse.contains(("Συστήματα Ηλεκτροκίνησης"))) { return greeklish ? "hlektrokinhsh" : "Ηλεκτροκίνηση"; - } else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας ΙΙΙ")) { + } else if (normalisedCourse.contains(("Συστήματα Ηλεκτρικής Ενέργειας III"))) { return greeklish ? "SHE_III" : "ΣΗΕ 3"; - } else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας ΙΙ")) { + } else if (normalisedCourse.contains(("Συστήματα Ηλεκτρικής Ενέργειας II"))) { return greeklish ? "SHE_II" : "ΣΗΕ 2"; - } else if (course.contains("Συστήματα Ηλεκτρικής Ενέργειας Ι")) { + } else if (normalisedCourse.contains(("Συστήματα Ηλεκτρικής Ενέργειας I"))) { return greeklish ? "SHE_I" : "ΣΗΕ 1"; - } else if (course.contains("Συστήματα Αυτομάτου Ελέγχου ΙΙI")) { + } else if (normalisedCourse.contains(("Συστήματα Αυτομάτου Ελέγχου III"))) { return greeklish ? "SAE_III" : "ΣΑΕ 3"; - } else if (course.contains("Συστήματα Αυτομάτου Ελέγχου ΙΙ")) { + } else if (normalisedCourse.contains(("Συστήματα Αυτομάτου Ελέγχου II"))) { return greeklish ? "SAE_II" : "ΣΑΕ 2"; - } else if (course.contains("Συστήματα Αυτομάτου Ελέγχου Ι")) { + } else if (normalisedCourse.contains(("Συστήματα Αυτομάτου Ελέγχου I"))) { return greeklish ? "SAE_1" : "ΣΑΕ 1"; - } else if (course.contains("Στοχαστικό Σήμα")) { + } else if (normalisedCourse.contains(("Στοχαστικό Σήμα"))) { return greeklish ? "stox_shma" : "Στοχ. Σήμα"; - } else if (course.contains("Σταθμοί Παραγωγής Ηλεκτρικής Ενέργειας")) { + } else if (normalisedCourse.contains(("Σταθμοί Παραγωγής Ηλεκτρικής Ενέργειας"))) { return greeklish ? "SPHE" : "ΣΠΗΕ"; - } else if (course.contains("Σερβοκινητήρια Συστήματα")) { + } else if (normalisedCourse.contains(("Σερβοκινητήρια Συστήματα"))) { return greeklish ? "servo" : "Σέρβο"; - } else if (course.contains("Σήματα και Συστήματα")) { + } else if (normalisedCourse.contains(("Σήματα και Συστήματα"))) { return greeklish ? "analog_shma" : "Σύματα & Συστήματα"; - } else if (course.contains("Ρομποτική")) { + } else if (normalisedCourse.contains(("Ρομποτική"))) { return greeklish ? "rompotikh" : "Ρομποτική"; - } else if (course.contains("Προσομοίωση και Μοντελοποίηση Συστημάτων")) { + } else if (normalisedCourse.contains(("Προσομοίωση και Μοντελοποίηση Συστημάτων"))) { return greeklish ? "montelopoihsh" : "Μοντελοποίηση"; - } else if (course.contains("Προηγμένες Τεχνικές Επεξεργασίας Σήματος")) { + } else if (normalisedCourse.contains(("Προηγμένες Τεχνικές Επεξεργασίας Σήματος"))) { return greeklish ? "ptes" : "ΠΤΕΣ"; - } else if (course.contains("Προγραμματιστικές Τεχνικές")) { + } else if (normalisedCourse.contains(("Προγραμματιστικές Τεχνικές"))) { return greeklish ? "cpp" : "Προγραμματ. Τεχν."; - } else if (course.contains("Προγραμματιζόμενα Κυκλώματα ASIC")) { + } else if (normalisedCourse.contains(("Προγραμματιζόμενα Κυκλώματα ASIC"))) { return greeklish ? "asic" : "ASIC"; - } else if (course.contains("Παράλληλα και Κατανεμημένα Συστήματα")) { + } else if (normalisedCourse.contains(("Παράλληλα και Κατανεμημένα Συστήματα"))) { return greeklish ? "parallhla" : "Παράλληλα"; - } else if (course.contains("Οργάνωση και Διοίκηση Εργοστασίων")) { + } else if (normalisedCourse.contains(("Οργάνωση και Διοίκηση Εργοστασίων"))) { return greeklish ? "organ_dioik_ergostasiwn" : "Οργάνωση και Διοίκηση Εργοστασίων"; - } else if (course.contains("Οργάνωση Υπολογιστών")) { + } else if (normalisedCourse.contains(("Οργάνωση Υπολογιστών"))) { return greeklish ? "org_ypol" : "Οργάνωση Υπολ."; - } else if (course.contains("Οπτική ΙΙ")) { + } else if (normalisedCourse.contains(("Οπτική II"))) { return greeklish ? "optikh_II" : "Οπτική 2"; - } else if (course.contains("Οπτική Ι")) { + } else if (normalisedCourse.contains(("Οπτική I"))) { return greeklish ? "optikh_I" : "Οπτική 1"; - } else if (course.contains("Οπτικές Επικοινωνίες")) { + } else if (normalisedCourse.contains(("Οπτικές Επικοινωνίες"))) { return greeklish ? "optikes_thlep" : "Οπτικές Τηλεπ."; - } else if (course.contains("Μικροκύματα II")) { + } else if (normalisedCourse.contains(("Μικροκύματα II"))) { return greeklish ? "mikrokymata_II" : "Μικροκύματα 2"; - } else if (course.contains("Μικροκύματα I")) { + } else if (normalisedCourse.contains(("Μικροκύματα I"))) { return greeklish ? "mikrokymata_I" : "Μικροκύματα 1"; - } else if (course.contains("Μικροκυματική Τηλεπισκόπηση")) { + } else if (normalisedCourse.contains(("Μικροκυματική Τηλεπισκόπηση"))) { return greeklish ? "thlepiskophsh" : "Τηλεπισκόπηση"; - } else if (course.contains("Μικροεπεξεργαστές και Περιφερειακά")) { + } else if (normalisedCourse.contains(("Μικροεπεξεργαστές και Περιφερειακά"))) { return greeklish ? "mikro_II" : "Μίκρο 2"; - } else if (course.contains("Μετάδοση Θερμότητας")) { + } else if (normalisedCourse.contains(("Μετάδοση Θερμότητας"))) { return greeklish ? "metadosi_therm" : "Μετάδοση Θερμ."; - } else if (course.contains("Λογισμός ΙΙ")) { + } else if (normalisedCourse.contains(("Λογισμός II"))) { return greeklish ? "logismos_II" : "Λογισμός 2"; - } else if (course.contains("Λογισμός Ι")) { + } else if (normalisedCourse.contains(("Λογισμός I"))) { return greeklish ? "logismos_I" : "Λογισμός 1"; - } else if (course.contains("Λογική Σχεδίαση")) { + } else if (normalisedCourse.contains(("Λογική Σχεδίαση"))) { return greeklish ? "logiki_sxediash" : "Λογική Σχεδίαση"; - } else if (course.contains("Λειτουργικά Συστήματα")) { + } else if (normalisedCourse.contains(("Λειτουργικά Συστήματα"))) { return greeklish ? "OS" : "Λειτουργικά"; - } else if (course.contains("Κινητές και Δορυφορικές Επικοινωνίες")) { + } else if (normalisedCourse.contains(("Κινητές και Δορυφορικές Επικοινωνίες"))) { return greeklish ? "kinhtes_doryforikes_epik" : "Κινητές & Δορυφορικές Επικοινωνίες"; - } else if (course.contains("Κβαντική Φυσική")) { + } else if (normalisedCourse.contains(("Κβαντική Φυσική"))) { return greeklish ? "kvantikh" : "Κβαντική"; - } else if (course.contains("Θεωρία και Τεχνολογία Πυρηνικών Αντιδραστήρων")) { + } else if (normalisedCourse.contains(("Θεωρία και Τεχνολογία Πυρηνικών Αντιδραστήρων"))) { return greeklish ? "texn_antidrasthrwn" : "Τεχνολογία Αντιδραστήρων"; - } else if (course.contains("Θεωρία Υπολογισμών και Αλγορίθμων")) { + } else if (normalisedCourse.contains(("Θεωρία Υπολογισμών και Αλγορίθμων"))) { return greeklish ? "thya" : "ΘΥΑ"; - } else if (course.contains("Θεωρία Σκέδασης")) { + } else if (normalisedCourse.contains(("Θεωρία Σκέδασης"))) { return greeklish ? "skedash" : "Σκέδαση"; - } else if (course.contains("Θεωρία Σημάτων και Γραμμικών Συστημάτων")) { + } else if (normalisedCourse.contains(("Θεωρία Σημάτων και Γραμμικών Συστημάτων"))) { return greeklish ? "analog_shma" : "Σύματα & Συστήματα"; - } else if (course.contains("Θεωρία Πληροφοριών")) { + } else if (normalisedCourse.contains(("Θεωρία Πληροφοριών"))) { return greeklish ? "theoria_plir" : "Θεωρία Πληρ."; - } else if (course.contains("Θεωρία Πιθανοτήτων και Στατιστική")) { + } else if (normalisedCourse.contains(("Θεωρία Πιθανοτήτων και Στατιστική"))) { return greeklish ? "pithanothtes" : "Πιθανότητες"; - } else if (course.contains("Ημιαγωγά Υλικά: Θεωρία-Διατάξεις")) { + } else if (normalisedCourse.contains(("Ημιαγωγά Υλικά: Θεωρία-Διατάξεις"))) { return greeklish ? "Hmiagwga_Ylika" : "Ημιαγωγά Υλικά"; - } else if (course.contains("Ηλεκτρονική ΙΙΙ")) { + } else if (normalisedCourse.contains(("Ηλεκτρονική III"))) { return greeklish ? "hlektronikh_III" : "Ηλεκτρονική 3"; - } else if (course.contains("Ηλεκτρονική ΙΙ")) { + } else if (normalisedCourse.contains(("Ηλεκτρονική II"))) { return greeklish ? "hlektronikh_2" : "Ηλεκτρονική 2"; - } else if (course.contains("Ηλεκτρονική Ι")) { + } else if (normalisedCourse.contains(("Ηλεκτρονική I"))) { return greeklish ? "hlektronikh_1" : "Ηλεκτρονική 1"; - } else if (course.contains("Ηλεκτρονικές Διατάξεις και Μετρήσεις")) { + } else if (normalisedCourse.contains(("Ηλεκτρονικές Διατάξεις και Μετρήσεις"))) { return greeklish ? "hlektron_diatakseis_metrhseis" : "Ηλεκτρονικές Διατάξεις και Μετρήσεις"; - } else if (course.contains("Ηλεκτρονικά Ισχύος ΙΙ")) { + } else if (normalisedCourse.contains(("Ηλεκτρονικά Iσχύος II"))) { return greeklish ? "isxyos_II" : "Ισχύος 2"; - } else if (course.contains("Ηλεκτρονικά Ισχύος Ι")) { + } else if (normalisedCourse.contains(("Ηλεκτρονικά Iσχύος I"))) { return greeklish ? "isxyos_I" : "Ισχύος 1"; - } else if (course.contains("Ηλεκτρομαγνητικό Πεδίο ΙΙ")) { + } else if (normalisedCourse.contains(("Ηλεκτρομαγνητικό Πεδίο II"))) { return greeklish ? "pedio_II" : "Πεδίο 2"; - } else if (course.contains("Ηλεκτρομαγνητικό Πεδίο Ι")) { + } else if (normalisedCourse.contains(("Ηλεκτρομαγνητικό Πεδίο I"))) { return greeklish ? "pedio_I" : "Πεδίο 1"; - } else if (course.contains("Ηλεκτρομαγνητική Συμβατότητα")) { + } else if (normalisedCourse.contains(("Ηλεκτρομαγνητική Συμβατότητα"))) { return greeklish ? "HM_symvatothta" : "H/M Συμβατότητα"; - } else if (course.contains("Ηλεκτρολογικά Υλικά")) { + } else if (normalisedCourse.contains(("Ηλεκτρολογικά Υλικά"))) { return greeklish ? "ylika" : "Ηλεκτρ. Υλικά"; - } else if (course.contains("Ηλεκτρική Οικονομία")) { + } else if (normalisedCourse.contains(("Ηλεκτρική Οικονομία"))) { return greeklish ? "hlektr_oikonomia" : "Ηλεκτρική Οικονομία"; - } else if (course.contains("Ηλεκτρικές Μηχανές Γ'")) { + } else if (normalisedCourse.contains(("Ηλεκτρικές Μηχανές Γ'"))) { return greeklish ? "mhxanes_C" : "Μηχανές Γ"; - } else if (course.contains("Ηλεκτρικές Μηχανές Β'")) { + } else if (normalisedCourse.contains(("Ηλεκτρικές Μηχανές Β'"))) { return greeklish ? "mhxanes_B" : "Μηχανές Β"; - } else if (course.contains("Ηλεκτρικές Μηχανές Α'")) { + } else if (normalisedCourse.contains(("Ηλεκτρικές Μηχανές Α'"))) { return greeklish ? "mhxanes_A" : "Μηχανές Α"; - } else if (course.contains("Ηλεκτρικές Μετρήσεις ΙΙ")) { + } else if (normalisedCourse.contains(("Ηλεκτρικές Μετρήσεις II"))) { return greeklish ? "metrhseis_II" : "Μετρήσεις 2"; - } else if (course.contains("Ηλεκτρικές Μετρήσεις Ι")) { + } else if (normalisedCourse.contains(("Ηλεκτρικές Μετρήσεις I"))) { return greeklish ? "metrhseis_1" : "Μετρήσεις 1"; - } else if (course.contains("Ηλεκτρικά Κυκλώματα ΙΙΙ")) { + } else if (normalisedCourse.contains(("Ηλεκτρικά Κυκλώματα III"))) { return greeklish ? "kyklwmata_I" : "Κυκλώματα 3"; - } else if (course.contains("Ηλεκτρικά Κυκλώματα ΙΙ")) { + } else if (normalisedCourse.contains(("Ηλεκτρικά Κυκλώματα II"))) { return greeklish ? "kyklwmata_II" : "Κυκλώματα 2"; - } else if (course.contains("Ηλεκτρικά Κυκλώματα Ι")) { + } else if (normalisedCourse.contains(("Ηλεκτρικά Κυκλώματα I"))) { return greeklish ? "kyklwmata_I" : "Κυκλώματα 1"; - } else if (course.contains("Ηλεκτρακουστική ΙΙ")) { + } else if (normalisedCourse.contains(("Ηλεκτρακουστική II"))) { return greeklish ? "hlektroakoystikh_II" : "Ηλεκτροακουστική 2"; - } else if (course.contains("Ηλεκτρακουστική Ι")) { + } else if (normalisedCourse.contains(("Ηλεκτρακουστική I"))) { return greeklish ? "hlektroakoystikh_I" : "Ηλεκτροακουστική 1"; - } else if (course.contains("Εφαρμοσμένη Θερμοδυναμική")) { + } else if (normalisedCourse.contains(("Εφαρμοσμένη Θερμοδυναμική"))) { return greeklish ? "thermodynamikh" : "Θερμοδυναμική"; - } else if (course.contains("Εφαρμοσμένα Μαθηματικά ΙΙ")) { + } else if (normalisedCourse.contains(("Εφαρμοσμένα Μαθηματικά II"))) { return greeklish ? "efarmosmena_math_II" : "Εφαρμοσμένα 2"; - } else if (course.contains("Εφαρμοσμένα Μαθηματικά Ι")) { + } else if (normalisedCourse.contains(("Εφαρμοσμένα Μαθηματικά I"))) { return greeklish ? "efarmosmena_math_I" : "Εφαρμοσμένα 1"; - } else if (course.contains("Εφαρμογές Τηλεπικοινωνιακών Διατάξεων")) { + } else if (normalisedCourse.contains(("Εφαρμογές Τηλεπικοινωνιακών Διατάξεων"))) { return greeklish ? "efarm_thlep_diataksewn" : "Εφαρμογές Τηλεπ. Διατάξεων"; - } else if (course.contains("Ευφυή Συστήματα Ρομπότ")) { + } else if (normalisedCourse.contains(("Ευφυή Συστήματα Ρομπότ"))) { return greeklish ? "eufuh" : "Ευφυή"; - } else if (course.contains("Ευρυζωνικά Δίκτυα")) { + } else if (normalisedCourse.contains(("Ευρυζωνικά Δίκτυα"))) { return greeklish ? "eyryzwnika" : "Ευρυζωνικά"; - } else if (course.contains("Επιχειρησιακή Έρευνα")) { + } else if (normalisedCourse.contains(("Επιχειρησιακή Έρευνα"))) { return greeklish ? "epixeirisiaki" : "Επιχειρησιακή Έρευνα"; - } else if (course.contains("Ενσωματωμένα Συστήματα Πραγματικού Χρόνου")) { + } else if (normalisedCourse.contains(("Ενσωματωμένα Συστήματα Πραγματικού Χρόνου"))) { return greeklish ? "enswmatwmena" : "Ενσωματωμένα"; - } else if (course.contains("Εισαγωγή στις εφαρμογές Πυρηνικής Τεχνολογίας")) { + } else if (normalisedCourse.contains(("Εισαγωγή στις εφαρμογές Πυρηνικής Τεχνολογίας"))) { return greeklish ? "Intro_Purhnikh_Texn" : "Εισ. Πυρηνικη Τεχν."; - } else if (course.contains("Εισαγωγή στην Πολιτική Οικονομία")) { + } else if (normalisedCourse.contains(("Εισαγωγή στην Πολιτική Οικονομία"))) { return greeklish ? "polit_oik" : "Πολιτική Οικονομία"; - } else if (course.contains("Εισαγωγή στην Ενεργειακή Τεχνολογία ΙΙ")) { + } else if (normalisedCourse.contains(("Εισαγωγή στην Ενεργειακή Τεχνολογία II"))) { return greeklish ? "EET_2" : "ΕΕΤ2"; - } else if (course.contains("Εισαγωγή στην Ενεργειακή Τεχνολογία Ι")) { + } else if (normalisedCourse.contains(("Εισαγωγή στην Ενεργειακή Τεχνολογία I"))) { return greeklish ? "EET_I" : "ΕΕΤ 1"; - } else if (course.contains("Ειδικές Κεραίες, Σύνθεση Κεραιών")) { + } else if (normalisedCourse.contains(("Ειδικές Κεραίες, Σύνθεση Κεραιών"))) { return greeklish ? "eidikes_keraies" : "Ειδικές Κεραίες, Σύνθεση Κεραιών"; - } else if (course.contains("Ειδικές Αρχιτεκτονικές Υπολογιστών")) { + } else if (normalisedCourse.contains(("Ειδικές Αρχιτεκτονικές Υπολογιστών"))) { return greeklish ? "eidikes_arx_ypolog" : "Ειδικές Αρχιτεκτονικές Υπολογιστών"; - } else if (course.contains("Ειδικά Κεφάλαια Συστημάτων Ηλεκτρικής Ενέργειας")) { + } else if (normalisedCourse.contains(("Ειδικά Κεφάλαια Συστημάτων Ηλεκτρικής Ενέργειας"))) { return greeklish ? "ekshe" : "ΕΚΣΗΕ"; - } else if (course.contains("Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου Ι")) { - return greeklish ? "eidika_kef_HM_pedioy_I" : "Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου Ι"; - } else if (course.contains("Ειδικά Κεφάλαια Διαφορικών Εξισώσεων")) { + } else if (normalisedCourse.contains(("Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I"))) { + return greeklish ? "eidika_kef_HM_pedioy_I" : "Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I"; + } else if (normalisedCourse.contains(("Ειδικά Κεφάλαια Διαφορικών Εξισώσεων"))) { return greeklish ? "eidika_kef_diaf_eksis" : "Ειδικά Κεφάλαια Διαφορικών Εξισώσεων"; - } else if (course.contains("Δομημένος Προγραμματισμός")) { + } else if (normalisedCourse.contains(("Δομημένος Προγραμματισμός"))) { return greeklish ? "C" : "Δομ. Προγραμμ."; - } else if (course.contains("Δομές Δεδομένων")) { + } else if (normalisedCourse.contains(("Δομές Δεδομένων"))) { return greeklish ? "dom_dedomenwn" : "Δομ. Δεδομ."; - } else if (course.contains("Διαχείριση Συστημάτων Ηλεκτρικής Ενέργειας")) { + } else if (normalisedCourse.contains(("Διαχείριση Συστημάτων Ηλεκτρικής Ενέργειας"))) { return greeklish ? "dshe" : "ΔΣΗΕ"; - } else if (course.contains("Διαφορικές Εξισώσεις")) { + } else if (normalisedCourse.contains(("Διαφορικές Εξισώσεις"))) { return greeklish ? "diaforikes" : "Διαφορικές"; - } else if (course.contains("Διανεμημένη Παραγωγή")) { + } else if (normalisedCourse.contains(("Διανεμημένη Παραγωγή"))) { return greeklish ? "dian_paragwgh" : "Διανεμημένη Παραγωγή"; - } else if (course.contains("Διακριτά μαθηματικά")) { + } else if (normalisedCourse.contains(("Διακριτά μαθηματικά"))) { return greeklish ? "diakrita" : "Διακριτά Μαθηματικά"; - } else if (course.contains("Διακριτά Μαθηματικά")) { + } else if (normalisedCourse.contains(("Διακριτά Μαθηματικά"))) { return greeklish ? "diakrita" : "Διακριτά Μαθηματικά"; - } else if (course.contains("Διάδοση Ηλεκτρομαγνητικού Κύματος Ι (πρώην Πεδίο ΙΙΙ)")) { + } else if (normalisedCourse.contains(("Διάδοση Ηλεκτρομαγνητικού Κύματος I (πρώην Πεδίο III)"))) { return greeklish ? "diadosi_1" : "Διάδοση 1"; - } else if (course.contains("Διάδοση Η/Μ Κύματος ΙΙ")) { + } else if (normalisedCourse.contains(("Διάδοση Η/Μ Κύματος II"))) { return greeklish ? "diadosi_II" : "Διάδοση 2"; - } else if (course.contains("Δίκτυα Υπολογιστών ΙΙ")) { + } else if (normalisedCourse.contains(("Δίκτυα Υπολογιστών II"))) { return greeklish ? "diktya_II" : "Δίκτυα 2"; - } else if (course.contains("Δίκτυα Υπολογιστών Ι")) { + } else if (normalisedCourse.contains(("Δίκτυα Υπολογιστών I"))) { return greeklish ? "diktya_I" : "Δίκτυα 1"; - } else if (course.contains("Δίκτυα Τηλεπικοινωνιών")) { + } else if (normalisedCourse.contains(("Δίκτυα Τηλεπικοινωνιών"))) { return greeklish ? "diktya_thlep" : "Δίκτυα Τηλέπ."; - } else if (course.contains("Γραφική με Υπολογιστές")) { + } else if (normalisedCourse.contains(("Γραφική με Υπολογιστές"))) { return greeklish ? "grafikh" : "Γραφική"; - } else if (course.contains("Γραμμική Άλγεβρα")) { + } else if (normalisedCourse.contains(("Γραμμική Άλγεβρα"))) { return greeklish ? "grammikh_algebra" : "Γραμμ. Άλγεβρ."; - } else if (course.contains("Γεωηλεκτρομαγνητισμός")) { + } else if (normalisedCourse.contains(("Γεωηλεκτρομαγνητισμός"))) { return greeklish ? "geohlektromagnitismos" : "Γεωηλεκτρομαγνητισμός"; - } else if (course.contains("Βιοϊατρική Τεχνολογία")) { + } else if (normalisedCourse.contains(("Βιοϊατρική Τεχνολογία"))) { return greeklish ? "vioiatriki" : "Βιοιατρική"; - } else if (course.contains("Βιομηχανική Πληροφορική")) { + } else if (normalisedCourse.contains(("Βιομηχανική Πληροφορική"))) { return greeklish ? "viomix_plir" : "Βιομηχανική Πληρ"; - } else if (course.contains("Βιομηχανικά Ηλεκτρονικά")) { + } else if (normalisedCourse.contains(("Βιομηχανικά Ηλεκτρονικά"))) { return greeklish ? "bhomix_hlektronika" : "Βιομηχανικά Ηλεκτρονικά"; - } else if (course.contains("Βάσεις Δεδομένων")) { + } else if (normalisedCourse.contains(("Βάσεις Δεδομένων"))) { return greeklish ? "vaseis" : "Βάσεις"; - } else if (course.contains("Ασύρματος Τηλεπικοινωνία ΙΙ")) { + } else if (normalisedCourse.contains(("Ασύρματος Τηλεπικοινωνία II"))) { return greeklish ? "asyrmatos_II" : "Ασύρματος 2"; - } else if (course.contains("Ασύρματος Τηλεπικοινωνία Ι")) { + } else if (normalisedCourse.contains(("Ασύρματος Τηλεπικοινωνία I"))) { return greeklish ? "asyrmatos_I" : "Ασύρματος 1"; - } else if (course.contains("Ασφάλεια Πληροφοριακών Συστημάτων")) { + } else if (normalisedCourse.contains(("Ασφάλεια Πληροφοριακών Συστημάτων"))) { return greeklish ? "asfaleia" : "Ασφάλεια"; - } else if (course.contains("Ασαφή Συστήματα")) { + } else if (normalisedCourse.contains(("Ασαφή Συστήματα"))) { return greeklish ? "asafh" : "Ασαφή"; - } else if (course.contains("Αρχιτεκτονική Υπολογιστών")) { + } else if (normalisedCourse.contains(("Αρχιτεκτονική Υπολογιστών"))) { return greeklish ? "arx_ypologistwn" : "Αρχ. Υπολογιστών"; - } else if (course.contains("Αρχές Παράλληλης Επεξεργασίας")) { + } else if (normalisedCourse.contains(("Αρχές Παράλληλης Επεξεργασίας"))) { return greeklish ? "arxes_parall_epeksergasias" : "Αρχές Παράλληλης Επεξεργασίας"; - } else if (course.contains("Αρχές Οικονομίας")) { + } else if (normalisedCourse.contains(("Αρχές Οικονομίας"))) { return greeklish ? "arx_oikonomias" : "Αρχές Οικονομίας"; - } else if (course.contains("Αριθμητική Ανάλυση")) { + } else if (normalisedCourse.contains(("Αριθμητική Ανάλυση"))) { return greeklish ? "arith_anal" : "Αριθμ. Ανάλυση"; - } else if (course.contains("Αξιοπιστία Συστημάτων")) { + } else if (normalisedCourse.contains(("Αξιοπιστία Συστημάτων"))) { return greeklish ? "aksiopistia_systhmatwn" : "Αξιοπιστία Συστημάτων"; - } else if (course.contains("Αντικειμενοστραφής Προγραμματισμός")) { + } else if (normalisedCourse.contains(("Αντικειμενοστραφής Προγραμματισμός"))) { return greeklish ? "OOP" : "Αντικειμενοστραφής"; - } else if (course.contains("Αναλογικές Τηλεπικοινωνίες (πρώην Τηλεπικοινωνιακά Συστήματα Ι)")) { + } else if (normalisedCourse.contains(("Αναλογικές Τηλεπικοινωνίες (πρώην Τηλεπικοινωνιακά Συστήματα I)"))) { return greeklish ? "anal_thlep" : "Αναλογικές Τηλεπ."; - } else if (course.contains("Αναγνώριση Προτύπων")) { + } else if (normalisedCourse.contains(("Αναγνώριση Προτύπων"))) { return greeklish ? "protipa" : "Αναγνώριση Προτύπων"; - } else if (course.contains("Ανάλυση και Σχεδίαση Αλγορίθμων")) { + } else if (normalisedCourse.contains(("Ανάλυση και Σχεδίαση Αλγορίθμων"))) { return greeklish ? "algorithms" : "Αλγόριθμοι"; - } else if (course.contains("Ανάλυση Χρονοσειρών")) { + } else if (normalisedCourse.contains(("Ανάλυση Χρονοσειρών"))) { return greeklish ? "xronoseires" : "Χρονοσειρές"; - } else if (course.contains("Ανάλυση Συστημάτων Ηλεκτρικής Ενέργειας")) { + } else if (normalisedCourse.contains(("Ανάλυση Συστημάτων Ηλεκτρικής Ενέργειας"))) { return greeklish ? "ASHE" : "ΑΣΗΕ"; - } else if (course.contains("Ανάλυση Ηλεκτρικών Κυκλωμάτων με Υπολογιστή")) { + } else if (normalisedCourse.contains(("Ανάλυση Ηλεκτρικών Κυκλωμάτων με Υπολογιστή"))) { return greeklish ? "analysh_hlektr_kykl" : "Ανάλυση Ηλεκτρικ. Κυκλ. με Υπολογιστή"; - } else if (course.contains("Ακουστική ΙΙ")) { + } else if (normalisedCourse.contains(("Ακουστική II"))) { return greeklish ? "akoystikh_II" : "Ακουστική 2"; - } else if (course.contains("Ακουστική Ι")) { + } else if (normalisedCourse.contains(("Ακουστική I"))) { return greeklish ? "akoystikh_I" : "Ακουστική 1"; } else { + Timber.wtf("Unrecognised course came in the upload fields generator! Course string = %s", course); return null; } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java index e5f5301b..1bb45c84 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java @@ -1,64 +1,44 @@ package gr.thmmy.mthmmy.activities.upload; import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Matrix; -import android.media.ExifInterface; import android.net.Uri; import android.os.Environment; -import android.provider.OpenableColumns; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.FileProvider; + +import android.util.Log; import android.widget.Toast; +import com.snatik.storage.Storage; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +import gr.thmmy.mthmmy.utils.FileUtils; import timber.log.Timber; -class UploadsHelper { - private static final int DEFAULT_MIN_WIDTH_QUALITY = 400; - private static final String CACHE_IMAGE_NAME = "tempUploadFile.jpg"; - - @NonNull - static String filenameFromUri(Context context, Uri uri) { - String filename = null; - if (uri.getScheme().equals("content")) { - try (Cursor cursor = context.getContentResolver().query(uri, null, null, null, null)) { - if (cursor != null && cursor.moveToFirst()) { - filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); - } - } - } - if (filename == null) { - filename = uri.getPath(); - int cut = filename.lastIndexOf('/'); - if (cut != -1) { - filename = filename.substring(cut + 1); - } - } - - return filename; - } +public class UploadsHelper { + private final static int BUFFER = 4096; + private static final String TEMP_FILES_DIRECTORY = "~tmp_mThmmy_uploads"; @SuppressWarnings("ResultOfMethodCallIgnored") @Nullable - static String createTempFile(Context context, Uri fileUri, String newFilename) { - String oldFilename = filenameFromUri(context, fileUri); + static Uri createTempFile(Context context, Storage storage, Uri fileUri, String newFilename) { + String oldFilename = FileUtils.filenameFromUri(context, fileUri); String fileExtension = oldFilename.substring(oldFilename.indexOf(".")); String destinationFilename = Environment.getExternalStorageDirectory().getPath() + - File.separatorChar + "~tmp_mThmmy_uploads" + File.separatorChar + newFilename + fileExtension; + File.separatorChar + TEMP_FILES_DIRECTORY + File.separatorChar + newFilename + fileExtension; File tempDirectory = new File(android.os.Environment.getExternalStorageDirectory().getPath() + - File.separatorChar + "~tmp_mThmmy_uploads"); + File.separatorChar + TEMP_FILES_DIRECTORY); if (!tempDirectory.exists()) { if (!tempDirectory.mkdirs()) { @@ -97,103 +77,65 @@ class UploadsHelper { } } - return destinationFilename; - } + return FileProvider.getUriForFile(context, context.getPackageName() + + ".provider", storage.getFile(destinationFilename)); - static File getCacheFile(Context context) { - File imageFile = new File(context.getExternalCacheDir(), CACHE_IMAGE_NAME); - //noinspection ResultOfMethodCallIgnored - imageFile.getParentFile().mkdirs(); - return imageFile; } - @SuppressWarnings("ResultOfMethodCallIgnored") - static void deleteTempFiles() { - 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(); + @Nullable + public static File createZipFile(@NonNull String zipFilename) { + // Create a zip file name + File zipFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + + File.separator + "mThmmy"); + + if (!zipFolder.exists()) { + if (!zipFolder.mkdirs()) { + Timber.w("Zip folder build returned false in %s", UploadsHelper.class.getSimpleName()); + return null; } - 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(); - } - } - - /** - * Resize to avoid using too much memory loading big images (e.g.: 2560*1920) - **/ - static Bitmap getImageResized(Context context, Uri selectedImage) { - Bitmap bm; - int[] sampleSizes = new int[]{5, 3, 2, 1}; - int i = 0; - do { - bm = decodeBitmap(context, selectedImage, sampleSizes[i]); - i++; - } while (bm.getWidth() < DEFAULT_MIN_WIDTH_QUALITY && i < sampleSizes.length); - return bm; - } - - private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = sampleSize; - - AssetFileDescriptor fileDescriptor = null; - try { - fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r"); - } catch (FileNotFoundException e) { - e.printStackTrace(); } - assert fileDescriptor != null; - return BitmapFactory.decodeFileDescriptor( - fileDescriptor.getFileDescriptor(), null, options); + return new File(zipFolder, zipFilename); } - static int getRotation(Context context, Uri imageUri) { - int rotation = 0; + public static void zip(Context context, Uri[] files, Uri zipFile) { try { - - context.getContentResolver().notifyChange(imageUri, null); - ExifInterface exif = new ExifInterface(imageUri.getPath()); - int orientation = exif.getAttributeInt( - ExifInterface.TAG_ORIENTATION, - ExifInterface.ORIENTATION_NORMAL); - - switch (orientation) { - case ExifInterface.ORIENTATION_ROTATE_270: - rotation = 270; - break; - case ExifInterface.ORIENTATION_ROTATE_180: - rotation = 180; - break; - case ExifInterface.ORIENTATION_ROTATE_90: - rotation = 90; - break; + BufferedInputStream origin; + OutputStream dest = context.getContentResolver().openOutputStream(zipFile); + assert dest != null; + ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); + byte data[] = new byte[BUFFER]; + + for (Uri file : files) { + InputStream inputStream = context.getContentResolver().openInputStream(file); + assert inputStream != null; + origin = new BufferedInputStream(inputStream, BUFFER); + + ZipEntry entry = new ZipEntry(FileUtils.filenameFromUri(context, file)); + out.putNextEntry(entry); + int count; + + while ((count = origin.read(data, 0, BUFFER)) != -1) { + out.write(data, 0, count); + } + origin.close(); } + + out.close(); } catch (Exception e) { e.printStackTrace(); } - return rotation; } - static Bitmap rotate(Bitmap bm, int rotation) { - if (rotation != 0) { - Matrix matrix = new Matrix(); - matrix.postRotate(rotation); - return Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); + public static void deleteTempFiles(Storage storage) { + File tempFilesDirectory = new File(Environment.getExternalStorageDirectory().getPath() + + File.separatorChar + TEMP_FILES_DIRECTORY); + + if (storage.isDirectoryExists(tempFilesDirectory.getAbsolutePath())) { + for (File tempFile : storage.getFiles(tempFilesDirectory.getAbsolutePath())) { + storage.deleteFile(tempFile.getAbsolutePath()); + } + storage.deleteDirectory(tempFilesDirectory.getAbsolutePath()); } - return bm; } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index d8019545..0671b7e3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -2,21 +2,34 @@ package gr.thmmy.mthmmy.base; import android.Manifest; import android.app.ProgressDialog; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ImageButton; +import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; +import androidx.lifecycle.ViewModelProviders; +import androidx.preference.PreferenceManager; + import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.firebase.messaging.FirebaseMessaging; import com.mikepenz.fontawesome_typeface_library.FontAwesome; @@ -28,6 +41,9 @@ import com.mikepenz.materialdrawer.Drawer; import com.mikepenz.materialdrawer.DrawerBuilder; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem; +import com.snatik.storage.Storage; + +import net.gotev.uploadservice.UploadService; import java.io.BufferedReader; import java.io.File; @@ -35,14 +51,6 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; -import androidx.core.content.ContextCompat; -import androidx.core.content.FileProvider; -import androidx.lifecycle.ViewModelProviders; -import androidx.preference.PreferenceManager; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.AboutActivity; import gr.thmmy.mthmmy.activities.LoginActivity; @@ -52,12 +60,15 @@ import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.settings.SettingsActivity; import gr.thmmy.mthmmy.activities.shoutbox.ShoutboxActivity; +import gr.thmmy.mthmmy.activities.upload.UploadActivity; import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.model.ThmmyFile; import gr.thmmy.mthmmy.services.DownloadHelper; +import gr.thmmy.mthmmy.services.UploadsReceiver; import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.utils.FileUtils; import gr.thmmy.mthmmy.viewmodel.BaseViewModel; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import okhttp3.OkHttpClient; import ru.noties.markwon.LinkResolverDef; import ru.noties.markwon.Markwon; @@ -72,6 +83,7 @@ import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_ import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DEFAULT_HOME_TAB; import static gr.thmmy.mthmmy.services.DownloadHelper.SAVE_DIR; +import static gr.thmmy.mthmmy.services.UploadsReceiver.UPLOAD_ID_KEY; import static gr.thmmy.mthmmy.session.SessionManager.SUCCESS; import static gr.thmmy.mthmmy.utils.FileUtils.getMimeType; @@ -82,6 +94,9 @@ public abstract class BaseActivity extends AppCompatActivity { //SessionManager protected static SessionManager sessionManager; + //Storage manager + protected Storage storage; + //Bookmarks public static final String BOOKMARKS_SHARED_PREFS = "bookmarksSharedPrefs"; public static final String BOOKMARKED_TOPICS_KEY = "bookmarkedTopicsKey"; @@ -96,6 +111,9 @@ public abstract class BaseActivity extends AppCompatActivity { //Common UI elements protected Toolbar toolbar; protected Drawer drawer; + //Uploads progress dialog + UploadsShowDialogReceiver uploadsShowDialogReceiver; + AlertDialog uploadsProgressDialog; private MainActivity mainActivity; private boolean isMainActivity; @@ -123,16 +141,25 @@ public abstract class BaseActivity extends AppCompatActivity { BaseViewModel baseViewModel = ViewModelProviders.of(this).get(BaseViewModel.class); baseViewModel.getCurrentPageBookmark().observe(this, thisPageBookmark -> setTopicBookmark(thisPageBookmarkMenuButton)); + + storage = new Storage(getApplicationContext()); } @Override protected void onResume() { super.onResume(); updateDrawer(); - if (!sharedPreferences.getBoolean(getString(R.string.user_consent_shared_preference_key), false) && !isUserConsentDialogShown){ - isUserConsentDialogShown=true; + if (!sharedPreferences.getBoolean(getString(R.string.user_consent_shared_preference_key), false) && !isUserConsentDialogShown) { + isUserConsentDialogShown = true; showUserConsentDialog(); } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + if (uploadsShowDialogReceiver == null) { + uploadsShowDialogReceiver = new UploadsShowDialogReceiver(this); + } + this.registerReceiver(uploadsShowDialogReceiver, new IntentFilter(UploadsReceiver.ACTION_COMBINED_UPLOAD)); + } } @Override @@ -140,6 +167,10 @@ public abstract class BaseActivity extends AppCompatActivity { super.onPause(); if (drawer != null) //close drawer animation after returning to activity drawer.closeDrawer(); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && uploadsShowDialogReceiver != null) { + this.unregisterReceiver(uploadsShowDialogReceiver); + } } @@ -151,6 +182,10 @@ public abstract class BaseActivity extends AppCompatActivity { return sessionManager; } + public Storage getStorage() { + return storage; + } + //TODO: move stuff below (?) //------------------------------------------DRAWER STUFF---------------------------------------- protected static final int HOME_ID = 0; @@ -254,14 +289,15 @@ public abstract class BaseActivity extends AppCompatActivity { .withName(R.string.downloads) .withIcon(downloadsIcon) .withSelectedIcon(downloadsIconSelected); -// uploadItem = new PrimaryDrawerItem() -// .withTextColor(primaryColor) -// .withSelectedColor(selectedPrimaryColor) -// .withSelectedTextColor(selectedSecondaryColor) -// .withIdentifier(UPLOAD_ID) -// .withName(R.string.upload) -// .withIcon(uploadIcon) -// .withSelectedIcon(uploadIconSelected); + + uploadItem = new PrimaryDrawerItem() + .withTextColor(primaryColor) + .withSelectedColor(selectedPrimaryColor) + .withSelectedTextColor(selectedSecondaryColor) + .withIdentifier(UPLOAD_ID) + .withName(R.string.upload) + .withIcon(uploadIcon) + .withSelectedIcon(uploadIconSelected); shoutboxItem = new PrimaryDrawerItem() .withTextColor(primaryColor) @@ -377,11 +413,11 @@ public abstract class BaseActivity extends AppCompatActivity { intent.putExtras(extras); startActivity(intent); } -// } else if (drawerItem.equals(UPLOAD_ID)) { -// if (!(BaseActivity.this instanceof UploadActivity)) { -// Intent intent = new Intent(BaseActivity.this, UploadActivity.class); -// startActivity(intent); -// } + } else if (drawerItem.equals(UPLOAD_ID)) { + if (!(BaseActivity.this instanceof UploadActivity)) { + Intent intent = new Intent(BaseActivity.this, UploadActivity.class); + startActivity(intent); + } } else if (drawerItem.equals(BOOKMARKS_ID)) { if (!(BaseActivity.this instanceof BookmarksActivity)) { Intent intent = new Intent(BaseActivity.this, BookmarksActivity.class); @@ -432,7 +468,7 @@ public abstract class BaseActivity extends AppCompatActivity { if (!sessionManager.isLoggedIn()) //When logged out or if user is guest { drawer.removeItem(DOWNLOADS_ID); -// drawer.removeItem(UPLOAD_ID); + drawer.removeItem(UPLOAD_ID); loginLogoutItem.withName(R.string.login).withIcon(loginIcon); //Swap logout with login profileDrawerItem.withName(sessionManager.getUsername()); setDefaultAvatar(); @@ -440,9 +476,9 @@ public abstract class BaseActivity extends AppCompatActivity { if (!drawer.getDrawerItems().contains(downloadsItem)) { drawer.addItemAtPosition(downloadsItem, 4); } -// if (!drawer.getDrawerItems().contains(uploadItem)) { -// drawer.addItemAtPosition(uploadItem, 5); -// } + if (!drawer.getDrawerItems().contains(uploadItem)) { + drawer.addItemAtPosition(uploadItem, 5); + } loginLogoutItem.withName(R.string.logout).withIcon(logoutIcon); //Swap login with logout profileDrawerItem.withName(sessionManager.getUsername()); if (sessionManager.hasAvatar()) @@ -667,10 +703,10 @@ public abstract class BaseActivity extends AppCompatActivity { //-------------------------------------------BOOKMARKS END------------------------------------------ //-------PERMS--------- - private static final int PERMISSIONS_REQUEST_CODE = 69; + private static final int DOWNLOAD_REQUEST_CODE = 69; //Arbitrary, application specific //True if permissions are OK - private boolean checkPerms() { + protected boolean checkPerms() { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, @@ -683,13 +719,13 @@ public abstract class BaseActivity extends AppCompatActivity { } //Display popup for user to grant permission - private void requestPerms() { //Runtime permissions request for devices with API >= 23 + protected void requestPerms(int code) { //Runtime permissions request for devices with API >= 23 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; - requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); + requestPermissions(PERMISSIONS_STORAGE, code); } } @@ -698,8 +734,9 @@ public abstract class BaseActivity extends AppCompatActivity { public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions , @NonNull int[] grantResults) { switch (permsRequestCode) { - case PERMISSIONS_REQUEST_CODE: - downloadFile(); + case DOWNLOAD_REQUEST_CODE: + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) + prepareDownload(tempThmmyFile); break; } } @@ -713,7 +750,7 @@ public abstract class BaseActivity extends AppCompatActivity { prepareDownload(thmmyFile); else { tempThmmyFile = thmmyFile; - requestPerms(); + requestPerms(DOWNLOAD_REQUEST_CODE); } } @@ -835,6 +872,93 @@ public abstract class BaseActivity extends AppCompatActivity { editor.putBoolean(getString(R.string.pref_privacy_analytics_enable_key), enabled).apply(); } + //------------------------------------------ UPLOADS ------------------------------------------- + private class UploadsShowDialogReceiver extends BroadcastReceiver { + private final Context activityContext; + + UploadsShowDialogReceiver(Context activityContext) { + this.activityContext = activityContext; + } + + @Override + public void onReceive(Context context, Intent intent) { + Bundle intentBundle = intent.getExtras(); + if (intentBundle == null) { + return; + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + String dialogUploadID = intentBundle.getString(UPLOAD_ID_KEY); + + /*String retryFilename = intentBundle.getString(UPLOAD_RETRY_FILENAME); + String retryCategory = intentBundle.getString(UPLOAD_RETRY_CATEGORY); + String retryTitleText = intentBundle.getString(UPLOAD_RETRY_TITLE); + String retryDescription = intentBundle.getString(UPLOAD_RETRY_DESCRIPTION); + String retryIcon = intentBundle.getString(UPLOAD_RETRY_ICON); + String retryUploaderProfile = intentBundle.getString(UPLOAD_RETRY_UPLOADER); + Uri retryFileUri = (Uri) intentBundle.get(UPLOAD_RETRY_FILE_URI); + + Intent retryIntent = new Intent(context, UploadsReceiver.class); + retryIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + retryIntent.setAction(UploadsReceiver.ACTION_RETRY_UPLOAD); + + retryIntent.putExtra(UPLOAD_RETRY_FILENAME, retryFilename); + retryIntent.putExtra(UPLOAD_RETRY_CATEGORY, retryCategory); + retryIntent.putExtra(UPLOAD_RETRY_TITLE, retryTitleText); + retryIntent.putExtra(UPLOAD_RETRY_DESCRIPTION, retryDescription); + retryIntent.putExtra(UPLOAD_RETRY_ICON, retryIcon); + retryIntent.putExtra(UPLOAD_RETRY_UPLOADER, retryUploaderProfile); + retryIntent.putExtra(UPLOAD_RETRY_FILE_URI, retryFileUri);*/ + + if (uploadsProgressDialog == null) { + AlertDialog.Builder progressDialogBuilder = new AlertDialog.Builder(activityContext); + LayoutInflater inflater = LayoutInflater.from(activityContext); + LinearLayout progressDialogLayout = (LinearLayout) inflater.inflate(R.layout.dialog_upload_progress, null); + + MaterialProgressBar dialogProgressBar = progressDialogLayout.findViewById(R.id.dialogProgressBar); + dialogProgressBar.setMax(100); + + progressDialogBuilder.setView(progressDialogLayout); + + uploadsProgressDialog = progressDialogBuilder.create(); + if (!UploadService.getTaskList().contains("" + dialogUploadID)) { + //Upload probably failed at this point + uploadsProgressDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Retry", (progressDialog, progressWhich) -> { + /*LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context.getApplicationContext()); + localBroadcastManager.sendBroadcast(multipartUploadRetryIntent);*/ + uploadsProgressDialog.dismiss(); + + //context.sendBroadcast(retryIntent); + }); + uploadsProgressDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Cancel", (progressDialog, progressWhich) -> { + uploadsProgressDialog.dismiss(); + }); + + TextView dialogProgressText = progressDialogLayout.findViewById(R.id.dialog_upload_progress_text); + dialogProgressBar.setVisibility(View.GONE); + dialogProgressText.setText("Upload failed."); + + uploadsProgressDialog.show(); + } else { + //Empty buttons are needed, they are updated with correct values in the receiver + uploadsProgressDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "placeholder", (progressDialog, progressWhich) -> { + }); + uploadsProgressDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "placeholder", (progressDialog, progressWhich) -> { + }); + + UploadsReceiver.setDialogDisplay(uploadsProgressDialog, dialogUploadID, null); + //UploadsReceiver.setDialogDisplay(uploadsProgressDialog, dialogUploadID, retryIntent); + uploadsProgressDialog.show(); + } + } else { + UploadsReceiver.setDialogDisplay(uploadsProgressDialog, dialogUploadID, null); + //UploadsReceiver.setDialogDisplay(uploadsProgressDialog, dialogUploadID, retryIntent); + uploadsProgressDialog.show(); + } + } + } + } + //----------------------------------MISC---------------------- protected void setMainActivity(MainActivity mainActivity) { this.mainActivity = mainActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/UploadFile.java b/app/src/main/java/gr/thmmy/mthmmy/model/UploadFile.java new file mode 100644 index 00000000..c1bdb539 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/model/UploadFile.java @@ -0,0 +1,44 @@ +package gr.thmmy.mthmmy.model; + +import android.net.Uri; +import androidx.annotation.Nullable; + +import java.io.File; + +public class UploadFile { + private final boolean isCameraPhoto; + private Uri fileUri; + private File photoFile; + + private UploadFile() { + isCameraPhoto = false; + fileUri = null; + photoFile = null; + } + + public UploadFile(boolean isCameraPhoto, Uri fileUri, @Nullable File photoFile) { + this.isCameraPhoto = isCameraPhoto; + this.fileUri = fileUri; + this.photoFile = photoFile; + } + + public boolean isCameraPhoto() { + return isCameraPhoto; + } + + public Uri getFileUri() { + return fileUri; + } + + public File getPhotoFile() { + return photoFile; + } + + public void setFileUri(Uri fileUri) { + this.fileUri = fileUri; + } + + public void setPhotoFile(File photoFile) { + this.photoFile = photoFile; + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java b/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java new file mode 100644 index 00000000..c7c56e86 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java @@ -0,0 +1,223 @@ +package gr.thmmy.mthmmy.services; + +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import androidx.appcompat.app.AlertDialog; + +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import com.snatik.storage.Storage; + +import net.gotev.uploadservice.ServerResponse; +import net.gotev.uploadservice.UploadInfo; +import net.gotev.uploadservice.UploadService; +import net.gotev.uploadservice.UploadServiceBroadcastReceiver; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.activities.upload.UploadsHelper; +import gr.thmmy.mthmmy.base.BaseApplication; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; + +public class UploadsReceiver extends UploadServiceBroadcastReceiver { + public static final String UPLOAD_ID_KEY = "UPLOAD_ID_KEY"; + + public static final String ACTION_COMBINED_UPLOAD = "ACTION_COMBINED_UPLOAD"; + public static final String ACTION_CANCEL_UPLOAD = "ACTION_CANCEL_UPLOAD"; + public static final String ACTION_RETRY_UPLOAD = "ACTION_RETRY_UPLOAD"; + + /*public static final String UPLOAD_RETRY_FILENAME = "UPLOAD_RETRY_FILENAME"; + public static final String UPLOAD_RETRY_CATEGORY = "UPLOAD_RETRY_CATEGORY"; + public static final String UPLOAD_RETRY_TITLE = "UPLOAD_RETRY_TITLE"; + public static final String UPLOAD_RETRY_DESCRIPTION = "UPLOAD_RETRY_DESCRIPTION"; + public static final String UPLOAD_RETRY_ICON = "UPLOAD_RETRY_ICON"; + public static final String UPLOAD_RETRY_UPLOADER = "UPLOAD_RETRY_UPLOADER"; + public static final String UPLOAD_RETRY_FILE_URI = "UPLOAD_RETRY_FILE_URI";*/ + + private Storage storage; + private static AlertDialog uploadProgressDialog; + private static String dialogUploadID; + //private static Intent multipartUploadRetryIntent; + + @Override + public void onReceive(Context context, Intent intent) { + String intentAction = intent.getAction(); + Bundle intentBundle = intent.getExtras(); + if (intentAction == null || intentBundle == null) { + super.onReceive(context, intent); + return; + } + + switch (intentAction) { + case ACTION_CANCEL_UPLOAD: + String uploadID = intentBundle.getString(UPLOAD_ID_KEY); + UploadService.stopUpload(uploadID); + break; + /*case ACTION_RETRY_UPLOAD: + String retryFilename = intentBundle.getString(UPLOAD_RETRY_FILENAME); + String retryCategory = intentBundle.getString(UPLOAD_RETRY_CATEGORY); + String retryTitleText = intentBundle.getString(UPLOAD_RETRY_TITLE); + String retryDescription = intentBundle.getString(UPLOAD_RETRY_DESCRIPTION); + String retryIcon = intentBundle.getString(UPLOAD_RETRY_ICON); + String retryUploaderProfile = intentBundle.getString(UPLOAD_RETRY_UPLOADER); + Uri retryFileUri = (Uri) intentBundle.get(UPLOAD_RETRY_FILE_URI); + String retryUploadID = UUID.randomUUID().toString(); + + UploadActivity.uploadFile(context, retryUploadID, + UploadActivity.getConfigForUpload(context, retryUploadID, retryFilename, retryCategory, + retryTitleText, retryDescription, retryIcon, retryUploaderProfile, retryFileUri), + retryCategory, retryTitleText, retryDescription, retryIcon, + retryUploaderProfile, retryFileUri); + + break;*/ + default: + super.onReceive(context, intent); + break; + } + } + + @Override + public void onProgress(Context context, UploadInfo uploadInfo) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && + uploadInfo.getUploadId().equals(dialogUploadID) && + uploadProgressDialog != null) { + Button alertDialogNeutral = uploadProgressDialog.getButton(AlertDialog.BUTTON_NEUTRAL); + alertDialogNeutral.setText("Resume on background"); + alertDialogNeutral.setOnClickListener(v -> uploadProgressDialog.dismiss()); + + Button alertDialogNegative = uploadProgressDialog.getButton(AlertDialog.BUTTON_NEGATIVE); + alertDialogNegative.setText("Cancel"); + alertDialogNegative.setOnClickListener(v -> { + UploadService.stopUpload(dialogUploadID); + uploadProgressDialog.dismiss(); + }); + + if (uploadProgressDialog.isShowing()) { + Window progressWindow = uploadProgressDialog.getWindow(); + if (progressWindow != null) { + MaterialProgressBar dialogProgressBar = progressWindow.findViewById(R.id.dialogProgressBar); + TextView dialogProgressText = progressWindow.findViewById(R.id.dialog_upload_progress_text); + + dialogProgressBar.setProgress(uploadInfo.getProgressPercent()); + dialogProgressText.setText(context.getResources().getString( + R.string.upload_progress_dialog_bytes_uploaded, + (float) uploadInfo.getUploadRate(), + (int) uploadInfo.getUploadedBytes() / 1000, + (int) uploadInfo.getTotalBytes() / 1000)); + } + + if (uploadInfo.getUploadedBytes() == uploadInfo.getTotalBytes()) { + uploadProgressDialog.dismiss(); + } + } + } + } + + @Override + public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse, + Exception exception) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && + uploadInfo.getUploadId().equals(dialogUploadID) && + uploadProgressDialog != null) { + /*Button alertDialogNeutral = uploadProgressDialog.getButton(AlertDialog.BUTTON_NEUTRAL); + alertDialogNeutral.setText("Retry"); + alertDialogNeutral.setOnClickListener(v -> { + if (multipartUploadRetryIntent != null) { + context.sendBroadcast(multipartUploadRetryIntent); + } + uploadProgressDialog.dismiss(); + });*/ + + Button alertDialogNegative = uploadProgressDialog.getButton(AlertDialog.BUTTON_NEGATIVE); + alertDialogNegative.setText("Cancel"); + alertDialogNegative.setOnClickListener(v -> { + NotificationManager notificationManager = (NotificationManager) context.getApplicationContext(). + getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager != null) { + notificationManager.cancel(uploadInfo.getNotificationID()); + } + UploadsHelper.deleteTempFiles(storage); + uploadProgressDialog.dismiss(); + }); + + if (uploadProgressDialog.isShowing()) { + Window progressWindow = uploadProgressDialog.getWindow(); + if (progressWindow != null) { + MaterialProgressBar dialogProgressBar = progressWindow.findViewById(R.id.dialogProgressBar); + TextView dialogProgressText = progressWindow.findViewById(R.id.dialog_upload_progress_text); + + dialogProgressBar.setVisibility(View.GONE); + dialogProgressText.setText("Upload failed."); + } + + if (uploadInfo.getUploadedBytes() == uploadInfo.getTotalBytes()) { + uploadProgressDialog.dismiss(); + } + } + } else { + NotificationManager notificationManager = (NotificationManager) context.getApplicationContext(). + getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager != null) { + notificationManager.cancel(uploadInfo.getNotificationID()); + } + + Intent combinedActionsIntent = new Intent(UploadsReceiver.ACTION_COMBINED_UPLOAD); + combinedActionsIntent.putExtra(UploadsReceiver.UPLOAD_ID_KEY, uploadInfo.getUploadId()); + context.sendBroadcast(combinedActionsIntent); + } + + Toast.makeText(context.getApplicationContext(), "Upload failed", Toast.LENGTH_SHORT).show(); + if (storage == null) { + storage = new Storage(context.getApplicationContext()); + } + } + + @Override + public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + uploadProgressDialog = null; + dialogUploadID = null; + } + + Toast.makeText(context.getApplicationContext(), "Upload completed successfully", Toast.LENGTH_SHORT).show(); + if (storage == null) { + storage = new Storage(context.getApplicationContext()); + } + + BaseApplication.getInstance().logFirebaseAnalyticsEvent("file_upload", null); + UploadsHelper.deleteTempFiles(storage); + } + + @Override + public void onCancelled(Context context, UploadInfo uploadInfo) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + uploadProgressDialog = null; + dialogUploadID = null; + } + + Toast.makeText(context.getApplicationContext(), "Upload canceled", Toast.LENGTH_SHORT).show(); + if (storage == null) { + storage = new Storage(context.getApplicationContext()); + } + + /*NotificationManager notificationManager = (NotificationManager) context.getApplicationContext(). + getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager != null) { + notificationManager.cancel(uploadInfo.getNotificationID()); + }*/ + UploadsHelper.deleteTempFiles(storage); + } + + public static void setDialogDisplay(AlertDialog uploadProgressDialog, String dialogUploadID, + Intent multipartUploadRetryIntent) { + UploadsReceiver.uploadProgressDialog = uploadProgressDialog; + UploadsReceiver.dialogUploadID = dialogUploadID; + //UploadsReceiver.multipartUploadRetryIntent = multipartUploadRetryIntent; + } +} \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java b/app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java index 1c8eb0b0..7beffeb6 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java @@ -1,10 +1,16 @@ package gr.thmmy.mthmmy.utils; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.provider.OpenableColumns; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import android.webkit.MimeTypeMap; import java.io.File; -import androidx.annotation.NonNull; +import gr.thmmy.mthmmy.R; import static gr.thmmy.mthmmy.services.DownloadHelper.SAVE_DIR; @@ -21,7 +27,94 @@ public class FileUtils { return type; } - public static boolean fileNameExists (String fileName) { + public static boolean fileNameExists(String fileName) { return fileName != null && (new File(SAVE_DIR.getAbsolutePath(), fileName)).isFile(); } + + @Nullable + public static String getFileExtension(@NonNull String filename) { + String fileExtension; + + if (!filename.contains(".")) { + return null; + } + if (filename.toLowerCase().endsWith(".tar.gz")) { + fileExtension = filename.substring(filename.length() - 7); + } else { + fileExtension = filename.substring(filename.lastIndexOf(".")); + } + + return fileExtension; + } + + public static String getFilenameWithoutExtension(String filename) { + String fileExtension = getFileExtension(filename); + + return fileExtension == null + ? filename + : filename.substring(0, filename.indexOf(fileExtension)); + } + + @NonNull + public static String filenameFromUri(Context context, Uri uri) { + String filename = null; + if (uri.getScheme().equals("content")) { + try (Cursor cursor = context.getContentResolver().query(uri, null, null, null, null)) { + if (cursor != null && cursor.moveToFirst()) { + filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); + } + } + } + if (filename == null) { + filename = uri.getPath(); + int cut = filename.lastIndexOf('/'); + if (cut != -1) { + filename = filename.substring(cut + 1); + } + } + + return filename; + } + + public static long sizeFromUri(Context context, @NonNull Uri uri) { + try (Cursor cursor = context.getContentResolver().query(uri, null, null, null, null)) { + if (cursor != null && cursor.moveToFirst()) { + return cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE)); + } + } + return -1; + } + + /** + * Returns a String with a single FontAwesome typeface character corresponding to this file's + * extension. + * + * @param filename String with filename containing file's extension + * @return FontAwesome character according to file's type + * @see FontAwesome + */ + @NonNull + public static String faIconFromFilename(Context context, String filename) { + filename = filename.toLowerCase(); + + if (filename.contains("jpg") || filename.contains("gif") || filename.contains("jpeg") + || filename.contains("png")) + return context.getResources().getString(R.string.fa_file_image_o); + else if (filename.contains("pdf")) + return context.getResources().getString(R.string.fa_file_pdf_o); + else if (filename.contains("zip") || filename.contains("rar") || filename.contains("tar.gz")) + return context.getResources().getString(R.string.fa_file_zip_o); + else if (filename.contains("txt")) + return context.getResources().getString(R.string.fa_file_text_o); + else if (filename.contains("doc") || filename.contains("docx")) + return context.getResources().getString(R.string.fa_file_word_o); + else if (filename.contains("xls") || filename.contains("xlsx")) + return context.getResources().getString(R.string.fa_file_excel_o); + else if (filename.contains("pps")) + return context.getResources().getString(R.string.fa_file_powerpoint_o); + else if (filename.contains("mpg")) + return context.getResources().getString(R.string.fa_file_video_o); + + return context.getResources().getString(R.string.fa_file); + } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java index a45e1a3f..06a355f2 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java @@ -2,15 +2,16 @@ package gr.thmmy.mthmmy.utils; import android.content.Context; import android.util.AttributeSet; +import android.util.Log; import android.view.View; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; - import androidx.annotation.NonNull; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.view.ViewCompat; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; + /** * Extends FloatingActionButton's behavior so the button will hide when scrolling down and show * otherwise. It also lifts the {@link FloatingActionButton} when a {@link Snackbar} is shown. @@ -37,7 +38,9 @@ public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior 0 || (!target.canScrollVertically(-1) && dyConsumed == 0 && dyUnconsumed > 50)) { + Log.d("THISSSS", "GOT_HIDE"); child.hide(new FloatingActionButton.OnVisibilityChangedListener() { @Override public void onHidden(FloatingActionButton fab) { @@ -47,7 +50,14 @@ public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior resInfoList = context.getPackageManager(). + queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY); + for (ResolveInfo resolveInfo : resInfoList) { + String packageName = resolveInfo.activityInfo.packageName; + context.grantUriPermission(packageName, photoURI, + Intent.FLAG_GRANT_WRITE_URI_PERMISSION | + Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + return takePictureIntent; + } + return null; + } + + public static Uri processResult(Context context, File photoFile) { + Bitmap bitmap; + Uri fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", photoFile); + + bitmap = getImageResized(context, fileUri); + int rotation = getRotation(context, fileUri); + bitmap = rotate(bitmap, rotation); + + try { + FileOutputStream out = new FileOutputStream(photoFile); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); + out.flush(); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + return fileUri; + } + + @Nullable + public static File createImageFile(Context context) { + // Create an image file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); + String imageFileName = "mThmmy_" + timeStamp + ".jpg"; + + File imageFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + + File.separator + "mThmmy"); + + if (!imageFolder.exists()) { + if (!imageFolder.mkdirs()) { + Timber.w("Photos folder build returned false in %s", TakePhoto.class.getSimpleName()); + Toast.makeText(context, "Couldn't create photos directory", Toast.LENGTH_SHORT).show(); + return null; + } + } + + return new File(imageFolder, imageFileName); + } + + public static void galleryAddPic(Context context, File photoFile) { + ContentValues values = new ContentValues(); + values.put(MediaStore.Images.Media.TITLE, photoFile.getName()); + values.put(MediaStore.Images.Media.DESCRIPTION, IMAGE_CONTENT_DESCRIPTION); + values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis()); + values.put(MediaStore.Images.ImageColumns.BUCKET_ID, photoFile.toString().toLowerCase(Locale.US).hashCode()); + values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, photoFile.getName().toLowerCase(Locale.US)); + values.put("_data", photoFile.getAbsolutePath()); + + ContentResolver cr = context.getContentResolver(); + cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); + } + + private static Bitmap getImageResized(Context context, Uri selectedImage) { + Bitmap bm; + int[] sampleSizes = new int[]{5, 3, 2, 1}; + int i = 0; + do { + bm = decodeBitmap(context, selectedImage, sampleSizes[i]); + i++; + } while (bm.getWidth() < DEFAULT_MIN_WIDTH_QUALITY && i < sampleSizes.length); + return bm; + } + + private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = sampleSize; + + AssetFileDescriptor fileDescriptor = null; + try { + fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + assert fileDescriptor != null; + return BitmapFactory.decodeFileDescriptor( + fileDescriptor.getFileDescriptor(), null, options); + } + + private static int getRotation(Context context, Uri imageUri) { + int rotation = 0; + try { + + context.getContentResolver().notifyChange(imageUri, null); + ExifInterface exif = new ExifInterface(imageUri.getPath()); + int orientation = exif.getAttributeInt( + ExifInterface.TAG_ORIENTATION, + ExifInterface.ORIENTATION_NORMAL); + + switch (orientation) { + case ExifInterface.ORIENTATION_ROTATE_270: + rotation = 270; + break; + case ExifInterface.ORIENTATION_ROTATE_180: + rotation = 180; + break; + case ExifInterface.ORIENTATION_ROTATE_90: + rotation = 90; + break; + } + } catch (Exception e) { + e.printStackTrace(); + } + return rotation; + } + + private static Bitmap rotate(Bitmap bm, int rotation) { + if (rotation != 0) { + Matrix matrix = new Matrix(); + matrix.postRotate(rotation); + return Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); + } + return bm; + } +} diff --git a/app/src/main/res/drawable/ic_attach_file_white_24dp.xml b/app/src/main/res/drawable/ic_attach_file_white_24dp.xml deleted file mode 100644 index 4834305b..00000000 --- a/app/src/main/res/drawable/ic_attach_file_white_24dp.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_cached_accent_24dp.xml b/app/src/main/res/drawable/ic_cached_accent_24dp.xml new file mode 100644 index 00000000..b4f3f7dd --- /dev/null +++ b/app/src/main/res/drawable/ic_cached_accent_24dp.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable/ic_cancel_accent_24dp.xml b/app/src/main/res/drawable/ic_cancel_accent_24dp.xml new file mode 100644 index 00000000..4c1d6837 --- /dev/null +++ b/app/src/main/res/drawable/ic_cancel_accent_24dp.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable/ic_info_outline_warning_24dp.xml b/app/src/main/res/drawable/ic_info_outline_warning_24dp.xml new file mode 100644 index 00000000..1c3b206c --- /dev/null +++ b/app/src/main/res/drawable/ic_info_outline_warning_24dp.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/layout/activity_board.xml b/app/src/main/res/layout/activity_board.xml index 9a51aa92..5ac81b3a 100644 --- a/app/src/main/res/layout/activity_board.xml +++ b/app/src/main/res/layout/activity_board.xml @@ -1,6 +1,5 @@ - + app:srcCompat="@drawable/ic_bookmark_false_accent_24dp" /> @@ -43,8 +42,8 @@ android:layout_marginTop="64dp" android:background="@color/background" android:scrollbars="none" - tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity"> - + app:layout_behavior="@string/appbar_scrolling_view_behavior" + tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity" /> + app:mpb_progressStyle="horizontal" /> + app:srcCompat="@drawable/ic_add_fab" /> - - diff --git a/app/src/main/res/layout/activity_downloads.xml b/app/src/main/res/layout/activity_downloads.xml index dc92a274..97e0afbc 100644 --- a/app/src/main/res/layout/activity_downloads.xml +++ b/app/src/main/res/layout/activity_downloads.xml @@ -48,7 +48,7 @@ app:mpb_indeterminateTint="@color/accent" app:mpb_progressStyle="horizontal"/> - + app:srcCompat="@drawable/ic_file_upload_white_24dp"/> diff --git a/app/src/main/res/layout/activity_topic.xml b/app/src/main/res/layout/activity_topic.xml index aaa13e4b..b61c41cf 100644 --- a/app/src/main/res/layout/activity_topic.xml +++ b/app/src/main/res/layout/activity_topic.xml @@ -45,8 +45,8 @@ android:layout_below="@id/appbar" android:layout_gravity="top|start" android:clipToPadding="false" - android:paddingBottom="4dp" android:paddingTop="4dp" + android:paddingBottom="4dp" android:scrollbars="none" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity" /> @@ -146,8 +146,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" - android:layout_marginBottom="50dp" android:layout_marginEnd="@dimen/fab_margins" + android:layout_marginBottom="50dp" app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareFABBehavior" app:srcCompat="@drawable/ic_reply" /> diff --git a/app/src/main/res/layout/activity_upload.xml b/app/src/main/res/layout/activity_upload.xml index 8639fd8c..fb985454 100644 --- a/app/src/main/res/layout/activity_upload.xml +++ b/app/src/main/res/layout/activity_upload.xml @@ -28,16 +28,16 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="top|start" - android:background="@color/background" - android:paddingEnd="@dimen/activity_horizontal_margin" + android:background="@color/primary_light" android:paddingStart="@dimen/activity_horizontal_margin" + android:paddingEnd="@dimen/activity_horizontal_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="gr.thmmy.mthmmy.activities.upload.UploadActivity"> @@ -45,15 +45,16 @@ android:id="@+id/upload_spinners" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/background" + android:layout_marginTop="8dp" + android:background="@color/primary_light" android:orientation="vertical"> @@ -61,8 +62,8 @@ + android:layout_marginTop="6dp" + android:layout_marginBottom="6dp"> + + + + + + + + + + + android:layout_marginTop="6dp" + android:layout_marginBottom="6dp"> - - - + + @@ -165,8 +193,8 @@ 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" + android:layout_marginBottom="@dimen/fab_margins" app:layout_behavior="gr.thmmy.mthmmy.utils.ScrollAwareFABBehavior" app:srcCompat="@drawable/ic_file_upload_white_24dp" /> diff --git a/app/src/main/res/layout/activity_upload_fields_builder.xml b/app/src/main/res/layout/activity_upload_fields_builder.xml index 0583b601..601cdeeb 100644 --- a/app/src/main/res/layout/activity_upload_fields_builder.xml +++ b/app/src/main/res/layout/activity_upload_fields_builder.xml @@ -27,7 +27,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="top|start" - android:background="@color/background" + android:background="@color/primary_light" android:paddingEnd="@dimen/activity_horizontal_margin" android:paddingStart="@dimen/activity_horizontal_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" diff --git a/app/src/main/res/layout/activity_upload_file_list_row.xml b/app/src/main/res/layout/activity_upload_file_list_row.xml new file mode 100644 index 00000000..08b74a4a --- /dev/null +++ b/app/src/main/res/layout/activity_upload_file_list_row.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_upload_filename_info_popup.xml b/app/src/main/res/layout/activity_upload_filename_info_popup.xml new file mode 100644 index 00000000..bb6a9704 --- /dev/null +++ b/app/src/main/res/layout/activity_upload_filename_info_popup.xml @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_upload_progress.xml b/app/src/main/res/layout/dialog_upload_progress.xml new file mode 100644 index 00000000..18444cb4 --- /dev/null +++ b/app/src/main/res/layout/dialog_upload_progress.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/editor_view_color_picker.xml b/app/src/main/res/layout/editor_view_color_picker.xml index b71214e1..be1ce295 100644 --- a/app/src/main/res/layout/editor_view_color_picker.xml +++ b/app/src/main/res/layout/editor_view_color_picker.xml @@ -1,11 +1,10 @@ - + android:layout_height="wrap_content" + android:background="@color/card_background"> - @@ -14,84 +13,84 @@ android:id="@+id/black" style="@style/PopupMenuItem.TopItem" android:text="@string/black" - android:textColor="@color/black"/> + android:textColor="@color/black" /> + android:textColor="@color/red" /> + android:textColor="@color/yellow" /> + android:textColor="@color/pink" /> + android:textColor="@color/green" /> + android:textColor="@color/orange" /> + android:textColor="@color/purple" /> + android:textColor="@color/blue" /> + android:textColor="@color/beige" /> + android:textColor="@color/brown" /> + android:textColor="@color/teal" /> + android:textColor="@color/navy" /> + android:textColor="@color/maroon" /> + android:textColor="@color/lime_green" /> \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f2209027..6a76e274 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -18,6 +18,7 @@ #8B8B8B #FF9800 #FAA61A + #890d0d #FFFFFF #CCCCCC diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bf3d9e5f..5d856f19 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -132,12 +132,20 @@ Upload - Generate title and description + Generate fields Title + Upload as (filename) Description - Select file + Add files Take photo Select a category + Please follow the filename rules as\ndescribed + in this topic.\n + \nThis does not rename your local files. + Uploading + Uploading: %1$.2f Kbit/s, %2$d/%3$d KBytes + "Cancel" + "Retry" Select type of upload diff --git a/app/src/main/res/xml/app_preferences_user.xml b/app/src/main/res/xml/app_preferences_user.xml index 2599df44..0ea00d34 100644 --- a/app/src/main/res/xml/app_preferences_user.xml +++ b/app/src/main/res/xml/app_preferences_user.xml @@ -49,7 +49,7 @@ app:iconSpaceReserved="false" /> - + Date: Mon, 17 Jun 2019 09:49:05 +0300 Subject: [PATCH 04/18] Fix post icons getting messed up --- .../create_content/NewTopicTask.java | 1 + .../activities/topic/tasks/EditTask.java | 1 + .../topic/tasks/PrepareForEditResult.java | 9 ++++++-- .../topic/tasks/PrepareForEditTask.java | 22 +++++++++++-------- .../activities/topic/tasks/ReplyTask.java | 1 + .../mthmmy/viewmodel/TopicViewModel.java | 2 +- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java index 985e0930..0749d367 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/create_content/NewTopicTask.java @@ -61,6 +61,7 @@ public class NewTopicTask extends AsyncTask { .addFormDataPart("sc", sc) .addFormDataPart("subject", strings[1]) .addFormDataPart("topic", topic) + .addFormDataPart("icon", "xx") .build(); Request post = new Request.Builder() diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/EditTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/EditTask.java index 3b5b46f0..c54d661c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/EditTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/EditTask.java @@ -38,6 +38,7 @@ public class EditTask extends AsyncTask { .addFormDataPart("sc", strings[4]) .addFormDataPart("subject", strings[5]) .addFormDataPart("topic", strings[6]) + .addFormDataPart("icon", strings[7]) .build(); Request post = new Request.Builder() .url(strings[0]) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditResult.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditResult.java index a8176072..1a74caa3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditResult.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditResult.java @@ -1,18 +1,19 @@ package gr.thmmy.mthmmy.activities.topic.tasks; public class PrepareForEditResult { - private final String postText, commitEditUrl, numReplies, seqnum, sc, topic; + private final String postText, commitEditUrl, numReplies, seqnum, sc, topic, icon; private int position; private boolean successful; public PrepareForEditResult(String postText, String commitEditUrl, String numReplies, String seqnum, - String sc, String topic, int position, boolean successful) { + String sc, String topic, String icon, int position, boolean successful) { this.postText = postText; this.commitEditUrl = commitEditUrl; this.numReplies = numReplies; this.seqnum = seqnum; this.sc = sc; this.topic = topic; + this.icon = icon; this.position = position; this.successful = successful; } @@ -41,6 +42,10 @@ public class PrepareForEditResult { return topic; } + public String getIcon() { + return icon; + } + public int getPosition() { return position; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditTask.java index 6efc2c03..09206a1c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForEditTask.java @@ -38,28 +38,32 @@ public class PrepareForEditTask extends AsyncTaskoption[selected]").first().attr("value"); - return new PrepareForEditResult(postText, commitEditURL, numReplies, seqnum, sc, topic, position, true); + return new PrepareForEditResult(postText, commitEditURL, numReplies, seqnum, sc, topic, icon, position, true); } catch (IOException | Selector.SelectorParseException e) { Timber.e(e, "Prepare failed."); - return new PrepareForEditResult(null, null, null, null, null, null, position, false); + return new PrepareForEditResult(null, null, null, null, null, null, null, position, false); } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/ReplyTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/ReplyTask.java index 13ad66d9..7ae2595c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/ReplyTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/ReplyTask.java @@ -42,6 +42,7 @@ public class ReplyTask extends AsyncTask { .addFormDataPart("sc", args[4]) .addFormDataPart("subject", args[0]) .addFormDataPart("topic", args[5]) + .addFormDataPart("icon", "xx") .build(); Request post = new Request.Builder() .url("https://www.thmmy.gr/smf/index.php?action=post2") diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java index a7e72883..c15e46db 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java +++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java @@ -219,7 +219,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa PrepareForEditResult editResult = prepareForEditResult.getValue(); Timber.i("Editing post"); new EditTask(editTaskCallbacks, position).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, editResult.getCommitEditUrl(), message, - editResult.getNumReplies(), editResult.getSeqnum(), editResult.getSc(), subject, editResult.getTopic()); + editResult.getNumReplies(), editResult.getSeqnum(), editResult.getSc(), subject, editResult.getTopic(), editResult.getIcon()); } /** From bc9fbcf56c73ae8d30a2de2a870707d0e6349ac6 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Mon, 17 Jun 2019 14:54:45 +0300 Subject: [PATCH 05/18] Fix permissions issue for Android API >28 --- app/src/main/AndroidManifest.xml | 1 + .../activities/upload/UploadActivity.java | 55 ++++++++++++++----- .../mthmmy/utils/ScrollAwareFABBehavior.java | 3 - 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1e8bf257..3f63279b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,7 @@ + 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) takePhoto(); break; + case UPLOAD_REQUEST_STORAGE_CODE: + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && + zipTask != null) { + Uri[] filesListArray = new Uri[filesList.size()]; + for (int i = 0; i < filesList.size(); ++i) { + filesListArray[i] = filesList.get(i).getFileUri(); + } + + zipTask.execute(filesListArray); + finish(); + } + break; } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java index 06a355f2..44c0d4f3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java @@ -38,9 +38,7 @@ public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior 0 || (!target.canScrollVertically(-1) && dyConsumed == 0 && dyUnconsumed > 50)) { - Log.d("THISSSS", "GOT_HIDE"); child.hide(new FloatingActionButton.OnVisibilityChangedListener() { @Override public void onHidden(FloatingActionButton fab) { @@ -50,7 +48,6 @@ public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior Date: Tue, 18 Jun 2019 17:58:51 +0300 Subject: [PATCH 06/18] Fix multiple file choosing, Fix options lost on orientation change --- app/src/main/AndroidManifest.xml | 1 + .../gr/thmmy/mthmmy/activities/upload/UploadActivity.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3f63279b..fd302031 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -110,6 +110,7 @@ Date: Wed, 19 Jun 2019 15:48:58 +0300 Subject: [PATCH 07/18] Add firebase event for shouts --- .../gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java index 848baa9d..35d86faf 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java @@ -17,6 +17,7 @@ import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProviders; import androidx.recyclerview.widget.LinearLayoutManager; import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.editorview.EditorView; import gr.thmmy.mthmmy.editorview.EmojiKeyboard; import gr.thmmy.mthmmy.model.Shout; @@ -133,6 +134,7 @@ public class ShoutboxFragment extends Fragment { progressBar.setVisibility(View.INVISIBLE); if (resultCode == NetworkResultCodes.SUCCESSFUL) { Timber.i("Shout was sent successfully"); + BaseApplication.getInstance().logFirebaseAnalyticsEvent("shout", null); editorView.getEditText().getText().clear(); shoutboxViewModel.loadShoutbox(true); } else if (resultCode == NetworkResultCodes.NETWORK_ERROR) { From b81b2fb0eb5fc58cf13b7fc510629619756aee46 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Wed, 19 Jun 2019 16:01:49 +0300 Subject: [PATCH 08/18] Up version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 337120bc..3fe9335d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "gr.thmmy.mthmmy" minSdkVersion 19 targetSdkVersion 28 - versionCode 18 - versionName "1.6.3" + versionCode 19 + versionName "1.7.0" archivesBaseName = "mTHMMY-v$versionName" buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\"" buildConfigField "String", "COMMIT_HASH", "\"" + getCommitHash() + "\"" From a28ea2874268c4340be6c6f01394f432c517c72e Mon Sep 17 00:00:00 2001 From: Apostolof Date: Wed, 19 Jun 2019 18:50:26 +0300 Subject: [PATCH 09/18] Various fixes --- .../activities/upload/UploadActivity.java | 59 +++++++++++-------- .../upload/UploadFieldsBuilderActivity.java | 4 +- app/src/main/res/layout/activity_board.xml | 1 - .../main/res/xml-v26/app_preferences_user.xml | 4 +- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java index 33a280f2..67f612e3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java @@ -360,29 +360,37 @@ public class UploadActivity extends BaseActivity { if (!editTextFilename.equals(selectedFileFilename)) { //File should be uploaded with a different name - if (!uploadFile.isCameraPhoto()) { - //Temporarily copies the file to a another location and renames it - tempFileUri = UploadsHelper.createTempFile(this, storage, - uploadFile.getFileUri(), - FileUtils.getFilenameWithoutExtension(editTextFilename)); - } else { - //Renames the photo taken - String photoPath = uploadFile.getPhotoFile().getPath(); - photoPath = photoPath.substring(0, photoPath.lastIndexOf(File.separator)); - String destinationFilename = photoPath + File.separator + - FileUtils.getFilenameWithoutExtension(editTextFilename) + ".jpg"; - - if (!storage.rename(uploadFile.getPhotoFile().getAbsolutePath(), destinationFilename)) { - //Something went wrong, abort - Toast.makeText(this, "Could not create temporary file for renaming", Toast.LENGTH_SHORT).show(); - progressBar.setVisibility(View.GONE); - return; - } - //Points photoFile and fileUri to the new copied and renamed file - uploadFile.setPhotoFile(storage.getFile(destinationFilename)); - uploadFile.setFileUri(FileProvider.getUriForFile(this, getPackageName() + - ".provider", uploadFile.getPhotoFile())); + if (checkPerms()) { + if (!uploadFile.isCameraPhoto()) { + //Temporarily copies the file to a another location and renames it + tempFileUri = UploadsHelper.createTempFile(this, storage, + uploadFile.getFileUri(), + FileUtils.getFilenameWithoutExtension(editTextFilename)); + } else { + //Renames the photo taken + String photoPath = uploadFile.getPhotoFile().getPath(); + photoPath = photoPath.substring(0, photoPath.lastIndexOf(File.separator)); + String destinationFilename = photoPath + File.separator + + FileUtils.getFilenameWithoutExtension(editTextFilename) + ".jpg"; + + if (!storage.rename(uploadFile.getPhotoFile().getAbsolutePath(), destinationFilename)) { + //Something went wrong, abort + Toast.makeText(this, "Could not create temporary file for renaming", Toast.LENGTH_SHORT).show(); + progressBar.setVisibility(View.GONE); + return; + } + + //Points photoFile and fileUri to the new copied and renamed file + uploadFile.setPhotoFile(storage.getFile(destinationFilename)); + uploadFile.setFileUri(FileProvider.getUriForFile(this, getPackageName() + + ".provider", uploadFile.getPhotoFile())); + } + } else { + requestPerms(UPLOAD_REQUEST_STORAGE_CODE); + zipTask = null; + dialog.cancel(); + return; } } } else { @@ -586,8 +594,9 @@ public class UploadActivity extends BaseActivity { if (previousName.isEmpty()) { uploadFilename.setText(data.getStringExtra(RESULT_FILENAME)); } else { + String extractedExtension = FileUtils.getFileExtension(previousName); String filenameWithExtension = data.getStringExtra(RESULT_FILENAME) + - FileUtils.getFileExtension(previousName); + (extractedExtension != null ? extractedExtension : ""); uploadFilename.setText(filenameWithExtension); } hasModifiedFilename = true; @@ -609,7 +618,7 @@ public class UploadActivity extends BaseActivity { break; case UPLOAD_REQUEST_STORAGE_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && - zipTask != null) { + zipTask != null) { Uri[] filesListArray = new Uri[filesList.size()]; for (int i = 0; i < filesList.size(); ++i) { filesListArray[i] = filesList.get(i).getFileUri(); @@ -617,6 +626,8 @@ public class UploadActivity extends BaseActivity { zipTask.execute(filesListArray); finish(); + } else { + Toast.makeText(this, "Please retry uploading.", Toast.LENGTH_SHORT).show(); } break; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java index e89fda41..ebf221f6 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java @@ -390,9 +390,9 @@ public class UploadFieldsBuilderActivity extends BaseActivity { return greeklish ? "hlektronikh_1" : "Ηλεκτρονική 1"; } else if (normalisedCourse.contains(("Ηλεκτρονικές Διατάξεις και Μετρήσεις"))) { return greeklish ? "hlektron_diatakseis_metrhseis" : "Ηλεκτρονικές Διατάξεις και Μετρήσεις"; - } else if (normalisedCourse.contains(("Ηλεκτρονικά Iσχύος II"))) { + } else if (normalisedCourse.contains(("Ηλεκτρονικά Ισχύος II"))) { return greeklish ? "isxyos_II" : "Ισχύος 2"; - } else if (normalisedCourse.contains(("Ηλεκτρονικά Iσχύος I"))) { + } else if (normalisedCourse.contains(("Ηλεκτρονικά Ισχύος I"))) { return greeklish ? "isxyos_I" : "Ισχύος 1"; } else if (normalisedCourse.contains(("Ηλεκτρομαγνητικό Πεδίο II"))) { return greeklish ? "pedio_II" : "Πεδίο 2"; diff --git a/app/src/main/res/layout/activity_board.xml b/app/src/main/res/layout/activity_board.xml index 5ac81b3a..0a61658e 100644 --- a/app/src/main/res/layout/activity_board.xml +++ b/app/src/main/res/layout/activity_board.xml @@ -42,7 +42,6 @@ android:layout_marginTop="64dp" android:background="@color/background" android:scrollbars="none" - app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="gr.thmmy.mthmmy.activities.topic.TopicActivity" /> - + Date: Thu, 20 Jun 2019 15:31:25 +0300 Subject: [PATCH 10/18] Up libs --- app/build.gradle | 8 ++++---- build.gradle | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3fe9335d..56b9112b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,7 +62,7 @@ tasks.whenTaskAdded { task -> dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'androidx.preference:preference:1.1.0-alpha02' + implementation 'androidx.preference:preference:1.1.0-beta01' implementation 'androidx.legacy:legacy-preference-v14:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' @@ -70,9 +70,9 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android.material:material:1.0.0' - implementation 'com.google.firebase:firebase-core:16.0.6' - implementation 'com.google.firebase:firebase-messaging:17.3.4' - implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8' + implementation 'com.google.firebase:firebase-core:17.0.0' + implementation 'com.google.firebase:firebase-messaging:19.0.0' + implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' implementation 'com.snatik:storage:2.1.0' implementation 'com.squareup.okhttp3:okhttp:3.12.0' implementation 'com.squareup.picasso:picasso:2.5.2' diff --git a/build.gradle b/build.gradle index 81176d71..677adbde 100644 --- a/build.gradle +++ b/build.gradle @@ -10,8 +10,8 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.4.1' classpath 'com.google.gms:google-services:4.2.0' - classpath 'io.fabric.tools:gradle:1.26.1' - classpath 'org.ajoberstar.grgit:grgit-core:3.0.0' // Also change in app/gradle/grgit.gradle + classpath 'io.fabric.tools:gradle:1.29.0' + classpath 'org.ajoberstar.grgit:grgit-core:3.1.1' // Also change in app/gradle/grgit.gradle } } From 81054f07689bd4fa84ff0e9e463c257fe16adfe0 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Fri, 21 Jun 2019 19:28:39 +0300 Subject: [PATCH 11/18] Uploads improvements (moved courses in resources, disabled Generate Button when needed) --- .../mthmmy/activities/AboutActivity.java | 5 +- .../mthmmy/activities/LoginActivity.java | 5 +- .../activities/board/BoardActivity.java | 9 +- .../mthmmy/activities/board/BoardAdapter.java | 3 +- .../bookmarks/BookmarksActivity.java | 11 +- .../bookmarks/BookmarksBoardFragment.java | 5 +- .../bookmarks/BookmarksTopicFragment.java | 5 +- .../downloads/DownloadsActivity.java | 12 +- .../downloads/DownloadsAdapter.java | 3 +- .../mthmmy/activities/main/MainActivity.java | 11 +- .../activities/main/forum/ForumAdapter.java | 5 +- .../activities/main/forum/ForumFragment.java | 7 +- .../activities/main/recent/RecentAdapter.java | 5 +- .../main/recent/RecentFragment.java | 7 +- .../activities/main/unread/UnreadAdapter.java | 5 +- .../main/unread/UnreadFragment.java | 9 +- .../activities/profile/ProfileActivity.java | 13 +- .../latestPosts/LatestPostsAdapter.java | 3 +- .../latestPosts/LatestPostsFragment.java | 7 +- .../profile/stats/StatsFragment.java | 3 +- .../profile/summary/SummaryFragment.java | 3 +- .../activities/settings/SettingsActivity.java | 1 + .../activities/settings/SettingsFragment.java | 5 +- .../activities/shoutbox/ShoutAdapter.java | 1 + .../activities/shoutbox/ShoutboxFragment.java | 1 + .../activities/topic/TopicActivity.java | 11 +- .../mthmmy/activities/topic/TopicAdapter.java | 15 +- .../activities/upload/UploadActivity.java | 170 ++++---- .../upload/UploadFieldsBuilderActivity.java | 383 ++---------------- .../activities/upload/UploadsCourse.java | 66 +++ .../activities/upload/UploadsHelper.java | 5 +- .../gr/thmmy/mthmmy/base/BaseApplication.java | 5 +- .../gr/thmmy/mthmmy/base/BaseFragment.java | 1 + .../thmmy/mthmmy/editorview/EditorView.java | 11 +- .../mthmmy/editorview/EmojiKeyboard.java | 5 +- .../editorview/EmojiKeyboardAdapter.java | 1 + .../editorview/FormatButtonsAdapter.java | 1 + .../java/gr/thmmy/mthmmy/model/Bookmark.java | 6 +- .../main/java/gr/thmmy/mthmmy/model/Post.java | 4 +- .../gr/thmmy/mthmmy/model/UploadFile.java | 1 + .../mthmmy/services/NotificationService.java | 7 +- .../mthmmy/services/UploadsReceiver.java | 4 +- .../thmmy/mthmmy/session/SessionManager.java | 5 +- .../utils/AppCompatSpinnerWithoutDefault.java | 4 +- .../utils/CustomLinearLayoutManager.java | 1 + .../java/gr/thmmy/mthmmy/utils/FileUtils.java | 3 +- .../mthmmy/utils/ScrollAwareFABBehavior.java | 1 - .../utils/ScrollAwareLinearBehavior.java | 4 +- .../java/gr/thmmy/mthmmy/utils/TakePhoto.java | 3 +- .../mthmmy/utils/ToggledBackgroundButton.java | 27 ++ .../mthmmy/utils/parsing/ParseHelpers.java | 2 +- .../thmmy/mthmmy/viewmodel/BaseViewModel.java | 1 + .../mthmmy/viewmodel/ShoutboxViewModel.java | 1 + .../mthmmy/viewmodel/TopicViewModel.java | 3 +- app/src/main/res/layout/activity_upload.xml | 2 +- app/src/main/res/values/uploads_courses.xml | 153 +++++++ 56 files changed, 516 insertions(+), 534 deletions(-) create mode 100644 app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java create mode 100644 app/src/main/java/gr/thmmy/mthmmy/utils/ToggledBackgroundButton.java create mode 100644 app/src/main/res/values/uploads_courses.xml diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java index 77a6aebd..0963be99 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java @@ -14,11 +14,12 @@ import android.widget.FrameLayout; import android.widget.ScrollView; import android.widget.TextView; -import com.google.android.material.appbar.AppBarLayout; - import androidx.appcompat.app.AlertDialog; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.drawerlayout.widget.DrawerLayout; + +import com.google.android.material.appbar.AppBarLayout; + import gr.thmmy.mthmmy.BuildConfig; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java index 29ab9b1b..a24209e5 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java @@ -10,10 +10,11 @@ import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.Toast; -import com.google.firebase.analytics.FirebaseAnalytics; - import androidx.appcompat.widget.AppCompatButton; import androidx.preference.PreferenceManager; + +import com.google.firebase.analytics.FirebaseAnalytics; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.base.BaseActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java index 0effdaa3..6f3cea60 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardActivity.java @@ -8,6 +8,11 @@ import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; +import androidx.appcompat.app.AlertDialog; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.google.android.material.floatingactionbutton.FloatingActionButton; import org.jsoup.nodes.Document; @@ -17,10 +22,6 @@ import org.jsoup.select.Elements; import java.util.ArrayList; import java.util.Objects; -import androidx.appcompat.app.AlertDialog; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.activities.create_content.CreateContentActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java index 6c5e50db..2e864229 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/board/BoardAdapter.java @@ -12,10 +12,11 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.recyclerview.widget.RecyclerView; + import java.util.ArrayList; import java.util.Objects; -import androidx.recyclerview.widget.RecyclerView; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.model.Board; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java index b42a8caf..3a00881c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksActivity.java @@ -4,16 +4,17 @@ import android.content.Intent; import android.os.Bundle; import android.widget.Toast; -import com.google.android.material.tabs.TabLayout; - -import java.util.ArrayList; -import java.util.List; - import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.tabs.TabLayout; + +import java.util.ArrayList; +import java.util.List; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.topic.TopicActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksBoardFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksBoardFragment.java index 5b8c8d01..814586ea 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksBoardFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksBoardFragment.java @@ -12,11 +12,12 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; -import java.util.ArrayList; - import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; + +import java.util.ArrayList; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.model.Bookmark; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksTopicFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksTopicFragment.java index 4316db4b..e9081fbd 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksTopicFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksTopicFragment.java @@ -12,11 +12,12 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; -import java.util.ArrayList; - import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; + +import java.util.ArrayList; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.model.Bookmark; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java index e4c3676c..95e0334c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsActivity.java @@ -10,6 +10,12 @@ import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; @@ -17,12 +23,6 @@ import org.jsoup.select.Elements; import java.util.ArrayList; import java.util.Objects; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.floatingactionbutton.FloatingActionButton; - import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.upload.UploadActivity; import gr.thmmy.mthmmy.base.BaseActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java index 5b6ec26e..d5ca46ad 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java @@ -12,12 +12,13 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.recyclerview.widget.RecyclerView; + import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Objects; -import androidx.recyclerview.widget.RecyclerView; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Download; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java index af1a4cf2..b102c7f7 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java @@ -7,11 +7,6 @@ import android.os.Build; import android.os.Bundle; import android.widget.Toast; -import com.google.android.material.tabs.TabLayout; - -import java.util.ArrayList; -import java.util.List; - import androidx.appcompat.app.AppCompatDelegate; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -19,6 +14,12 @@ import androidx.fragment.app.FragmentPagerAdapter; import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.preference.PreferenceManager; import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.tabs.TabLayout; + +import java.util.ArrayList; +import java.util.List; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.LoginActivity; import gr.thmmy.mthmmy.activities.board.BoardActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java index 718c1b8d..d7ab706a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumAdapter.java @@ -6,14 +6,15 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + import com.bignerdranch.expandablerecyclerview.ChildViewHolder; import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter; import com.bignerdranch.expandablerecyclerview.ParentViewHolder; import java.util.List; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.Board; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java index 70e78af5..f366f295 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java @@ -9,6 +9,10 @@ import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.Toast; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter; import org.jsoup.nodes.Document; @@ -19,9 +23,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseApplication; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java index 31871069..15589d45 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java @@ -6,10 +6,11 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import java.util.List; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.TopicSummary; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java index 6c194c0e..4f4517d1 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java @@ -9,6 +9,10 @@ import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.Toast; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import org.jsoup.nodes.Document; import org.jsoup.select.Elements; @@ -17,9 +21,6 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.TopicSummary; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java index 8810da1a..3818145a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java @@ -5,10 +5,11 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import java.util.List; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.TopicSummary; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java index 0c47bac5..cec14e97 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java @@ -10,6 +10,11 @@ import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; @@ -18,10 +23,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.TopicSummary; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java index 38181f46..e3425c3c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java @@ -18,6 +18,13 @@ import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.content.res.ResourcesCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; + import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.tabs.TabLayout; import com.squareup.picasso.Picasso; @@ -31,12 +38,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.core.content.res.ResourcesCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentPagerAdapter; -import androidx.viewpager.widget.ViewPager; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.profile.latestPosts.LatestPostsFragment; import gr.thmmy.mthmmy.activities.profile.stats.StatsFragment; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java index 6054a05f..d2a4d1cb 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java @@ -8,9 +8,10 @@ import android.webkit.WebView; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.recyclerview.widget.RecyclerView; + import java.util.ArrayList; -import androidx.recyclerview.widget.RecyclerView; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.model.PostSummary; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java index f2c17ff2..59fa6421 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java @@ -8,6 +8,10 @@ import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.Toast; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -17,9 +21,6 @@ import java.util.ArrayList; import javax.net.ssl.SSLHandshakeException; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseFragment; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java index 8ecf48bd..a0b3dafc 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java @@ -12,6 +12,8 @@ import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; +import androidx.fragment.app.Fragment; + import com.github.mikephil.charting.charts.HorizontalBarChart; import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.components.AxisBase; @@ -37,7 +39,6 @@ import java.util.List; import javax.net.ssl.SSLHandshakeException; -import androidx.fragment.app.Fragment; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; import me.zhanghai.android.materialprogressbar.MaterialProgressBar; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java index 2d4ba9bf..4df4598f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java @@ -13,6 +13,8 @@ import android.webkit.WebView; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.fragment.app.Fragment; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -21,7 +23,6 @@ import org.jsoup.select.Elements; import java.util.ArrayList; import java.util.Objects; -import androidx.fragment.app.Fragment; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import timber.log.Timber; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java index a884d3a6..c9637dd0 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsActivity.java @@ -3,6 +3,7 @@ package gr.thmmy.mthmmy.activities.settings; import android.os.Bundle; import androidx.fragment.app.FragmentTransaction; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java index a66f91ae..ec5907b6 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/settings/SettingsFragment.java @@ -11,12 +11,13 @@ import android.provider.Settings; import android.view.View; import android.widget.Toast; -import java.util.ArrayList; - import androidx.annotation.NonNull; import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; + +import java.util.ArrayList; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseApplication; import timber.log.Timber; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutAdapter.java index 82a3389e..9976975e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutAdapter.java @@ -16,6 +16,7 @@ import android.webkit.WebViewClient; import android.widget.TextView; import androidx.annotation.NonNull; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java index 35d86faf..ad42a414 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/shoutbox/ShoutboxFragment.java @@ -16,6 +16,7 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProviders; import androidx.recyclerview.widget.LinearLayoutManager; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.editorview.EditorView; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java index 639ab3c7..d3d97663 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java @@ -28,16 +28,17 @@ import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; - -import java.util.ArrayList; - import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatDelegate; import androidx.core.content.res.ResourcesCompat; import androidx.lifecycle.ViewModelProviders; import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; + +import java.util.ArrayList; + import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.topic.tasks.EditTask; import gr.thmmy.mthmmy.activities.topic.tasks.PrepareForEditTask; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java index 5472a742..0e885cc3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java @@ -39,6 +39,14 @@ import android.widget.RadioGroup; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.appcompat.widget.AppCompatButton; +import androidx.core.content.res.ResourcesCompat; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.RecyclerView; + import com.github.mikephil.charting.charts.HorizontalBarChart; import com.github.mikephil.charting.components.XAxis; import com.github.mikephil.charting.components.YAxis; @@ -53,13 +61,6 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.content.res.AppCompatResources; -import androidx.appcompat.widget.AppCompatButton; -import androidx.core.content.res.ResourcesCompat; -import androidx.lifecycle.ViewModelProviders; -import androidx.recyclerview.widget.RecyclerView; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java index 67f612e3..31f51b8e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java @@ -6,6 +6,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.content.res.Resources; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -53,6 +54,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.Locale; import java.util.UUID; @@ -71,7 +73,9 @@ import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import timber.log.Timber; import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.UPLOADING_APP_SIGNATURE_ENABLE_KEY; -import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.BUNDLE_UPLOAD_FIELD_BUILDER_COURSE; +import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_GREEKLISH_NAME; +import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_MINIFIED_NAME; +import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_NAME; import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER; import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.RESULT_DESCRIPTION; import static gr.thmmy.mthmmy.activities.upload.UploadFieldsBuilderActivity.RESULT_FILENAME; @@ -84,7 +88,7 @@ public class UploadActivity extends BaseActivity { */ 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 uploadedFromThmmyPromptHtml = "
uploaded from mTHMMY"; + private static final String uploadedFromTHMMYPromptHtml = "
uploaded from mTHMMY"; /** * Request codes used in activities for result (AFR) calls */ @@ -100,12 +104,15 @@ public class UploadActivity extends BaseActivity { private static final int MAX_FILE_SIZE_SUPPORTED = 45000000; - //private UploadsReceiver uploadsReceiver = new UploadsReceiver(); + private HashMap uploadsCourses; + private ArrayList uploadRootCategories = new ArrayList<>(); private ParseUploadPageTask parseUploadPageTask; private ArrayList bundleCategory; private String categorySelected = "-1"; private String uploaderProfileIndex = "1"; + private UploadsCourse uploadsCourse; + private String semester = ""; private ArrayList filesList = new ArrayList<>(); private File photoFileCreated = null; @@ -168,64 +175,19 @@ public class UploadActivity extends BaseActivity { rootCategorySpinner.setOnItemSelectedListener(new CustomOnItemSelectedListener(uploadRootCategories)); titleDescriptionBuilderButton = findViewById(R.id.upload_title_description_builder); + titleDescriptionBuilderButton.setEnabled(false); titleDescriptionBuilderButton.setOnClickListener(view -> { - if (categorySelected.equals("-1")) { - Toast.makeText(view.getContext(), "Please choose a category first", Toast.LENGTH_SHORT).show(); - return; - } - - int numberOfSpinners = categoriesSpinners.getChildCount(); - - if (numberOfSpinners < 3) { - Toast.makeText(view.getContext(), "Please choose a course category", Toast.LENGTH_SHORT).show(); - return; - } - - String maybeSemester = "", maybeCourse = ""; - - if (numberOfSpinners == 5) { - if (((AppCompatSpinnerWithoutDefault) categoriesSpinners.getChildAt(numberOfSpinners - 1)). - getSelectedItemPosition() == -1) { - maybeSemester = (String) ((AppCompatSpinnerWithoutDefault) - categoriesSpinners.getChildAt(numberOfSpinners - 4)).getSelectedItem(); - maybeCourse = (String) ((AppCompatSpinnerWithoutDefault) - categoriesSpinners.getChildAt(numberOfSpinners - 2)).getSelectedItem(); - } else { - Toast.makeText(view.getContext(), "Please choose a course category", Toast.LENGTH_SHORT).show(); - } - } else if (numberOfSpinners == 4) { - maybeSemester = (String) ((AppCompatSpinnerWithoutDefault) - categoriesSpinners.getChildAt(numberOfSpinners - 3)).getSelectedItem(); - maybeCourse = (String) ((AppCompatSpinnerWithoutDefault) - categoriesSpinners.getChildAt(numberOfSpinners - 1)).getSelectedItem(); - } else { - maybeSemester = (String) ((AppCompatSpinnerWithoutDefault) - categoriesSpinners.getChildAt(numberOfSpinners - 2)).getSelectedItem(); - maybeCourse = (String) ((AppCompatSpinnerWithoutDefault) - categoriesSpinners.getChildAt(numberOfSpinners - 1)).getSelectedItem(); - } - - if (!maybeSemester.contains("εξάμηνο") && !maybeSemester.contains("Εξάμηνο")) { - Toast.makeText(view.getContext(), "Please choose a course category", Toast.LENGTH_SHORT).show(); - return; + if(uploadsCourse!=null && !uploadsCourse.getName().equals("") && !semester.equals("")){ + Intent intent = new Intent(UploadActivity.this, UploadFieldsBuilderActivity.class); + Bundle builderExtras = new Bundle(); + builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_NAME, uploadsCourse.getName()); + builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_MINIFIED_NAME, uploadsCourse.getMinifiedName()); + builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_GREEKLISH_NAME, uploadsCourse.getGreeklishName()); + builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER, semester); + intent.putExtras(builderExtras); + startActivityForResult(intent, AFR_REQUEST_CODE_FIELDS_BUILDER); } - if (maybeCourse == null) { - Toast.makeText(view.getContext(), "Please choose a course", Toast.LENGTH_SHORT).show(); - return; - } - - //Fixes course and semester - String course = maybeCourse.replaceAll("-", "").replace("(ΝΠΣ)", "").trim(); - String semester = maybeSemester.replaceAll("-", "").trim().substring(0, 1); - - Intent intent = new Intent(UploadActivity.this, UploadFieldsBuilderActivity.class); - Bundle builderExtras = new Bundle(); - builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE, course); - builderExtras.putString(BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER, semester); - intent.putExtras(builderExtras); - startActivityForResult(intent, AFR_REQUEST_CODE_FIELDS_BUILDER); }); - titleDescriptionBuilderButton.setEnabled(false); uploadTitle = findViewById(R.id.upload_title); uploadDescription = findViewById(R.id.upload_description); @@ -343,7 +305,7 @@ public class UploadActivity extends BaseActivity { //Checks settings and possibly adds "Uploaded from mTHMMY" string to description SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(view.getContext()); if (sharedPrefs.getBoolean(UPLOADING_APP_SIGNATURE_ENABLE_KEY, true)) { - uploadDescriptionText[0] += uploadedFromThmmyPromptHtml; + uploadDescriptionText[0] += uploadedFromTHMMYPromptHtml; } for (UploadFile file : filesList) { @@ -450,6 +412,10 @@ public class UploadActivity extends BaseActivity { updateUIElements(); titleDescriptionBuilderButton.setEnabled(true); } + + Resources res = getResources(); + uploadsCourses = new HashMap<>(UploadsCourse + .generateUploadsCourses(res.getStringArray(R.array.string_array_uploads_courses))); } @Override @@ -493,7 +459,7 @@ public class UploadActivity extends BaseActivity { if (!hasModifiedFilename) { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); - String zipFilename = "mThmmy_" + timeStamp + ".zip"; + String zipFilename = "mTHMMY_" + timeStamp + ".zip"; uploadFilename.setText(zipFilename); hasModifiedFilename = false; } @@ -542,7 +508,7 @@ public class UploadActivity extends BaseActivity { if (!hasModifiedFilename) { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); - String zipFilename = "mThmmy_" + timeStamp + ".zip"; + String zipFilename = "mTHMMY_" + timeStamp + ".zip"; uploadFilename.setText(zipFilename); hasModifiedFilename = false; } @@ -574,7 +540,7 @@ public class UploadActivity extends BaseActivity { if (!hasModifiedFilename) { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); - String zipFilename = "mThmmy_" + timeStamp + ".zip"; + String zipFilename = "mTHMMY_" + timeStamp + ".zip"; uploadFilename.setText(zipFilename); hasModifiedFilename = false; } @@ -881,6 +847,7 @@ public class UploadActivity extends BaseActivity { } categorySelected = parentCategories.get(position).getValue(); + setCourseAndSemester(); //Adds new sub-category spinner if (parentCategories.get(position).hasSubCategories()) { @@ -924,7 +891,72 @@ public class UploadActivity extends BaseActivity { } @Override - public void onNothingSelected(AdapterView parent) { + public void onNothingSelected(AdapterView parent) { } + + private void setCourseAndSemester(){ + uploadsCourse = null; + semester = ""; + + if (categorySelected.equals("-1")) { + titleDescriptionBuilderButton.setEnabled(false); + return; + } + + int numberOfSpinners = categoriesSpinners.getChildCount(); + + if (numberOfSpinners < 3) { + titleDescriptionBuilderButton.setEnabled(false); + return; + } + + String maybeSemester = ""; + String maybeCourse = ""; + + if (numberOfSpinners == 5) { + if (((AppCompatSpinnerWithoutDefault) categoriesSpinners.getChildAt(numberOfSpinners - 1)). + getSelectedItemPosition() == -1) { + maybeSemester = (String) ((AppCompatSpinnerWithoutDefault) + categoriesSpinners.getChildAt(numberOfSpinners - 4)).getSelectedItem(); + maybeCourse = (String) ((AppCompatSpinnerWithoutDefault) + categoriesSpinners.getChildAt(numberOfSpinners - 2)).getSelectedItem(); + } + else return; + } else if (numberOfSpinners == 4) { + maybeSemester = (String) ((AppCompatSpinnerWithoutDefault) + categoriesSpinners.getChildAt(numberOfSpinners - 3)).getSelectedItem(); + maybeCourse = (String) ((AppCompatSpinnerWithoutDefault) + categoriesSpinners.getChildAt(numberOfSpinners - 1)).getSelectedItem(); + } else { + maybeSemester = (String) ((AppCompatSpinnerWithoutDefault) + categoriesSpinners.getChildAt(numberOfSpinners - 2)).getSelectedItem(); + maybeCourse = (String) ((AppCompatSpinnerWithoutDefault) + categoriesSpinners.getChildAt(numberOfSpinners - 1)).getSelectedItem(); + } + + if (!maybeSemester.contains("εξάμηνο") && !maybeSemester.contains("Εξάμηνο")) { + titleDescriptionBuilderButton.setEnabled(false); + return; + } + + if (maybeCourse == null) { + titleDescriptionBuilderButton.setEnabled(false); + return; + } + + String retrievedCourse = maybeCourse.replaceAll("-", "").replace("(ΝΠΣ)", "").trim(); + String retrievedSemester = maybeSemester.replaceAll("-", "").trim().substring(0, 1); + + UploadsCourse foundUploadsCourse = UploadsCourse.findCourse(retrievedCourse, uploadsCourses); + + if(foundUploadsCourse != null){ + uploadsCourse = foundUploadsCourse; + semester = retrievedSemester; + Timber.i("Selected course: %s, semester: %s", uploadsCourse.getName(), semester); + titleDescriptionBuilderButton.setEnabled(true); + return; + } + + titleDescriptionBuilderButton.setEnabled(false); } } @@ -987,7 +1019,6 @@ public class UploadActivity extends BaseActivity { @Override protected void postExecution(ResultCode result) { updateUIElements(); - titleDescriptionBuilderButton.setEnabled(true); progressBar.setVisibility(ProgressBar.GONE); } } @@ -1032,14 +1063,14 @@ public class UploadActivity extends BaseActivity { @Override protected Boolean doInBackground(Uri... filesToZip) { - if (weakActivity == null || zipFilename == null) { + if (weakActivity == null || zipFilename == null) return false; - } + File zipFile = UploadsHelper.createZipFile(zipFilename); - if (zipFile == null) { + if (zipFile == null) return false; - } + zipFileUri = FileProvider.getUriForFile(weakActivity.get(), weakActivity.get().getPackageName() + ".provider", zipFile); @@ -1050,9 +1081,8 @@ public class UploadActivity extends BaseActivity { @Override protected void onPostExecute(Boolean result) { - if (weakActivity == null) { + if (weakActivity == null) return; - } if (!result) { Toast.makeText(weakActivity.get(), "Couldn't create zip!", Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java index ebf221f6..ffa6f26e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadFieldsBuilderActivity.java @@ -3,7 +3,6 @@ package gr.thmmy.mthmmy.activities.upload; import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import androidx.annotation.Nullable; import android.text.Editable; import android.text.TextWatcher; import android.view.View; @@ -12,23 +11,26 @@ import android.widget.LinearLayout; import android.widget.RadioGroup; import android.widget.Toast; +import androidx.annotation.Nullable; + import java.util.Calendar; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.base.BaseActivity; import timber.log.Timber; public class UploadFieldsBuilderActivity extends BaseActivity { - static final String BUNDLE_UPLOAD_FIELD_BUILDER_COURSE = "UPLOAD_FIELD_BUILDER_COURSE"; + + static final String BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_NAME = "BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_NAME"; + static final String BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_MINIFIED_NAME = "BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_MINIFIED_NAME"; + static final String BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_GREEKLISH_NAME = "BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_GREEKLISH_NAME"; static final String BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER = "UPLOAD_FIELD_BUILDER_SEMESTER"; static final String RESULT_FILENAME = "RESULT_FILENAME"; static final String RESULT_TITLE = "RESULT_TITLE"; static final String RESULT_DESCRIPTION = "RESULT_DESCRIPTION"; - private String course, semester; + private String courseName, courseMinifiedName, courseGreeklishName, semester; private boolean isValidYear; private LinearLayout semesterChooserLinear; @@ -46,25 +48,20 @@ public class UploadFieldsBuilderActivity extends BaseActivity { int inputYear = Integer.parseInt(working); isValidYear = inputYear <= currentYear && inputYear > 1980; - } else { + } else isValidYear = false; - } - if (!isValidYear) { + if (!isValidYear) year.setError("Please enter a valid year"); - } else { + else year.setError(null); - } - } @Override - public void afterTextChanged(Editable s) { - } + public void afterTextChanged(Editable s) { } @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } + public void beforeTextChanged(CharSequence s, int start, int count, int after) { } }; @Override @@ -74,9 +71,11 @@ public class UploadFieldsBuilderActivity extends BaseActivity { Bundle extras = getIntent().getExtras(); if (extras != null) { - course = extras.getString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE); + courseName = extras.getString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_NAME); + courseMinifiedName = extras.getString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_MINIFIED_NAME); + courseGreeklishName = extras.getString(BUNDLE_UPLOAD_FIELD_BUILDER_COURSE_GREEKLISH_NAME); semester = extras.getString(BUNDLE_UPLOAD_FIELD_BUILDER_SEMESTER); - if (course == null || course.equals("") || semester == null || semester.equals("")) { + if (courseName == null || courseName.equals("") || semester == null || semester.equals("")) { Toast.makeText(this, "Something went wrong!", Toast.LENGTH_SHORT).show(); Timber.e("Bundle came empty in %s", UploadFieldsBuilderActivity.class.getSimpleName()); @@ -143,11 +142,11 @@ public class UploadFieldsBuilderActivity extends BaseActivity { private String buildFilename() { switch (typeRadio.getCheckedRadioButtonId()) { case R.id.upload_fields_builder_radio_button_exams: - return getGreeklishCourseName() + "_" + getGreeklishPeriod() + "_" + year.getText().toString(); + return courseGreeklishName + "_" + getGreeklishPeriod() + "_" + year.getText().toString(); case R.id.upload_fields_builder_radio_button_exam_solutions: - return getGreeklishCourseName() + "_" + getGreeklishPeriod() + "_" + year.getText().toString() + "_Lyseis"; + return courseGreeklishName + "_" + getGreeklishPeriod() + "_" + year.getText().toString() + "_Lyseis"; case R.id.upload_fields_builder_radio_button_notes: - return getGreeklishCourseName() + "_" + year.getText().toString() + "_Shmeiwseis"; + return courseGreeklishName + "_" + year.getText().toString() + "_Simeioseis"; default: return null; } @@ -157,11 +156,11 @@ public class UploadFieldsBuilderActivity extends BaseActivity { private String buildTitle() { switch (typeRadio.getCheckedRadioButtonId()) { case R.id.upload_fields_builder_radio_button_exams: - return getMinifiedCourseName() + " - " + "Θέματα εξετάσεων " + getPeriod() + " " + year.getText().toString(); + return courseMinifiedName + " - " + "Θέματα εξετάσεων " + getPeriod() + " " + year.getText().toString(); case R.id.upload_fields_builder_radio_button_exam_solutions: - return getMinifiedCourseName() + " - " + "Λύσεις θεμάτων " + getPeriod() + " " + year.getText().toString(); + return courseMinifiedName + " - " + "Λύσεις θεμάτων " + getPeriod() + " " + year.getText().toString(); case R.id.upload_fields_builder_radio_button_notes: - return getMinifiedCourseName() + " - " + "Σημειώσεις παραδόσεων " + year.getText().toString(); + return courseMinifiedName + " - " + "Σημειώσεις παραδόσεων " + year.getText().toString(); default: return null; } @@ -170,11 +169,11 @@ public class UploadFieldsBuilderActivity extends BaseActivity { private String buildDescription() { switch (typeRadio.getCheckedRadioButtonId()) { case R.id.upload_fields_builder_radio_button_exams: - return "Θέματα εξετάσεων " + getPeriod() + " " + year.getText().toString() + " του μαθήματος \"" + course + "\""; + return "Θέματα εξετάσεων " + getPeriod() + " " + year.getText().toString() + " του μαθήματος \"" + courseName + "\""; case R.id.upload_fields_builder_radio_button_exam_solutions: - return "Λύσεις των θεμάτων των εξετάσεων " + getPeriod() + " " + year.getText().toString() + " του μαθήματος \"" + course + "\""; + return "Λύσεις των θεμάτων των εξετάσεων " + getPeriod() + " " + year.getText().toString() + " του μαθήματος \"" + courseName + "\""; case R.id.upload_fields_builder_radio_button_notes: - return "Σημειώσεις των παραδόσεων του μαθήματος \"" + course + "\" από το " + year.getText().toString(); + return "Σημειώσεις των παραδόσεων του μαθήματος \"" + courseName + "\" από το " + year.getText().toString(); default: return null; } @@ -205,336 +204,4 @@ public class UploadFieldsBuilderActivity extends BaseActivity { return null; } } - - @Nullable - private String getGreeklishCourseName() { - return getGreeklishOrMinifiedCourseName(true); - } - - @Nullable - private String getMinifiedCourseName() { - return getGreeklishOrMinifiedCourseName(false); - } - - private String normalizeLatinNumbers(String stringWithLatinNumbers) { - String greekLatinOne = "Ι", englishLatinOne = "I"; - String normalisedString; - - //Separates the latin number suffix from the course name - final String regex = "(.+)\\ ([IΙ]+)"; - final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); - final Matcher matcher = pattern.matcher(stringWithLatinNumbers); - - if (matcher.matches() && matcher.groupCount() == 2) { - normalisedString = matcher.group(1) + " " + matcher.group(2).replaceAll(greekLatinOne, englishLatinOne); - } else { - normalisedString = stringWithLatinNumbers; - } - - return normalisedString; - } - - @Nullable - private String getGreeklishOrMinifiedCourseName(boolean greeklish) { - String normalisedCourse = normalizeLatinNumbers(course); - - if (normalisedCourse.contains(("Ψηφιακή Επεξεργασία Σήματος"))) { - return greeklish ? "PSES" : "ΨΕΣ"; - } else if (normalisedCourse.contains(("Ψηφιακή Επεξεργασία Εικόνας"))) { - return greeklish ? "psee" : "ΨΕΕ"; - } else if (normalisedCourse.contains(("Ψηφιακές Τηλεπικοινωνίες II"))) { - return greeklish ? "pshf_thlep_II" : "Ψηφιακές Τηλεπ. 2"; - } else if (normalisedCourse.contains(("Ψηφιακές Τηλεπικοινωνίες I"))) { - return greeklish ? "pshf_thlep_I" : "Ψηφιακές Τηλεπ. 1"; - } else if (normalisedCourse.contains(("Ψηφιακά Φίλτρα"))) { - return greeklish ? "filtra" : "Φίλτρα"; - } else if (normalisedCourse.contains(("Ψηφιακά Συστήματα III"))) { - return greeklish ? "pshfiaka_III" : "Ψηφιακά 3"; - } else if (normalisedCourse.contains(("Ψηφιακά Συστήματα II"))) { - return greeklish ? "pshfiaka_II" : "Ψηφιακά 2"; - } else if (normalisedCourse.contains(("Ψηφιακά Συστήματα I"))) { - return greeklish ? "pshfiaka_I" : "Ψηφιακά 1"; - } else if (normalisedCourse.contains(("Φωτονική Τεχνολογία"))) { - return greeklish ? "fwtonikh" : "Φωτονική"; - } else if (normalisedCourse.contains(("Φυσική I"))) { - return greeklish ? "fysikh_I" : "Φυσική 1"; - } else if (normalisedCourse.contains(("Υψηλές Τάσεις III"))) { - return greeklish ? "ypshles_III" : "Υψηλές 3"; - } else if (normalisedCourse.contains(("Υψηλές Τάσεις II"))) { - return greeklish ? "ypshles_II" : "Υψηλές 2"; - } else if (normalisedCourse.contains(("Υψηλές Τάσεις I"))) { - return greeklish ? "ypshles_I" : "Υψηλές 1"; - } else if (normalisedCourse.contains(("Υψηλές Τάσεις 4"))) { - return greeklish ? "ypshles_IV" : "Υψηλές 4"; - } else if (normalisedCourse.contains(("Υπολογιστικός Ηλεκτρομαγνητισμός"))) { - return greeklish ? "ypologistikos_HM" : "Υπολογιστικός Η/Μ"; - } else if (normalisedCourse.contains(("Υπολογιστικές Μέθοδοι στα Ενεργειακά Συστήματα"))) { - return greeklish ? "ymes" : "ΥΜΕΣ"; - } else if (normalisedCourse.contains(("Τηλεπικοινωνιακή Ηλεκτρονική"))) { - return greeklish ? "tilep_ilektr" : "Τηλεπ. Ηλεκτρ."; - } else if (normalisedCourse.contains(("Τηλεοπτικά Συστήματα"))) { - return greeklish ? "tileoptika" : "Τηλεοπτικά"; - } else if (normalisedCourse.contains(("Τεχνολογία Λογισμικού"))) { - return greeklish ? "SE" : "Τεχνολογία Λογισμικού"; - } else if (normalisedCourse.contains(("Τεχνολογία Ηλεκτροτεχνικών Υλικών"))) { - return greeklish ? "Hlektrotexnika_Ylika" : "Ηλεκτροτεχνικά Υλικά"; - } else if (normalisedCourse.contains(("Τεχνολογία Ήχου και Εικόνας"))) { - return greeklish ? "texn_hxoy_eikonas" : "Τεχνολογία Ήχου και Εικόνας"; - } else if (normalisedCourse.contains(("Τεχνική Μηχανική"))) { - return greeklish ? "texn_mhxan" : "Τεχν. Μηχαν."; - } else if (normalisedCourse.contains(("Τεχνικές μη Καταστρεπτικών Δοκιμών"))) { - return greeklish ? "non_destructive_tests" : "Μη Καταστρεπτικές Δοκιμές"; - } else if (normalisedCourse.contains(("Τεχνικές Σχεδίασης με Η/Υ"))) { - return greeklish ? "sxedio" : "Σχέδιο"; - } else if (normalisedCourse.contains(("Τεχνικές Κωδικοποίησης"))) { - return greeklish ? "texn_kwdikopoihshs" : "Τεχνικές Κωδικοποίησης"; - } else if (normalisedCourse.contains(("Τεχνικές Βελτιστοποίησης"))) { - return greeklish ? "veltistopoihsh" : "Βελτιστοποίηση"; - } else if (normalisedCourse.contains(("Σύνθεση Τηλεπικοινωνιακών Διατάξεων"))) { - return greeklish ? "synth_thlep_diataksewn" : "Σύνθεση Τηλεπ. Διατάξεων"; - } else if (normalisedCourse.contains(("Σύνθεση Ενεργών και Παθητικών Κυκλωμάτων"))) { - return greeklish ? "synthesh" : "Σύνθεση"; - } else if (normalisedCourse.contains(("Σχεδίαση Συστημάτων VLSI"))) { - return greeklish ? "VLSI" : "VLSI"; - } else if (normalisedCourse.contains(("Συστήματα Υπολογιστών (Υπολογιστικά Συστήματα)"))) { - return greeklish ? "sys_ypologistwn" : "Συσ. Υπολογιστών"; - } else if (normalisedCourse.contains(("Συστήματα Πολυμέσων και Εικονική Πραγματικότητα"))) { - return greeklish ? "polymesa" : "Πολυμέσα"; - } else if (normalisedCourse.contains(("Συστήματα Μικροϋπολογιστών"))) { - return greeklish ? "mikro_I" : "Μίκρο 1"; - } else if (normalisedCourse.contains(("Συστήματα Ηλεκτροκίνησης"))) { - return greeklish ? "hlektrokinhsh" : "Ηλεκτροκίνηση"; - } else if (normalisedCourse.contains(("Συστήματα Ηλεκτρικής Ενέργειας III"))) { - return greeklish ? "SHE_III" : "ΣΗΕ 3"; - } else if (normalisedCourse.contains(("Συστήματα Ηλεκτρικής Ενέργειας II"))) { - return greeklish ? "SHE_II" : "ΣΗΕ 2"; - } else if (normalisedCourse.contains(("Συστήματα Ηλεκτρικής Ενέργειας I"))) { - return greeklish ? "SHE_I" : "ΣΗΕ 1"; - } else if (normalisedCourse.contains(("Συστήματα Αυτομάτου Ελέγχου III"))) { - return greeklish ? "SAE_III" : "ΣΑΕ 3"; - } else if (normalisedCourse.contains(("Συστήματα Αυτομάτου Ελέγχου II"))) { - return greeklish ? "SAE_II" : "ΣΑΕ 2"; - } else if (normalisedCourse.contains(("Συστήματα Αυτομάτου Ελέγχου I"))) { - return greeklish ? "SAE_1" : "ΣΑΕ 1"; - } else if (normalisedCourse.contains(("Στοχαστικό Σήμα"))) { - return greeklish ? "stox_shma" : "Στοχ. Σήμα"; - } else if (normalisedCourse.contains(("Σταθμοί Παραγωγής Ηλεκτρικής Ενέργειας"))) { - return greeklish ? "SPHE" : "ΣΠΗΕ"; - } else if (normalisedCourse.contains(("Σερβοκινητήρια Συστήματα"))) { - return greeklish ? "servo" : "Σέρβο"; - } else if (normalisedCourse.contains(("Σήματα και Συστήματα"))) { - return greeklish ? "analog_shma" : "Σύματα & Συστήματα"; - } else if (normalisedCourse.contains(("Ρομποτική"))) { - return greeklish ? "rompotikh" : "Ρομποτική"; - } else if (normalisedCourse.contains(("Προσομοίωση και Μοντελοποίηση Συστημάτων"))) { - return greeklish ? "montelopoihsh" : "Μοντελοποίηση"; - } else if (normalisedCourse.contains(("Προηγμένες Τεχνικές Επεξεργασίας Σήματος"))) { - return greeklish ? "ptes" : "ΠΤΕΣ"; - } else if (normalisedCourse.contains(("Προγραμματιστικές Τεχνικές"))) { - return greeklish ? "cpp" : "Προγραμματ. Τεχν."; - } else if (normalisedCourse.contains(("Προγραμματιζόμενα Κυκλώματα ASIC"))) { - return greeklish ? "asic" : "ASIC"; - } else if (normalisedCourse.contains(("Παράλληλα και Κατανεμημένα Συστήματα"))) { - return greeklish ? "parallhla" : "Παράλληλα"; - } else if (normalisedCourse.contains(("Οργάνωση και Διοίκηση Εργοστασίων"))) { - return greeklish ? "organ_dioik_ergostasiwn" : "Οργάνωση και Διοίκηση Εργοστασίων"; - } else if (normalisedCourse.contains(("Οργάνωση Υπολογιστών"))) { - return greeklish ? "org_ypol" : "Οργάνωση Υπολ."; - } else if (normalisedCourse.contains(("Οπτική II"))) { - return greeklish ? "optikh_II" : "Οπτική 2"; - } else if (normalisedCourse.contains(("Οπτική I"))) { - return greeklish ? "optikh_I" : "Οπτική 1"; - } else if (normalisedCourse.contains(("Οπτικές Επικοινωνίες"))) { - return greeklish ? "optikes_thlep" : "Οπτικές Τηλεπ."; - } else if (normalisedCourse.contains(("Μικροκύματα II"))) { - return greeklish ? "mikrokymata_II" : "Μικροκύματα 2"; - } else if (normalisedCourse.contains(("Μικροκύματα I"))) { - return greeklish ? "mikrokymata_I" : "Μικροκύματα 1"; - } else if (normalisedCourse.contains(("Μικροκυματική Τηλεπισκόπηση"))) { - return greeklish ? "thlepiskophsh" : "Τηλεπισκόπηση"; - } else if (normalisedCourse.contains(("Μικροεπεξεργαστές και Περιφερειακά"))) { - return greeklish ? "mikro_II" : "Μίκρο 2"; - } else if (normalisedCourse.contains(("Μετάδοση Θερμότητας"))) { - return greeklish ? "metadosi_therm" : "Μετάδοση Θερμ."; - } else if (normalisedCourse.contains(("Λογισμός II"))) { - return greeklish ? "logismos_II" : "Λογισμός 2"; - } else if (normalisedCourse.contains(("Λογισμός I"))) { - return greeklish ? "logismos_I" : "Λογισμός 1"; - } else if (normalisedCourse.contains(("Λογική Σχεδίαση"))) { - return greeklish ? "logiki_sxediash" : "Λογική Σχεδίαση"; - } else if (normalisedCourse.contains(("Λειτουργικά Συστήματα"))) { - return greeklish ? "OS" : "Λειτουργικά"; - } else if (normalisedCourse.contains(("Κινητές και Δορυφορικές Επικοινωνίες"))) { - return greeklish ? "kinhtes_doryforikes_epik" : "Κινητές & Δορυφορικές Επικοινωνίες"; - } else if (normalisedCourse.contains(("Κβαντική Φυσική"))) { - return greeklish ? "kvantikh" : "Κβαντική"; - } else if (normalisedCourse.contains(("Θεωρία και Τεχνολογία Πυρηνικών Αντιδραστήρων"))) { - return greeklish ? "texn_antidrasthrwn" : "Τεχνολογία Αντιδραστήρων"; - } else if (normalisedCourse.contains(("Θεωρία Υπολογισμών και Αλγορίθμων"))) { - return greeklish ? "thya" : "ΘΥΑ"; - } else if (normalisedCourse.contains(("Θεωρία Σκέδασης"))) { - return greeklish ? "skedash" : "Σκέδαση"; - } else if (normalisedCourse.contains(("Θεωρία Σημάτων και Γραμμικών Συστημάτων"))) { - return greeklish ? "analog_shma" : "Σύματα & Συστήματα"; - } else if (normalisedCourse.contains(("Θεωρία Πληροφοριών"))) { - return greeklish ? "theoria_plir" : "Θεωρία Πληρ."; - } else if (normalisedCourse.contains(("Θεωρία Πιθανοτήτων και Στατιστική"))) { - return greeklish ? "pithanothtes" : "Πιθανότητες"; - } else if (normalisedCourse.contains(("Ημιαγωγά Υλικά: Θεωρία-Διατάξεις"))) { - return greeklish ? "Hmiagwga_Ylika" : "Ημιαγωγά Υλικά"; - } else if (normalisedCourse.contains(("Ηλεκτρονική III"))) { - return greeklish ? "hlektronikh_III" : "Ηλεκτρονική 3"; - } else if (normalisedCourse.contains(("Ηλεκτρονική II"))) { - return greeklish ? "hlektronikh_2" : "Ηλεκτρονική 2"; - } else if (normalisedCourse.contains(("Ηλεκτρονική I"))) { - return greeklish ? "hlektronikh_1" : "Ηλεκτρονική 1"; - } else if (normalisedCourse.contains(("Ηλεκτρονικές Διατάξεις και Μετρήσεις"))) { - return greeklish ? "hlektron_diatakseis_metrhseis" : "Ηλεκτρονικές Διατάξεις και Μετρήσεις"; - } else if (normalisedCourse.contains(("Ηλεκτρονικά Ισχύος II"))) { - return greeklish ? "isxyos_II" : "Ισχύος 2"; - } else if (normalisedCourse.contains(("Ηλεκτρονικά Ισχύος I"))) { - return greeklish ? "isxyos_I" : "Ισχύος 1"; - } else if (normalisedCourse.contains(("Ηλεκτρομαγνητικό Πεδίο II"))) { - return greeklish ? "pedio_II" : "Πεδίο 2"; - } else if (normalisedCourse.contains(("Ηλεκτρομαγνητικό Πεδίο I"))) { - return greeklish ? "pedio_I" : "Πεδίο 1"; - } else if (normalisedCourse.contains(("Ηλεκτρομαγνητική Συμβατότητα"))) { - return greeklish ? "HM_symvatothta" : "H/M Συμβατότητα"; - } else if (normalisedCourse.contains(("Ηλεκτρολογικά Υλικά"))) { - return greeklish ? "ylika" : "Ηλεκτρ. Υλικά"; - } else if (normalisedCourse.contains(("Ηλεκτρική Οικονομία"))) { - return greeklish ? "hlektr_oikonomia" : "Ηλεκτρική Οικονομία"; - } else if (normalisedCourse.contains(("Ηλεκτρικές Μηχανές Γ'"))) { - return greeklish ? "mhxanes_C" : "Μηχανές Γ"; - } else if (normalisedCourse.contains(("Ηλεκτρικές Μηχανές Β'"))) { - return greeklish ? "mhxanes_B" : "Μηχανές Β"; - } else if (normalisedCourse.contains(("Ηλεκτρικές Μηχανές Α'"))) { - return greeklish ? "mhxanes_A" : "Μηχανές Α"; - } else if (normalisedCourse.contains(("Ηλεκτρικές Μετρήσεις II"))) { - return greeklish ? "metrhseis_II" : "Μετρήσεις 2"; - } else if (normalisedCourse.contains(("Ηλεκτρικές Μετρήσεις I"))) { - return greeklish ? "metrhseis_1" : "Μετρήσεις 1"; - } else if (normalisedCourse.contains(("Ηλεκτρικά Κυκλώματα III"))) { - return greeklish ? "kyklwmata_I" : "Κυκλώματα 3"; - } else if (normalisedCourse.contains(("Ηλεκτρικά Κυκλώματα II"))) { - return greeklish ? "kyklwmata_II" : "Κυκλώματα 2"; - } else if (normalisedCourse.contains(("Ηλεκτρικά Κυκλώματα I"))) { - return greeklish ? "kyklwmata_I" : "Κυκλώματα 1"; - } else if (normalisedCourse.contains(("Ηλεκτρακουστική II"))) { - return greeklish ? "hlektroakoystikh_II" : "Ηλεκτροακουστική 2"; - } else if (normalisedCourse.contains(("Ηλεκτρακουστική I"))) { - return greeklish ? "hlektroakoystikh_I" : "Ηλεκτροακουστική 1"; - } else if (normalisedCourse.contains(("Εφαρμοσμένη Θερμοδυναμική"))) { - return greeklish ? "thermodynamikh" : "Θερμοδυναμική"; - } else if (normalisedCourse.contains(("Εφαρμοσμένα Μαθηματικά II"))) { - return greeklish ? "efarmosmena_math_II" : "Εφαρμοσμένα 2"; - } else if (normalisedCourse.contains(("Εφαρμοσμένα Μαθηματικά I"))) { - return greeklish ? "efarmosmena_math_I" : "Εφαρμοσμένα 1"; - } else if (normalisedCourse.contains(("Εφαρμογές Τηλεπικοινωνιακών Διατάξεων"))) { - return greeklish ? "efarm_thlep_diataksewn" : "Εφαρμογές Τηλεπ. Διατάξεων"; - } else if (normalisedCourse.contains(("Ευφυή Συστήματα Ρομπότ"))) { - return greeklish ? "eufuh" : "Ευφυή"; - } else if (normalisedCourse.contains(("Ευρυζωνικά Δίκτυα"))) { - return greeklish ? "eyryzwnika" : "Ευρυζωνικά"; - } else if (normalisedCourse.contains(("Επιχειρησιακή Έρευνα"))) { - return greeklish ? "epixeirisiaki" : "Επιχειρησιακή Έρευνα"; - } else if (normalisedCourse.contains(("Ενσωματωμένα Συστήματα Πραγματικού Χρόνου"))) { - return greeklish ? "enswmatwmena" : "Ενσωματωμένα"; - } else if (normalisedCourse.contains(("Εισαγωγή στις εφαρμογές Πυρηνικής Τεχνολογίας"))) { - return greeklish ? "Intro_Purhnikh_Texn" : "Εισ. Πυρηνικη Τεχν."; - } else if (normalisedCourse.contains(("Εισαγωγή στην Πολιτική Οικονομία"))) { - return greeklish ? "polit_oik" : "Πολιτική Οικονομία"; - } else if (normalisedCourse.contains(("Εισαγωγή στην Ενεργειακή Τεχνολογία II"))) { - return greeklish ? "EET_2" : "ΕΕΤ2"; - } else if (normalisedCourse.contains(("Εισαγωγή στην Ενεργειακή Τεχνολογία I"))) { - return greeklish ? "EET_I" : "ΕΕΤ 1"; - } else if (normalisedCourse.contains(("Ειδικές Κεραίες, Σύνθεση Κεραιών"))) { - return greeklish ? "eidikes_keraies" : "Ειδικές Κεραίες, Σύνθεση Κεραιών"; - } else if (normalisedCourse.contains(("Ειδικές Αρχιτεκτονικές Υπολογιστών"))) { - return greeklish ? "eidikes_arx_ypolog" : "Ειδικές Αρχιτεκτονικές Υπολογιστών"; - } else if (normalisedCourse.contains(("Ειδικά Κεφάλαια Συστημάτων Ηλεκτρικής Ενέργειας"))) { - return greeklish ? "ekshe" : "ΕΚΣΗΕ"; - } else if (normalisedCourse.contains(("Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I"))) { - return greeklish ? "eidika_kef_HM_pedioy_I" : "Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I"; - } else if (normalisedCourse.contains(("Ειδικά Κεφάλαια Διαφορικών Εξισώσεων"))) { - return greeklish ? "eidika_kef_diaf_eksis" : "Ειδικά Κεφάλαια Διαφορικών Εξισώσεων"; - } else if (normalisedCourse.contains(("Δομημένος Προγραμματισμός"))) { - return greeklish ? "C" : "Δομ. Προγραμμ."; - } else if (normalisedCourse.contains(("Δομές Δεδομένων"))) { - return greeklish ? "dom_dedomenwn" : "Δομ. Δεδομ."; - } else if (normalisedCourse.contains(("Διαχείριση Συστημάτων Ηλεκτρικής Ενέργειας"))) { - return greeklish ? "dshe" : "ΔΣΗΕ"; - } else if (normalisedCourse.contains(("Διαφορικές Εξισώσεις"))) { - return greeklish ? "diaforikes" : "Διαφορικές"; - } else if (normalisedCourse.contains(("Διανεμημένη Παραγωγή"))) { - return greeklish ? "dian_paragwgh" : "Διανεμημένη Παραγωγή"; - } else if (normalisedCourse.contains(("Διακριτά μαθηματικά"))) { - return greeklish ? "diakrita" : "Διακριτά Μαθηματικά"; - } else if (normalisedCourse.contains(("Διακριτά Μαθηματικά"))) { - return greeklish ? "diakrita" : "Διακριτά Μαθηματικά"; - } else if (normalisedCourse.contains(("Διάδοση Ηλεκτρομαγνητικού Κύματος I (πρώην Πεδίο III)"))) { - return greeklish ? "diadosi_1" : "Διάδοση 1"; - } else if (normalisedCourse.contains(("Διάδοση Η/Μ Κύματος II"))) { - return greeklish ? "diadosi_II" : "Διάδοση 2"; - } else if (normalisedCourse.contains(("Δίκτυα Υπολογιστών II"))) { - return greeklish ? "diktya_II" : "Δίκτυα 2"; - } else if (normalisedCourse.contains(("Δίκτυα Υπολογιστών I"))) { - return greeklish ? "diktya_I" : "Δίκτυα 1"; - } else if (normalisedCourse.contains(("Δίκτυα Τηλεπικοινωνιών"))) { - return greeklish ? "diktya_thlep" : "Δίκτυα Τηλέπ."; - } else if (normalisedCourse.contains(("Γραφική με Υπολογιστές"))) { - return greeklish ? "grafikh" : "Γραφική"; - } else if (normalisedCourse.contains(("Γραμμική Άλγεβρα"))) { - return greeklish ? "grammikh_algebra" : "Γραμμ. Άλγεβρ."; - } else if (normalisedCourse.contains(("Γεωηλεκτρομαγνητισμός"))) { - return greeklish ? "geohlektromagnitismos" : "Γεωηλεκτρομαγνητισμός"; - } else if (normalisedCourse.contains(("Βιοϊατρική Τεχνολογία"))) { - return greeklish ? "vioiatriki" : "Βιοιατρική"; - } else if (normalisedCourse.contains(("Βιομηχανική Πληροφορική"))) { - return greeklish ? "viomix_plir" : "Βιομηχανική Πληρ"; - } else if (normalisedCourse.contains(("Βιομηχανικά Ηλεκτρονικά"))) { - return greeklish ? "bhomix_hlektronika" : "Βιομηχανικά Ηλεκτρονικά"; - } else if (normalisedCourse.contains(("Βάσεις Δεδομένων"))) { - return greeklish ? "vaseis" : "Βάσεις"; - } else if (normalisedCourse.contains(("Ασύρματος Τηλεπικοινωνία II"))) { - return greeklish ? "asyrmatos_II" : "Ασύρματος 2"; - } else if (normalisedCourse.contains(("Ασύρματος Τηλεπικοινωνία I"))) { - return greeklish ? "asyrmatos_I" : "Ασύρματος 1"; - } else if (normalisedCourse.contains(("Ασφάλεια Πληροφοριακών Συστημάτων"))) { - return greeklish ? "asfaleia" : "Ασφάλεια"; - } else if (normalisedCourse.contains(("Ασαφή Συστήματα"))) { - return greeklish ? "asafh" : "Ασαφή"; - } else if (normalisedCourse.contains(("Αρχιτεκτονική Υπολογιστών"))) { - return greeklish ? "arx_ypologistwn" : "Αρχ. Υπολογιστών"; - } else if (normalisedCourse.contains(("Αρχές Παράλληλης Επεξεργασίας"))) { - return greeklish ? "arxes_parall_epeksergasias" : "Αρχές Παράλληλης Επεξεργασίας"; - } else if (normalisedCourse.contains(("Αρχές Οικονομίας"))) { - return greeklish ? "arx_oikonomias" : "Αρχές Οικονομίας"; - } else if (normalisedCourse.contains(("Αριθμητική Ανάλυση"))) { - return greeklish ? "arith_anal" : "Αριθμ. Ανάλυση"; - } else if (normalisedCourse.contains(("Αξιοπιστία Συστημάτων"))) { - return greeklish ? "aksiopistia_systhmatwn" : "Αξιοπιστία Συστημάτων"; - } else if (normalisedCourse.contains(("Αντικειμενοστραφής Προγραμματισμός"))) { - return greeklish ? "OOP" : "Αντικειμενοστραφής"; - } else if (normalisedCourse.contains(("Αναλογικές Τηλεπικοινωνίες (πρώην Τηλεπικοινωνιακά Συστήματα I)"))) { - return greeklish ? "anal_thlep" : "Αναλογικές Τηλεπ."; - } else if (normalisedCourse.contains(("Αναγνώριση Προτύπων"))) { - return greeklish ? "protipa" : "Αναγνώριση Προτύπων"; - } else if (normalisedCourse.contains(("Ανάλυση και Σχεδίαση Αλγορίθμων"))) { - return greeklish ? "algorithms" : "Αλγόριθμοι"; - } else if (normalisedCourse.contains(("Ανάλυση Χρονοσειρών"))) { - return greeklish ? "xronoseires" : "Χρονοσειρές"; - } else if (normalisedCourse.contains(("Ανάλυση Συστημάτων Ηλεκτρικής Ενέργειας"))) { - return greeklish ? "ASHE" : "ΑΣΗΕ"; - } else if (normalisedCourse.contains(("Ανάλυση Ηλεκτρικών Κυκλωμάτων με Υπολογιστή"))) { - return greeklish ? "analysh_hlektr_kykl" : "Ανάλυση Ηλεκτρικ. Κυκλ. με Υπολογιστή"; - } else if (normalisedCourse.contains(("Ακουστική II"))) { - return greeklish ? "akoystikh_II" : "Ακουστική 2"; - } else if (normalisedCourse.contains(("Ακουστική I"))) { - return greeklish ? "akoystikh_I" : "Ακουστική 1"; - } else { - Timber.wtf("Unrecognised course came in the upload fields generator! Course string = %s", course); - return null; - } - } } \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java new file mode 100644 index 00000000..0fbedce8 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java @@ -0,0 +1,66 @@ +package gr.thmmy.mthmmy.activities.upload; + +import java.util.HashMap; +import java.util.Map; + +import timber.log.Timber; + +public class UploadsCourse { + private String name; + private String minifiedName; + private String greeklishName; + + public UploadsCourse(String fullName, String minifiedName, String greeklishName) { + this.name = fullName; + this.minifiedName = minifiedName; + this.greeklishName = greeklishName; + } + + String getName() { + return name; + } + + String getMinifiedName() { + return minifiedName; + } + + String getGreeklishName() { + return greeklishName; + } + + static Map generateUploadsCourses(String[] uploadsCoursesRes){ + Map uploadsCourses = new HashMap<>(); + for(String uploadsCourseStr:uploadsCoursesRes) { + String[] split = uploadsCourseStr.split(","); + UploadsCourse uploadsCourse = new UploadsCourse(split[0], split[1], split[2]); + uploadsCourses.put(uploadsCourse.getName(),uploadsCourse); + } + return uploadsCourses; + } + + static UploadsCourse findCourse(String retrievedCourse, + Map uploadsCourses){ + retrievedCourse = normalizeGreekNumbers(retrievedCourse); + Timber.w("AAAAAAAA %s",retrievedCourse); + UploadsCourse uploadsCourse = uploadsCourses.get(retrievedCourse); + if(uploadsCourse != null) return uploadsCourse; + + String foundKey = null; + for (Map.Entry entry : uploadsCourses.entrySet()) { + String key = entry.getKey(); + if (key.contains(retrievedCourse)&& (foundKey==null || key.length()>foundKey.length())) + foundKey = key; + } + + if(foundKey==null){ + Timber.w("Couldn't find course that matches %s", retrievedCourse); + //TODO: report to Firebase for a new Course + } + + return uploadsCourses.get(foundKey); + } + + private static String normalizeGreekNumbers(String stringWithGreekNumbers) { + return stringWithGreekNumbers.replaceAll("Ι", "I"); + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java index 1bb45c84..5bb385c2 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java @@ -3,13 +3,12 @@ package gr.thmmy.mthmmy.activities.upload; import android.content.Context; import android.net.Uri; import android.os.Environment; +import android.widget.Toast; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.FileProvider; -import android.util.Log; -import android.widget.Toast; - import com.snatik.storage.Storage; import java.io.BufferedInputStream; diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java index ce4e4068..6ba7d3cc 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java @@ -10,6 +10,9 @@ import android.os.Bundle; import android.util.DisplayMetrics; import android.widget.ImageView; +import androidx.core.content.ContextCompat; +import androidx.preference.PreferenceManager; + import com.crashlytics.android.Crashlytics; import com.crashlytics.android.core.CrashlyticsCore; import com.franmontiel.persistentcookiejar.PersistentCookieJar; @@ -33,8 +36,6 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; -import androidx.core.content.ContextCompat; -import androidx.preference.PreferenceManager; import gr.thmmy.mthmmy.BuildConfig; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.session.SessionManager; diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java index 03622e83..c2c1a578 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseFragment.java @@ -5,6 +5,7 @@ import android.os.Bundle; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; + import okhttp3.OkHttpClient; public abstract class BaseFragment extends Fragment { diff --git a/app/src/main/java/gr/thmmy/mthmmy/editorview/EditorView.java b/app/src/main/java/gr/thmmy/mthmmy/editorview/EditorView.java index 3b41d07c..97f7d42f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/editorview/EditorView.java +++ b/app/src/main/java/gr/thmmy/mthmmy/editorview/EditorView.java @@ -26,16 +26,17 @@ import android.widget.PopupWindow; import android.widget.ScrollView; import android.widget.TextView; -import com.google.android.material.textfield.TextInputEditText; -import com.google.android.material.textfield.TextInputLayout; - -import java.util.Objects; - import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatImageButton; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; + +import java.util.Objects; + import gr.thmmy.mthmmy.R; import timber.log.Timber; diff --git a/app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java b/app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java index cd57fb5e..903ff5fe 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java +++ b/app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java @@ -9,11 +9,12 @@ import android.view.MotionEvent; import android.view.inputmethod.InputConnection; import android.widget.LinearLayout; -import java.util.HashSet; - import androidx.appcompat.widget.AppCompatImageButton; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; + +import java.util.HashSet; + import gr.thmmy.mthmmy.R; public class EmojiKeyboard extends LinearLayout implements IEmojiKeyboard { diff --git a/app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboardAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboardAdapter.java index c3b0758b..efcb9519 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboardAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboardAdapter.java @@ -8,6 +8,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageButton; import androidx.recyclerview.widget.RecyclerView; + import gr.thmmy.mthmmy.R; public class EmojiKeyboardAdapter extends RecyclerView.Adapter { diff --git a/app/src/main/java/gr/thmmy/mthmmy/editorview/FormatButtonsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/editorview/FormatButtonsAdapter.java index 98277550..732149ae 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/editorview/FormatButtonsAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/editorview/FormatButtonsAdapter.java @@ -7,6 +7,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageButton; import androidx.recyclerview.widget.RecyclerView; + import gr.thmmy.mthmmy.R; public class FormatButtonsAdapter extends RecyclerView.Adapter { diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java b/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java index ac622a64..1da43458 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java @@ -1,11 +1,11 @@ package gr.thmmy.mthmmy.model; -import java.util.ArrayList; -import java.util.Objects; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import java.util.ArrayList; +import java.util.Objects; + public class Bookmark implements java.io.Serializable { private final String title, id; private boolean isNotificationsEnabled; diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Post.java b/app/src/main/java/gr/thmmy/mthmmy/model/Post.java index 0c66ba83..7e0b7f55 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/Post.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Post.java @@ -1,10 +1,10 @@ package gr.thmmy.mthmmy.model; +import androidx.annotation.Nullable; + import java.util.ArrayList; import java.util.Objects; -import androidx.annotation.Nullable; - /** * Class that defines a topic's post. All member variables are declared final (thus no setters are * supplied). Class has two constructors and getter methods for all variables. diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/UploadFile.java b/app/src/main/java/gr/thmmy/mthmmy/model/UploadFile.java index c1bdb539..fb5c2161 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/UploadFile.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/UploadFile.java @@ -1,6 +1,7 @@ package gr.thmmy.mthmmy.model; import android.net.Uri; + import androidx.annotation.Nullable; import java.io.File; diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java b/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java index 5631b325..41ff3d95 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java @@ -13,6 +13,10 @@ import android.os.Build; import android.os.Bundle; import android.service.notification.StatusBarNotification; +import androidx.annotation.RequiresApi; +import androidx.core.app.NotificationCompat; +import androidx.preference.PreferenceManager; + import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; @@ -23,9 +27,6 @@ import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; -import androidx.annotation.RequiresApi; -import androidx.core.app.NotificationCompat; -import androidx.preference.PreferenceManager; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.base.BaseApplication; diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java b/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java index c7c56e86..f8b06e28 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/UploadsReceiver.java @@ -5,14 +5,14 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; -import androidx.appcompat.app.AlertDialog; - import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.app.AlertDialog; + import com.snatik.storage.Storage; import net.gotev.uploadservice.ServerResponse; diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java index 42f02375..4e91bc72 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -2,6 +2,9 @@ package gr.thmmy.mthmmy.session; import android.content.SharedPreferences; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.franmontiel.persistentcookiejar.PersistentCookieJar; import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor; @@ -14,8 +17,6 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import gr.thmmy.mthmmy.utils.parsing.ParseException; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import okhttp3.Cookie; diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/AppCompatSpinnerWithoutDefault.java b/app/src/main/java/gr/thmmy/mthmmy/utils/AppCompatSpinnerWithoutDefault.java index b64bb57d..77293dfe 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/AppCompatSpinnerWithoutDefault.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/AppCompatSpinnerWithoutDefault.java @@ -10,12 +10,12 @@ import android.widget.AdapterView; import android.widget.SpinnerAdapter; import android.widget.TextView; +import androidx.appcompat.widget.AppCompatSpinner; + import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import androidx.appcompat.widget.AppCompatSpinner; - public class AppCompatSpinnerWithoutDefault extends AppCompatSpinner { public AppCompatSpinnerWithoutDefault(Context context) { super(context); diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/CustomLinearLayoutManager.java b/app/src/main/java/gr/thmmy/mthmmy/utils/CustomLinearLayoutManager.java index de9abfd0..f4dd5042 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/CustomLinearLayoutManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/CustomLinearLayoutManager.java @@ -4,6 +4,7 @@ import android.content.Context; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; + import timber.log.Timber; public class CustomLinearLayoutManager extends LinearLayoutManager { diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java b/app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java index 7beffeb6..e1ef6f9e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java @@ -4,9 +4,10 @@ import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.OpenableColumns; +import android.webkit.MimeTypeMap; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import android.webkit.MimeTypeMap; import java.io.File; diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java index 44c0d4f3..a77502f3 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java @@ -2,7 +2,6 @@ package gr.thmmy.mthmmy.utils; import android.content.Context; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import androidx.annotation.NonNull; diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java index 91e2305c..cc877deb 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareLinearBehavior.java @@ -6,13 +6,13 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewPropertyAnimator; -import com.google.android.material.snackbar.Snackbar; - import androidx.annotation.NonNull; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.view.ViewCompat; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; +import com.google.android.material.snackbar.Snackbar; + /** * Extends LinearLayout's behavior. Used for bottom navigation bar. *

When a nested ScrollView is scrolled down, the view will disappear. diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java b/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java index b2ef977f..1ac9c6a8 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java @@ -14,10 +14,11 @@ import android.media.ExifInterface; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; +import android.widget.Toast; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.FileProvider; -import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ToggledBackgroundButton.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ToggledBackgroundButton.java new file mode 100644 index 00000000..6c189e87 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ToggledBackgroundButton.java @@ -0,0 +1,27 @@ +package gr.thmmy.mthmmy.utils; +import android.content.Context; +import android.util.AttributeSet; + +import androidx.appcompat.widget.AppCompatButton; + +public class ToggledBackgroundButton extends AppCompatButton { + + public ToggledBackgroundButton(Context context) { + super(context); + } + + public ToggledBackgroundButton(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ToggledBackgroundButton(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public void setEnabled(boolean enabled) { + setAlpha(enabled ? 1 : 0.5f); + super.setEnabled(enabled); + } +} + diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java index f937578a..62380f80 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java @@ -235,7 +235,7 @@ public class ParseHelpers { stringBuilder.append(Character.toString((char) i)); } - Timber.i("Email deobfuscated."); + Timber.d("Email deobfuscated."); return stringBuilder.toString(); } diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/BaseViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/BaseViewModel.java index a038c033..5787b36d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/BaseViewModel.java +++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/BaseViewModel.java @@ -3,6 +3,7 @@ package gr.thmmy.mthmmy.viewmodel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; + import gr.thmmy.mthmmy.model.Bookmark; public class BaseViewModel extends ViewModel { diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/ShoutboxViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/ShoutboxViewModel.java index 25092578..c3f4dce5 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/ShoutboxViewModel.java +++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/ShoutboxViewModel.java @@ -4,6 +4,7 @@ import android.os.AsyncTask; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; + import gr.thmmy.mthmmy.activities.shoutbox.SendShoutTask; import gr.thmmy.mthmmy.activities.shoutbox.ShoutboxTask; import gr.thmmy.mthmmy.model.Shoutbox; diff --git a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java index c15e46db..750e6a34 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java +++ b/app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java @@ -8,9 +8,10 @@ import android.widget.CheckBox; import android.widget.LinearLayout; import android.widget.RadioGroup; +import androidx.lifecycle.MutableLiveData; + import java.util.ArrayList; -import androidx.lifecycle.MutableLiveData; import gr.thmmy.mthmmy.activities.settings.SettingsActivity; import gr.thmmy.mthmmy.activities.topic.tasks.DeleteTask; import gr.thmmy.mthmmy.activities.topic.tasks.EditTask; diff --git a/app/src/main/res/layout/activity_upload.xml b/app/src/main/res/layout/activity_upload.xml index fb985454..0eea2f63 100644 --- a/app/src/main/res/layout/activity_upload.xml +++ b/app/src/main/res/layout/activity_upload.xml @@ -118,7 +118,7 @@ android:inputType="textMultiLine" /> - + + + + Ακουστική I,Ακουστική 1,akoystikh_I + Ακουστική II,Ακουστική 2,akoystikh_II + Ανάλυση Ηλεκτρικών Κυκλωμάτων με Υπολογιστή,Ανάλυση Ηλεκτρικ. Κυκλ. με Υπολογιστή,analysh_hlektr_kykl + Ανάλυση Συστημάτων Ηλεκτρικής Ενέργειας,ΑΣΗΕ,ASHE + Ανάλυση Χρονοσειρών,Χρονοσειρές,xronoseires + Ανάλυση και Σχεδίαση Αλγορίθμων,Αλγόριθμοι,algorithms + Αναγνώριση Προτύπων,Αναγνώριση Προτύπων,protipa + Αναλογικές Τηλεπικοινωνίες (πρώην Τηλεπικοινωνιακά Συστήματα I),Αναλογικές Τηλεπ.,anal_thlep + Αντικειμενοστραφής Προγραμματισμός,Αντικειμενοστραφής,OOP + Αξιοπιστία Συστημάτων,Αξιοπιστία Συστημάτων,aksiopistia_systhmatwn + Αριθμητική Ανάλυση,Αριθμ. Ανάλυση,arith_anal + Αρχές Οικονομίας,Αρχές Οικονομίας,arx_oikonomias + Αρχές Παράλληλης Επεξεργασίας,Αρχές Παράλληλης Επεξεργασίας,arxes_parall_epeksergasias + Αρχιτεκτονική Υπολογιστών,Αρχ. Υπολογιστών,arx_ypologistwn + Ασαφή Συστήματα,Ασαφή,asafh + Ασφάλεια Πληροφοριακών Συστημάτων,Ασφάλεια,asfaleia + Ασύρματος Τηλεπικοινωνία I,Ασύρματος 1,asyrmatos_I + Ασύρματος Τηλεπικοινωνία II,Ασύρματος 2,asyrmatos_II + Βάσεις Δεδομένων,Βάσεις,vaseis + Βιομηχανικά Ηλεκτρονικά,Βιομηχανικά Ηλεκτρονικά,bhomix_hlektronika + Βιομηχανική Πληροφορική,Βιομηχανική Πληρ,viomix_plir + Βιοϊατρική Τεχνολογία,Βιοιατρική,vioiatriki + Γεωηλεκτρομαγνητισμός,Γεωηλεκτρομαγνητισμός,geohlektromagnitismos + Γραμμική Άλγεβρα,Γραμμ. Άλγεβρ.,grammikh_algebra + Γραφική με Υπολογιστές,Γραφική,grafikh + Δίκτυα Τηλεπικοινωνιών,Δίκτυα Τηλέπ.,diktya_thlep + Δίκτυα Υπολογιστών I,Δίκτυα 1,diktya_I + Δίκτυα Υπολογιστών II,Δίκτυα 2,diktya_II + Διάδοση Η/Μ Κύματος II,Διάδοση 2,diadosi_II + Διάδοση Ηλεκτρομαγνητικού Κύματος I (πρώην Πεδίο III),Διάδοση 1,diadosi_I + Διακριτά Μαθηματικά,Διακριτά Μαθηματικά,diakrita + Διακριτά μαθηματικά,Διακριτά Μαθηματικά,diakrita + Διανεμημένη Παραγωγή,Διανεμημένη Παραγωγή,dian_paragwgh + Διαφορικές Εξισώσεις,Διαφορικές,diaforikes + Διαχείριση Συστημάτων Ηλεκτρικής Ενέργειας,ΔΣΗΕ,dshe + Δομές Δεδομένων,Δομ. Δεδομ.,dom_dedomenwn + Δομημένος Προγραμματισμός,Δομ. Προγραμμ.,C + Ειδικά Κεφάλαια Διαφορικών Εξισώσεων,Ειδικά Κεφάλαια Διαφορικών Εξισώσεων,eidika_kef_diaf_eksis + Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I,Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I,eidika_kef_HM_pedioy_I + Ειδικά Κεφάλαια Συστημάτων Ηλεκτρικής Ενέργειας,ΕΚΣΗΕ,ekshe + Ειδικές Αρχιτεκτονικές Υπολογιστών,Ειδικές Αρχιτεκτονικές Υπολογιστών,eidikes_arx_ypolog + Ειδικές Κεραίες,eidikes_keraies, Σύνθεση Κεραιών + Εισαγωγή στην Ενεργειακή Τεχνολογία I,ΕΕΤ 1,EET_I + Εισαγωγή στην Ενεργειακή Τεχνολογία II,ΕΕΤ2,EET_II + Εισαγωγή στην Πολιτική Οικονομία,Πολιτική Οικονομία,polit_oik + Εισαγωγή στις εφαρμογές Πυρηνικής Τεχνολογίας,Εισ. Πυρηνικη Τεχν.,Intro_Purhnikh_Texn + Ενσωματωμένα Συστήματα Πραγματικού Χρόνου,Ενσωματωμένα,enswmatwmena + Επιχειρησιακή Έρευνα,Επιχειρησιακή Έρευνα,epixeirisiaki + Ευρυζωνικά Δίκτυα,Ευρυζωνικά,eyryzwnika + Ευφυή Συστήματα Ρομπότ,Ευφυή,eufuh + Εφαρμογές Τηλεπικοινωνιακών Διατάξεων,Εφαρμογές Τηλεπ. Διατάξεων,efarm_thlep_diataksewn + Εφαρμοσμένα Μαθηματικά I,Εφαρμοσμένα 1,efarmosmena_math_I + Εφαρμοσμένα Μαθηματικά II,Εφαρμοσμένα 2,efarmosmena_math_II + Εφαρμοσμένη Θερμοδυναμική,Θερμοδυναμική,thermodynamikh + Ηλεκτρακουστική I,Ηλεκτροακουστική 1,hlektroakoystikh_I + Ηλεκτρακουστική II,Ηλεκτροακουστική 2,hlektroakoystikh_II + Ηλεκτρικά Κυκλώματα I,Κυκλώματα 1,kyklwmata_I + Ηλεκτρικά Κυκλώματα II,Κυκλώματα 2,kyklwmata_II + Ηλεκτρικά Κυκλώματα III,Κυκλώματα 3,kyklwmata_I + Ηλεκτρικές Μετρήσεις I,Μετρήσεις 1,metrhseis_I + Ηλεκτρικές Μετρήσεις II,Μετρήσεις 2,metrhseis_II + Ηλεκτρικές Μηχανές Α\',Μηχανές Α,mhxanes_A + Ηλεκτρικές Μηχανές Β\',Μηχανές Β,mhxanes_B + Ηλεκτρικές Μηχανές Γ\',Μηχανές Γ,mhxanes_C + Ηλεκτρική Οικονομία,Ηλεκτρική Οικονομία,hlektr_oikonomia + Ηλεκτρολογικά Υλικά,Ηλεκτρ. Υλικά,ylika + Ηλεκτρομαγνητική Συμβατότητα,H/M Συμβατότητα,HM_symvatothta + Ηλεκτρομαγνητικό Πεδίο I,Πεδίο 1,pedio_I + Ηλεκτρομαγνητικό Πεδίο II,Πεδίο 2,pedio_II + Ηλεκτρονικά Iσχύος I,Iσχύος 1,isxyos_I + Ηλεκτρονικά Iσχύος II,Iσχύος 2,isxyos_II + Ηλεκτρονικές Διατάξεις και Μετρήσεις,Ηλεκτρονικές Διατάξεις και Μετρήσεις,hlektron_diatakseis_metrhseis + Ηλεκτρονική I,Ηλεκτρονική 1,hlektronikh_I + Ηλεκτρονική II,Ηλεκτρονική 2,hlektronikh_II + Ηλεκτρονική III,Ηλεκτρονική 3,hlektronikh_III + Ημιαγωγά Υλικά: Θεωρία-Διατάξεις,Ημιαγωγά Υλικά,Hmiagwga_Ylika + Θεωρία Πιθανοτήτων και Στατιστική,Πιθανότητες,pithanothtes + Θεωρία Πληροφοριών,Θεωρία Πληρ.,theoria_plir + Θεωρία Σημάτων και Γραμμικών Συστημάτων,Σύματα & Συστήματα,analog_shma + Θεωρία Σκέδασης,Σκέδαση,skedash + Θεωρία Υπολογισμών και Αλγορίθμων,ΘΥΑ,thya + Θεωρία και Τεχνολογία Πυρηνικών Αντιδραστήρων,Τεχνολογία Αντιδραστήρων,texn_antidrasthrwn + Κβαντική Φυσική,Κβαντική,kvantikh + Κινητές και Δορυφορικές Επικοινωνίες,Κινητές & Δορυφορικές Επικοινωνίες,kinhtes_doryforikes_epik + Λειτουργικά Συστήματα,Λειτουργικά,OS + Λογική Σχεδίαση,Λογική Σχεδίαση,logiki_sxediash + Λογισμός I,Λογισμός 1,logismos_I + Λογισμός II,Λογισμός 2,logismos_II + Μετάδοση Θερμότητας,Μετάδοση Θερμ.,metadosi_therm + Μικροεπεξεργαστές και Περιφερειακά,Μίκρο 2,mikro_II + Μικροκυματική Τηλεπισκόπηση,Τηλεπισκόπηση,thlepiskophsh + Μικροκύματα I,Μικροκύματα 1,mikrokymata_I + Μικροκύματα II,Μικροκύματα 2,mikrokymata_II + Οπτικές Επικοινωνίες,Οπτικές Τηλεπ.,optikes_thlep + Οπτική I,Οπτική 1,optikh_I + Οπτική II,Οπτική 2,optikh_II + Οργάνωση Υπολογιστών,Οργάνωση Υπολ.,org_ypol + Οργάνωση και Διοίκηση Εργοστασίων,Οργάνωση και Διοίκηση Εργοστασίων,organ_dioik_ergostasiwn + Παράλληλα και Κατανεμημένα Συστήματα,Παράλληλα,parallhla + Προγραμματιζόμενα Κυκλώματα ASIC,ASIC,asic + Προγραμματιστικές Τεχνικές,Προγραμματ. Τεχν.,cpp + Προηγμένες Τεχνικές Επεξεργασίας Σήματος,ΠΤΕΣ,ptes + Προσομοίωση και Μοντελοποίηση Συστημάτων,Μοντελοποίηση,montelopoihsh + Ρομποτική,Ρομποτική,rompotikh + Σήματα και Συστήματα,Σύματα & Συστήματα,analog_shma + Σερβοκινητήρια Συστήματα,Σέρβο,servo + Σταθμοί Παραγωγής Ηλεκτρικής Ενέργειας,ΣΠΗΕ,SPHE + Στοχαστικό Σήμα,Στοχ. Σήμα,stox_shma + Συστήματα Αυτομάτου Ελέγχου I,ΣΑΕ 1,SAE_I + Συστήματα Αυτομάτου Ελέγχου II,ΣΑΕ 2,SAE_II + Συστήματα Αυτομάτου Ελέγχου III,ΣΑΕ 3,SAE_III + Συστήματα Ηλεκτρικής Ενέργειας I,ΣΗΕ 1,SHE_I + Συστήματα Ηλεκτρικής Ενέργειας II,ΣΗΕ 2,SHE_II + Συστήματα Ηλεκτρικής Ενέργειας III,ΣΗΕ 3,SHE_III + Συστήματα Ηλεκτροκίνησης,Ηλεκτροκίνηση,hlektrokinhsh + Συστήματα Μικροϋπολογιστών,Μίκρο 1,mikro_I + Συστήματα Πολυμέσων και Εικονική Πραγματικότητα,Πολυμέσα,polymesa + Συστήματα Υπολογιστών (Υπολογιστικά Συστήματα),Συσ. Υπολογιστών,sys_ypologistwn + Σχεδίαση Συστημάτων VLSI,VLSI,VLSI + Σύνθεση Ενεργών και Παθητικών Κυκλωμάτων,Σύνθεση,synthesh + Σύνθεση Τηλεπικοινωνιακών Διατάξεων,Σύνθεση Τηλεπ. Διατάξεων,synth_thlep_diataksewn + Τεχνικές Βελτιστοποίησης,Βελτιστοποίηση,veltistopoihsh + Τεχνικές Κωδικοποίησης,Τεχνικές Κωδικοποίησης,texn_kwdikopoihshs + Τεχνικές Σχεδίασης με Η/Υ,Σχέδιο,sxedio + Τεχνικές μη Καταστρεπτικών Δοκιμών,Μη Καταστρεπτικές Δοκιμές,non_destructive_tests + Τεχνική Μηχανική,Τεχν. Μηχαν.,texn_mhxan + Τεχνολογία Ήχου και Εικόνας,Τεχνολογία Ήχου και Εικόνας,texn_hxoy_eikonas + Τεχνολογία Ηλεκτροτεχνικών Υλικών,Ηλεκτροτεχνικά Υλικά,Hlektrotexnika_Ylika + Τεχνολογία Λογισμικού,Τεχνολογία Λογισμικού,SE + Τηλεοπτικά Συστήματα,Τηλεοπτικά,tileoptika + Τηλεπικοινωνιακή Ηλεκτρονική,Τηλεπ. Ηλεκτρ.,tilep_ilektr + Υπολογιστικές Μέθοδοι στα Ενεργειακά Συστήματα,ΥΜΕΣ,ymes + Υπολογιστικός Ηλεκτρομαγνητισμός,Υπολογιστικός Η/Μ,ypologistikos_HM + Υψηλές Τάσεις 4,Υψηλές 4,ypshles_IV + Υψηλές Τάσεις I,Υψηλές 1,ypshles_I + Υψηλές Τάσεις II,Υψηλές 2,ypshles_II + Υψηλές Τάσεις III,Υψηλές 3,ypshles_III + Φυσική I,Φυσική 1,fysikh_I + Φωτονική Τεχνολογία,Φωτονική,fwtonikh + Ψηφιακά Συστήματα I,Ψηφιακά 1,pshfiaka_I + Ψηφιακά Συστήματα II,Ψηφιακά 2,pshfiaka_II + Ψηφιακά Συστήματα III,Ψηφιακά 3,pshfiaka_III + Ψηφιακά Φίλτρα,Φίλτρα,filtra + Ψηφιακές Τηλεπικοινωνίες I,Ψηφιακές Τηλεπ. 1,pshf_thlep_I + Ψηφιακές Τηλεπικοινωνίες II,Ψηφιακές Τηλεπ. 2,pshf_thlep_II + Ψηφιακή Επεξεργασία Εικόνας,ΨΕΕ,PSEE + Ψηφιακή Επεξεργασία Σήματος,ΨΕΣ,PSES + + \ No newline at end of file From 6a76d7e399a8e0fdf86c70576b1374628cb960f8 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 22 Jun 2019 12:48:09 +0300 Subject: [PATCH 12/18] Uploads improvements & fixes --- .../activities/upload/UploadActivity.java | 36 ++++++++----------- .../activities/upload/UploadsCourse.java | 21 ++++++++--- .../activities/upload/UploadsHelper.java | 28 +++++++-------- .../mthmmy/utils/CrashReportingTree.java | 3 +- .../java/gr/thmmy/mthmmy/utils/TakePhoto.java | 6 ++-- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java index 31f51b8e..d6fb274a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java @@ -457,12 +457,8 @@ public class UploadActivity extends BaseActivity { fileIcon = "archive.gif"; textWatcher.setFileExtension(".zip"); - if (!hasModifiedFilename) { - String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); - String zipFilename = "mTHMMY_" + timeStamp + ".zip"; - uploadFilename.setText(zipFilename); - hasModifiedFilename = false; - } + if (!hasModifiedFilename) + setZipUploadFilename(); for (int fileIndex = 0; fileIndex < data.getClipData().getItemCount(); ++fileIndex) { Uri newFileUri = data.getClipData().getItemAt(fileIndex).getUri(); @@ -506,12 +502,8 @@ public class UploadActivity extends BaseActivity { fileIcon = "archive.gif"; textWatcher.setFileExtension(".zip"); - if (!hasModifiedFilename) { - String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); - String zipFilename = "mTHMMY_" + timeStamp + ".zip"; - uploadFilename.setText(zipFilename); - hasModifiedFilename = false; - } + if (!hasModifiedFilename) + setZipUploadFilename(); } addFileViewToList(filename); @@ -538,12 +530,8 @@ public class UploadActivity extends BaseActivity { fileIcon = "archive.gif"; textWatcher.setFileExtension(".zip"); - if (!hasModifiedFilename) { - String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); - String zipFilename = "mTHMMY_" + timeStamp + ".zip"; - uploadFilename.setText(zipFilename); - hasModifiedFilename = false; - } + if (!hasModifiedFilename) + setZipUploadFilename(); } UploadFile newFile = new UploadFile(true, TakePhoto.processResult(this, @@ -599,6 +587,13 @@ public class UploadActivity extends BaseActivity { } } + private void setZipUploadFilename(){ + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); + String zipFilename = "mTHMMY_" + timeStamp + ".zip"; + uploadFilename.setText(zipFilename); + hasModifiedFilename = false; + } + // Should only be called after making sure permissions are granted private void takePhoto() { // Create the File where the photo should go @@ -768,8 +763,7 @@ public class UploadActivity extends BaseActivity { } @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } + public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { @@ -951,7 +945,7 @@ public class UploadActivity extends BaseActivity { if(foundUploadsCourse != null){ uploadsCourse = foundUploadsCourse; semester = retrievedSemester; - Timber.i("Selected course: %s, semester: %s", uploadsCourse.getName(), semester); + Timber.d("Selected course: %s, semester: %s", uploadsCourse.getName(), semester); titleDescriptionBuilderButton.setEnabled(true); return; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java index 0fbedce8..6b4af081 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java @@ -1,16 +1,21 @@ package gr.thmmy.mthmmy.activities.upload; +import android.os.Bundle; + import java.util.HashMap; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import gr.thmmy.mthmmy.base.BaseApplication; import timber.log.Timber; -public class UploadsCourse { +class UploadsCourse { private String name; private String minifiedName; private String greeklishName; - public UploadsCourse(String fullName, String minifiedName, String greeklishName) { + private UploadsCourse(String fullName, String minifiedName, String greeklishName) { this.name = fullName; this.minifiedName = minifiedName; this.greeklishName = greeklishName; @@ -41,7 +46,6 @@ public class UploadsCourse { static UploadsCourse findCourse(String retrievedCourse, Map uploadsCourses){ retrievedCourse = normalizeGreekNumbers(retrievedCourse); - Timber.w("AAAAAAAA %s",retrievedCourse); UploadsCourse uploadsCourse = uploadsCourses.get(retrievedCourse); if(uploadsCourse != null) return uploadsCourse; @@ -54,13 +58,20 @@ public class UploadsCourse { if(foundKey==null){ Timber.w("Couldn't find course that matches %s", retrievedCourse); - //TODO: report to Firebase for a new Course + Bundle bundle = new Bundle(); + bundle.putString("COURSE_NAME", retrievedCourse); + BaseApplication.getInstance().logFirebaseAnalyticsEvent("UNSUPPORTED_UPLOADS_COURSE", bundle); } return uploadsCourses.get(foundKey); } private static String normalizeGreekNumbers(String stringWithGreekNumbers) { - return stringWithGreekNumbers.replaceAll("Ι", "I"); + StringBuilder normalizedStrBuilder = new StringBuilder(stringWithGreekNumbers); + Pattern pattern = Pattern.compile("(Ι+)(?:\\s|\\(|\\)|$)"); + Matcher matcher = pattern.matcher(stringWithGreekNumbers); + while (matcher.find()) + normalizedStrBuilder.replace(matcher.start(1), matcher.end(1), matcher.group(1).replaceAll("Ι", "I")); + return normalizedStrBuilder.toString(); } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java index 5bb385c2..92b71cb0 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsHelper.java @@ -25,26 +25,24 @@ import gr.thmmy.mthmmy.utils.FileUtils; import timber.log.Timber; public class UploadsHelper { - private final static int BUFFER = 4096; - private static final String TEMP_FILES_DIRECTORY = "~tmp_mThmmy_uploads"; + private static final int BUFFER = 4096; + private static final String TEMP_FILES_DIRECTORY = "~tmp_mTHMMY_uploads"; @SuppressWarnings("ResultOfMethodCallIgnored") @Nullable static Uri createTempFile(Context context, Storage storage, Uri fileUri, String newFilename) { String oldFilename = FileUtils.filenameFromUri(context, fileUri); - String fileExtension = oldFilename.substring(oldFilename.indexOf(".")); + String fileExtension = oldFilename.substring(oldFilename.indexOf('.')); String destinationFilename = Environment.getExternalStorageDirectory().getPath() + File.separatorChar + TEMP_FILES_DIRECTORY + File.separatorChar + newFilename + fileExtension; File tempDirectory = new File(android.os.Environment.getExternalStorageDirectory().getPath() + File.separatorChar + TEMP_FILES_DIRECTORY); - if (!tempDirectory.exists()) { - if (!tempDirectory.mkdirs()) { - Timber.w("Temporary directory build returned false in %s", UploadActivity.class.getSimpleName()); - Toast.makeText(context, "Couldn't create temporary directory", Toast.LENGTH_SHORT).show(); - return null; - } + if (!tempDirectory.exists() && !tempDirectory.mkdirs()) { + Timber.w("Temporary directory build returned false in %s", UploadActivity.class.getSimpleName()); + Toast.makeText(context, "Couldn't create temporary directory", Toast.LENGTH_SHORT).show(); + return null; } InputStream inputStream; @@ -82,28 +80,26 @@ public class UploadsHelper { } @Nullable - public static File createZipFile(@NonNull String zipFilename) { + static File createZipFile(@NonNull String zipFilename) { // Create a zip file name File zipFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + - File.separator + "mThmmy"); + File.separator + "mTHMMY"); - if (!zipFolder.exists()) { - if (!zipFolder.mkdirs()) { + if (!zipFolder.exists() && !zipFolder.mkdirs()) { Timber.w("Zip folder build returned false in %s", UploadsHelper.class.getSimpleName()); return null; - } } return new File(zipFolder, zipFilename); } - public static void zip(Context context, Uri[] files, Uri zipFile) { + static void zip(Context context, Uri[] files, Uri zipFile) { try { BufferedInputStream origin; OutputStream dest = context.getContentResolver().openOutputStream(zipFile); assert dest != null; ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); - byte data[] = new byte[BUFFER]; + byte[] data = new byte[BUFFER]; for (Uri file : files) { InputStream inputStream = context.getContentResolver().openInputStream(file); diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java b/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java index c4674134..8f85459a 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/CrashReportingTree.java @@ -27,8 +27,7 @@ public class CrashReportingTree extends DebugTree { Crashlytics.log(level + "/" + tag + ": " + message); - if(priority == Log.ERROR) - { + if(priority == Log.ERROR) { if (t!=null) Crashlytics.logException(t); else diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java b/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java index 1ac9c6a8..f1d7d990 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java @@ -32,7 +32,7 @@ import timber.log.Timber; public class TakePhoto { private static final int DEFAULT_MIN_WIDTH_QUALITY = 400; - private static final String IMAGE_CONTENT_DESCRIPTION = "mThmmy uploads image"; + private static final String IMAGE_CONTENT_DESCRIPTION = "mTHMMY uploads image"; @Nullable public static Intent getIntent(Context context, @NonNull File photoFile) { @@ -81,10 +81,10 @@ public class TakePhoto { public static File createImageFile(Context context) { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(new Date()); - String imageFileName = "mThmmy_" + timeStamp + ".jpg"; + String imageFileName = "mTHMMY_" + timeStamp + ".jpg"; File imageFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + - File.separator + "mThmmy"); + File.separator + "mTHMMY"); if (!imageFolder.exists()) { if (!imageFolder.mkdirs()) { From 8b06c9727b75748249f766ccb29482bc874ce7a9 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 22 Jun 2019 13:22:31 +0300 Subject: [PATCH 13/18] Updated uploads courses XML --- .../activities/upload/UploadsCourse.java | 4 +- app/src/main/res/values/uploads_courses.xml | 296 +++++++++--------- 2 files changed, 150 insertions(+), 150 deletions(-) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java index 6b4af081..8fe986c9 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadsCourse.java @@ -36,7 +36,7 @@ class UploadsCourse { static Map generateUploadsCourses(String[] uploadsCoursesRes){ Map uploadsCourses = new HashMap<>(); for(String uploadsCourseStr:uploadsCoursesRes) { - String[] split = uploadsCourseStr.split(","); + String[] split = uploadsCourseStr.split(":"); UploadsCourse uploadsCourse = new UploadsCourse(split[0], split[1], split[2]); uploadsCourses.put(uploadsCourse.getName(),uploadsCourse); } @@ -52,7 +52,7 @@ class UploadsCourse { String foundKey = null; for (Map.Entry entry : uploadsCourses.entrySet()) { String key = entry.getKey(); - if (key.contains(retrievedCourse)&& (foundKey==null || key.length()>foundKey.length())) + if ((key.contains(retrievedCourse))&& (foundKey==null || key.length()>foundKey.length())) foundKey = key; } diff --git a/app/src/main/res/values/uploads_courses.xml b/app/src/main/res/values/uploads_courses.xml index 68e82be2..8f872389 100644 --- a/app/src/main/res/values/uploads_courses.xml +++ b/app/src/main/res/values/uploads_courses.xml @@ -1,153 +1,153 @@ - + - Ακουστική I,Ακουστική 1,akoystikh_I - Ακουστική II,Ακουστική 2,akoystikh_II - Ανάλυση Ηλεκτρικών Κυκλωμάτων με Υπολογιστή,Ανάλυση Ηλεκτρικ. Κυκλ. με Υπολογιστή,analysh_hlektr_kykl - Ανάλυση Συστημάτων Ηλεκτρικής Ενέργειας,ΑΣΗΕ,ASHE - Ανάλυση Χρονοσειρών,Χρονοσειρές,xronoseires - Ανάλυση και Σχεδίαση Αλγορίθμων,Αλγόριθμοι,algorithms - Αναγνώριση Προτύπων,Αναγνώριση Προτύπων,protipa - Αναλογικές Τηλεπικοινωνίες (πρώην Τηλεπικοινωνιακά Συστήματα I),Αναλογικές Τηλεπ.,anal_thlep - Αντικειμενοστραφής Προγραμματισμός,Αντικειμενοστραφής,OOP - Αξιοπιστία Συστημάτων,Αξιοπιστία Συστημάτων,aksiopistia_systhmatwn - Αριθμητική Ανάλυση,Αριθμ. Ανάλυση,arith_anal - Αρχές Οικονομίας,Αρχές Οικονομίας,arx_oikonomias - Αρχές Παράλληλης Επεξεργασίας,Αρχές Παράλληλης Επεξεργασίας,arxes_parall_epeksergasias - Αρχιτεκτονική Υπολογιστών,Αρχ. Υπολογιστών,arx_ypologistwn - Ασαφή Συστήματα,Ασαφή,asafh - Ασφάλεια Πληροφοριακών Συστημάτων,Ασφάλεια,asfaleia - Ασύρματος Τηλεπικοινωνία I,Ασύρματος 1,asyrmatos_I - Ασύρματος Τηλεπικοινωνία II,Ασύρματος 2,asyrmatos_II - Βάσεις Δεδομένων,Βάσεις,vaseis - Βιομηχανικά Ηλεκτρονικά,Βιομηχανικά Ηλεκτρονικά,bhomix_hlektronika - Βιομηχανική Πληροφορική,Βιομηχανική Πληρ,viomix_plir - Βιοϊατρική Τεχνολογία,Βιοιατρική,vioiatriki - Γεωηλεκτρομαγνητισμός,Γεωηλεκτρομαγνητισμός,geohlektromagnitismos - Γραμμική Άλγεβρα,Γραμμ. Άλγεβρ.,grammikh_algebra - Γραφική με Υπολογιστές,Γραφική,grafikh - Δίκτυα Τηλεπικοινωνιών,Δίκτυα Τηλέπ.,diktya_thlep - Δίκτυα Υπολογιστών I,Δίκτυα 1,diktya_I - Δίκτυα Υπολογιστών II,Δίκτυα 2,diktya_II - Διάδοση Η/Μ Κύματος II,Διάδοση 2,diadosi_II - Διάδοση Ηλεκτρομαγνητικού Κύματος I (πρώην Πεδίο III),Διάδοση 1,diadosi_I - Διακριτά Μαθηματικά,Διακριτά Μαθηματικά,diakrita - Διακριτά μαθηματικά,Διακριτά Μαθηματικά,diakrita - Διανεμημένη Παραγωγή,Διανεμημένη Παραγωγή,dian_paragwgh - Διαφορικές Εξισώσεις,Διαφορικές,diaforikes - Διαχείριση Συστημάτων Ηλεκτρικής Ενέργειας,ΔΣΗΕ,dshe - Δομές Δεδομένων,Δομ. Δεδομ.,dom_dedomenwn - Δομημένος Προγραμματισμός,Δομ. Προγραμμ.,C - Ειδικά Κεφάλαια Διαφορικών Εξισώσεων,Ειδικά Κεφάλαια Διαφορικών Εξισώσεων,eidika_kef_diaf_eksis - Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I,Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I,eidika_kef_HM_pedioy_I - Ειδικά Κεφάλαια Συστημάτων Ηλεκτρικής Ενέργειας,ΕΚΣΗΕ,ekshe - Ειδικές Αρχιτεκτονικές Υπολογιστών,Ειδικές Αρχιτεκτονικές Υπολογιστών,eidikes_arx_ypolog - Ειδικές Κεραίες,eidikes_keraies, Σύνθεση Κεραιών - Εισαγωγή στην Ενεργειακή Τεχνολογία I,ΕΕΤ 1,EET_I - Εισαγωγή στην Ενεργειακή Τεχνολογία II,ΕΕΤ2,EET_II - Εισαγωγή στην Πολιτική Οικονομία,Πολιτική Οικονομία,polit_oik - Εισαγωγή στις εφαρμογές Πυρηνικής Τεχνολογίας,Εισ. Πυρηνικη Τεχν.,Intro_Purhnikh_Texn - Ενσωματωμένα Συστήματα Πραγματικού Χρόνου,Ενσωματωμένα,enswmatwmena - Επιχειρησιακή Έρευνα,Επιχειρησιακή Έρευνα,epixeirisiaki - Ευρυζωνικά Δίκτυα,Ευρυζωνικά,eyryzwnika - Ευφυή Συστήματα Ρομπότ,Ευφυή,eufuh - Εφαρμογές Τηλεπικοινωνιακών Διατάξεων,Εφαρμογές Τηλεπ. Διατάξεων,efarm_thlep_diataksewn - Εφαρμοσμένα Μαθηματικά I,Εφαρμοσμένα 1,efarmosmena_math_I - Εφαρμοσμένα Μαθηματικά II,Εφαρμοσμένα 2,efarmosmena_math_II - Εφαρμοσμένη Θερμοδυναμική,Θερμοδυναμική,thermodynamikh - Ηλεκτρακουστική I,Ηλεκτροακουστική 1,hlektroakoystikh_I - Ηλεκτρακουστική II,Ηλεκτροακουστική 2,hlektroakoystikh_II - Ηλεκτρικά Κυκλώματα I,Κυκλώματα 1,kyklwmata_I - Ηλεκτρικά Κυκλώματα II,Κυκλώματα 2,kyklwmata_II - Ηλεκτρικά Κυκλώματα III,Κυκλώματα 3,kyklwmata_I - Ηλεκτρικές Μετρήσεις I,Μετρήσεις 1,metrhseis_I - Ηλεκτρικές Μετρήσεις II,Μετρήσεις 2,metrhseis_II - Ηλεκτρικές Μηχανές Α\',Μηχανές Α,mhxanes_A - Ηλεκτρικές Μηχανές Β\',Μηχανές Β,mhxanes_B - Ηλεκτρικές Μηχανές Γ\',Μηχανές Γ,mhxanes_C - Ηλεκτρική Οικονομία,Ηλεκτρική Οικονομία,hlektr_oikonomia - Ηλεκτρολογικά Υλικά,Ηλεκτρ. Υλικά,ylika - Ηλεκτρομαγνητική Συμβατότητα,H/M Συμβατότητα,HM_symvatothta - Ηλεκτρομαγνητικό Πεδίο I,Πεδίο 1,pedio_I - Ηλεκτρομαγνητικό Πεδίο II,Πεδίο 2,pedio_II - Ηλεκτρονικά Iσχύος I,Iσχύος 1,isxyos_I - Ηλεκτρονικά Iσχύος II,Iσχύος 2,isxyos_II - Ηλεκτρονικές Διατάξεις και Μετρήσεις,Ηλεκτρονικές Διατάξεις και Μετρήσεις,hlektron_diatakseis_metrhseis - Ηλεκτρονική I,Ηλεκτρονική 1,hlektronikh_I - Ηλεκτρονική II,Ηλεκτρονική 2,hlektronikh_II - Ηλεκτρονική III,Ηλεκτρονική 3,hlektronikh_III - Ημιαγωγά Υλικά: Θεωρία-Διατάξεις,Ημιαγωγά Υλικά,Hmiagwga_Ylika - Θεωρία Πιθανοτήτων και Στατιστική,Πιθανότητες,pithanothtes - Θεωρία Πληροφοριών,Θεωρία Πληρ.,theoria_plir - Θεωρία Σημάτων και Γραμμικών Συστημάτων,Σύματα & Συστήματα,analog_shma - Θεωρία Σκέδασης,Σκέδαση,skedash - Θεωρία Υπολογισμών και Αλγορίθμων,ΘΥΑ,thya - Θεωρία και Τεχνολογία Πυρηνικών Αντιδραστήρων,Τεχνολογία Αντιδραστήρων,texn_antidrasthrwn - Κβαντική Φυσική,Κβαντική,kvantikh - Κινητές και Δορυφορικές Επικοινωνίες,Κινητές & Δορυφορικές Επικοινωνίες,kinhtes_doryforikes_epik - Λειτουργικά Συστήματα,Λειτουργικά,OS - Λογική Σχεδίαση,Λογική Σχεδίαση,logiki_sxediash - Λογισμός I,Λογισμός 1,logismos_I - Λογισμός II,Λογισμός 2,logismos_II - Μετάδοση Θερμότητας,Μετάδοση Θερμ.,metadosi_therm - Μικροεπεξεργαστές και Περιφερειακά,Μίκρο 2,mikro_II - Μικροκυματική Τηλεπισκόπηση,Τηλεπισκόπηση,thlepiskophsh - Μικροκύματα I,Μικροκύματα 1,mikrokymata_I - Μικροκύματα II,Μικροκύματα 2,mikrokymata_II - Οπτικές Επικοινωνίες,Οπτικές Τηλεπ.,optikes_thlep - Οπτική I,Οπτική 1,optikh_I - Οπτική II,Οπτική 2,optikh_II - Οργάνωση Υπολογιστών,Οργάνωση Υπολ.,org_ypol - Οργάνωση και Διοίκηση Εργοστασίων,Οργάνωση και Διοίκηση Εργοστασίων,organ_dioik_ergostasiwn - Παράλληλα και Κατανεμημένα Συστήματα,Παράλληλα,parallhla - Προγραμματιζόμενα Κυκλώματα ASIC,ASIC,asic - Προγραμματιστικές Τεχνικές,Προγραμματ. Τεχν.,cpp - Προηγμένες Τεχνικές Επεξεργασίας Σήματος,ΠΤΕΣ,ptes - Προσομοίωση και Μοντελοποίηση Συστημάτων,Μοντελοποίηση,montelopoihsh - Ρομποτική,Ρομποτική,rompotikh - Σήματα και Συστήματα,Σύματα & Συστήματα,analog_shma - Σερβοκινητήρια Συστήματα,Σέρβο,servo - Σταθμοί Παραγωγής Ηλεκτρικής Ενέργειας,ΣΠΗΕ,SPHE - Στοχαστικό Σήμα,Στοχ. Σήμα,stox_shma - Συστήματα Αυτομάτου Ελέγχου I,ΣΑΕ 1,SAE_I - Συστήματα Αυτομάτου Ελέγχου II,ΣΑΕ 2,SAE_II - Συστήματα Αυτομάτου Ελέγχου III,ΣΑΕ 3,SAE_III - Συστήματα Ηλεκτρικής Ενέργειας I,ΣΗΕ 1,SHE_I - Συστήματα Ηλεκτρικής Ενέργειας II,ΣΗΕ 2,SHE_II - Συστήματα Ηλεκτρικής Ενέργειας III,ΣΗΕ 3,SHE_III - Συστήματα Ηλεκτροκίνησης,Ηλεκτροκίνηση,hlektrokinhsh - Συστήματα Μικροϋπολογιστών,Μίκρο 1,mikro_I - Συστήματα Πολυμέσων και Εικονική Πραγματικότητα,Πολυμέσα,polymesa - Συστήματα Υπολογιστών (Υπολογιστικά Συστήματα),Συσ. Υπολογιστών,sys_ypologistwn - Σχεδίαση Συστημάτων VLSI,VLSI,VLSI - Σύνθεση Ενεργών και Παθητικών Κυκλωμάτων,Σύνθεση,synthesh - Σύνθεση Τηλεπικοινωνιακών Διατάξεων,Σύνθεση Τηλεπ. Διατάξεων,synth_thlep_diataksewn - Τεχνικές Βελτιστοποίησης,Βελτιστοποίηση,veltistopoihsh - Τεχνικές Κωδικοποίησης,Τεχνικές Κωδικοποίησης,texn_kwdikopoihshs - Τεχνικές Σχεδίασης με Η/Υ,Σχέδιο,sxedio - Τεχνικές μη Καταστρεπτικών Δοκιμών,Μη Καταστρεπτικές Δοκιμές,non_destructive_tests - Τεχνική Μηχανική,Τεχν. Μηχαν.,texn_mhxan - Τεχνολογία Ήχου και Εικόνας,Τεχνολογία Ήχου και Εικόνας,texn_hxoy_eikonas - Τεχνολογία Ηλεκτροτεχνικών Υλικών,Ηλεκτροτεχνικά Υλικά,Hlektrotexnika_Ylika - Τεχνολογία Λογισμικού,Τεχνολογία Λογισμικού,SE - Τηλεοπτικά Συστήματα,Τηλεοπτικά,tileoptika - Τηλεπικοινωνιακή Ηλεκτρονική,Τηλεπ. Ηλεκτρ.,tilep_ilektr - Υπολογιστικές Μέθοδοι στα Ενεργειακά Συστήματα,ΥΜΕΣ,ymes - Υπολογιστικός Ηλεκτρομαγνητισμός,Υπολογιστικός Η/Μ,ypologistikos_HM - Υψηλές Τάσεις 4,Υψηλές 4,ypshles_IV - Υψηλές Τάσεις I,Υψηλές 1,ypshles_I - Υψηλές Τάσεις II,Υψηλές 2,ypshles_II - Υψηλές Τάσεις III,Υψηλές 3,ypshles_III - Φυσική I,Φυσική 1,fysikh_I - Φωτονική Τεχνολογία,Φωτονική,fwtonikh - Ψηφιακά Συστήματα I,Ψηφιακά 1,pshfiaka_I - Ψηφιακά Συστήματα II,Ψηφιακά 2,pshfiaka_II - Ψηφιακά Συστήματα III,Ψηφιακά 3,pshfiaka_III - Ψηφιακά Φίλτρα,Φίλτρα,filtra - Ψηφιακές Τηλεπικοινωνίες I,Ψηφιακές Τηλεπ. 1,pshf_thlep_I - Ψηφιακές Τηλεπικοινωνίες II,Ψηφιακές Τηλεπ. 2,pshf_thlep_II - Ψηφιακή Επεξεργασία Εικόνας,ΨΕΕ,PSEE - Ψηφιακή Επεξεργασία Σήματος,ΨΕΣ,PSES + Ακουστική I:Ακουστική 1:Akoustiki_I + Ακουστική II:Ακουστική 2:Akoustiki_II + Ανάλυση Ηλεκτρικών Κυκλωμάτων με Υπολογιστή:Ανάλυση Ηλεκτρικ. Κυκλ. με Υπολογιστή:Analysi_Ilektr_Kykl + Ανάλυση Συστημάτων Ηλεκτρικής Ενέργειας:ΑΣΗΕ:ASHE + Ανάλυση Χρονοσειρών:Χρονοσειρές:Xronoseires + Ανάλυση και Σχεδίαση Αλγορίθμων:Αλγόριθμοι:Algorithms + Αναγνώριση Προτύπων:Αναγνώριση Προτύπων:protipa + Αναλογικές Τηλεπικοινωνίες (πρώην Τηλεπικοινωνιακά Συστήματα I):Αναλογικές Τηλεπ.:Anal_Tilep + Αντικειμενοστραφής Προγραμματισμός:Αντικειμενοστραφής:OOP + Αξιοπιστία Συστημάτων:Αξιοπιστία Συστημάτων:Aksiopistia_Systimaton + Αριθμητική Ανάλυση:Αριθμ. Ανάλυση:Arith_Anal + Αρχές Οικονομίας:Αρχές Οικονομίας:Arx_Oikonomias + Αρχές Παράλληλης Επεξεργασίας:Αρχές Παράλληλης Επεξεργασίας:Arxes_Parall_Epeksergasias + Αρχιτεκτονική Υπολογιστών:Αρχ. Υπολογιστών:Arx_Ypologiston + Ασαφή Συστήματα:Ασαφή:Asafi + Ασφάλεια Πληροφοριακών Συστημάτων:Ασφάλεια:Asfaleia + Ασύρματος Τηλεπικοινωνία I:Ασύρματος 1:Asyrmatos_I + Ασύρματος Τηλεπικοινωνία II:Ασύρματος 2:Asyrmatos_II + Βάσεις Δεδομένων:Βάσεις:Vaseis + Βιομηχανικά Ηλεκτρονικά:Βιομηχανικά Ηλεκτρονικά:Viomix_Ilektronika + Βιομηχανική Πληροφορική:Βιομηχανική Πληρ:Viomix_Plir + Βιοϊατρική Τεχνολογία:Βιοιατρική:Vioiatriki + Γεωηλεκτρομαγνητισμός:Γεωηλεκτρομαγνητισμός:Geoilektromagnitismos + Γραμμική Άλγεβρα:Γραμμ. Άλγεβρ.:Grammiki_Algevra + Γραφική με Υπολογιστές:Γραφική:Grafiki + Δίκτυα Τηλεπικοινωνιών:Δίκτυα Τηλέπ.:Diktya_Tilep + Δίκτυα Υπολογιστών I:Δίκτυα 1:Diktya_I + Δίκτυα Υπολογιστών II:Δίκτυα 2:Diktya_II + Διάδοση Η/Μ Κύματος II:Διάδοση 2:Diadosi_II + Διάδοση Ηλεκτρομαγνητικού Κύματος I (πρώην Πεδίο III):Διάδοση 1:Diadosi_I + Διακριτά Μαθηματικά:Διακριτά Μαθηματικά:Diakrita + Διακριτά μαθηματικά:Διακριτά Μαθηματικά:Diakrita + Διανεμημένη Παραγωγή:Διανεμημένη Παραγωγή:Dian_Paragogi + Διαφορικές Εξισώσεις:Διαφορικές:Diaforikes + Διαχείριση Συστημάτων Ηλεκτρικής Ενέργειας:ΔΣΗΕ:DSHE + Δομές Δεδομένων:Δομ. Δεδομ.:Domes_Dedomenon + Δομημένος Προγραμματισμός:Δομ. Προγραμμ.:C + Ειδικά Κεφάλαια Διαφορικών Εξισώσεων:Ειδικά Κεφάλαια Διαφορικών Εξισώσεων:Eidika_Kef_Diaf_Eksis + Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I:Ειδικά Κεφάλαια Ηλεκτρομαγνητικού Πεδίου I:Eidika_Kef_HM_Pediou_I + Ειδικά Κεφάλαια Συστημάτων Ηλεκτρικής Ενέργειας:ΕΚΣΗΕ:EKSHE + Ειδικές Αρχιτεκτονικές Υπολογιστών:Ειδικές Αρχιτεκτονικές Υπολογιστών:Eidikes_Arx_Ypolog + Ειδικές Κεραίες, Σύνθεση Κεραιών:Ειδικές Κεραίες, Σύνθεση Κεραιών:Eidikes_Keraies + Εισαγωγή στην Ενεργειακή Τεχνολογία I:ΕΕΤ 1:EET_I + Εισαγωγή στην Ενεργειακή Τεχνολογία II:ΕΕΤ2:EET_II + Εισαγωγή στην Πολιτική Οικονομία:Πολιτική Οικονομία:Polit_Oik + Εισαγωγή στις εφαρμογές Πυρηνικής Τεχνολογίας:Εισ. Πυρηνικη Τεχν.:Intro_Pyriniki_Texn + Ενσωματωμένα Συστήματα Πραγματικού Χρόνου:Ενσωματωμένα:Enswmatwmena + Επιχειρησιακή Έρευνα:Επιχειρησιακή Έρευνα:Epixeirisiaki + Ευρυζωνικά Δίκτυα:Ευρυζωνικά:Evryzonika + Ευφυή Συστήματα Ρομπότ:Ευφυή:eufuh + Εφαρμογές Τηλεπικοινωνιακών Διατάξεων:Εφαρμογές Τηλεπ. Διατάξεων:Efarm_Tilep_Diatakseon + Εφαρμοσμένα Μαθηματικά I:Εφαρμοσμένα 1:Efarmosmena_Math_I + Εφαρμοσμένα Μαθηματικά II:Εφαρμοσμένα 2:Efarmosmena_Math_II + Εφαρμοσμένη Θερμοδυναμική:Θερμοδυναμική:Thermodynamiki + Ηλεκτρακουστική I:Ηλεκτρακουστική 1:Ilektrakoustiki_I + Ηλεκτρακουστική II:Ηλεκτρακουστική 2:Ilektrakoustiki_II + Ηλεκτρικά Κυκλώματα I:Κυκλώματα 1:Kyklomata_I + Ηλεκτρικά Κυκλώματα II:Κυκλώματα 2:Kyklomata_II + Ηλεκτρικά Κυκλώματα III:Κυκλώματα 3:Kyklomata_I + Ηλεκτρικές Μετρήσεις I:Μετρήσεις 1:Metriseis_I + Ηλεκτρικές Μετρήσεις II:Μετρήσεις 2:Metriseis_II + Ηλεκτρικές Μηχανές Α\':Μηχανές Α:Mixanes_A + Ηλεκτρικές Μηχανές Β\':Μηχανές Β:Mixanes_B + Ηλεκτρικές Μηχανές Γ\':Μηχανές Γ:Mixanes_C + Ηλεκτρική Οικονομία:Ηλεκτρική Οικονομία:Ilektr_Oikonomia + Ηλεκτρολογικά Υλικά:Ηλεκτρ. Υλικά:Ylika + Ηλεκτρομαγνητική Συμβατότητα:H/M Συμβατότητα:HM_Symvatotita + Ηλεκτρομαγνητικό Πεδίο I:Πεδίο 1:Pedio_I + Ηλεκτρομαγνητικό Πεδίο II:Πεδίο 2:Pedio_II + Ηλεκτρονικά Ισχύος I:Ισχύος 1:Isxyos_I + Ηλεκτρονικά Ισχύος II:Ισχύος 2:Isxyos_II + Ηλεκτρονικές Διατάξεις και Μετρήσεις:Ηλεκτρονικές Διατάξεις και Μετρήσεις:Ilektron_Diatakseis_Metriseis + Ηλεκτρονική I:Ηλεκτρονική 1:Ilektroniki_I + Ηλεκτρονική II:Ηλεκτρονική 2:Ilektroniki_II + Ηλεκτρονική III:Ηλεκτρονική 3:Ilektroniki_III + Ημιαγωγά Υλικά: Θεωρία-Διατάξεις:Ημιαγωγά Υλικά:Imiagoga_Ylika + Θεωρία Πιθανοτήτων και Στατιστική:Πιθανότητες:Pithanotites + Θεωρία Πληροφοριών:Θεωρία Πληρ.:Theoria_Plir + Θεωρία Σημάτων και Γραμμικών Συστημάτων:Σήματα & Συστήματα:Analog_Sima + Θεωρία Σκέδασης:Σκέδαση:Skedasi + Θεωρία Υπολογισμών και Αλγορίθμων:ΘΥΑ:THYA + Θεωρία και Τεχνολογία Πυρηνικών Αντιδραστήρων:Τεχνολογία Αντιδραστήρων:Texn_Antidrasthron + Κβαντική Φυσική:Κβαντική:Kvantiki + Κινητές και Δορυφορικές Επικοινωνίες:Κινητές & Δορυφορικές Επικοινωνίες:Kinites_Doryforikes_Epik + Λειτουργικά Συστήματα:Λειτουργικά:OS + Λογική Σχεδίαση:Λογική Σχεδίαση:Logiki_Sxediasi + Λογισμός I:Λογισμός 1:Logismos_I + Λογισμός II:Λογισμός 2:Logismos_II + Μετάδοση Θερμότητας:Μετάδοση Θερμ.:Metadosi_Therm + Μικροεπεξεργαστές και Περιφερειακά:Μίκρο 2:Mikro_II + Μικροκυματική Τηλεπισκόπηση:Τηλεπισκόπηση:Tilepiskopisi + Μικροκύματα I:Μικροκύματα 1:Mikrokymata_I + Μικροκύματα II:Μικροκύματα 2:Mikrokymata_II + Οπτικές Επικοινωνίες:Οπτικές Τηλεπ.:Optikes_Tilep + Οπτική I:Οπτική 1:Optiki_I + Οπτική II:Οπτική 2:Optiki_II + Οργάνωση Υπολογιστών:Οργάνωση Υπολ.:Org_Ypol + Οργάνωση και Διοίκηση Εργοστασίων:Οργάνωση και Διοίκηση Εργοστασίων:Organ_Dioik_Ergostasion + Παράλληλα και Κατανεμημένα Συστήματα:Παράλληλα:Parallila + Προγραμματιζόμενα Κυκλώματα ASIC:ASIC:ASIC + Προγραμματιστικές Τεχνικές:Προγραμματ. Τεχν.:CPP + Προηγμένες Τεχνικές Επεξεργασίας Σήματος:ΠΤΕΣ:PTES + Προσομοίωση και Μοντελοποίηση Συστημάτων:Μοντελοποίηση:Montelopoiisi + Ρομποτική:Ρομποτική:Robotiki + Σήματα και Συστήματα:Σήματα & Συστήματα:Analog_Sima + Σερβοκινητήρια Συστήματα:Σέρβο:Servo + Σταθμοί Παραγωγής Ηλεκτρικής Ενέργειας:ΣΠΗΕ:SPHE + Στοχαστικό Σήμα:Στοχ. Σήμα:Stox_Sima + Συστήματα Αυτομάτου Ελέγχου I:ΣΑΕ 1:SAE_I + Συστήματα Αυτομάτου Ελέγχου II:ΣΑΕ 2:SAE_II + Συστήματα Αυτομάτου Ελέγχου III:ΣΑΕ 3:SAE_III + Συστήματα Ηλεκτρικής Ενέργειας I:ΣΗΕ 1:SHE_I + Συστήματα Ηλεκτρικής Ενέργειας II:ΣΗΕ 2:SHE_II + Συστήματα Ηλεκτρικής Ενέργειας III:ΣΗΕ 3:SHE_III + Συστήματα Ηλεκτροκίνησης:Ηλεκτροκίνηση:Ilektrokinisi + Συστήματα Μικροϋπολογιστών:Μίκρο 1:Mikro_I + Συστήματα Πολυμέσων και Εικονική Πραγματικότητα:Πολυμέσα:Polymesa + Συστήματα Υπολογιστών (Υπολογιστικά Συστήματα):Συσ. Υπολογιστών:Sys_Ypologiston + Σχεδίαση Συστημάτων VLSI:VLSI:VLSI + Σύνθεση Ενεργών και Παθητικών Κυκλωμάτων:Σύνθεση:Synthesi + Σύνθεση Τηλεπικοινωνιακών Διατάξεων:Σύνθεση Τηλεπ. Διατάξεων:Synth_Tilep_Diatakseon + Τεχνικές Βελτιστοποίησης:Βελτιστοποίηση:Veltistopoiisi + Τεχνικές Κωδικοποίησης:Τεχνικές Κωδικοποίησης:Texn_Kodikopoiisis + Τεχνικές Σχεδίασης με Η/Υ:Σχέδιο:sxedio + Τεχνικές μη Καταστρεπτικών Δοκιμών:Μη Καταστρεπτικές Δοκιμές:Non_Destructive_Tests + Τεχνική Μηχανική:Τεχν. Μηχαν.:Texn_Mixan + Τεχνολογία Ήχου και Εικόνας:Τεχνολογία Ήχου και Εικόνας:Texn_Ixou_Eikonas + Τεχνολογία Ηλεκτροτεχνικών Υλικών:Ηλεκτροτεχνικά Υλικά:Ilektrotexnika_Ylika + Τεχνολογία Λογισμικού:Τεχνολογία Λογισμικού:SE + Τηλεοπτικά Συστήματα:Τηλεοπτικά:Tileoptika + Τηλεπικοινωνιακή Ηλεκτρονική:Τηλεπ. Ηλεκτρ.:Tilep_Ilektr + Υπολογιστικές Μέθοδοι στα Ενεργειακά Συστήματα:ΥΜΕΣ:YMES + Υπολογιστικός Ηλεκτρομαγνητισμός:Υπολογιστικός Η/Μ:Ypologistikos_HM + Υψηλές Τάσεις I:Υψηλές 1:Ypsiles_I + Υψηλές Τάσεις II:Υψηλές 2:Ypsiles_II + Υψηλές Τάσεις III:Υψηλές 3:Ypsiles_III + Υψηλές Τάσεις 4:Υψηλές 4:Ypsiles_IV + Φυσική I:Φυσική 1:Fysiki_I + Φωτονική Τεχνολογία:Φωτονική:Fotoniki + Ψηφιακά Συστήματα I:Ψηφιακά 1:Psifiaka_I + Ψηφιακά Συστήματα II:Ψηφιακά 2:Psifiaka_II + Ψηφιακά Συστήματα III:Ψηφιακά 3:Psifiaka_III + Ψηφιακά Φίλτρα:Φίλτρα:Filtra + Ψηφιακές Τηλεπικοινωνίες I:Ψηφιακές Τηλεπ. 1:Psif_Tilep_I + Ψηφιακές Τηλεπικοινωνίες II:Ψηφιακές Τηλεπ. 2:Psif_Tilep_II + Ψηφιακή Επεξεργασία Εικόνας:ΨΕΕ:PSEE + Ψηφιακή Επεξεργασία Σήματος:ΨΕΣ:PSES \ No newline at end of file From 165acddce1e3a1f5ea542735c6d35e7627bd5c2d Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 22 Jun 2019 14:02:42 +0300 Subject: [PATCH 14/18] Grgit up version fix --- app/gradle/grgit.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/gradle/grgit.gradle b/app/gradle/grgit.gradle index dc0d5e7f..da262dd7 100644 --- a/app/gradle/grgit.gradle +++ b/app/gradle/grgit.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'org.ajoberstar.grgit:grgit-core:3.0.0' + classpath 'org.ajoberstar.grgit:grgit-core:3.1.1' } } @@ -48,4 +48,4 @@ ext { getCurrentBranch = this.&getCurrentBranch getCommitHash = this.&getCommitHash isClean = this.&isClean -} \ No newline at end of file +} From f894090e21e59ad212239da42dceebaabc64fede Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 22 Jun 2019 14:08:33 +0300 Subject: [PATCH 15/18] Added gradle-versions-plugin --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 677adbde..108b8fa6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,5 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: "com.github.ben-manes.versions" buildscript { repositories { @@ -12,6 +13,7 @@ buildscript { classpath 'com.google.gms:google-services:4.2.0' classpath 'io.fabric.tools:gradle:1.29.0' classpath 'org.ajoberstar.grgit:grgit-core:3.1.1' // Also change in app/gradle/grgit.gradle + classpath "com.github.ben-manes:gradle-versions-plugin:0.21.0" } } From 225585b7323a692d5b38fbe2bb021f321d79be54 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 22 Jun 2019 14:21:37 +0300 Subject: [PATCH 16/18] Up libs --- app/build.gradle | 12 ++++++------ app/src/main/assets/apache_libraries.html | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 56b9112b..390fcb78 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,10 +71,10 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android.material:material:1.0.0' implementation 'com.google.firebase:firebase-core:17.0.0' - implementation 'com.google.firebase:firebase-messaging:19.0.0' + implementation 'com.google.firebase:firebase-messaging:19.0.1' implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' implementation 'com.snatik:storage:2.1.0' - implementation 'com.squareup.okhttp3:okhttp:3.12.0' + implementation 'com.squareup.okhttp3:okhttp:3.14.2' implementation 'com.squareup.picasso:picasso:2.5.2' implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' implementation 'org.jsoup:jsoup:1.10.3' //TODO: Warning: upgrading from 1.10.3 will break stuff! @@ -87,10 +87,10 @@ dependencies { implementation 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'//TODO: deprecated! implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2' implementation 'com.jakewharton.timber:timber:4.7.1' - implementation 'ru.noties:markwon:2.0.0' - implementation 'net.gotev:uploadservice:3.4.2' - implementation 'net.gotev:uploadservice-okhttp:3.4.2' - implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.4' //Plugin: https://plugins.jetbrains.com/plugin/11249-okhttp-profiler + implementation 'ru.noties:markwon:2.0.2' + implementation 'net.gotev:uploadservice:3.5.2' + implementation 'net.gotev:uploadservice-okhttp:3.5.2' + implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.5' //Plugin: https://plugins.jetbrains.com/plugin/11249-okhttp-profiler } apply plugin: 'com.google.gms.google-services' diff --git a/app/src/main/assets/apache_libraries.html b/app/src/main/assets/apache_libraries.html index b0e33882..911a8e50 100644 --- a/app/src/main/assets/apache_libraries.html +++ b/app/src/main/assets/apache_libraries.html @@ -39,7 +39,7 @@

From 5a5c9a7cfe0e8d2adb0f1aa74c92f5e81131207c Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 22 Jun 2019 17:53:17 +0300 Subject: [PATCH 17/18] More up libs --- app/build.gradle | 12 +++++++----- .../thmmy/mthmmy/services/NotificationService.java | 5 ++--- .../main/java/gr/thmmy/mthmmy/utils/TakePhoto.java | 12 +++++------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 390fcb78..fa5831b8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -61,14 +61,15 @@ tasks.whenTaskAdded { task -> dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.appcompat:appcompat:1.1.0-beta01' implementation 'androidx.preference:preference:1.1.0-beta01' implementation 'androidx.legacy:legacy-preference-v14:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.0.0' - implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha01' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.exifinterface:exifinterface:1.1.0-alpha01' implementation 'com.google.android.material:material:1.0.0' implementation 'com.google.firebase:firebase-core:17.0.0' implementation 'com.google.firebase:firebase-messaging:19.0.1' @@ -78,8 +79,8 @@ dependencies { implementation 'com.squareup.picasso:picasso:2.5.2' implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' implementation 'org.jsoup:jsoup:1.10.3' //TODO: Warning: upgrading from 1.10.3 will break stuff! - implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1' - implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3' + implementation 'com.github.franmontiel:PersistentCookieJar:1.0.1' + implementation 'com.github.PhilJay:MPAndroidChart:3.0.3' implementation 'com.mikepenz:materialdrawer:6.1.1' implementation 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar' implementation 'com.mikepenz:google-material-typeface:3.0.1.2.original@aar' @@ -90,7 +91,8 @@ dependencies { implementation 'ru.noties:markwon:2.0.2' implementation 'net.gotev:uploadservice:3.5.2' implementation 'net.gotev:uploadservice-okhttp:3.5.2' - implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.5' //Plugin: https://plugins.jetbrains.com/plugin/11249-okhttp-profiler + implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.5' +//Plugin: https://plugins.jetbrains.com/plugin/11249-okhttp-profiler } apply plugin: 'com.google.gms.google-services' diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java b/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java index 41ff3d95..79c36d4b 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java @@ -261,10 +261,9 @@ public class NotificationService extends FirebaseMessagingService { NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // Since Android Oreo notification channel is needed. - if (buildVersion >= Build.VERSION_CODES.O){ - if (notificationManager.getNotificationChannel(CHANNEL_ID) == null) + if (buildVersion >= Build.VERSION_CODES.O && notificationManager.getNotificationChannel(CHANNEL_ID) == null) notificationManager.createNotificationChannel(new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH)); - } + notificationManager.notify(NEW_POST_TAG, notificationId, notificationBuilder.build()); diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java b/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java index f1d7d990..c5b4c490 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/TakePhoto.java @@ -10,7 +10,6 @@ import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; -import android.media.ExifInterface; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; @@ -19,6 +18,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.FileProvider; +import androidx.exifinterface.media.ExifInterface; import java.io.File; import java.io.FileNotFoundException; @@ -86,12 +86,10 @@ public class TakePhoto { File imageFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + "mTHMMY"); - if (!imageFolder.exists()) { - if (!imageFolder.mkdirs()) { - Timber.w("Photos folder build returned false in %s", TakePhoto.class.getSimpleName()); - Toast.makeText(context, "Couldn't create photos directory", Toast.LENGTH_SHORT).show(); - return null; - } + if (!imageFolder.exists()&&!imageFolder.mkdirs()) { + Timber.w("Photos folder build returned false in %s", TakePhoto.class.getSimpleName()); + Toast.makeText(context, "Couldn't create photos directory", Toast.LENGTH_SHORT).show(); + return null; } return new File(imageFolder, imageFileName); From 6d88b32b0ae669cdcb98cc7118f09292bf4888a4 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Fri, 28 Jun 2019 21:41:50 +0300 Subject: [PATCH 18/18] Version code fix --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index fa5831b8..44028151 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,7 +13,7 @@ android { applicationId "gr.thmmy.mthmmy" minSdkVersion 19 targetSdkVersion 28 - versionCode 19 + versionCode 18 versionName "1.7.0" archivesBaseName = "mTHMMY-v$versionName" buildConfigField "String", "CURRENT_BRANCH", "\"" + getCurrentBranch() + "\""