diff --git a/CHANGELOG.md b/CHANGELOG.md index ec08cac15..9b43279c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ Changelog ========== +Version 4.2.0 *(2018-06-18)* +---------------------------- + + * Move some actions at the fullscreen view to the bottom of the screen + * Allow filtering out RAW images separately + * Add a warning if the user tries deleting a folder + * Properly reset the temporary Skip Delete Confirmation dialog + * Show a Pause button over video if not in fullscreen mode + * Fix some glitches around inserting pin/pattern/fingerprint + * Many other stability and ux improvements + Version 4.1.1 *(2018-05-26)* ---------------------------- diff --git a/app/build.gradle b/app/build.gradle index 77b4f15bb..01162895e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { applicationId "com.simplemobiletools.gallery" minSdkVersion 16 targetSdkVersion 27 - versionCode 179 - versionName "4.1.1" + versionCode 180 + versionName "4.2.0" multiDexEnabled true setProperty("archivesBaseName", "gallery") } @@ -47,12 +47,13 @@ ext { } dependencies { - implementation 'com.simplemobiletools:commons:4.1.4' + implementation 'com.simplemobiletools:commons:4.2.8' implementation 'com.theartofdev.edmodo:android-image-cropper:2.7.0' implementation 'com.android.support:multidex:1.0.3' implementation 'it.sephiroth.android.exif:library:1.0.1' implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.12' implementation 'com.github.chrisbanes:PhotoView:2.1.3' + implementation 'com.android.support.constraint:constraint-layout:1.1.2' kapt "android.arch.persistence.room:compiler:1.1.0" implementation "android.arch.persistence.room:runtime:1.1.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7f0b41b8a..601881fd6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,8 @@ android:name=".activities.SplashActivity" android:theme="@style/SplashTheme"> + + diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt index 09098adaf..cfb34cdad 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt @@ -37,6 +37,7 @@ import com.simplemobiletools.gallery.models.Directory import com.simplemobiletools.gallery.models.Medium import kotlinx.android.synthetic.main.activity_main.* import java.io.* +import java.util.* class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { private val PICK_MEDIA = 2 @@ -55,6 +56,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { private var mIsGettingDirs = false private var mLoadedInitialPhotos = false private var mIsPasswordProtectionPending = false + private var mWasProtectionHandled = false private var mLatestMediaId = 0L private var mLatestMediaDateId = 0L private var mLastMediaHandler = Handler() @@ -74,6 +76,8 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { setContentView(R.layout.activity_main) appLaunched(BuildConfig.APPLICATION_ID) + config.temporarilyShowHidden = false + config.tempSkipDeleteConfirmation = false mIsPickImageIntent = isPickImageIntent(intent) mIsPickVideoIntent = isPickVideoIntent(intent) mIsGetImageContentIntent = isGetImageContentIntent(intent) @@ -152,8 +156,9 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { directories_empty_text_label.setTextColor(config.textColor) directories_empty_text.setTextColor(getAdjustedPrimaryColor()) - if (mIsPasswordProtectionPending) { + if (mIsPasswordProtectionPending && !mWasProtectionHandled) { handleAppPasswordProtection { + mWasProtectionHandled = it if (it) { mIsPasswordProtectionPending = false tryLoadGallery() @@ -176,9 +181,10 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { override fun onStop() { super.onStop() - if (config.temporarilyShowHidden) { + if (config.temporarilyShowHidden || config.tempSkipDeleteConfirmation) { mTempShowHiddenHandler.postDelayed({ config.temporarilyShowHidden = false + config.tempSkipDeleteConfirmation = false }, SHOW_TEMP_HIDDEN_DURATION) } else { mTempShowHiddenHandler.removeCallbacksAndMessages(null) @@ -228,6 +234,16 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { return true } + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putBoolean(WAS_PROTECTION_HANDLED, mWasProtectionHandled) + } + + override fun onRestoreInstanceState(savedInstanceState: Bundle) { + super.onRestoreInstanceState(savedInstanceState) + mWasProtectionHandled = savedInstanceState.getBoolean(WAS_PROTECTION_HANDLED, false) + } + private fun getRecyclerAdapter() = directories_grid.adapter as? DirectoryAdapter private fun storeStateVariables() { @@ -593,42 +609,46 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { val mediumDao = galleryDB.MediumDao() val directoryDao = galleryDB.DirectoryDao() val getProperDateTaken = config.directorySorting and SORT_BY_DATE_TAKEN != 0 + val favoritePaths = getFavoritePaths() - for (directory in dirs) { - val curMedia = mediaFetcher.getFilesFrom(directory.path, getImagesOnly, getVideosOnly, getProperDateTaken) - val newDir = if (curMedia.isEmpty()) { - directory - } else { - createDirectoryFromMedia(directory.path, curMedia, albumCovers, hiddenString, includedFolders, isSortingAscending) - } + try { + for (directory in dirs) { + val curMedia = mediaFetcher.getFilesFrom(directory.path, getImagesOnly, getVideosOnly, getProperDateTaken, favoritePaths) + val newDir = if (curMedia.isEmpty()) { + directory + } else { + createDirectoryFromMedia(directory.path, curMedia, albumCovers, hiddenString, includedFolders, isSortingAscending) + } - // we are looping through the already displayed folders looking for changes, do not do anything if nothing changed - if (directory == newDir) { - continue - } + // we are looping through the already displayed folders looking for changes, do not do anything if nothing changed + if (directory == newDir) { + continue + } - directory.apply { - tmb = newDir.tmb - name = newDir.name - mediaCnt = newDir.mediaCnt - modified = newDir.modified - taken = newDir.taken - this@apply.size = newDir.size - types = newDir.types - } + directory.apply { + tmb = newDir.tmb + name = newDir.name + mediaCnt = newDir.mediaCnt + modified = newDir.modified + taken = newDir.taken + this@apply.size = newDir.size + types = newDir.types + } - showSortedDirs(dirs) + showSortedDirs(dirs) - // update directories and media files in the local db, delete invalid items - updateDBDirectory(directory) - mediumDao.insertAll(curMedia) - getCachedMedia(directory.path, getVideosOnly, getImagesOnly) { - it.forEach { - if (!curMedia.contains(it)) { - mediumDao.deleteMediumPath(it.path) + // update directories and media files in the local db, delete invalid items + updateDBDirectory(directory) + mediumDao.insertAll(curMedia) + getCachedMedia(directory.path, getVideosOnly, getImagesOnly) { + it.forEach { + if (!curMedia.contains(it)) { + mediumDao.deleteMediumPath(it.path) + } } } } + } catch (ignored: ConcurrentModificationException) { } val foldersToScan = mediaFetcher.getFoldersToScan() @@ -638,7 +658,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { // check the remaining folders which were not cached at all yet for (folder in foldersToScan) { - val newMedia = mediaFetcher.getFilesFrom(folder, getImagesOnly, getVideosOnly, getProperDateTaken) + val newMedia = mediaFetcher.getFilesFrom(folder, getImagesOnly, getVideosOnly, getProperDateTaken, favoritePaths) if (newMedia.isEmpty()) { continue } @@ -875,6 +895,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { add(Release(163, R.string.release_163)) add(Release(177, R.string.release_177)) add(Release(178, R.string.release_178)) + add(Release(180, R.string.release_180)) checkWhatsNew(this, BuildConfig.VERSION_CODE) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt index fa5ebcb5f..29c5d956b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt @@ -162,9 +162,10 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { super.onStop() mSearchMenuItem?.collapseActionView() - if (config.temporarilyShowHidden) { + if (config.temporarilyShowHidden || config.tempSkipDeleteConfirmation) { mTempShowHiddenHandler.postDelayed({ config.temporarilyShowHidden = false + config.tempSkipDeleteConfirmation = false }, SHOW_TEMP_HIDDEN_DURATION) } else { mTempShowHiddenHandler.removeCallbacksAndMessages(null) diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/PhotoVideoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/PhotoVideoActivity.kt index d230fa2f6..516b24a16 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/PhotoVideoActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/PhotoVideoActivity.kt @@ -1,6 +1,7 @@ package com.simplemobiletools.gallery.activities import android.content.Intent +import android.content.res.Configuration import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.net.Uri @@ -20,6 +21,7 @@ import com.simplemobiletools.gallery.fragments.VideoFragment import com.simplemobiletools.gallery.fragments.ViewPagerFragment import com.simplemobiletools.gallery.helpers.* import com.simplemobiletools.gallery.models.Medium +import kotlinx.android.synthetic.main.bottom_actions.* import kotlinx.android.synthetic.main.fragment_holder.* import java.io.File @@ -46,6 +48,8 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList finish() } } + + initBottomActions() } override fun onResume() { @@ -87,10 +91,11 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList val type = when { file.isImageFast() -> TYPE_IMAGES file.isVideoFast() -> TYPE_VIDEOS - else -> TYPE_GIFS + file.isGif() -> TYPE_GIFS + else -> TYPE_RAWS } - mMedium = Medium(null, getFilenameFromUri(mUri!!), mUri.toString(), mUri!!.path.getParentPath(), 0, 0, file.length(), type) + mMedium = Medium(null, getFilenameFromUri(mUri!!), mUri.toString(), mUri!!.path.getParentPath(), 0, 0, file.length(), type, false) supportActionBar?.title = mMedium!!.name bundle.putSerializable(MEDIUM, mMedium) @@ -98,7 +103,7 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList mFragment = if (mIsVideo) VideoFragment() else PhotoFragment() mFragment!!.listener = this mFragment!!.arguments = bundle - supportFragmentManager.beginTransaction().replace(R.id.fragment_holder, mFragment).commit() + supportFragmentManager.beginTransaction().replace(R.id.fragment_placeholder, mFragment).commit() } if (config.blackBackground) { @@ -111,6 +116,11 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList } } + override fun onConfigurationChanged(newConfig: Configuration?) { + super.onConfigurationChanged(newConfig) + initBottomActionsLayout() + } + private fun sendViewPagerIntent(path: String) { Intent(this, ViewPagerActivity::class.java).apply { putExtra(IS_VIEW_INTENT, true) @@ -125,15 +135,16 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList menu.apply { findItem(R.id.menu_set_as).isVisible = mMedium?.isImage() == true - findItem(R.id.menu_edit).isVisible = mMedium?.isImage() == true && mUri?.scheme == "file" + findItem(R.id.menu_edit).isVisible = mMedium?.isImage() == true && mUri?.scheme == "file" && !config.bottomActions findItem(R.id.menu_properties).isVisible = mUri?.scheme == "file" + findItem(R.id.menu_share).isVisible = !config.bottomActions } return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (mMedium == null) { + if (mMedium == null || mUri == null) { return true } @@ -152,6 +163,33 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList PropertiesDialog(this, mUri!!.path) } + private fun initBottomActions() { + initBottomActionsLayout() + initBottomActionButtons() + } + + private fun initBottomActionsLayout() { + bottom_actions.layoutParams.height = resources.getDimension(R.dimen.bottom_actions_height).toInt() + navigationBarHeight + if (config.bottomActions) { + bottom_actions.beVisible() + } else { + bottom_actions.beGone() + } + } + + private fun initBottomActionButtons() { + bottom_favorite.beGone() + bottom_delete.beGone() + + bottom_edit.setOnClickListener { + openEditor(mUri!!.toString()) + } + + bottom_share.setOnClickListener { + sharePath(mUri!!.toString()) + } + } + override fun fragmentClicked() { mIsFullScreen = !mIsFullScreen if (mIsFullScreen) { @@ -159,6 +197,10 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList } else { showSystemUI() } + + if (!bottom_actions.isGone()) { + bottom_actions.animate().alpha(if (mIsFullScreen) 0f else 1f).start() + } } override fun videoEnded() = false diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt index e50c30caf..197d2071a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt @@ -51,12 +51,12 @@ class SettingsActivity : SimpleActivity() { setupScrollHorizontally() setupScreenRotation() setupHideSystemUI() - setupReplaceShare() setupPasswordProtection() setupAppPasswordProtection() setupDeleteEmptyFolders() setupAllowPhotoGestures() setupAllowVideoGestures() + setupBottomActions() setupShowMediaCount() setupKeepLastModified() setupShowInfoBubble() @@ -219,14 +219,6 @@ class SettingsActivity : SimpleActivity() { } } - private fun setupReplaceShare() { - settings_replace_share.isChecked = config.replaceShare - settings_replace_share_holder.setOnClickListener { - settings_replace_share.toggle() - config.replaceShare = settings_replace_share.isChecked - } - } - private fun setupPasswordProtection() { settings_password_protection.isChecked = config.isPasswordProtectionOn settings_password_protection_holder.setOnClickListener { @@ -295,6 +287,14 @@ class SettingsActivity : SimpleActivity() { } } + private fun setupBottomActions() { + settings_bottom_actions.isChecked = config.bottomActions + settings_bottom_actions_holder.setOnClickListener { + settings_bottom_actions.toggle() + config.bottomActions = settings_bottom_actions.isChecked + } + } + private fun setupShowMediaCount() { settings_show_media_count.isChecked = config.showMediaCount settings_show_media_count_holder.setOnClickListener { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt index 31a23202a..dfd2b21d5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt @@ -45,6 +45,7 @@ import com.simplemobiletools.gallery.fragments.ViewPagerFragment import com.simplemobiletools.gallery.helpers.* import com.simplemobiletools.gallery.models.Medium import kotlinx.android.synthetic.main.activity_medium.* +import kotlinx.android.synthetic.main.bottom_actions.* import java.io.File import java.io.FileOutputStream import java.io.InputStream @@ -69,7 +70,9 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View private var mIsOrientationLocked = false private var mStoredReplaceZoomableImages = false + private var mStoredBottomActions = true private var mMediaFiles = ArrayList() + private var mFavoritePaths = ArrayList() companion object { var screenWidth = 0 @@ -80,7 +83,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_medium) - setTranslucentNavigation() mMediaFiles = MediaActivity.mMedia.clone() as ArrayList handlePermission(PERMISSION_WRITE_STORAGE) { @@ -93,8 +95,11 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View } storeStateVariables() + initBottomActions() + initFavorites() } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) override fun onResume() { super.onResume() if (!hasPermission(PERMISSION_WRITE_STORAGE)) { @@ -102,11 +107,23 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View return } + if (config.bottomActions) { + if (isLollipopPlus()) { + window.navigationBarColor = Color.TRANSPARENT + } + } else { + setTranslucentNavigation() + } + if (mStoredReplaceZoomableImages != config.replaceZoomableImages) { mPrevHashcode = 0 refreshViewPager() } + if (mStoredBottomActions != config.bottomActions) { + initBottomActions() + } + supportActionBar?.setBackgroundDrawable(resources.getDrawable(R.drawable.actionbar_gradient_background)) if (config.maxBrightness) { @@ -232,10 +249,24 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View view_pager.adapter?.let { (it as MyPagerAdapter).toggleFullscreen(mIsFullScreen) checkSystemUI() + if (!bottom_actions.isGone()) { + bottom_actions.animate().alpha(if (mIsFullScreen) 0f else 1f).start() + } } } } + private fun initBottomActions() { + initBottomActionsLayout() + initBottomActionButtons() + } + + private fun initFavorites() { + Thread { + mFavoritePaths = getFavoritePaths() + }.start() + } + private fun setupRotation() { if (mIsOrientationLocked) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { @@ -251,14 +282,18 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_viewpager, menu) val currentMedium = getCurrentMedium() ?: return true + currentMedium.isFavorite = mFavoritePaths.contains(currentMedium.path) menu.apply { - findItem(R.id.menu_share_1).isVisible = !config.replaceShare - findItem(R.id.menu_share_2).isVisible = config.replaceShare + findItem(R.id.menu_delete).isVisible = !config.bottomActions + findItem(R.id.menu_share).isVisible = !config.bottomActions + findItem(R.id.menu_edit).isVisible = !config.bottomActions findItem(R.id.menu_rotate).isVisible = currentMedium.isImage() findItem(R.id.menu_save_as).isVisible = mRotationDegrees != 0 findItem(R.id.menu_hide).isVisible = !currentMedium.name.startsWith('.') findItem(R.id.menu_unhide).isVisible = currentMedium.name.startsWith('.') + findItem(R.id.menu_add_to_favorites).isVisible = !currentMedium.isFavorite && !config.bottomActions + findItem(R.id.menu_remove_from_favorites).isVisible = currentMedium.isFavorite && !config.bottomActions findItem(R.id.menu_lock_orientation).isVisible = mRotationDegrees == 0 findItem(R.id.menu_lock_orientation).title = getString(if (mIsOrientationLocked) R.string.unlock_orientation else R.string.lock_orientation) findItem(R.id.menu_rotate).setShowAsAction( @@ -269,6 +304,9 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View }) } + if (config.bottomActions) { + updateFavoriteIcon(currentMedium) + } return true } @@ -284,8 +322,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View R.id.menu_open_with -> openPath(getCurrentPath(), true) R.id.menu_hide -> toggleFileVisibility(true) R.id.menu_unhide -> toggleFileVisibility(false) - R.id.menu_share_1 -> shareMedium(getCurrentMedium()!!) - R.id.menu_share_2 -> shareMedium(getCurrentMedium()!!) + R.id.menu_share -> shareMedium(getCurrentMedium()!!) R.id.menu_delete -> checkDeleteConfirmation() R.id.menu_rename -> renameFile() R.id.menu_edit -> openEditor(getCurrentPath()) @@ -293,6 +330,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View R.id.menu_show_on_map -> showOnMap() R.id.menu_rotate_right -> rotateImage(90) R.id.menu_rotate_left -> rotateImage(270) + R.id.menu_add_to_favorites -> toggleFavorite() + R.id.menu_remove_from_favorites -> toggleFavorite() R.id.menu_rotate_one_eighty -> rotateImage(180) R.id.menu_lock_orientation -> toggleLockOrientation() R.id.menu_save_as -> saveImageAs() @@ -305,6 +344,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View private fun storeStateVariables() { config.apply { mStoredReplaceZoomableImages = replaceZoomableImages + mStoredBottomActions = bottomActions } } @@ -711,6 +751,52 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View return (floatD + floatM / 60 + floatS / 3600).toFloat() } + private fun initBottomActionsLayout() { + bottom_actions.layoutParams.height = resources.getDimension(R.dimen.bottom_actions_height).toInt() + navigationBarHeight + if (config.bottomActions) { + bottom_actions.beVisible() + } else { + bottom_actions.beGone() + } + } + + private fun initBottomActionButtons() { + bottom_favorite.setOnClickListener { + toggleFavorite() + } + + bottom_edit.setOnClickListener { + openEditor(getCurrentPath()) + } + + bottom_share.setOnClickListener { + shareMedium(getCurrentMedium()!!) + } + + bottom_delete.setOnClickListener { + checkDeleteConfirmation() + } + } + + private fun updateFavoriteIcon(medium: Medium) { + val icon = if (medium.isFavorite) R.drawable.ic_star_on else R.drawable.ic_star_off + bottom_favorite.setImageResource(icon) + } + + private fun toggleFavorite() { + val medium = getCurrentMedium() ?: return + medium.isFavorite = !medium.isFavorite + Thread { + galleryDB.MediumDao().updateFavorite(medium.path, medium.isFavorite) + if (medium.isFavorite) { + mFavoritePaths.add(medium.path) + } else { + mFavoritePaths.remove(medium.path) + } + invalidateOptionsMenu() + }.start() + } + override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { if (requestCode == REQUEST_EDIT_IMAGE) { if (resultCode == Activity.RESULT_OK && resultData != null) { @@ -776,6 +862,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View override fun onConfigurationChanged(newConfig: Configuration?) { super.onConfigurationChanged(newConfig) measureScreen() + initBottomActionsLayout() } private fun measureScreen() { @@ -920,7 +1007,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View mPos = position updateActionbarTitle() mRotationDegrees = 0 - supportInvalidateOptionsMenu() + invalidateOptionsMenu() scheduleSwipe() } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt index 66c7e08fa..b44e0f7f4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt @@ -47,12 +47,12 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList() - (0 until itemViews.size()) - .filter { itemViews[it] != null } - .forEachIndexed { curIndex, i -> newItems.put(curIndex, itemViews[i]) } + val newViewHolders = SparseArray() + val cnt = viewHolders.size() + for (i in 0..cnt) { + if (affectedPositions.contains(i)) { + continue + } + val view = viewHolders.get(i, null) + val newIndex = i - selectedPositions.count { it <= i } + newViewHolders.put(newIndex, view) + } + viewHolders = newViewHolders currentDirectoriesHash = newDirs.hashCode() - itemViews = newItems dirs = newDirs + finishActMode() fastScroller?.measureRecyclerView() listener?.updateDirectories(newDirs) @@ -290,7 +296,7 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList TYPE_IMAGES directory.tmb.isVideoFast() -> TYPE_VIDEOS - else -> TYPE_GIFS + directory.tmb.isGif() -> TYPE_GIFS + else -> TYPE_RAWS } activity.loadImage(thumbnailType, directory.tmb, dir_thumbnail, scrollHorizontally, animateGifs, cropThumbnails) diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageFoldersAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageFoldersAdapter.kt index e27d56887..c65112f01 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageFoldersAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageFoldersAdapter.kt @@ -25,10 +25,10 @@ class ManageFoldersAdapter(activity: BaseSimpleActivity, var folders: ArrayList< override fun prepareActionMode(menu: Menu) {} - override fun prepareItemSelection(view: View) {} + override fun prepareItemSelection(viewHolder: ViewHolder) {} - override fun markItemSelection(select: Boolean, view: View?) { - view?.manage_folder_holder?.isSelected = select + override fun markViewHolderSelection(select: Boolean, viewHolder: ViewHolder?) { + viewHolder?.itemView?.manage_folder_holder?.isSelected = select } override fun actionItemPressed(id: Int) { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageHiddenFoldersAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageHiddenFoldersAdapter.kt index 931348420..31c35bb38 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageHiddenFoldersAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageHiddenFoldersAdapter.kt @@ -27,10 +27,10 @@ class ManageHiddenFoldersAdapter(activity: BaseSimpleActivity, var folders: Arra override fun prepareActionMode(menu: Menu) {} - override fun prepareItemSelection(view: View) {} + override fun prepareItemSelection(viewHolder: ViewHolder) {} - override fun markItemSelection(select: Boolean, view: View?) { - view?.manage_folder_holder?.isSelected = select + override fun markViewHolderSelection(select: Boolean, viewHolder: ViewHolder?) { + viewHolder?.itemView?.manage_folder_holder?.isSelected = select } override fun actionItemPressed(id: Int) { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt index d1ed183ec..2e2199529 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt @@ -49,12 +49,12 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList, override fun getActionMenuId() = R.menu.cab_media - override fun prepareItemSelection(view: View) { - view.medium_check?.background?.applyColorFilter(primaryColor) + override fun prepareItemSelection(viewHolder: ViewHolder) { + viewHolder.itemView?.medium_check?.background?.applyColorFilter(primaryColor) } - override fun markItemSelection(select: Boolean, view: View?) { - view?.medium_check?.beVisibleIf(select) + override fun markViewHolderSelection(select: Boolean, viewHolder: ViewHolder?) { + viewHolder?.itemView?.medium_check?.beVisibleIf(select) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetMediaAsynctask.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetMediaAsynctask.kt index 1f03be404..07b9bb630 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetMediaAsynctask.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetMediaAsynctask.kt @@ -3,8 +3,8 @@ package com.simplemobiletools.gallery.asynctasks import android.content.Context import android.os.AsyncTask import com.simplemobiletools.commons.helpers.SORT_BY_DATE_TAKEN -import com.simplemobiletools.commons.models.FileDirItem.Companion.sorting import com.simplemobiletools.gallery.extensions.config +import com.simplemobiletools.gallery.extensions.getFavoritePaths import com.simplemobiletools.gallery.helpers.MediaFetcher import com.simplemobiletools.gallery.models.Medium import java.util.* @@ -15,19 +15,20 @@ class GetMediaAsynctask(val context: Context, val mPath: String, val isPickImage private val mediaFetcher = MediaFetcher(context) override fun doInBackground(vararg params: Void): ArrayList { - val getProperDateTaken = sorting and SORT_BY_DATE_TAKEN != 0 + val getProperDateTaken = context.config.getFileSorting(mPath) and SORT_BY_DATE_TAKEN != 0 + val favoritePaths = context.getFavoritePaths() return if (showAll) { val foldersToScan = mediaFetcher.getFoldersToScan() val media = ArrayList() foldersToScan.forEach { - val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken) + val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken, favoritePaths) media.addAll(newMedia) } MediaFetcher(context).sortMedia(media, context.config.getFileSorting("")) media } else { - mediaFetcher.getFilesFrom(mPath, isPickImage, isPickVideo, getProperDateTaken) + mediaFetcher.getFilesFrom(mPath, isPickImage, isPickVideo, getProperDateTaken, favoritePaths) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/databases/GalleryDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/databases/GalleryDatabase.kt index b8bd5f47c..56896a30b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/databases/GalleryDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/databases/GalleryDatabase.kt @@ -9,7 +9,7 @@ import com.simplemobiletools.gallery.interfaces.MediumDao import com.simplemobiletools.gallery.models.Directory import com.simplemobiletools.gallery.models.Medium -@Database(entities = [(Directory::class), (Medium::class)], version = 2) +@Database(entities = [(Directory::class), (Medium::class)], version = 3) abstract class GalleryDatabase : RoomDatabase() { abstract fun DirectoryDao(): DirectoryDao diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/FilterMediaDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/FilterMediaDialog.kt index ec3cd7faa..4c1925b04 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/FilterMediaDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/FilterMediaDialog.kt @@ -7,6 +7,7 @@ import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.extensions.config import com.simplemobiletools.gallery.helpers.TYPE_GIFS import com.simplemobiletools.gallery.helpers.TYPE_IMAGES +import com.simplemobiletools.gallery.helpers.TYPE_RAWS import com.simplemobiletools.gallery.helpers.TYPE_VIDEOS import kotlinx.android.synthetic.main.dialog_filter_media.view.* @@ -19,10 +20,11 @@ class FilterMediaDialog(val activity: BaseSimpleActivity, val callback: (result: filter_media_images.isChecked = filterMedia and TYPE_IMAGES != 0 filter_media_videos.isChecked = filterMedia and TYPE_VIDEOS != 0 filter_media_gifs.isChecked = filterMedia and TYPE_GIFS != 0 + filter_media_raws.isChecked = filterMedia and TYPE_RAWS != 0 } AlertDialog.Builder(activity) - .setPositiveButton(R.string.ok, { dialog, which -> dialogConfirmed() }) + .setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() } .setNegativeButton(R.string.cancel, null) .create().apply { activity.setupDialogStuff(view, this, R.string.filter_media) @@ -37,6 +39,8 @@ class FilterMediaDialog(val activity: BaseSimpleActivity, val callback: (result: result += TYPE_VIDEOS if (view.filter_media_gifs.isChecked) result += TYPE_GIFS + if (view.filter_media_raws.isChecked) + result += TYPE_RAWS activity.config.filterMedia = result callback(result) diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/ArrayList.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/ArrayList.kt index afd1c36e5..5d221bffa 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/ArrayList.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/ArrayList.kt @@ -2,6 +2,7 @@ package com.simplemobiletools.gallery.extensions import com.simplemobiletools.gallery.helpers.TYPE_GIFS import com.simplemobiletools.gallery.helpers.TYPE_IMAGES +import com.simplemobiletools.gallery.helpers.TYPE_RAWS import com.simplemobiletools.gallery.helpers.TYPE_VIDEOS import com.simplemobiletools.gallery.models.Medium @@ -19,5 +20,9 @@ fun ArrayList.getDirMediaTypes(): Int { types += TYPE_GIFS } + if (any { it.isRaw() }) { + types += TYPE_RAWS + } + return types } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Context.kt index 9ed2214b5..1fb50627e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Context.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.content.res.Configuration import android.database.Cursor +import android.database.sqlite.SQLiteException import android.graphics.Point import android.media.AudioManager import android.os.Build @@ -203,7 +204,7 @@ fun Context.checkAppendingHidden(path: String, hidden: String, includedFolders: fun Context.loadImage(type: Int, path: String, target: MySquareImageView, horizontalScroll: Boolean, animateGifs: Boolean, cropThumbnails: Boolean) { target.isHorizontalScrolling = horizontalScroll - if (type == TYPE_IMAGES || type == TYPE_VIDEOS) { + if (type == TYPE_IMAGES || type == TYPE_VIDEOS || type == TYPE_RAWS) { if (type == TYPE_IMAGES && path.isPng()) { loadPng(path, target, cropThumbnails) } else { @@ -276,7 +277,11 @@ fun Context.loadJpg(path: String, target: MySquareImageView, cropThumbnails: Boo fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, callback: (ArrayList) -> Unit) { Thread { val directoryDao = galleryDB.DirectoryDao() - val directories = directoryDao.getAll() as ArrayList + val directories = try { + directoryDao.getAll() as ArrayList + } catch (e: SQLiteException) { + ArrayList() + } val shouldShowHidden = config.shouldShowHidden val excludedPaths = config.excludedFolders val includedPaths = config.includedFolders @@ -289,7 +294,8 @@ fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly: else -> filteredDirectories.filter { (filterMedia and TYPE_IMAGES != 0 && it.types and TYPE_IMAGES != 0) || (filterMedia and TYPE_VIDEOS != 0 && it.types and TYPE_VIDEOS != 0) || - (filterMedia and TYPE_GIFS != 0 && it.types and TYPE_GIFS != 0) + (filterMedia and TYPE_GIFS != 0 && it.types and TYPE_GIFS != 0) || + (filterMedia and TYPE_RAWS != 0 && it.types and TYPE_RAWS != 0) } }) as ArrayList @@ -316,8 +322,11 @@ fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImag var media = ArrayList() val shouldShowHidden = config.shouldShowHidden foldersToScan.forEach { - val currMedia = mediumDao.getMediaFromPath(it) - media.addAll(currMedia) + try { + val currMedia = mediumDao.getMediaFromPath(it) + media.addAll(currMedia) + } catch (ignored: IllegalStateException) { + } } if (!shouldShowHidden) { @@ -331,7 +340,8 @@ fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImag else -> media.filter { (filterMedia and TYPE_IMAGES != 0 && it.type == TYPE_IMAGES) || (filterMedia and TYPE_VIDEOS != 0 && it.type == TYPE_VIDEOS) || - (filterMedia and TYPE_GIFS != 0 && it.type == TYPE_GIFS) + (filterMedia and TYPE_GIFS != 0 && it.type == TYPE_GIFS) || + (filterMedia and TYPE_RAWS != 0 && it.type == TYPE_RAWS) } }) as ArrayList @@ -364,3 +374,5 @@ fun Context.updateDBDirectory(directory: Directory) { fun Context.getOTGFolderChildren(path: String) = getDocumentFile(path)?.listFiles() fun Context.getOTGFolderChildrenNames(path: String) = getOTGFolderChildren(path)?.map { it.name }?.toList() + +fun Context.getFavoritePaths() = galleryDB.MediumDao().getFavoritePaths() as ArrayList diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/String.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/String.kt index a8f4a9f57..ad9a4ec58 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/String.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/String.kt @@ -3,6 +3,7 @@ package com.simplemobiletools.gallery.extensions import com.bumptech.glide.signature.ObjectKey import com.simplemobiletools.commons.helpers.OTG_PATH import java.io.File +import java.io.IOException fun String.getFileSignature(): ObjectKey { val file = File(this) @@ -35,4 +36,10 @@ fun String.shouldFolderBeVisible(excludedPaths: MutableSet, includedPath } // recognize /sdcard/DCIM as the same folder as /storage/emulated/0/DCIM -fun String.getDistinctPath() = if (startsWith(OTG_PATH)) toLowerCase() else File(this).canonicalPath.toLowerCase() +fun String.getDistinctPath(): String { + return try { + if (startsWith(OTG_PATH)) toLowerCase() else File(this).canonicalPath.toLowerCase() + } catch (e: IOException) { + toLowerCase() + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt index 09a0a976c..d69f35829 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt @@ -116,7 +116,7 @@ class PhotoFragment : ViewPagerFragment() { isFullscreen = activity!!.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN loadImage() - checkExtendedDetails() + initExtendedDetails() wasInit = true return view @@ -130,7 +130,7 @@ class PhotoFragment : ViewPagerFragment() { override fun onResume() { super.onResume() if (wasInit && (context!!.config.showExtendedDetails != storedShowExtendedDetails || context!!.config.extendedDetails != storedExtendedDetails)) { - checkExtendedDetails() + initExtendedDetails() } val allowPhotoGestures = context!!.config.allowPhotoGestures @@ -287,7 +287,7 @@ class PhotoFragment : ViewPagerFragment() { } private fun addZoomableView() { - if (!context!!.config.replaceZoomableImages && medium.isImage() && isFragmentVisible && view.subsampling_view.isGone() && !medium.isDng()) { + if (!context!!.config.replaceZoomableImages && medium.isImage() && isFragmentVisible && view.subsampling_view.isGone()) { ViewPagerActivity.wasDecodedByGlide = false view.subsampling_view.apply { maxScale = 10f @@ -376,16 +376,19 @@ class PhotoFragment : ViewPagerFragment() { loadBitmap(degrees) } - private fun checkExtendedDetails() { + private fun initExtendedDetails() { if (context!!.config.showExtendedDetails) { view.photo_details.apply { + beInvisible() // make it invisible so we can measure it, but not show yet text = getMediumExtendedDetails(medium) - setTextColor(context.config.textColor) - beVisibleIf(text.isNotEmpty()) - alpha = if (!context!!.config.hideExtendedDetails || !isFullscreen) 1f else 0f onGlobalLayout { - if (height != 0 && isAdded) { - y = getExtendedDetailsY(height) + if (isAdded) { + val realY = getExtendedDetailsY(height) + if (realY > 0) { + y = realY + beVisibleIf(text.isNotEmpty()) + alpha = if (!context!!.config.hideExtendedDetails || !isFullscreen) 1f else 0f + } } } } @@ -405,7 +408,7 @@ class PhotoFragment : ViewPagerFragment() { override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) loadImage() - checkExtendedDetails() + initExtendedDetails() } private fun photoClicked() { @@ -415,7 +418,7 @@ class PhotoFragment : ViewPagerFragment() { override fun fullscreenToggled(isFullscreen: Boolean) { this.isFullscreen = isFullscreen view.photo_details.apply { - if (storedShowExtendedDetails) { + if (storedShowExtendedDetails && isVisible()) { animate().y(getExtendedDetailsY(height)) if (storedHideExtendedDetails) { @@ -428,6 +431,7 @@ class PhotoFragment : ViewPagerFragment() { private fun getExtendedDetailsY(height: Int): Float { val smallMargin = resources.getDimension(R.dimen.small_margin) val fullscreenOffset = context!!.navigationBarHeight.toFloat() - smallMargin - return context!!.usableScreenSize.y - height + if (isFullscreen) fullscreenOffset else -(if (context!!.navigationBarHeight == 0) smallMargin else 0f) + val actionsHeight = if (context!!.config.bottomActions && !isFullscreen) resources.getDimension(R.dimen.bottom_actions_height) else 0f + return context!!.usableScreenSize.y - height - actionsHeight + if (isFullscreen) fullscreenOffset else -smallMargin } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt index 4349441ec..af7024ff4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt @@ -53,6 +53,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee private var mStoredShowExtendedDetails = false private var mStoredHideExtendedDetails = false + private var mStoredBottomActions = true private var mStoredExtendedDetails = 0 private lateinit var brightnessSideScroll: MediaSideScroll @@ -76,6 +77,8 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee } mIsFullscreen = activity!!.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN + mView!!.video_play_outline.alpha = if (mIsFullscreen) 0f else 1f + setupPlayer() if (savedInstanceState != null) { mCurrTime = savedInstanceState.getInt(PROGRESS) @@ -118,6 +121,11 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee if (context!!.config.showExtendedDetails != mStoredShowExtendedDetails || context!!.config.extendedDetails != mStoredExtendedDetails) { checkExtendedDetails() } + + if (context!!.config.bottomActions != mStoredBottomActions) { + initTimeHolder() + } + storeStateVariables() } @@ -139,6 +147,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee mStoredShowExtendedDetails = showExtendedDetails mStoredHideExtendedDetails = hideExtendedDetails mStoredExtendedDetails = extendedDetails + mStoredBottomActions = bottomActions } } @@ -199,9 +208,14 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee right += context!!.navigationBarWidth bottom += context!!.navigationBarHeight } - mTimeHolder!!.setPadding(left, top, right, bottom) } + if (context!!.config.bottomActions) { + bottom += resources.getDimension(R.dimen.bottom_actions_height).toInt() + } + + mTimeHolder!!.setPadding(left, top, right, bottom) + mCurrTimeView = mView!!.video_curr_time mSeekBar = mView!!.video_seekbar mSeekBar!!.setOnSeekBarChangeListener(this) @@ -302,7 +316,8 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee } else { mPlayOnPrepare = true } - mView!!.video_play_outline.setImageDrawable(null) + + mView!!.video_play_outline.setImageDrawable(resources.getDrawable(R.drawable.img_pause_outline_big)) activity!!.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) } @@ -462,13 +477,16 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee private fun checkExtendedDetails() { if (context!!.config.showExtendedDetails) { mView!!.video_details.apply { + beInvisible() // make it invisible so we can measure it, but not show yet text = getMediumExtendedDetails(medium) - setTextColor(context.config.textColor) - beVisibleIf(text.isNotEmpty()) - alpha = if (!context!!.config.hideExtendedDetails || !mIsFullscreen) 1f else 0f onGlobalLayout { - if (height != 0 && isAdded) { - y = getExtendedDetailsY(height) + if (isAdded) { + val realY = getExtendedDetailsY(height) + if (realY > 0) { + y = realY + beVisibleIf(text.isNotEmpty()) + alpha = if (!context!!.config.hideExtendedDetails || !mIsFullscreen) 1f else 0f + } } } } @@ -522,7 +540,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee mIsFullscreen = isFullscreen checkFullscreen() mView!!.video_details.apply { - if (mStoredShowExtendedDetails) { + if (mStoredShowExtendedDetails && isVisible()) { animate().y(getExtendedDetailsY(height)) if (mStoredHideExtendedDetails) { @@ -530,12 +548,14 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee } } } + + mView!!.video_play_outline.animate().alpha(if (isFullscreen) 0f else 1f).start() } private fun getExtendedDetailsY(height: Int): Float { val smallMargin = resources.getDimension(R.dimen.small_margin) val timeHolderHeight = mTimeHolder!!.height - context!!.navigationBarHeight.toFloat() val fullscreenOffset = context!!.navigationBarHeight.toFloat() - smallMargin - return context!!.usableScreenSize.y - height + if (mIsFullscreen) fullscreenOffset else -(timeHolderHeight + if (context!!.navigationBarHeight == 0) smallMargin else 0f) + return context!!.usableScreenSize.y - height + if (mIsFullscreen) fullscreenOffset else -(timeHolderHeight + smallMargin) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Config.kt index f52fc5215..73d6db933 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Config.kt @@ -151,7 +151,7 @@ class Config(context: Context) : BaseConfig(context) { set(darkBackground) = prefs.edit().putBoolean(DARK_BACKGROUND, darkBackground).apply() var filterMedia: Int - get() = prefs.getInt(FILTER_MEDIA, TYPE_IMAGES or TYPE_VIDEOS or TYPE_GIFS) + get() = prefs.getInt(FILTER_MEDIA, TYPE_IMAGES or TYPE_VIDEOS or TYPE_GIFS or TYPE_RAWS) set(filterMedia) = prefs.edit().putInt(FILTER_MEDIA, filterMedia).apply() var dirColumnCnt: Int @@ -227,10 +227,6 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getBoolean(HIDE_SYSTEM_UI, false) set(hideSystemUI) = prefs.edit().putBoolean(HIDE_SYSTEM_UI, hideSystemUI).apply() - var replaceShare: Boolean - get() = prefs.getBoolean(REPLACE_SHARE_WITH_ROTATE, false) - set(replaceShare) = prefs.edit().putBoolean(REPLACE_SHARE_WITH_ROTATE, replaceShare).apply() - var deleteEmptyFolders: Boolean get() = prefs.getBoolean(DELETE_EMPTY_FOLDERS, false) set(deleteEmptyFolders) = prefs.edit().putBoolean(DELETE_EMPTY_FOLDERS, deleteEmptyFolders).apply() @@ -243,6 +239,10 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getBoolean(ALLOW_VIDEO_GESTURES, true) set(allowVideoGestures) = prefs.edit().putBoolean(ALLOW_VIDEO_GESTURES, allowVideoGestures).apply() + var bottomActions: Boolean + get() = prefs.getBoolean(BOTTOM_ACTIONS, true) + set(bottomActions) = prefs.edit().putBoolean(BOTTOM_ACTIONS, bottomActions).apply() + var showMediaCount: Boolean get() = prefs.getBoolean(SHOW_MEDIA_COUNT, true) set(showMediaCount) = prefs.edit().putBoolean(SHOW_MEDIA_COUNT, showMediaCount).apply() diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt index 9d73f8dfe..39fdd8a4b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt @@ -30,7 +30,6 @@ const val EXCLUDED_FOLDERS = "excluded_folders" const val INCLUDED_FOLDERS = "included_folders" const val ALBUM_COVERS = "album_covers" const val HIDE_SYSTEM_UI = "hide_system_ui" -const val REPLACE_SHARE_WITH_ROTATE = "replace_share_with_rotate" const val DELETE_EMPTY_FOLDERS = "delete_empty_folders" const val ALLOW_PHOTO_GESTURES = "allow_photo_gestures" const val ALLOW_VIDEO_GESTURES = "allow_video_gestures" @@ -49,6 +48,7 @@ const val WAS_NEW_APP_SHOWN = "was_new_app_shown_clock" const val LAST_FILEPICKER_PATH = "last_filepicker_path" const val WAS_OTG_HANDLED = "was_otg_handled" const val TEMP_SKIP_DELETE_CONFIRMATION = "temp_skip_delete_confirmation" +const val BOTTOM_ACTIONS = "bottom_actions" // slideshow const val SLIDESHOW_INTERVAL = "slideshow_interval" @@ -63,8 +63,9 @@ const val SLIDESHOW_DEFAULT_INTERVAL = 5 const val SLIDESHOW_SCROLL_DURATION = 500L const val NOMEDIA = ".nomedia" +const val FAVORITES = "favorites" const val MAX_COLUMN_COUNT = 20 -const val SHOW_TEMP_HIDDEN_DURATION = 600000L +const val SHOW_TEMP_HIDDEN_DURATION = 300000L const val CLICK_MAX_DURATION = 150 const val DRAG_THRESHOLD = 8 @@ -104,6 +105,7 @@ const val EXT_ALBUM = 1024 const val TYPE_IMAGES = 1 const val TYPE_VIDEOS = 2 const val TYPE_GIFS = 4 +const val TYPE_RAWS = 8 const val LOCAITON_INTERNAL = 1 const val LOCATION_SD = 2 diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt index bb577941c..9afb95ccf 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt @@ -16,7 +16,7 @@ import java.io.File class MediaFetcher(val context: Context) { var shouldStop = false - fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean, getProperDateTaken: Boolean): ArrayList { + fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean, getProperDateTaken: Boolean, favoritePaths: ArrayList): ArrayList { val filterMedia = context.config.filterMedia if (filterMedia == 0) { return ArrayList() @@ -24,10 +24,10 @@ class MediaFetcher(val context: Context) { val curMedia = ArrayList() if (curPath.startsWith(OTG_PATH)) { - val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia) + val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia, favoritePaths) curMedia.addAll(newMedia) } else { - val newMedia = getMediaInFolder(curPath, isPickImage, isPickVideo, filterMedia, getProperDateTaken) + val newMedia = getMediaInFolder(curPath, isPickImage, isPickVideo, filterMedia, getProperDateTaken, favoritePaths) curMedia.addAll(newMedia) } @@ -67,7 +67,13 @@ class MediaFetcher(val context: Context) { } if (filterMedia and TYPE_GIFS != 0) { - query.append("${MediaStore.Images.Media.DATA} LIKE ?") + query.append("${MediaStore.Images.Media.DATA} LIKE ? OR ") + } + + if (filterMedia and TYPE_RAWS != 0) { + rawExtensions.forEach { + query.append("${MediaStore.Images.Media.DATA} LIKE ? OR ") + } } var selectionQuery = query.toString().trim().removeSuffix("OR") @@ -93,10 +99,17 @@ class MediaFetcher(val context: Context) { args.add("%.gif") } + if (filterMedia and TYPE_RAWS != 0) { + rawExtensions.forEach { + args.add("%$it") + } + } + return args } private fun parseCursor(cursor: Cursor): ArrayList { + val foldersToIgnore = arrayListOf("/storage/emulated/legacy") val config = context.config val includedFolders = config.includedFolders var foldersToScan = ArrayList() @@ -106,7 +119,7 @@ class MediaFetcher(val context: Context) { do { val path = cursor.getStringValue(MediaStore.Images.Media.DATA).trim() val parentPath = File(path).parent?.trimEnd('/') ?: continue - if (!includedFolders.contains(parentPath)) { + if (!includedFolders.contains(parentPath) && !foldersToIgnore.contains(parentPath.toLowerCase())) { foldersToScan.add(parentPath) } } while (cursor.moveToNext()) @@ -143,7 +156,8 @@ class MediaFetcher(val context: Context) { } } - private fun getMediaInFolder(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int, getProperDateTaken: Boolean): ArrayList { + private fun getMediaInFolder(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int, getProperDateTaken: Boolean, + favoritePaths: ArrayList): ArrayList { val media = ArrayList() val files = File(folder).listFiles() ?: return media val doExtraCheck = context.config.doExtraCheck @@ -159,8 +173,9 @@ class MediaFetcher(val context: Context) { val isImage = filename.isImageFast() val isVideo = if (isImage) false else filename.isVideoFast() val isGif = if (isImage || isVideo) false else filename.isGif() + val isRaw = if (isImage || isVideo || isGif) false else filename.isRawFast() - if (!isImage && !isVideo && !isGif) + if (!isImage && !isVideo && !isGif && !isRaw) continue if (isVideo && (isPickImage || filterMedia and TYPE_VIDEOS == 0)) @@ -172,6 +187,9 @@ class MediaFetcher(val context: Context) { if (isGif && filterMedia and TYPE_GIFS == 0) continue + if (isRaw && filterMedia and TYPE_RAWS == 0) + continue + if (!showHidden && filename.startsWith('.')) continue @@ -189,16 +207,19 @@ class MediaFetcher(val context: Context) { val type = when { isImage -> TYPE_IMAGES isVideo -> TYPE_VIDEOS - else -> TYPE_GIFS + isGif -> TYPE_GIFS + else -> TYPE_RAWS } - val medium = Medium(null, filename, file.absolutePath, folder, lastModified, dateTaken, size, type) + val path = file.absolutePath + val isFavorite = favoritePaths.contains(path) + val medium = Medium(null, filename, path, folder, lastModified, dateTaken, size, type, isFavorite) media.add(medium) } return media } - private fun getMediaOnOTG(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int): ArrayList { + private fun getMediaOnOTG(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int, favoritePaths: ArrayList): ArrayList { val media = ArrayList() val files = context.getDocumentFile(folder)?.listFiles() ?: return media val doExtraCheck = context.config.doExtraCheck @@ -213,8 +234,9 @@ class MediaFetcher(val context: Context) { val isImage = filename.isImageFast() val isVideo = if (isImage) false else filename.isVideoFast() val isGif = if (isImage || isVideo) false else filename.isGif() + val isRaw = if (isImage || isVideo || isGif) false else filename.isRawFast() - if (!isImage && !isVideo && !isGif) + if (!isImage && !isVideo && !isGif || !isRaw) continue if (isVideo && (isPickImage || filterMedia and TYPE_VIDEOS == 0)) @@ -226,6 +248,9 @@ class MediaFetcher(val context: Context) { if (isGif && filterMedia and TYPE_GIFS == 0) continue + if (isRaw && filterMedia and TYPE_RAWS == 0) + continue + if (!showHidden && filename.startsWith('.')) continue @@ -239,11 +264,13 @@ class MediaFetcher(val context: Context) { val type = when { isImage -> TYPE_IMAGES isVideo -> TYPE_VIDEOS - else -> TYPE_GIFS + isGif -> TYPE_GIFS + else -> TYPE_RAWS } val path = Uri.decode(file.uri.toString().replaceFirst("${context.config.OTGTreeUri}/document/${context.config.OTGPartition}%3A", OTG_PATH)) - val medium = Medium(null, filename, path, folder, dateModified, dateTaken, size, type) + val isFavorite = favoritePaths.contains(path) + val medium = Medium(null, filename, path, folder, dateModified, dateTaken, size, type, isFavorite) media.add(medium) } @@ -262,7 +289,7 @@ class MediaFetcher(val context: Context) { val dateTakens = HashMap() val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) - cursor.use { + cursor?.use { if (cursor.moveToFirst()) { do { try { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/interfaces/MediumDao.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/interfaces/MediumDao.kt index 1c076f768..451f92e27 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/interfaces/MediumDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/interfaces/MediumDao.kt @@ -8,9 +8,12 @@ import com.simplemobiletools.gallery.models.Medium @Dao interface MediumDao { - @Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type FROM media WHERE parent_path = :path") + @Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type, is_favorite FROM media WHERE parent_path = :path") fun getMediaFromPath(path: String): List + @Query("SELECT full_path FROM media WHERE is_favorite = 1") + fun getFavoritePaths(): List + @Insert(onConflict = REPLACE) fun insert(medium: Medium) @@ -22,4 +25,7 @@ interface MediumDao { @Query("UPDATE OR REPLACE media SET filename = :newFilename, full_path = :newFullPath, parent_path = :newParentPath WHERE full_path = :oldPath") fun updateMedium(oldPath: String, newParentPath: String, newFilename: String, newFullPath: String) + + @Query("UPDATE media SET is_favorite = :isFavorite WHERE full_path = :path") + fun updateFavorite(path: String, isFavorite: Boolean) } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/models/Medium.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/models/Medium.kt index 9203db306..60e551038 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/models/Medium.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/models/Medium.kt @@ -6,13 +6,13 @@ import android.arch.persistence.room.Index import android.arch.persistence.room.PrimaryKey import com.simplemobiletools.commons.extensions.formatDate import com.simplemobiletools.commons.extensions.formatSize -import com.simplemobiletools.commons.extensions.isDng import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED import com.simplemobiletools.commons.helpers.SORT_BY_NAME import com.simplemobiletools.commons.helpers.SORT_BY_PATH import com.simplemobiletools.commons.helpers.SORT_BY_SIZE import com.simplemobiletools.gallery.helpers.TYPE_GIFS import com.simplemobiletools.gallery.helpers.TYPE_IMAGES +import com.simplemobiletools.gallery.helpers.TYPE_RAWS import com.simplemobiletools.gallery.helpers.TYPE_VIDEOS import java.io.Serializable @@ -25,7 +25,8 @@ data class Medium( @ColumnInfo(name = "last_modified") val modified: Long, @ColumnInfo(name = "date_taken") var taken: Long, @ColumnInfo(name = "size") val size: Long, - @ColumnInfo(name = "type") val type: Int) : Serializable { + @ColumnInfo(name = "type") val type: Int, + @ColumnInfo(name = "is_favorite") var isFavorite: Boolean) : Serializable { companion object { private const val serialVersionUID = -6553149366975455L @@ -37,7 +38,7 @@ data class Medium( fun isVideo() = type == TYPE_VIDEOS - fun isDng() = path.isDng() + fun isRaw() = type == TYPE_RAWS fun getBubbleText(sorting: Int) = when { sorting and SORT_BY_NAME != 0 -> name diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/receivers/RefreshMediaReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/receivers/RefreshMediaReceiver.kt index 8b3f9921e..7e6de9293 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/receivers/RefreshMediaReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/receivers/RefreshMediaReceiver.kt @@ -3,14 +3,12 @@ package com.simplemobiletools.gallery.receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import com.simplemobiletools.commons.extensions.getFilenameFromPath -import com.simplemobiletools.commons.extensions.getParentPath -import com.simplemobiletools.commons.extensions.isImageFast -import com.simplemobiletools.commons.extensions.isVideoFast +import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.REFRESH_PATH import com.simplemobiletools.gallery.extensions.galleryDB import com.simplemobiletools.gallery.helpers.TYPE_GIFS import com.simplemobiletools.gallery.helpers.TYPE_IMAGES +import com.simplemobiletools.gallery.helpers.TYPE_RAWS import com.simplemobiletools.gallery.helpers.TYPE_VIDEOS import com.simplemobiletools.gallery.models.Medium import java.io.File @@ -21,7 +19,7 @@ class RefreshMediaReceiver : BroadcastReceiver() { Thread { val medium = Medium(null, path.getFilenameFromPath(), path, path.getParentPath(), System.currentTimeMillis(), System.currentTimeMillis(), - File(path).length(), getFileType(path)) + File(path).length(), getFileType(path), false) context.galleryDB.MediumDao().insert(medium) }.start() } @@ -29,6 +27,7 @@ class RefreshMediaReceiver : BroadcastReceiver() { private fun getFileType(path: String) = when { path.isImageFast() -> TYPE_IMAGES path.isVideoFast() -> TYPE_VIDEOS - else -> TYPE_GIFS + path.isGif() -> TYPE_GIFS + else -> TYPE_RAWS } } diff --git a/app/src/main/res/drawable-hdpi/img_pause_outline_big.png b/app/src/main/res/drawable-hdpi/img_pause_outline_big.png new file mode 100644 index 000000000..eda00d096 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/img_pause_outline_big.png differ diff --git a/app/src/main/res/drawable-hdpi/img_play_outline_big.png b/app/src/main/res/drawable-hdpi/img_play_outline_big.png index 96933587c..67419faa2 100644 Binary files a/app/src/main/res/drawable-hdpi/img_play_outline_big.png and b/app/src/main/res/drawable-hdpi/img_play_outline_big.png differ diff --git a/app/src/main/res/drawable-xhdpi/img_pause_outline_big.png b/app/src/main/res/drawable-xhdpi/img_pause_outline_big.png new file mode 100644 index 000000000..0dccd18e2 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_pause_outline_big.png differ diff --git a/app/src/main/res/drawable-xhdpi/img_play_outline_big.png b/app/src/main/res/drawable-xhdpi/img_play_outline_big.png index 29599d2ba..e95083552 100644 Binary files a/app/src/main/res/drawable-xhdpi/img_play_outline_big.png and b/app/src/main/res/drawable-xhdpi/img_play_outline_big.png differ diff --git a/app/src/main/res/drawable-xxhdpi/img_pause_outline_big.png b/app/src/main/res/drawable-xxhdpi/img_pause_outline_big.png new file mode 100644 index 000000000..4aa3cd3cc Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/img_pause_outline_big.png differ diff --git a/app/src/main/res/drawable-xxhdpi/img_play_outline_big.png b/app/src/main/res/drawable-xxhdpi/img_play_outline_big.png index 3d1b5c2e2..8e32fbd54 100644 Binary files a/app/src/main/res/drawable-xxhdpi/img_play_outline_big.png and b/app/src/main/res/drawable-xxhdpi/img_play_outline_big.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/img_pause_outline_big.png b/app/src/main/res/drawable-xxxhdpi/img_pause_outline_big.png new file mode 100644 index 000000000..57fb987a1 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/img_pause_outline_big.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/img_play_outline_big.png b/app/src/main/res/drawable-xxxhdpi/img_play_outline_big.png index 66f27f62b..b8d6cff39 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/img_play_outline_big.png and b/app/src/main/res/drawable-xxxhdpi/img_play_outline_big.png differ diff --git a/app/src/main/res/drawable/gradient_background_lighter.xml b/app/src/main/res/drawable/gradient_background_lighter.xml new file mode 100644 index 000000000..ba3477dc5 --- /dev/null +++ b/app/src/main/res/drawable/gradient_background_lighter.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/layout/activity_medium.xml b/app/src/main/res/layout/activity_medium.xml index 1d8dc6c42..63559ebf0 100644 --- a/app/src/main/res/layout/activity_medium.xml +++ b/app/src/main/res/layout/activity_medium.xml @@ -10,4 +10,8 @@ android:layout_width="match_parent" android:layout_height="match_parent"/> + + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index a41f8df5c..94cc6ea57 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -557,29 +557,6 @@ - - - - - - + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_filter_media.xml b/app/src/main/res/layout/dialog_filter_media.xml index 37f2aba11..1554adec9 100644 --- a/app/src/main/res/layout/dialog_filter_media.xml +++ b/app/src/main/res/layout/dialog_filter_media.xml @@ -33,4 +33,12 @@ android:paddingTop="@dimen/activity_margin" android:text="@string/gifs"/> + + diff --git a/app/src/main/res/layout/fragment_holder.xml b/app/src/main/res/layout/fragment_holder.xml index 9a0863df0..d10a3a193 100644 --- a/app/src/main/res/layout/fragment_holder.xml +++ b/app/src/main/res/layout/fragment_holder.xml @@ -1,6 +1,17 @@ - + android:layout_height="match_parent"> + + + + + + diff --git a/app/src/main/res/layout/pager_photo_item.xml b/app/src/main/res/layout/pager_photo_item.xml index b8bff9183..deb877e71 100644 --- a/app/src/main/res/layout/pager_photo_item.xml +++ b/app/src/main/res/layout/pager_photo_item.xml @@ -18,7 +18,7 @@ android:layout_height="match_parent" android:visibility="gone"/> - diff --git a/app/src/main/res/layout/pager_video_item.xml b/app/src/main/res/layout/pager_video_item.xml index 1c19114cb..b7658ca01 100644 --- a/app/src/main/res/layout/pager_video_item.xml +++ b/app/src/main/res/layout/pager_video_item.xml @@ -43,7 +43,7 @@ android:layout_height="@dimen/play_outline_size_big" android:layout_centerInParent="true" android:background="@android:color/transparent" - android:padding="@dimen/activity_margin" + android:padding="@dimen/big_margin" android:src="@drawable/img_play_outline_big"/> - diff --git a/app/src/main/res/menu/menu_viewpager.xml b/app/src/main/res/menu/menu_viewpager.xml index 047c77d9f..c26c45eb8 100644 --- a/app/src/main/res/menu/menu_viewpager.xml +++ b/app/src/main/res/menu/menu_viewpager.xml @@ -13,7 +13,7 @@ android:title="@string/delete" app:showAsAction="ifRoom"/> @@ -35,10 +35,14 @@ + الصور الفديوهات الصور المتحركة + RAW images لم يتم العثور على ملفات وسائط مع الفلاتر المحددة تغيير الفلاتر @@ -151,6 +152,7 @@ استبدل الصور التي يمكن تكبيرها بعمق باستخدام صور ذات جودة أفضل إخفاء التفاصيل الموسعة عند إخفاء شريط الحالة قم بإجراء فحص إضافي لتجنب إظهار الملفات التالفة + Show some action buttons at the bottom of the screen المصغرات diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index f6db484e3..e89acd681 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -30,6 +30,7 @@ Imatges Vídeos GIFs + RAW images No s\'han tronat arxius amb els filtres seleccionats. Canviar filtres @@ -110,16 +111,16 @@ Canviar el tipus de vista Reixeta Llista - Group direct subfolders + Agrupar carpetes directes - Group by - Do not group files - Folder - Last modified - Date taken - File type - Extension + Agrupar per + No agrupar fitxers + Carpeta + Darrer modificat + Data de presa + Tipus de fitxer + Extensió Reproduir vídeos automàticament @@ -147,6 +148,7 @@ Substituïr imatges ampliades per les de millor quialitat Amaga els detalls estesos quan la barra d\'estat està amagada Fer una verificació addicional per evitar que es mostrin fitxers no vàlids + Show some action buttons at the bottom of the screen Miniatures diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 6b121b7ff..d75d1e2ce 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -30,6 +30,7 @@ Images Videos GIFs + RAW images No media files have been found with the selected filters. Change filters @@ -147,6 +148,7 @@ Replace deep zoomable images with better quality ones Hide extended details when status bar is hidden Do an extra check to avoid showing invalid files + Show some action buttons at the bottom of the screen Thumbnails diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 1d83821bb..df8088856 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -30,6 +30,7 @@ Billeder Videoer GIF\'er + RAW images Der blev ikke fundet nogen filer med det valgte filter. Skift filter @@ -147,6 +148,7 @@ Erstat stærkt zoombare billeder med nogle i bedre kvalitet Skjul udvidede oplysninger når statuslinjen er skjult Tjek en ekstra gang for at undgå visning af ugyldige filer + Show some action buttons at the bottom of the screen Thumbnails diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 7686ee191..c3bee513c 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5,7 +5,7 @@ Bearbeiten Kamera öffnen (versteckt) - (excluded) + (ausgenohmen) Ordner anheften Ordner loslösen Oben anheften @@ -30,6 +30,7 @@ Bilder Videos GIFs + RAW images Keine Medien für die ausgewählten Filter gefunden Filter ändern @@ -110,15 +111,15 @@ Darstellung ändern Gitter Liste - Group direct subfolders + Direkte Unterordner gruppieren - Group by - Do not group files - Folder - Last modified - Date taken - File type + Gruppieren bei + Dateien nicht gruppieren + Ordner + Zuletzt geändert + Erstelldatum + Dateitype Extension @@ -147,6 +148,7 @@ Stark zoombare Bilder durch Bilder mit hoher Qualität ersetzen Erweiterte Details nicht anzeigen, wenn die Systemleiste versteckt ist Zusätzliche Überprüfung, um ungültige Dateien nicht anzuzeigen + Show some action buttons at the bottom of the screen Thumbnails diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index f3349bef4..dc4f69114 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -30,6 +30,7 @@ Εικόνες Βίντεο GIFs + RAW images Δεν βρέθηκε κανένα αρχείο πολυμέσων με τα επιλεγμένα φίλτρα. Αλλαγή φίλτρων @@ -148,6 +149,7 @@ Αντικατάσταση των φωτογραφιών που απαιτούν ζούμ με άλλες καλύτερης ποιότητας Απόκρυψη λεπτομερειών όταν η μπάρα κατάστασης είναι κρυμμένη Επιπλέον έλεγχος για την αποφυγή εμφάνισης λανθασμένων αρχείων + Show some action buttons at the bottom of the screen Εικονίδια diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 8011439d0..db762f7b7 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -30,6 +30,7 @@ Imágenes Vídeos GIFs + RAW images No se han encontrado ficheros con los filtros seleccionados. Cambiar filtros @@ -110,16 +111,16 @@ Cambiar tipo de vista Cuadrícula Lista - Group direct subfolders + Agrupar subcarpetas directas - Group by - Do not group files - Folder - Last modified - Date taken - File type - Extension + Agrupar por + No agrupar ficheros + Carpeta + Último modificado + Data de toma + Tipo de fichero + Extensión Reproducir vídeos automáticamente @@ -147,6 +148,7 @@ Reemplace las imágenes con mucho zoom por otras de mejor calidad Ocultar detalles ampliados cuando la barra de estado está oculta Hacer una comprobación adicional para evitar mostrar archivos inválidos + Show some action buttons at the bottom of the screen Miniaturas @@ -160,7 +162,7 @@ He protegido la aplicación con una contraseña, pero la he olvidado. ¿Que puedo hacer? Puedes resolverlo de 2 maneras. Puede reinstalar la aplicación o encontrar la aplicación en la configuración de su dispositivo y seleccionar \"Borrar datos \". Restablecerá todas sus configuraciones, no eliminará ningún archivo multimedia. ¿Cómo puedo hacer que un álbum siempre aparezca en la parte superior? - Puede aguantar pulaso el álbum deseado y seleccionar el ícono Pin en el menú de acción, que lo fijará en la parte superior. También puede anclar varias carpetas, los artículos fijados se ordenarán por el método de clasificación predeterminado. + Puede aguantar pulsado el álbum deseado y seleccionar el ícono Pin en el menú de acción, que lo fijará en la parte superior. También puede anclar varias carpetas, los artículos fijados se ordenarán por el método de clasificación predeterminado. ¿Cómo puedo avanzar videos? Puede hacer clic en los textos de duración actual o máxima cerca de la barra de búsqueda, que moverán el video hacia atrás o hacia adelante. ¿Cuál es la diferencia entre ocultar y excluir una carpeta? diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 0fbd55c3c..cec932677 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -30,6 +30,7 @@ Kuvat Videot GIFit + RAW images Mediaa ei löytynyt valituilla suotimilla. Muuta suotimia @@ -147,6 +148,7 @@ Korvaa syvälle lähennettävät kuvat parempilaatuisella Piilota yksityiskohtaiset tiedot kun tilapalkki on piilotettu Tee ylimääräinen tarkistus rikkinäisten tiedostojen varalta + Show some action buttons at the bottom of the screen Esikatselukuvat diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6a7c63a9e..704f7ed5c 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -30,6 +30,7 @@ Images Vidéos GIF + RAW images Aucun fichier média trouvé avec les filtres sélectionnés. Changer les filtres @@ -147,6 +148,7 @@ Remplacer les images zoomables profondes par des images de meilleure qualité Masquer les détails supplémentaires lorsque la barre d\'état est masquée Faire une vérification supplémentaire pour éviter de montrer des fichiers invalides + Show some action buttons at the bottom of the screen Vignettes diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 78d103389..3e93aac93 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -5,7 +5,7 @@ Editar Abrir cámara (oculto) - (excluded) + (excluído) Fixar cartafol Soltar cartafol Fixar arriba @@ -30,6 +30,7 @@ Imaxes Vídeos GIFs + RAW images Non se atoparon medios dos indicados polo filtro. Cambiar filtro @@ -81,12 +82,12 @@ Editar con - Simple Fondo + Fondo de pantalla Establecer como fondo de pantalla Fallou establecer fondo de pantalla Establecer fondo de pantalla con: Establecendo fondo de pantalla… - Fondo de pantalla establecido con éxito + Fondo de pantalla establecido correctamente Proporción de Retrato Proporción de Paisaxe Pantalla de incio @@ -110,16 +111,16 @@ Cambiar o tipo de vista Grella Lista - Group direct subfolders + Agrupar subcartafoles directos - Group by - Do not group files - Folder - Last modified - Date taken - File type - Extension + Agrupar por + Non agrupar ficheiros + Cartafol + Último modificado + Data de captura + Tipo de ficheior + Extensión Reproducir vídeos automticamente @@ -147,6 +148,7 @@ Substituír imaxes con un gran zoom por por outras con mellor calidade Agochar detalles extendidos cando a barra de estado está oculta Facer unha comprobación extra para evitar mostrar ficheiros non válidos + Show some action buttons at the bottom of the screen Iconas @@ -185,7 +187,7 @@ A Galería tamén se ofrece como aplicación de terceiros para vista previa de imaxes / vídeos, engadir anexos en correos etc. É perfecta para o uso diario. - The fingerprint permission is needed for locking either hidden item visibility, or the whole app. + O permiso de pegada é preciso para bloquear a visibilidade de elementos ocultos ou o aplicativo completo. Non contén anuncios nin solicita permisos innecesarios. É de código aberto, con cores personalizadas. diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 8f9fba4bf..403bc5513 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -30,6 +30,7 @@ Slike Video GIF-ovi + RAW images Nije pronađena nijedna datoteka s odabranim filtrom. Promijeni filter @@ -147,6 +148,7 @@ Zamijenite slike s dubokim zumom za one s boljom kvalitetom Sakrij proširene pojedinosti kada je traka statusa skrivena Napravite dodatnu provjeru da biste izbjegli prikazivanje nevažećih datoteka + Show some action buttons at the bottom of the screen Sličice diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index dfccccaec..3711293f5 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -30,6 +30,7 @@ Images Videos GIFs + RAW images No media files have been found with the selected filters. Change filters @@ -147,6 +148,7 @@ Replace deep zoomable images with better quality ones Hide extended details when status bar is hidden Do an extra check to avoid showing invalid files + Show some action buttons at the bottom of the screen Thumbnails diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3c97e5a73..53c9dc299 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -30,6 +30,7 @@ Immagini Video GIF + RAW images Nessun file trovato per il filtro selezionato. Cambia filtro @@ -147,6 +148,7 @@ Sostituisci le immagini ingrandibili a fondo con altre di migliore qualità Nascondi i dettagli estesi quando la barra di stato è nascosta Fai un controllo ulteriore per evitare di mostrare file non validi + Show some action buttons at the bottom of the screen Miniature diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 8ed3387ef..c5ca12576 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -30,6 +30,7 @@ 画像 ビデオ GIF + RAW images 絞り込み条件に該当するメディアがありません。 絞り込み条件を変更 @@ -147,6 +148,7 @@ ズーム可能な画像をより高画質なものに置き換える ステータスバーが非表示の時は詳細を表示しない 無効なファイルを表示しないための調査を行います + Show some action buttons at the bottom of the screen サムネイル diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 214230c6a..bb6804892 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -30,6 +30,7 @@ 이미지 비디오 GIFs + RAW images 설정된 필터와 일치하는 컨텐츠가 존재하지 않습니다. 필터 변경 @@ -147,6 +148,7 @@ 확대 축소 가능한 이미지를 더 좋은 품질로 교체 상태 표시 줄이 숨겨져있을 때 확장 된 세부 정보 숨김 잘못된 파일 표시를 방지하기 위해 추가 검사 수행 + Show some action buttons at the bottom of the screen 섬네일 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 31bad5186..96011e86e 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -30,6 +30,7 @@ Atvaizdai Vaizdo įrašai GIF\'ai + RAW images Su pasirinktais filtrais nerasta medijos bylų. Pakeisti filtrus @@ -147,6 +148,7 @@ Pakeisti giliai priartinamus atvaizdus su geresnės kokybės atvaizdais Slėpti išsamią informaciją, kai būsenos juosta yra paslėpta Atlikti papildomą patikrinimą, kad nebūtų rodomos sugadintos bylos + Show some action buttons at the bottom of the screen Miniatiūros diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 9a71c89dc..5ea56bfbd 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -30,6 +30,7 @@ Bilder Videoer GIF-bilder + RAW images Ingen media-filer er funnet med de valgte filtrene. Endre filtere @@ -147,6 +148,7 @@ Erstatt dyp-zoombare bilder med bilder av bedre kvalitet Skjul utvidede detaljer når statuslinjen er skjult Gjør en ekstra sjekk for å unngå visning av ugyldige filer + Show some action buttons at the bottom of the screen Minibilder diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 5baae93d3..8e12577dd 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -30,6 +30,7 @@ Afbeeldingen Video\'s GIF-bestanden + RAW-afbeeldingen Er zijn geen bestanden gevonden met de huidige filters. Filters aanpassen @@ -147,6 +148,7 @@ In hoge kwaliteit weergeven (ten koste van ver inzoomen) Uitgebreide informatie niet tonen als de statusbalk is verborgen Ongeldige bestanden verbergen + Enkele actieknoppen onderaan het scherm tonen Miniatuurvoorbeelden diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 7e27a6fe9..e6232ee27 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5,7 +5,7 @@ Edytuj Uruchom aplikację aparatu (ukryty) - (excluded) + (wykluczony) Przypnij folder Wypakuj folder    Przypnij na górze @@ -30,6 +30,7 @@ Obrazy Filmy GIFy + Obrazy RAW Nie znalazłem multimediów z wybranymi filtrami. Zmień filtry @@ -110,16 +111,16 @@    Zmień typ widoku    Siatka    Lista - Group direct subfolders + Grupuj bezpośrednie podfoldery - Group by - Do not group files - Folder - Last modified - Date taken - File type - Extension + Grupuj według + Nie grupuj plików + Folderu + Daty ostatniej modyfikacji + Daty utworzenia + Typu + Rozszerzenia Odtwarzaj filmy automatycznie @@ -147,6 +148,7 @@    Zamieniaj powiększalne obrazy na te o lepszej jakości    Ukrywaj dodatkowe szczegóły gdy pasek stanu jest ukryty    Dodatkowe sprawdzenie w celu uniknięcia pokazywania niewłaściwych plików + Pokazuj niektóre przyciski akcji na dole ekranu    Miniatury @@ -165,15 +167,15 @@    Jaka jest różnica pomiędzy ukryciem, a wykluczeniem folderu?    Wykluczenie działa tylko w obrębie niniejszej aplikacji (wszędzie indziej pliki są normalnie widoczne), ukrywanie - w obrębie całego systemu (nie widać ich nigdzie), dodawany jest wtedy do folderu pusty plik \'.nomedia\', który możesz usunąć w dowolnym menedżerze plików.    Dlaczego pokazują mi się foldery z okładkami do piosenek i tym podobne rzeczy? -    Cóż, zdjęcie to zdjęcie. Aplikacja nie wie, czy to jest akurat okładka od piosenki, czy cokolwiek innego. Aby ukryć niechciane rzeczy, przytrzymaj je i wybierz opcję \'Wyklucz\' z paska akcji. + Aplikacja niestety nie wie, czy dane zdjęcie jest okładką od piosenki czy czymś innym. Aby ukryć niechciane rzeczy, przytrzymaj je i wybierz opcję \'Wyklucz\' z paska akcji.    Nie pokazuje(-ą) mi się folder(y) ze zdjęciami / filmami. Co mogę zrobić?    Wejdź do ustawień aplikacji i w sekcji z dołączonymi folderami dodaj tenże folder do listy.    Co jeśli chcę widzieć tylko.wybrane foldery?    Przejdź do sekcji z wykluczonymi folderami w ustawieniach aplikacji, dodaj tam folder główny (\"/\"), a następnie dodaj pożądane foldery w sekcji z dołączonymi folderami.    Zdjęcia w widoku pełnoekranowym mają dziwne artefakty. Jak mogę to naprawić?    U ustawieniach aplikacji włącz opcję \'Zamieniaj powiększalne obrazy na te o lepszej jakości\'. Poprawi ona jakość zdjęć, jednak przy bardzo dużych powiększeniach mogą się stać one zbyt rozmazane. - Can I crop images with this app? - Yes, you can crop images in the editor, by dragging the image corners. You can get to the editor either by long pressing an image thumbnail and selecting Edit, or selecting Edit from the fullscreen view. + Czy mogę w tej aplikacji przycinać obrazy? + Tak, możesz to zrobić w edytorze, przeciągając krawędzie obrazu. Edytor otworzysz przytrzymując miniaturę obrazu i wybierając opcję \'Edytuj\', bądź wybierając tą samą opcję w menu pełnoekranowym. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 418287be2..52c6f82c4 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -30,6 +30,7 @@ Imagens Vídeos GIFs + RAW images Nenhum arquivo de mídia encontrado a partir dos filtros selecionados. Mudar filtros @@ -147,6 +148,7 @@ Substituir imagens aptas a grande quantitade de zoom por imagens de melhor qualidade Ocultar detalhes extendidos quando a barra de status estiver oculta Realizar verificação extra para evitar mostrar arquivos inválidos + Show some action buttons at the bottom of the screen Miniaturas diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index e89ed8d41..67cf01651 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -30,6 +30,7 @@ Imagens Vídeos GIF + RAW images Não foram encontrados ficheiros que cumpram os requisitos. Alterar filtros @@ -147,6 +148,7 @@ Replace deep zoomable images with better quality ones Ocultar detalhes extra se a barra de estado estiver oculta Efetuar uma dupla verificação para evitar mostrar os ficheiros inválidos + Show some action buttons at the bottom of the screen Miniaturas diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 036af35c8..58c8f5e51 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -30,6 +30,7 @@ Изображения Видео GIF + RAW images При заданных фильтрах медиафайлы не найдены Изменить фильтры @@ -147,6 +148,7 @@ Заменять масштабируемые изображения высококачественными Не показывать подробности при скрытой строке состояния Делать дополнительную проверку, чтобы избежать показа неподдерживаемых файлов + Show some action buttons at the bottom of the screen Миниатюры diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index e20e1788e..9d8fb036f 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -30,6 +30,7 @@ Obrázky Videá GIFká + RAW obrázky So zvolenými filtrami sa nenašli žiadne média súbory. Zmeniť filtre @@ -147,6 +148,7 @@ Nahradiť hlboko priblížiteľné obrázky s obrázkami s lepšou kvalitou Skryť rozšírené vlastnosti ak je skrytá stavová lišta Predísť zobrazovaniu neplatných súborov dodatočnou kontrolou + Zobraziť niektoré akčné tlačidlá na spodku obrazovky Náhľady diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 067406436..989736b9d 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -30,6 +30,7 @@ Bilder Videor GIF-bilder + RAW images Inga mediefiler hittades med valda filter. Ändra filter @@ -81,12 +82,12 @@ Redigera med - Bakgrundsbild - Ange som bakgrundsbild - Det gick inte att byta bakgrundsbild - Ange som bakgrundsbild med: - Inställningar för bakgrundsbild… - Bakgrundsbilden är ändrad + Bakgrund + Använd som bakgrund + Det gick inte att ställa in bakgrunden + Ställ in som bakgrund med: + Ställer in bakgrunden… + Bakgrunden har ställts in Stående bildförhållande Liggande bildförhållande Startskärm @@ -110,16 +111,16 @@ Ändra vy Rutnät Lista - Group direct subfolders + Gruppera direkta undermappar - Group by - Do not group files - Folder - Last modified - Date taken - File type - Extension + Gruppera efter + Gruppera inte filer + Mapp + Senast ändrad + Fotodatum + Filtyp + Filnamnstillägg Spela upp videor automatiskt @@ -147,6 +148,7 @@ Ersätt djupt zoombara bilder med bilder av bättre kvalitet Dölj utökad information när statusfältet är dolt Gör en extra kontroll för att hindra ogiltiga filer från att visas + Show some action buttons at the bottom of the screen Miniatyrer diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml index 5ce6c1c68..051c76507 100644 --- a/app/src/main/res/values-sw600dp/dimens.xml +++ b/app/src/main/res/values-sw600dp/dimens.xml @@ -4,6 +4,6 @@ 120dp 30dp 38dp - 230dp + 200dp 60dp diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 62b88f9c5..63c4966fc 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -30,6 +30,7 @@ Images Videos GIFs + RAW images No media files have been found with the selected filters. Change filters @@ -147,6 +148,7 @@ Replace deep zoomable images with better quality ones Hide extended details when status bar is hidden Do an extra check to avoid showing invalid files + Show some action buttons at the bottom of the screen Thumbnails diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 7ad76f03c..655f35f8e 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -30,6 +30,7 @@ 图片 视频 GIFs + RAW images 所选的过滤器没有找到媒体文件。 更改过滤器 @@ -147,6 +148,7 @@ 用质量更好的图像替换可深度缩放的图像 当状态栏隐藏时隐藏扩展详情 额外检查以避免显示无效的文件 + Show some action buttons at the bottom of the screen 缩略图 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 4f8a69048..e9ddc409a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -30,6 +30,7 @@ 圖片 影片 GIF + RAW images 選擇的篩選條件未發現媒體檔案。 更改篩選條件 @@ -115,11 +116,11 @@ Group by Do not group files - Folder - Last modified - Date taken - File type - Extension + 資料夾 + 最後修改 + 拍照日期 + 檔案類型 + 副檔名 自動播放影片 @@ -147,6 +148,7 @@ 可深度縮放的圖片用品質更佳的來取代 狀態欄隱藏時,同時隱藏詳細資訊 進行額外檢查,避免顯示無效的檔案 + Show some action buttons at the bottom of the screen 縮圖 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 0a0cdcd24..dc4653591 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -5,9 +5,10 @@ 20dp 22dp 26dp - 150dp + 130dp 60dp 60dp 30dp 72dp + 54dp diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 585eaa0e8..b27383d5b 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -2,6 +2,7 @@ + Allow filtering out RAW images separately Added sorting by Date Taken Allow customizing the app launcher icon color Added toggles for disabling Pull-to-refresh and permanent Delete dialog confirmation skipping diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b2fd79fae..199e012db 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,6 +30,7 @@ Images Videos GIFs + RAW images No media files have been found with the selected filters. Change filters @@ -147,6 +148,7 @@ Replace deep zoomable images with better quality ones Hide extended details when status bar is hidden Do an extra check to avoid showing invalid files + Show some action buttons at the bottom of the screen Thumbnails diff --git a/build.gradle b/build.gradle index 0a7f22883..ce1386288 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.2.41' + ext.kotlin_version = '1.2.50' repositories { jcenter() @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'com.android.tools.build:gradle:3.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong