Browse Source

Multiple files upload, Other fixes and improvements

uploads
Apostolos Fanakis 6 years ago
parent
commit
3c0edf3ae8
  1. 176
      app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java
  2. 2
      app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java
  3. 10
      app/src/main/res/layout/activity_upload.xml
  4. 2
      app/src/main/res/layout/activity_upload_file_list_row.xml
  5. 5
      app/src/main/res/values-v21/styles.xml
  6. 2
      app/src/main/res/values/strings.xml
  7. 4
      app/src/main/res/values/styles.xml

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

@ -21,6 +21,7 @@ import android.text.Spannable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
@ -96,6 +97,9 @@ public class UploadActivity extends BaseActivity {
private ArrayList<UploadFile> filesList = new ArrayList<>(); private ArrayList<UploadFile> filesList = new ArrayList<>();
private File photoFileCreated = null; private File photoFileCreated = null;
private String fileIcon; private String fileIcon;
private AppCompatImageButton uploadFilenameInfo;
private CustomTextWatcher textWatcher;
private boolean hasModifiedFilename = false;
//UI elements //UI elements
private MaterialProgressBar progressBar; private MaterialProgressBar progressBar;
@ -211,7 +215,7 @@ public class UploadActivity extends BaseActivity {
uploadTitle = findViewById(R.id.upload_title); uploadTitle = findViewById(R.id.upload_title);
uploadDescription = findViewById(R.id.upload_description); uploadDescription = findViewById(R.id.upload_description);
AppCompatImageButton uploadFilenameInfo = findViewById(R.id.upload_filename_info); uploadFilenameInfo = findViewById(R.id.upload_filename_info);
uploadFilenameInfo.setOnClickListener(view -> { uploadFilenameInfo.setOnClickListener(view -> {
//Inflates the popup menu content //Inflates the popup menu content
LayoutInflater layoutInflater = (LayoutInflater) view.getContext(). LayoutInflater layoutInflater = (LayoutInflater) view.getContext().
@ -236,61 +240,8 @@ public class UploadActivity extends BaseActivity {
}); });
uploadFilename = findViewById(R.id.upload_filename); uploadFilename = findViewById(R.id.upload_filename);
uploadFilename.addTextChangedListener(new TextWatcher() { textWatcher = new CustomTextWatcher();
String oldFilename, fileExtension; uploadFilename.addTextChangedListener(textWatcher);
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
oldFilename = s.toString();
String uriExtension;
if (filesList.isEmpty()) {
fileExtension = null;
return;
} else if (filesList.size() == 1) {
uriExtension = FileUtils.getFileExtension(FileUtils.
filenameFromUri(getApplicationContext(), filesList.get(0).getFileUri()));
} else {
uriExtension = ".zip";
}
if (fileExtension == null || !fileExtension.equals(uriExtension)) {
//New file selected
//Changes the extension of the saved filename instance
oldFilename = FileUtils.getFilenameWithoutExtension(oldFilename) +
uriExtension;
}
fileExtension = uriExtension;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
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) {
return;
}
if (!s.toString().endsWith(fileExtension)) {
uploadFilename.setText(oldFilename);
return;
}
s.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.secondary_text)),
s.length() - fileExtension.length(), s.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
});
filesListView = findViewById(R.id.upload_files_list); filesListView = findViewById(R.id.upload_files_list);
@ -305,7 +256,8 @@ public class UploadActivity extends BaseActivity {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT) Intent intent = new Intent(Intent.ACTION_GET_CONTENT)
//.setType("*/*") //.setType("*/*")
.setType("image/jpeg") .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); startActivityForResult(intent, AFR_REQUEST_CODE_CHOOSE_FILE);
}); });
@ -459,6 +411,7 @@ public class UploadActivity extends BaseActivity {
uploadTitle.setText(null); uploadTitle.setText(null);
uploadFilename.setText(null); uploadFilename.setText(null);
hasModifiedFilename = false;
uploadDescription.setText(null); uploadDescription.setText(null);
filesList.clear(); filesList.clear();
filesListView.removeAllViews(); filesListView.removeAllViews();
@ -526,13 +479,27 @@ public class UploadActivity extends BaseActivity {
return; return;
} }
if (data.getClipData() != null) {
fileIcon = "archive.gif";
textWatcher.setFileExtension(".zip");
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(); Uri newFileUri = data.getData();
if (newFileUri != null) { if (newFileUri != null) {
String filename = FileUtils.filenameFromUri(this, newFileUri); String filename = FileUtils.filenameFromUri(this, newFileUri);
if (filesList.isEmpty()) { if (filesList.isEmpty()) {
if (uploadFilename.getText().toString().isEmpty()) { textWatcher.setFileExtension(FileUtils.getFileExtension(filename));
if (!hasModifiedFilename) {
uploadFilename.setText(filename); uploadFilename.setText(filename);
hasModifiedFilename = false;
} }
filename = filename.toLowerCase(); filename = filename.toLowerCase();
@ -556,16 +523,13 @@ public class UploadActivity extends BaseActivity {
} }
} else { } else {
fileIcon = "archive.gif"; fileIcon = "archive.gif";
textWatcher.setFileExtension(".zip");
String currentFilename = uploadFilename.getText().toString();
String newFilename = FileUtils.getFilenameWithoutExtension(currentFilename) +
".zip";
uploadFilename.setText(newFilename);
} }
addFileViewToList(filename); addFileViewToList(filename);
filesList.add(new UploadFile(false, newFileUri, null)); filesList.add(new UploadFile(false, newFileUri, null));
} }
}
} else if (requestCode == AFR_REQUEST_CODE_CAMERA) { } else if (requestCode == AFR_REQUEST_CODE_CAMERA) {
if (resultCode == Activity.RESULT_CANCELED) { if (resultCode == Activity.RESULT_CANCELED) {
//Deletes image file //Deletes image file
@ -574,18 +538,17 @@ public class UploadActivity extends BaseActivity {
} }
if (filesList.isEmpty()) { if (filesList.isEmpty()) {
if (uploadFilename.getText().toString().isEmpty()) { textWatcher.setFileExtension(FileUtils.getFileExtension(photoFileCreated.getName()));
if (!hasModifiedFilename) {
uploadFilename.setText(photoFileCreated.getName()); uploadFilename.setText(photoFileCreated.getName());
hasModifiedFilename = false;
} }
fileIcon = "jpg_image.gif"; fileIcon = "jpg_image.gif";
} else { } else {
fileIcon = "archive.gif"; fileIcon = "archive.gif";
textWatcher.setFileExtension(".zip");
String currentFilename = uploadFilename.getText().toString();
String newFilename = FileUtils.getFilenameWithoutExtension(currentFilename) +
".zip";
uploadFilename.setText(newFilename);
} }
UploadFile newFile = new UploadFile(true, TakePhoto.processResult(this, UploadFile newFile = new UploadFile(true, TakePhoto.processResult(this,
@ -606,6 +569,7 @@ public class UploadActivity extends BaseActivity {
FileUtils.getFileExtension(previousName); FileUtils.getFileExtension(previousName);
uploadFilename.setText(filenameWithExtension); uploadFilename.setText(filenameWithExtension);
} }
hasModifiedFilename = true;
uploadTitle.setText(data.getStringExtra(RESULT_TITLE)); uploadTitle.setText(data.getStringExtra(RESULT_TITLE));
uploadDescription.setText(data.getStringExtra(RESULT_DESCRIPTION)); uploadDescription.setText(data.getStringExtra(RESULT_DESCRIPTION));
@ -651,9 +615,16 @@ public class UploadActivity extends BaseActivity {
setOnClickListener(view -> { setOnClickListener(view -> {
int fileIndex = filesListView.indexOfChild(newFileRow); int fileIndex = filesListView.indexOfChild(newFileRow);
filesListView.removeViewAt(fileIndex); filesListView.removeViewAt(fileIndex);
if (filesList.get(fileIndex).isCameraPhoto()) {
storage.deleteFile(filesList.get(fileIndex).getPhotoFile().getAbsolutePath());
}
filesList.remove(fileIndex); filesList.remove(fileIndex);
if (filesList.isEmpty()) { if (filesList.isEmpty()) {
filesListView.setVisibility(View.GONE); filesListView.setVisibility(View.GONE);
} else if (filesList.size() == 1) {
textWatcher.setFileExtension(FileUtils.getFileExtension(FileUtils.
filenameFromUri(this, filesList.get(0).getFileUri())));
} }
}); });
@ -661,6 +632,73 @@ public class UploadActivity extends BaseActivity {
filesListView.setVisibility(View.VISIBLE); filesListView.setVisibility(View.VISIBLE);
} }
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 class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
private ArrayList<UploadCategory> parentCategories, childCategories; private ArrayList<UploadCategory> parentCategories, childCategories;

2
app/src/main/java/gr/thmmy/mthmmy/utils/FileUtils.java

@ -30,7 +30,7 @@ public class FileUtils {
} }
@Nullable @Nullable
public static String getFileExtension(String filename) { public static String getFileExtension(@NonNull String filename) {
String fileExtension; String fileExtension;
if (!filename.contains(".")) { if (!filename.contains(".")) {

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

@ -157,11 +157,6 @@
android:text="@string/upload_select_file" android:text="@string/upload_select_file"
android:textColor="@color/primary_text" /> android:textColor="@color/primary_text" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.v7.widget.AppCompatButton <android.support.v7.widget.AppCompatButton
android:id="@+id/upload_take_photo_button" android:id="@+id/upload_take_photo_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -172,6 +167,11 @@
android:gravity="center_vertical" android:gravity="center_vertical"
android:text="@string/upload_take_photo" android:text="@string/upload_take_photo"
android:textColor="@color/primary_text" /> android:textColor="@color/primary_text" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</android.support.v4.widget.NestedScrollView> </android.support.v4.widget.NestedScrollView>

2
app/src/main/res/layout/activity_upload_file_list_row.xml

@ -9,6 +9,7 @@
android:id="@+id/upload_file_item_text" android:id="@+id/upload_file_item_text"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1" android:layout_weight="1"
android:drawablePadding="5dp" android:drawablePadding="5dp"
android:ellipsize="marquee" android:ellipsize="marquee"
@ -19,5 +20,6 @@
android:id="@+id/upload_file_item_remove" android:id="@+id/upload_file_item_remove"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/LightBackgroundColoredButton"
app:srcCompat="@drawable/ic_delete_accent_24dp" /> app:srcCompat="@drawable/ic_delete_accent_24dp" />
</LinearLayout> </LinearLayout>

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

@ -1,4 +1,5 @@
<resources> <resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/primary</item> <item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item> <item name="colorPrimaryDark">@color/primary_dark</item>
@ -30,4 +31,8 @@
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="colorControlActivated">@color/accent</item> <item name="colorControlActivated">@color/accent</item>
</style> </style>
<style name="LightBackgroundColoredButton" parent="Widget.AppCompat.ImageButton">
<item name="android:colorButtonNormal">@color/background</item>
</style>
</resources> </resources>

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

@ -118,7 +118,7 @@
<string name="upload_title_hint">Title</string> <string name="upload_title_hint">Title</string>
<string name="upload_filename">Upload as (filename)</string> <string name="upload_filename">Upload as (filename)</string>
<string name="upload_description_hint">Description</string> <string name="upload_description_hint">Description</string>
<string name="upload_select_file">Select file</string> <string name="upload_select_file">Add files</string>
<string name="upload_take_photo">Take photo</string> <string name="upload_take_photo">Take photo</string>
<string name="upload_spinners_hint">Select a category</string> <string name="upload_spinners_hint">Select a category</string>
<string name="upload_filename_info">Please follow the filename rules as\ndescribed <string name="upload_filename_info">Please follow the filename rules as\ndescribed

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

@ -82,4 +82,8 @@
<item name="android:textColorPrimary">@color/primary_text</item> <item name="android:textColorPrimary">@color/primary_text</item>
<item name="android:colorBackground">@color/dialog_bg_semi_transparent</item> <item name="android:colorBackground">@color/dialog_bg_semi_transparent</item>
</style> </style>
<style name="LightBackgroundColoredButton" parent="Widget.AppCompat.ImageButton">
<item name="colorButtonNormal">@color/background</item>
</style>
</resources> </resources>

Loading…
Cancel
Save