diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 70b85191b406..168d18b8cc86 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -149,7 +149,8 @@ android:exported="false" /> + android:exported="false" + android:enabled="false"> @@ -163,7 +164,8 @@ android:exported="false" /> + android:exported="false" + android:enabled="false"> @@ -248,6 +250,7 @@ androidInjector() { public static void setAppTheme(DarkMode mode) { - switch (mode) { + /* switch (mode) { case LIGHT: AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); break; case DARK: AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); break; - case SYSTEM: - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); - break; - } + case SYSTEM:*/ + //NMC Customization + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); + /* break; + }*/ } } diff --git a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java index 8a8572e3002f..4e79da29aba9 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java @@ -27,6 +27,7 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Environment; +import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -58,6 +59,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import javax.inject.Inject; @@ -196,12 +198,26 @@ public void onCreate(Bundle savedInstanceState) { binding.uploadFilesBtnUpload.setOnClickListener(this); binding.uploadFilesBtnUpload.setEnabled(mLocalFolderPickerMode); + //reduce the button text size so that the text doesn't go to next line + //this should only happen for GERMAN language + //and device should not be tablet and should be in portrait mode + if (!DisplayUtils.isTablet() && !DisplayUtils.isLandscapeOrientation()) { + if (Locale.getDefault().getLanguage().equals(Locale.GERMAN.getLanguage()) + || Locale.getDefault().getLanguage().equals(Locale.GERMANY.getLanguage())) { + binding.uploadFilesBtnUpload.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.txt_size_13sp)); + binding.uploadFilesBtnCancel.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.txt_size_13sp)); + } + } + int localBehaviour = preferences.getUploaderBehaviour(); // file upload spinner List behaviours = new ArrayList<>(); - behaviours.add(getString(R.string.uploader_upload_files_behaviour_move_to_nextcloud_folder, - themeUtils.getDefaultDisplayNameForRootFolder(this))); + // Not required this option for NMC + // behaviours.add(getString(R.string.uploader_upload_files_behaviour_move_to_nextcloud_folder, + // themeUtils.getDefaultDisplayNameForRootFolder(this))); behaviours.add(getString(R.string.uploader_upload_files_behaviour_only_upload)); behaviours.add(getString(R.string.uploader_upload_files_behaviour_upload_and_delete_from_source)); @@ -210,6 +226,18 @@ public void onCreate(Bundle savedInstanceState) { behaviourAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); binding.uploadFilesSpinnerBehaviour.setAdapter(behaviourAdapter); binding.uploadFilesSpinnerBehaviour.setSelection(localBehaviour); + binding.uploadFilesSpinnerBehaviour.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int i, long l) { + // store behaviour + preferences.setUploaderBehaviour(binding.uploadFilesSpinnerBehaviour.getSelectedItemPosition()); + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + + } + }); // setup the toolbar setupToolbar(); @@ -272,7 +300,11 @@ public void showToolbarSpinner() { private void fillDirectoryDropdown() { File currentDir = mCurrentDir; while (currentDir != null && currentDir.getParentFile() != null) { - mDirectories.add(currentDir.getName()); + if (currentDir.getName().equals("0")) { + mDirectories.add(getResources().getString(R.string.storage_internal_storage)); + } else { + mDirectories.add(currentDir.getName()); + } currentDir = currentDir.getParentFile(); } mDirectories.add(File.separator); @@ -501,15 +533,16 @@ public void onCheckAvailableSpaceFinish(boolean hasEnoughSpaceAvailable, String. // set result code switch (binding.uploadFilesSpinnerBehaviour.getSelectedItemPosition()) { - case 0: // move to nextcloud folder + // Not required for NMC + /*case 0: // move to nextcloud folder setResult(RESULT_OK_AND_MOVE, data); - break; + break;*/ - case 1: // only upload + case 0: // only upload setResult(RESULT_OK_AND_DO_NOTHING, data); break; - case 2: // upload and delete from source + case 1: // upload and delete from source setResult(RESULT_OK_AND_DELETE, data); break; @@ -577,7 +610,7 @@ private void checkWritableFolder(File folder) { int localBehaviour = preferences.getUploaderBehaviour(); binding.uploadFilesSpinnerBehaviour.setSelection(localBehaviour); } else { - binding.uploadFilesSpinnerBehaviour.setSelection(1); + binding.uploadFilesSpinnerBehaviour.setSelection(0); textView.setText(new StringBuilder().append(getString(R.string.uploader_upload_files_behaviour)) .append(' ') .append(getString(R.string.uploader_upload_files_behaviour_not_writable)) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java index 7ebc62326ae5..1743feee93ed 100755 --- a/app/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java @@ -30,6 +30,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; +import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.view.Menu; @@ -56,11 +57,14 @@ import com.owncloud.android.operations.CheckCurrentCredentialsOperation; import com.owncloud.android.ui.adapter.UploadListAdapter; import com.owncloud.android.ui.decoration.MediaGridItemDecoration; +import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration; +import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.FilesSyncHelper; import com.owncloud.android.utils.theme.ViewThemeUtils; import javax.inject.Inject; +import androidx.annotation.NonNull; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.recyclerview.widget.GridLayoutManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -108,6 +112,8 @@ public class UploadListActivity extends FileActivity { private UploadListLayoutBinding binding; + private SimpleListItemDividerDecoration simpleListItemDividerDecoration; + public static Intent createIntent(OCFile file, User user, Integer flag, Context context) { Intent intent = new Intent(context, UploadListActivity.class); if (flag != null) { @@ -172,6 +178,8 @@ private void setupContent() { int spacing = getResources().getDimensionPixelSize(R.dimen.media_grid_spacing); binding.list.addItemDecoration(new MediaGridItemDecoration(spacing)); binding.list.setLayoutManager(lm); + simpleListItemDividerDecoration = new SimpleListItemDividerDecoration(this, R.drawable.item_divider, true); + addListItemDecorator(); binding.list.setAdapter(uploadListAdapter); viewThemeUtils.androidx.themeSwipeRefreshLayout(swipeListRefreshLayout); @@ -180,6 +188,23 @@ private void setupContent() { loadItems(); } + private void addListItemDecorator() { + if (DisplayUtils.isShowDividerForList()) { + //check and remove divider item decorator if exist then add item decorator + removeListDividerDecorator(); + binding.list.addItemDecoration(simpleListItemDividerDecoration); + } + } + + /** + * method to remove the divider item decorator + */ + private void removeListDividerDecorator() { + if (binding.list.getItemDecorationCount() > 0) { + binding.list.removeItemDecoration(simpleListItemDividerDecoration); + } + } + private void loadItems() { uploadListAdapter.loadUploadItemsFromDb(); @@ -362,4 +387,20 @@ public void onReceive(Context context, Intent intent) { }); } } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + //this should only run when device is not tablet because we are adding dividers in tablet for both the + // orientations + if (!DisplayUtils.isTablet()) { + if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { + //add the divider item decorator when orientation is landscape + addListItemDecorator(); + } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { + //remove the divider item decorator when orientation is portrait + removeListDividerDecorator(); + } + } + } } diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt b/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt index 2a7945ba36a5..0ddad8188873 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt @@ -83,7 +83,8 @@ class GalleryAdapter( transferServiceGetter, showMetadata = false, showShareAvatar = false, - viewThemeUtils + viewThemeUtils, + true ) } diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java index 81f6c1320e6a..f2b2b3cd88b2 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java @@ -176,6 +176,7 @@ public OCFileListAdapter( .getVersion() .isShareesOnDavSupported(), viewThemeUtils, + false, syncedFolderProvider); // initialise thumbnails cache on background thread @@ -312,6 +313,8 @@ public boolean isEmpty() { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { switch (viewType) { default: + // change required for NMC + case VIEWTYPE_IMAGE: case VIEWTYPE_ITEM: if (gridView) { return new OCFileListGridItemViewHolder( @@ -323,17 +326,6 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int ); } - case VIEWTYPE_IMAGE: - if (gridView) { - return new OCFileListGridImageViewHolder( - GridImageBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false) - ); - } else { - return new OCFileListItemViewHolder( - ListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false) - ); - } - case VIEWTYPE_FOOTER: return new OCFileListFooterViewHolder( ListFooterBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false) @@ -502,15 +494,10 @@ private void bindListItemViewHolder(ListItemViewHolder holder, OCFile file) { private void bindListGridItemViewHolder(ListGridItemViewHolder holder, OCFile file) { holder.getFileName().setText(file.getDecryptedFileName()); - boolean gridImage = MimeTypeUtil.isImage(file) || MimeTypeUtil.isVideo(file); - if (gridView && gridImage) { + if (gridView && ocFileListFragmentInterface.getColumnsCount() > showFilenameColumnThreshold) { holder.getFileName().setVisibility(View.GONE); } else { - if (gridView && ocFileListFragmentInterface.getColumnsCount() > showFilenameColumnThreshold) { - holder.getFileName().setVisibility(View.GONE); - } else { - holder.getFileName().setVisibility(View.VISIBLE); - } + holder.getFileName().setVisibility(View.VISIBLE); } } @@ -585,7 +572,7 @@ public boolean shouldShowHeader() { return false; } - if (MainApp.isOnlyOnDevice()) { + if (MainApp.isOnlyOnDevice() || ocFileListFragmentInterface.isSearchFragment()) { return false; } @@ -749,6 +736,8 @@ private void parseShares(List objects) { } List files = OCShareToOCFileConverter.buildOCFilesFromShares(shares); + //clearing list before adding all items to avoid duplicacy of elements in Shared Tab + mFiles.clear(); mFiles.addAll(files); mStorageManager.saveShares(shares); } @@ -957,6 +946,7 @@ public void cancelAllPendingTasks() { public void setGridView(boolean bool) { gridView = bool; + ocFileListDelegate.setGridView(bool); } public void setShowMetadata(boolean bool) { diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt index 058cf2c8df97..5d36d074f4fa 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt @@ -58,11 +58,12 @@ class OCFileListDelegate( private val storageManager: FileDataStorageManager, private val hideItemOptions: Boolean, private val preferences: AppPreferences, - private val gridView: Boolean, + private var gridView: Boolean, private val transferServiceGetter: ComponentsGetter, private val showMetadata: Boolean, private var showShareAvatar: Boolean, private var viewThemeUtils: ViewThemeUtils, + private val isMediaGallery: Boolean, private val syncFolderProvider: SyncedFolderProvider? = null ) { private val checkedFiles: MutableSet = HashSet() @@ -219,7 +220,8 @@ class OCFileListDelegate( gridViewHolder.shimmerThumbnail, preferences, viewThemeUtils, - syncFolderProvider + syncFolderProvider, + isMediaGallery ) // item layout + click listeners bindGridItemLayout(file, gridViewHolder) @@ -277,9 +279,8 @@ class OCFileListDelegate( context.resources .getColor(R.color.selected_item_background) ) - gridViewHolder.checkbox.setImageDrawable( - viewThemeUtils.platform.tintPrimaryDrawable(context, R.drawable.ic_checkbox_marked) - ) + gridViewHolder.checkbox.setImageResource(R.drawable.ic_checkbox_marked) + } else { gridViewHolder.itemLayout.setBackgroundColor(context.resources.getColor(R.color.bg_default)) gridViewHolder.checkbox.setImageResource(R.drawable.ic_checkbox_blank_outline) @@ -370,6 +371,10 @@ class OCFileListDelegate( showShareAvatar = bool } + fun setGridView(bool: Boolean){ + gridView = bool + } + companion object { private val TAG = OCFileListDelegate::class.java.simpleName } diff --git a/app/src/main/java/com/owncloud/android/ui/decoration/SimpleListItemDividerDecoration.java b/app/src/main/java/com/owncloud/android/ui/decoration/SimpleListItemDividerDecoration.java index f4f705ed095b..6dc9de8a8bff 100644 --- a/app/src/main/java/com/owncloud/android/ui/decoration/SimpleListItemDividerDecoration.java +++ b/app/src/main/java/com/owncloud/android/ui/decoration/SimpleListItemDividerDecoration.java @@ -28,6 +28,7 @@ import android.util.DisplayMetrics; import android.view.View; +import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.RecyclerView; @@ -39,7 +40,8 @@ public class SimpleListItemDividerDecoration extends DividerItemDecoration { private final Rect bounds = new Rect(); private Drawable divider; - private int leftPadding; + private int leftPadding = 0; + private boolean hasFooter; /** * Default divider will be used @@ -52,6 +54,17 @@ public SimpleListItemDividerDecoration(Context context) { styledAttributes.recycle(); } + /** + * Custom divider will be used + * + * @param hasFooter if recyclerview has footer and no divider should be shown for footer then pass true else false + */ + public SimpleListItemDividerDecoration(Context context, int resId, boolean hasFooter) { + super(context, DividerItemDecoration.VERTICAL); + this.hasFooter = hasFooter; + divider = ContextCompat.getDrawable(context, resId); + } + @Override public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) { canvas.save(); @@ -65,7 +78,12 @@ public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) right = parent.getWidth(); } - final int childCount = parent.getChildCount(); + int childCount = parent.getChildCount(); + + if (hasFooter) { + childCount = childCount - 1; + } + for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); parent.getDecoratedBoundsWithMargins(child, bounds); diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java b/app/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java index 46937b7a677d..5cee0eceb9d1 100644 --- a/app/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java +++ b/app/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java @@ -215,7 +215,8 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { null, null, viewThemeUtils, - syncedFolderProvider); + syncedFolderProvider, + false); View.OnClickListener checkBoxClickListener = v -> positiveButton.setEnabled(binding.newCheckbox.isChecked() || binding.existingCheckbox.isChecked()); diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/LocalStoragePathPickerDialogFragment.java b/app/src/main/java/com/owncloud/android/ui/dialog/LocalStoragePathPickerDialogFragment.java index 96e39d372ade..d11d67a14461 100644 --- a/app/src/main/java/com/owncloud/android/ui/dialog/LocalStoragePathPickerDialogFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/dialog/LocalStoragePathPickerDialogFragment.java @@ -140,12 +140,14 @@ private List getPathList() { Environment.getExternalStoragePublicDirectory(standardDirectory.getName()).getAbsolutePath()); } - String sdCard = getString(R.string.storage_internal_storage); for (String dir : FileStorageUtils.getStorageDirectories(requireActivity())) { + //NMC Customisation if (internalStoragePaths.contains(dir)) { - addIfExists(storagePathItems, R.drawable.ic_sd_grey600, sdCard, dir); + String internalStorage = getString(R.string.storage_internal_storage); + addIfExists(storagePathItems, R.drawable.ic_sd_grey600, internalStorage, dir); } else { - addIfExists(storagePathItems, R.drawable.ic_sd_grey600, new File(dir).getName(), dir); + String sdCard = getString(R.string.storage_sd_card); + addIfExists(storagePathItems, R.drawable.ic_sd, sdCard, dir); } } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.java index c7260043e822..268898118427 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.java @@ -25,6 +25,7 @@ package com.owncloud.android.ui.fragment; import android.animation.LayoutTransition; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; @@ -322,21 +323,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, mRecyclerView.setHasFixedSize(true); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - mScale = preferences.getGridColumns(); setGridViewColumns(1f); - mScaleGestureDetector = new ScaleGestureDetector(MainApp.getAppContext(), new ScaleListener()); - - getRecyclerView().setOnTouchListener((view, motionEvent) -> { - mScaleGestureDetector.onTouchEvent(motionEvent); - - if (motionEvent.getAction() == MotionEvent.ACTION_UP) { - view.performClick(); - } - - return false; - }); - // Pull-down to refresh layout mRefreshListLayout = binding.swipeContainingList; viewThemeUtils.androidx.themeSwipeRefreshLayout(mRefreshListLayout); @@ -360,6 +348,26 @@ public void onDestroyView() { binding = null; } + /** + * method to enable recyclerview zooming for grid view + */ + @SuppressLint("ClickableViewAccessibility") + public void enableRecyclerViewGridZooming() { + mScale = preferences.getGridColumns(); + + mScaleGestureDetector = new ScaleGestureDetector(MainApp.getAppContext(), new ScaleListener()); + + getRecyclerView().setOnTouchListener((view, motionEvent) -> { + mScaleGestureDetector.onTouchEvent(motionEvent); + + if (motionEvent.getAction() == MotionEvent.ACTION_UP) { + view.performClick(); + } + + return false; + }); + } + private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java index 8cde64eb1969..6121188a9c1d 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java @@ -23,7 +23,6 @@ package com.owncloud.android.ui.fragment; -import android.annotation.SuppressLint; import android.content.Intent; import android.content.res.Configuration; import android.os.AsyncTask; @@ -131,6 +130,8 @@ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { } }); + enableRecyclerViewGridZooming(); + Log_OC.i(this, "onCreateView() in GalleryFragment end"); return v; } @@ -398,4 +399,4 @@ private void updateSubtitle(GalleryFragmentBottomSheetDialog.MediaState mediaSta protected void setGridViewColumns(float scaleFactor) { // do nothing } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 159b89991c35..a725009df8d0 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -27,6 +27,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; @@ -40,6 +41,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.widget.AbsListView; import android.widget.Toast; @@ -57,6 +59,7 @@ import com.nextcloud.client.jobs.BackgroundJobManager; import com.nextcloud.client.network.ClientFactory; import com.nextcloud.client.preferences.AppPreferences; +import com.nextcloud.client.preferences.AppPreferencesImpl; import com.nextcloud.client.utils.Throttler; import com.nextcloud.common.NextcloudClient; import com.nextcloud.ui.fileactions.FileActionsBottomSheet; @@ -86,6 +89,8 @@ import com.owncloud.android.ui.activity.UploadFilesActivity; import com.owncloud.android.ui.adapter.CommonOCFileListAdapterInterface; import com.owncloud.android.ui.adapter.OCFileListAdapter; +import com.owncloud.android.ui.decoration.MediaGridItemDecoration; +import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration; import com.owncloud.android.ui.dialog.ChooseRichDocumentsTemplateDialogFragment; import com.owncloud.android.ui.dialog.ChooseTemplateDialogFragment; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; @@ -121,6 +126,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -226,8 +232,18 @@ public class OCFileListFragment extends ExtendedListFragment implements protected String mLimitToMimeType; private FloatingActionButton mFabMain; + private SimpleListItemDividerDecoration simpleListItemDividerDecoration; + private MediaGridItemDecoration mediaGridItemDecoration; + @Inject DeviceInfo deviceInfo; + private int maxColumnSizeLandscape = 5; + + //this variable will help us to provide number of span count for grid view + //the width for single item is approx to 360 + private static final int GRID_ITEM_DEFAULT_WIDTH = 360; + private static final int DEFAULT_FALLBACK_SPAN_COUNT = 1; + protected enum MenuItemAddRemove { DO_NOTHING, REMOVE_SORT, @@ -434,6 +450,10 @@ protected void setAdapter(Bundle args) { viewThemeUtils ); + simpleListItemDividerDecoration = new SimpleListItemDividerDecoration(getContext(), R.drawable.item_divider, true); + int spacing = getResources().getDimensionPixelSize(R.dimen.media_grid_spacing); + mediaGridItemDecoration = new MediaGridItemDecoration(spacing); + setRecyclerViewAdapter(mAdapter); fastScrollUtils.applyFastScroll(getRecyclerView()); @@ -544,7 +564,7 @@ public void uploadFiles() { getActivity(), ((FileActivity) getActivity()).getUser().orElseThrow(RuntimeException::new), FileDisplayActivity.REQUEST_CODE__SELECT_FILES_FROM_FILE_SYSTEM, - getCurrentFile().isEncrypted() + getCurrentFile().isEncrypted() ); } @@ -595,8 +615,10 @@ public void onOverflowIconClicked(OCFile file, View view) { public void openActionsMenu(final int filesCount, final Set checkedFiles, final boolean isOverflow) { throttler.run("overflowClick", () -> { + //need to hide the share menu because we have renamed another menu for sharing (NMC) + List additionalToHide = Collections.singletonList(R.id.action_send_share_file); final FragmentManager childFragmentManager = getChildFragmentManager(); - FileActionsBottomSheet.newInstance(filesCount, checkedFiles, isOverflow) + FileActionsBottomSheet.newInstance(filesCount, checkedFiles, isOverflow, additionalToHide) .setResultListener(childFragmentManager, this, (id) -> { onFileActionChosen(id, checkedFiles); }) @@ -1430,6 +1452,7 @@ public void switchToListView() { if (isGridEnabled()) { switchLayoutManager(false); } + addRemoveRecyclerViewItemDecorator(); } public void setGridAsPreferred() { @@ -1441,6 +1464,35 @@ public void switchToGridView() { if (!isGridEnabled()) { switchLayoutManager(true); } + addRemoveRecyclerViewItemDecorator(); + } + + private void addRemoveRecyclerViewItemDecorator() { + if (getRecyclerView().getLayoutManager() instanceof GridLayoutManager) { + removeListDividerDecorator(); + if (getRecyclerView().getItemDecorationCount() == 0) { + getRecyclerView().addItemDecoration(mediaGridItemDecoration); + int padding = getResources().getDimensionPixelSize(R.dimen.grid_recyclerview_padding); + getRecyclerView().setPadding(padding, padding, padding, padding); + } + } else { + if (getRecyclerView().getItemDecorationCount() > 0) { + getRecyclerView().removeItemDecoration(mediaGridItemDecoration); + } + if (getRecyclerView().getItemDecorationCount() == 0 && DisplayUtils.isShowDividerForList()) { + getRecyclerView().addItemDecoration(simpleListItemDividerDecoration); + getRecyclerView().setPadding(0, 0, 0, 0); + } + } + } + + /** + * method to remove the divider item decorator + */ + private void removeListDividerDecorator() { + if (getRecyclerView().getItemDecorationCount() > 0) { + getRecyclerView().removeItemDecoration(simpleListItemDividerDecoration); + } } public void switchLayoutManager(boolean grid) { @@ -1471,12 +1523,40 @@ public int getSpanSize(int position) { } getRecyclerView().setLayoutManager(layoutManager); + calculateAndUpdateSpanCount(grid); getRecyclerView().scrollToPosition(position); getAdapter().setGridView(grid); getRecyclerView().setAdapter(getAdapter()); getAdapter().notifyDataSetChanged(); } + /** + * method will calculate the number of spans required for grid item and will update the span accordingly + * + * @param isGrid + */ + private void calculateAndUpdateSpanCount(boolean isGrid) { + getRecyclerView().getViewTreeObserver().addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + getRecyclerView().getViewTreeObserver().removeOnGlobalLayoutListener(this); + if (isGrid) { + int viewWidth = getRecyclerView().getMeasuredWidth(); + int newSpanCount = viewWidth / GRID_ITEM_DEFAULT_WIDTH; + RecyclerView.LayoutManager layoutManager = getRecyclerView().getLayoutManager(); + if (layoutManager instanceof GridLayoutManager) { + if (newSpanCount < 1) { + newSpanCount = DEFAULT_FALLBACK_SPAN_COUNT; + } + ((GridLayoutManager) layoutManager).setSpanCount(newSpanCount); + layoutManager.requestLayout(); + } + } + } + }); + } + public CommonOCFileListAdapterInterface getCommonAdapter() { return mAdapter; } @@ -1962,4 +2042,52 @@ public void setFabEnabled(final boolean enabled) { public boolean isEmpty() { return mAdapter == null || mAdapter.isEmpty(); } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (getAdapter() != null) { + getAdapter().notifyDataSetChanged(); + } + updateSpanCount(newConfig); + } + + /** + * method will update the span count on basis of device orientation for the file listing + * + * @param newConfig current configuration + */ + private void updateSpanCount(Configuration newConfig) { + //this should only run when current view is not media gallery + if (getAdapter() != null) { + int maxColumnSize = (int) AppPreferencesImpl.DEFAULT_GRID_COLUMN; + if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { + //add the divider item decorator when orientation is landscape and device is not tablet + //because we don't have to add divider again as it is already added + if (!DisplayUtils.isTablet()) { + addRemoveRecyclerViewItemDecorator(); + } + maxColumnSize = maxColumnSizeLandscape; + } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { + //remove the divider item decorator when orientation is portrait and when device is not tablet + //because we have to show divider in both landscape and portrait mode + if (!DisplayUtils.isTablet()) { + removeListDividerDecorator(); + } + maxColumnSize = (int) AppPreferencesImpl.DEFAULT_GRID_COLUMN; + } + + if (isGridEnabled()) { + //for tablet calculate size on the basis of screen width + if (DisplayUtils.isTablet()) { + calculateAndUpdateSpanCount(true); + } else { + //and for phones directly show the hardcoded column size + if (getRecyclerView().getLayoutManager() instanceof GridLayoutManager) { + ((GridLayoutManager) getRecyclerView().getLayoutManager()).setSpanCount(maxColumnSize); + } + } + } + } + } } diff --git a/app/src/main/java/com/owncloud/android/ui/interfaces/OCFileListFragmentInterface.java b/app/src/main/java/com/owncloud/android/ui/interfaces/OCFileListFragmentInterface.java index 5b2fd546d57f..0925623ef05d 100644 --- a/app/src/main/java/com/owncloud/android/ui/interfaces/OCFileListFragmentInterface.java +++ b/app/src/main/java/com/owncloud/android/ui/interfaces/OCFileListFragmentInterface.java @@ -48,4 +48,6 @@ public interface OCFileListFragmentInterface { boolean isLoading(); void onHeaderClicked(); + + boolean isSearchFragment(); } diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java index 3ec44ab3cfd5..3f8db9eac68c 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java @@ -379,7 +379,9 @@ private void showFileActions(OCFile file) { R.id.action_move, R.id.action_copy, R.id.action_favorite, - R.id.action_unset_favorite + R.id.action_unset_favorite, + //hide this option for NMC + R.id.action_see_details )); if (getFile() != null && getFile().isSharedWithMe() && !getFile().canReshare()) { additionalFilter.add(R.id.action_send_share_file); diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java index f8b012551d3d..e7a6ced180f2 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java @@ -409,7 +409,9 @@ private void showFileActions(OCFile file) { R.id.action_move, R.id.action_copy, R.id.action_favorite, - R.id.action_unset_favorite + R.id.action_unset_favorite, + //hide this option for NMC + R.id.action_see_details )); if (getFile() != null && getFile().isSharedWithMe() && !getFile().canReshare()) { additionalFilter.add(R.id.action_send_share_file); diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFileFragment.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFileFragment.java index a26988735df6..9be04595175b 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFileFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewTextFileFragment.java @@ -304,7 +304,9 @@ private void showFileActions(OCFile file) { R.id.action_move, R.id.action_copy, R.id.action_favorite, - R.id.action_unset_favorite + R.id.action_unset_favorite, + //hide this option for NMC + R.id.action_see_details )); if (getFile() != null && getFile().isSharedWithMe() && !getFile().canReshare()) { additionalFilter.add(R.id.action_send_share_file); diff --git a/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java b/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java index 7a823e21fb7b..7f792b25a127 100644 --- a/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java @@ -24,6 +24,7 @@ package com.owncloud.android.ui.trashbin; import android.content.Intent; +import android.content.res.Configuration; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; @@ -45,6 +46,7 @@ import com.owncloud.android.ui.EmptyRecyclerView; import com.owncloud.android.ui.activity.DrawerActivity; import com.owncloud.android.ui.adapter.TrashbinListAdapter; +import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration; import com.owncloud.android.ui.dialog.SortingOrderDialogFragment; import com.owncloud.android.ui.interfaces.TrashbinActivityInterface; import com.owncloud.android.utils.DisplayUtils; @@ -55,6 +57,7 @@ import javax.inject.Inject; +import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.core.content.res.ResourcesCompat; import androidx.recyclerview.widget.LinearLayoutManager; @@ -84,6 +87,8 @@ public class TrashbinActivity extends DrawerActivity implements private boolean active; private TrashbinActivityBinding binding; + private SimpleListItemDividerDecoration simpleListItemDividerDecoration; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -150,6 +155,8 @@ private void setupContent() { recyclerView.setHasFixedSize(true); recyclerView.setHasFooter(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); + simpleListItemDividerDecoration = new SimpleListItemDividerDecoration(this, R.drawable.item_divider, true); + addListItemDecorator(); viewThemeUtils.androidx.themeSwipeRefreshLayout(binding.swipeContainingList); binding.swipeContainingList.setOnRefreshListener(this::loadFolder); @@ -166,6 +173,23 @@ private void setupContent() { loadFolder(); } + private void addListItemDecorator() { + if (DisplayUtils.isShowDividerForList()) { + //check and remove divider item decorator if exist then add item decorator + removeListDividerDecorator(); + binding.list.addItemDecoration(simpleListItemDividerDecoration); + } + } + + /** + * method to remove the divider item decorator + */ + private void removeListDividerDecorator() { + if (binding.list.getItemDecorationCount() > 0) { + binding.list.removeItemDecoration(simpleListItemDividerDecoration); + } + } + protected void loadFolder() { if (trashbinListAdapter.getItemCount() > EMPTY_LIST_COUNT) { binding.swipeContainingList.setRefreshing(true); @@ -331,4 +355,20 @@ public void showError(int message) { binding.emptyList.emptyListView.setVisibility(View.VISIBLE); } } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + //this should only run when device is not tablet because we are adding dividers in tablet for both the + // orientations + if (!DisplayUtils.isTablet()) { + if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { + //add the divider item decorator when orientation is landscape + addListItemDecorator(); + } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { + //remove the divider item decorator when orientation is portrait + removeListDividerDecorator(); + } + } + } } diff --git a/app/src/main/java/com/owncloud/android/utils/DisplayUtils.java b/app/src/main/java/com/owncloud/android/utils/DisplayUtils.java index bbf7bbe1ded3..b61c7fcec87a 100644 --- a/app/src/main/java/com/owncloud/android/utils/DisplayUtils.java +++ b/app/src/main/java/com/owncloud/android/utils/DisplayUtils.java @@ -32,6 +32,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Color; @@ -105,6 +106,7 @@ import java.util.Locale; import java.util.Map; import java.util.TimeZone; +import java.util.concurrent.RejectedExecutionException; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -847,9 +849,12 @@ public static void setThumbnail(OCFile file, LoaderImageView shimmerThumbnail, AppPreferences preferences, ViewThemeUtils viewThemeUtils, - SyncedFolderProvider syncedFolderProvider) { + SyncedFolderProvider syncedFolderProvider, + boolean isMediaGallery) { if (file.isFolder()) { stopShimmer(shimmerThumbnail, thumbnailView); + //reset the padding as this will change for files and we don't this for folders + thumbnailView.setPadding(0, 0, 0, 0); thumbnailView.setImageDrawable(MimeTypeUtil .getFolderTypeIcon(file.isSharedWithMe() || file.isSharedWithSharee(), file.isSharedViaLink(), @@ -860,102 +865,113 @@ public static void setThumbnail(OCFile file, context, viewThemeUtils)); } else { - if (file.getRemoteId() != null && file.isPreviewAvailable()) { - // Thumbnail in cache? - Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache( - ThumbnailsCacheManager.PREFIX_THUMBNAIL + file.getRemoteId() - ); - - if (thumbnail != null && !file.isUpdateThumbnailNeeded()) { - stopShimmer(shimmerThumbnail, thumbnailView); + try { + if (file.getRemoteId() != null && file.isPreviewAvailable()) { + // Thumbnail in cache? + Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache( + ThumbnailsCacheManager.PREFIX_THUMBNAIL + file.getRemoteId() + ); + + if (thumbnail != null && !file.isUpdateThumbnailNeeded()) { + setThumbnailViewPadding(thumbnailView, gridView, context, isMediaGallery, R.dimen.alternate_padding); + stopShimmer(shimmerThumbnail, thumbnailView); + + if (MimeTypeUtil.isVideo(file)) { + thumbnail = ThumbnailsCacheManager.addVideoOverlay(thumbnail, context); + } - if (MimeTypeUtil.isVideo(file)) { - Bitmap withOverlay = ThumbnailsCacheManager.addVideoOverlay(thumbnail, context); - thumbnailView.setImageBitmap(withOverlay); - } else { + //set the corner for both video and image thumbnail if (gridView) { BitmapUtils.setRoundedBitmapForGridMode(thumbnail, thumbnailView); } else { BitmapUtils.setRoundedBitmap(thumbnail, thumbnailView); } - } - } else { - // generate new thumbnail - if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailView)) { - for (ThumbnailsCacheManager.ThumbnailGenerationTask task : asyncTasks) { - if (file.getRemoteId() != null && task.getImageKey() != null && - file.getRemoteId().equals(task.getImageKey())) { - return; - } - } - try { - final ThumbnailsCacheManager.ThumbnailGenerationTask task = - new ThumbnailsCacheManager.ThumbnailGenerationTask(thumbnailView, - storageManager, - user, - asyncTasks, - gridView, - file.getRemoteId()); - if (thumbnail == null) { - Drawable drawable = MimeTypeUtil.getFileTypeIcon(file.getMimeType(), - file.getFileName(), - context, - viewThemeUtils); - if (drawable == null) { - drawable = ResourcesCompat.getDrawable(context.getResources(), - R.drawable.file_image, - null); - } - if (drawable == null) { - drawable = new ColorDrawable(Color.GRAY); + } else { + // generate new thumbnail + if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailView)) { + for (ThumbnailsCacheManager.ThumbnailGenerationTask task : asyncTasks) { + if (file.getRemoteId() != null && task.getImageKey() != null && + file.getRemoteId().equals(task.getImageKey())) { + return; } - - int px = ThumbnailsCacheManager.getThumbnailDimension(); - thumbnail = BitmapUtils.drawableToBitmap(drawable, px, px); } - final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable = - new ThumbnailsCacheManager.AsyncThumbnailDrawable(context.getResources(), - thumbnail, task); - - if (shimmerThumbnail != null && shimmerThumbnail.getVisibility() == View.GONE) { - if (gridView) { - configShimmerGridImageSize(shimmerThumbnail, preferences.getGridColumns()); + try { + final ThumbnailsCacheManager.ThumbnailGenerationTask task = + new ThumbnailsCacheManager.ThumbnailGenerationTask(thumbnailView, + storageManager, + user, + asyncTasks, + gridView, + file.getRemoteId()); + if (thumbnail == null) { + Drawable drawable = MimeTypeUtil.getFileTypeIcon(file.getMimeType(), + file.getFileName(), + context, + viewThemeUtils); + if (drawable == null) { + drawable = ResourcesCompat.getDrawable(context.getResources(), + R.drawable.file_image, + null); + } + if (drawable == null) { + drawable = new ColorDrawable(Color.GRAY); + } + + int px = ThumbnailsCacheManager.getThumbnailDimension(); + thumbnail = BitmapUtils.drawableToBitmap(drawable, px, px); + //set thumbnailView padding for no thumbnail + setThumbnailViewPadding(thumbnailView, gridView, context, isMediaGallery, R.dimen.standard_quarter_padding); } - startShimmer(shimmerThumbnail, thumbnailView); - } - - task.setListener(new ThumbnailsCacheManager.ThumbnailGenerationTask.Listener() { - @Override - public void onSuccess() { - stopShimmer(shimmerThumbnail, thumbnailView); + final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable = + new ThumbnailsCacheManager.AsyncThumbnailDrawable(context.getResources(), + thumbnail, task); + + if (shimmerThumbnail != null && shimmerThumbnail.getVisibility() == View.GONE) { + if (gridView) { + configShimmerGridImageSize(shimmerThumbnail, preferences.getGridColumns()); + } + startShimmer(shimmerThumbnail, thumbnailView); } - @Override - public void onError() { - stopShimmer(shimmerThumbnail, thumbnailView); - } - }); - - thumbnailView.setImageDrawable(asyncDrawable); - asyncTasks.add(task); - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, - new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, - file.getRemoteId())); - } catch (IllegalArgumentException e) { - Log_OC.d(TAG, "ThumbnailGenerationTask : " + e.getMessage()); + task.setListener(new ThumbnailsCacheManager.ThumbnailGenerationTask.Listener() { + @Override + public void onSuccess() { + stopShimmer(shimmerThumbnail, thumbnailView); + } + + @Override + public void onError() { + stopShimmer(shimmerThumbnail, thumbnailView); + } + }); + + thumbnailView.setImageDrawable(asyncDrawable); + asyncTasks.add(task); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, + new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, + file.getRemoteId())); + } catch (IllegalArgumentException e) { + Log_OC.d(TAG, "ThumbnailGenerationTask : " + e.getMessage()); + } catch (RejectedExecutionException | OutOfMemoryError e) { + // Executor queue is full, ignore + // OutOfMemory, ignore + } } } - } - if ("image/png".equalsIgnoreCase(file.getMimeType())) { - thumbnailView.setBackgroundColor(context.getResources().getColor(R.color.bg_default)); + if ("image/png".equalsIgnoreCase(file.getMimeType())) { + thumbnailView.setBackgroundColor(context.getResources().getColor(R.color.bg_default)); + } + } else { + stopShimmer(shimmerThumbnail, thumbnailView); + setThumbnailViewPadding(thumbnailView, gridView, context, isMediaGallery, R.dimen.standard_quarter_padding); + thumbnailView.setImageDrawable(MimeTypeUtil.getFileTypeIcon(file.getMimeType(), + file.getFileName(), + context, + viewThemeUtils)); } - } else { - stopShimmer(shimmerThumbnail, thumbnailView); - thumbnailView.setImageDrawable(MimeTypeUtil.getFileTypeIcon(file.getMimeType(), - file.getFileName(), - context, - viewThemeUtils)); + } catch (OutOfMemoryError ignored) { + // OutOfMemory, ignore will be thrown from BitmapUtils.drawableToBitmap(Drawable, int, int) } } } @@ -1004,4 +1020,40 @@ private static Point getScreenSize(Context context) throws Exception { throw new Exception("WindowManager not found"); } } + + /** + * method to set the padding to thumbnail view this is required for files so that there will be space between file + * and file name + * + * @param thumbnailView + * @param gridView + * @param context + * @param isMediaGallery + * @param dimensPadding + */ + private static void setThumbnailViewPadding(ImageView thumbnailView, boolean gridView, Context context, + boolean isMediaGallery, int dimensPadding) { + if (gridView && !isMediaGallery) { + int padding = context.getResources().getDimensionPixelSize(dimensPadding); + thumbnailView.setPadding(0, 0, 0, padding); + } + } + + /** + * check if list divider has to be shown when orientation is landscape or device is tablet + * + * @return + */ + public static boolean isShowDividerForList() { + return isTablet() || isLandscapeOrientation(); + } + + public static boolean isTablet() { + return MainApp.getAppContext().getResources().getBoolean(R.bool.isTablet); + } + + public static boolean isLandscapeOrientation() { + return MainApp.getAppContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; + } + } diff --git a/app/src/main/java/com/owncloud/android/utils/MimeTypeUtil.java b/app/src/main/java/com/owncloud/android/utils/MimeTypeUtil.java index f6790d5bc3ab..f9683002465d 100644 --- a/app/src/main/java/com/owncloud/android/utils/MimeTypeUtil.java +++ b/app/src/main/java/com/owncloud/android/utils/MimeTypeUtil.java @@ -167,9 +167,7 @@ public static Drawable getFolderTypeIcon(boolean isSharedViaUsers, drawableId = R.drawable.folder; } - Drawable drawable = ContextCompat.getDrawable(context, drawableId); - viewThemeUtils.platform.tintPrimaryDrawable(context, drawable); - return drawable; + return ContextCompat.getDrawable(context, drawableId); } public static Drawable getDefaultFolderIcon(Context context, diff --git a/app/src/main/res/drawable/cursor_drawable.xml b/app/src/main/res/drawable/cursor_drawable.xml new file mode 100644 index 000000000000..dd35b659e8ae --- /dev/null +++ b/app/src/main/res/drawable/cursor_drawable.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/item_divider.xml b/app/src/main/res/drawable/item_divider.xml new file mode 100644 index 000000000000..9f742e91d67c --- /dev/null +++ b/app/src/main/res/drawable/item_divider.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/file_thumbnail.xml b/app/src/main/res/layout/file_thumbnail.xml index aa09fac93306..4fde21a26d82 100644 --- a/app/src/main/res/layout/file_thumbnail.xml +++ b/app/src/main/res/layout/file_thumbnail.xml @@ -41,7 +41,7 @@ android:layout_width="@dimen/file_icon_size" android:layout_height="@dimen/file_icon_size" android:contentDescription="@null" - android:src="@drawable/folder" /> + tools:src="@drawable/folder" /> - - - - - + diff --git a/app/src/main/res/layout/grid_item.xml b/app/src/main/res/layout/grid_item.xml index 00055001cba5..76cc9c3e4f07 100644 --- a/app/src/main/res/layout/grid_item.xml +++ b/app/src/main/res/layout/grid_item.xml @@ -29,44 +29,43 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - + - - + app:layout_constraintBottom_toTopOf="@+id/Filename" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"> + + + + android:layout_gravity="center" + tools:src="@drawable/folder" /> - + android:contentDescription="@string/shared_icon_shared_via_link" + app:tint="@color/list_icon_color"/> - - - - + + + + + + + diff --git a/app/src/main/res/layout/list_item.xml b/app/src/main/res/layout/list_item.xml index 0ae8ab93d252..3b514f1e655e 100644 --- a/app/src/main/res/layout/list_item.xml +++ b/app/src/main/res/layout/list_item.xml @@ -53,10 +53,9 @@ + android:visibility="gone" + app:tint="@color/list_icon_color" /> + android:src="@drawable/ic_dots_vertical" + app:tint="@color/list_icon_color" /> diff --git a/app/src/main/res/layout/receive_external_files.xml b/app/src/main/res/layout/receive_external_files.xml index a8bcc106619d..e7069cf5d953 100644 --- a/app/src/main/res/layout/receive_external_files.xml +++ b/app/src/main/res/layout/receive_external_files.xml @@ -22,6 +22,7 @@ android:id="@+id/upload_files_layout" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/bg_default" android:orientation="vertical"> diff --git a/app/src/main/res/layout/synced_folders_settings_layout.xml b/app/src/main/res/layout/synced_folders_settings_layout.xml index 248b932d86a2..995845b0cd7c 100644 --- a/app/src/main/res/layout/synced_folders_settings_layout.xml +++ b/app/src/main/res/layout/synced_folders_settings_layout.xml @@ -22,6 +22,7 @@ android:id="@+id/root" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:background="@color/bg_default" android:gravity="center" android:orientation="vertical"> @@ -231,6 +232,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="marquee" + android:maxLines="2" android:text="@string/instant_upload_existing" android:textAppearance="?attr/textAppearanceListItem" /> diff --git a/app/src/main/res/layout/toolbar_standard.xml b/app/src/main/res/layout/toolbar_standard.xml index 6798d5e28165..b768840eb99b 100644 --- a/app/src/main/res/layout/toolbar_standard.xml +++ b/app/src/main/res/layout/toolbar_standard.xml @@ -54,12 +54,12 @@ android:text="@string/menu_item_sort_by_date_newest_first" android:textAlignment="textStart" android:textAllCaps="false" - android:textColor="@color/fontAppbar" + android:textColor="@color/sort_text_color" android:textSize="14sp" app:icon="@drawable/ic_keyboard_arrow_down" app:iconGravity="textEnd" - app:iconSize="16dp" - app:iconTint="@color/fontAppbar" + app:iconSize="12dp" + app:iconTint="@color/sort_text_color" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -73,7 +73,7 @@ android:contentDescription="@string/action_switch_grid_view" app:cornerRadius="24dp" app:icon="@drawable/ic_view_module" - app:iconTint="@color/fontAppbar" + app:iconTint="@color/icon_color" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -97,6 +97,7 @@ android:id="@+id/preview_image" android:layout_width="match_parent" android:layout_height="@dimen/nav_drawer_header_height" + android:background="@color/bg_default" android:contentDescription="@string/preview_image_description" android:scaleType="centerCrop" /> diff --git a/app/src/main/res/layout/trashbin_item.xml b/app/src/main/res/layout/trashbin_item.xml index 5d38155e6a7c..70ea73fa10c3 100644 --- a/app/src/main/res/layout/trashbin_item.xml +++ b/app/src/main/res/layout/trashbin_item.xml @@ -17,6 +17,7 @@ along with this program. If not, see . --> + android:src="@drawable/ic_history" + app:tint="@color/list_icon_color"/> + android:src="@drawable/ic_dots_vertical" + app:tint="@color/list_icon_color"/> diff --git a/app/src/main/res/layout/upload_files_layout.xml b/app/src/main/res/layout/upload_files_layout.xml index ee799542bc77..a33b9390b902 100644 --- a/app/src/main/res/layout/upload_files_layout.xml +++ b/app/src/main/res/layout/upload_files_layout.xml @@ -34,18 +34,10 @@ android:layout_height="0dp" android:layout_weight="1" /> - - - - - + android:layout_height="0.5dp" + android:background="@color/divider_color" /> E-Mail senden Speicherordner existiert nicht! Ursache könnte die Wiederherstellung einer Sicherungskopie auf einem anderen Gerät sein. Der Standard-Ordner wird jetzt wieder verwendet. Bitte überprüfen Sie die Einstellungen bezüglich des Speicherortes. + SD-Karte Inhalte von %1$d Datei konnten nicht synchronisiert werden (Konflikte: %2$d) Inhalte von %1$d Dateien konnten nicht synchronisiert werden (Konflikte: %2$d) diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 08bf64d552ad..aba4eda04079 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -20,23 +20,32 @@ --> + @color/grey_30 #E3E3E3 #000000 #ff6F6F6F #A5A5A5 + @color/grey_70 #222222 + #FFFFFF + @color/grey_30 + @color/grey_30 + #CCCCCC #ffffff #121212 #000000 + #2D2D2D #818181 #222222 #ffffff + @color/grey_80 + @color/grey_0 @color/appbar - #373535 + @color/grey_70 #222222 #DADADA @@ -46,6 +55,6 @@ @color/white - #1E1E1E + #121212 @android:color/white diff --git a/app/src/main/res/values-sw480dp/bool.xml b/app/src/main/res/values-sw480dp/bool.xml new file mode 100644 index 000000000000..8e66f10e898c --- /dev/null +++ b/app/src/main/res/values-sw480dp/bool.xml @@ -0,0 +1,4 @@ + + + true + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index f5d46ac6a728..afcbfa9dfd5e 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -2,13 +2,15 @@ @string/pref_behaviour_entries_keep_file - @string/pref_behaviour_entries_move + + @string/pref_behaviour_entries_delete_file LOCAL_BEHAVIOUR_FORGET - LOCAL_BEHAVIOUR_MOVE + + LOCAL_BEHAVIOUR_DELETE diff --git a/app/src/main/res/values/bool.xml b/app/src/main/res/values/bool.xml new file mode 100644 index 000000000000..c2dcd8baf0ea --- /dev/null +++ b/app/src/main/res/values/bool.xml @@ -0,0 +1,4 @@ + + + false + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f844b3156f33..08b5a5db930c 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -18,11 +18,11 @@ --> - @color/secondary_text_color + @color/grey_600 #000000 #ffffff #B3FFFFFF - #333333 + #191919 @color/secondary_text_color #ffffff #ff888888 @@ -31,13 +31,28 @@ #DDDDDD #EEEEEE #00000000 - #666666 + @color/grey_30 + @color/grey_30 #e53935 + #191919 + @color/primary + #191919 + #191919 + @color/grey_30 + @color/design_snackbar_background_color + @color/white #757575 #222222 #EEEEEE + #666666 + #101010 + #F2F2F2 + #B2B2B2 + #4C4C4C + #E5E5E5 + #333333 #BDBDBD #666666 @@ -51,6 +66,7 @@ #ffffff #ffffff #FFFFFF + #FFFFFF #000000 @color/color_accent #ffffff @@ -70,15 +86,16 @@ #40162233 - @color/fontAppbar - #ECECEC + @color/white + @color/grey_0 #757575 #616161 - #80000000 + #919191 @android:color/white - #666666 + #191919 #A5A5A5 + #B3FFFFFF diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 000000000000..7c23544141a7 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,34 @@ + + + 116dp + 4dp + 16dp + 24dp + 6dp + 14sp + 16sp + 18sp + 15sp + 15dp + 56dp + 86dp + 80dp + 11sp + 30dp + 55dp + 258dp + 17sp + 20dp + 160dp + 50dp + 150dp + 55dp + 48dp + 48dp + 24dp + 26dp + 20sp + 145dp + 1dp + 13sp + \ No newline at end of file diff --git a/app/src/main/res/values/dims.xml b/app/src/main/res/values/dims.xml index 7e0f67983a54..c0e5a7b7ebb7 100644 --- a/app/src/main/res/values/dims.xml +++ b/app/src/main/res/values/dims.xml @@ -25,9 +25,9 @@ 80dp 112dp 40dp - 128dp - 8dp - 3dp + 512dp + 32dp + 16dp 128dp 512 28dp @@ -73,7 +73,7 @@ 15dp 40dp 240dp - 16sp + 14sp 32dp 200dp 20dp @@ -113,14 +113,14 @@ 14dp 14dp 24dp - 16dp - 16dp + 24dp + 24dp 22sp 22sp 14dp 14dp - 12dp - 12dp + 24dp + 24dp 72dp 72dp 26sp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca3a8e205ea2..225d82b010a6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -991,6 +991,7 @@ Delete Link Settings Confirm + SD Card Strict mode: no HTTP connection allowed! Destination filename Suggest diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c95797f2b65a..a1a3daf63921 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -39,6 +39,12 @@ @color/bg_default @style/Widget.App.TextInputLayout @dimen/dialogBorderRadius + + @style/SnackBarBackgroundStyle + @style/SnackBarTextViewStyle + + @style/AutoCompleteCursorColorStyle + @style/AutoCompleteCursorColorStyle + + + + + +