diff --git a/CHANGELOG.md b/CHANGELOG.md index 6024cdef7..375d504a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,27 @@ Changelog ========== +Version 3.4.1 *(2018-02-09)* +---------------------------- + + * Fix some glitches around swiping fullscreen media with instant media switch or gesture brightness change enabled + * Make changing image brightness with gestures disabled by default + * Allow skipping forward/backward videos by pressing max/current time + * Fix some cases of editing third party images + * Couple other stability improvements + +Version 3.4.0 *(2018-02-05)* +---------------------------- + + * Allow changing the brightness by vertical gestures on images (by trubitsyn) + * Properly fetch all media files from recognized folders + * Make thumbnail info on the main screen a bit easier to read + * Fix seeing blank thumbnail after deleting files in some cases + * Reset zoom level on orientation change at fullscreen media + * Add an optional extra check to avoid showing invalid files + * Add a toggle to prevent showing What's new on startup + * Many other stability and performance improvements + Version 3.3.1 *(2018-01-29)* ---------------------------- diff --git a/app/build.gradle b/app/build.gradle index 45a3d649c..b02036847 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.simplemobiletools.gallery" minSdkVersion 16 targetSdkVersion 27 - versionCode 159 - versionName "3.3.1" + versionCode 161 + versionName "3.4.1" multiDexEnabled true setProperty("archivesBaseName", "gallery") } @@ -21,6 +21,9 @@ android { } buildTypes { + debug { + applicationIdSuffix ".debug" + } release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' @@ -43,7 +46,7 @@ ext { } dependencies { - implementation 'com.simplemobiletools:commons:3.9.4' + implementation 'com.simplemobiletools:commons:3.11.1' implementation 'com.theartofdev.edmodo:android-image-cropper:2.6.0' implementation 'com.android.support:multidex:1.0.2' implementation 'com.google.code.gson:gson:2.8.2' @@ -52,7 +55,7 @@ dependencies { implementation 'com.github.chrisbanes:PhotoView:2.1.3' //implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.9.0' - implementation 'com.github.tibbi:subsampling-scale-image-view:v3.9.0-fork' + implementation 'com.github.tibbi:subsampling-scale-image-view:v3.9.0.1-fork' debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakCanaryVersion" releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$leakCanaryVersion" diff --git a/app/src/debug/res/values/strings.xml b/app/src/debug/res/values/strings.xml new file mode 100644 index 000000000..ebf8b9d2a --- /dev/null +++ b/app/src/debug/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Gallery_debug + \ No newline at end of file diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt index 8e3d4d6c4..c1408b2c9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt @@ -144,24 +144,28 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener override fun onCropImageComplete(view: CropImageView, result: CropImageView.CropResult) { if (result.error == null) { if (isCropIntent) { - var inputStream: InputStream? = null - var outputStream: OutputStream? = null - try { - val stream = ByteArrayOutputStream() - result.bitmap.compress(CompressFormat.JPEG, 100, stream) - inputStream = ByteArrayInputStream(stream.toByteArray()) - outputStream = contentResolver.openOutputStream(saveUri) - inputStream.copyTo(outputStream) - } finally { - inputStream?.close() - outputStream?.close() - } + if (saveUri.scheme == "file") { + saveBitmapToFile(result.bitmap, saveUri.path) + } else { + var inputStream: InputStream? = null + var outputStream: OutputStream? = null + try { + val stream = ByteArrayOutputStream() + result.bitmap.compress(CompressFormat.JPEG, 100, stream) + inputStream = ByteArrayInputStream(stream.toByteArray()) + outputStream = contentResolver.openOutputStream(saveUri) + inputStream.copyTo(outputStream) + } finally { + inputStream?.close() + outputStream?.close() + } - Intent().apply { - addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - setResult(RESULT_OK, this) + Intent().apply { + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + setResult(RESULT_OK, this) + } + finish() } - finish() } else if (saveUri.scheme == "file") { SaveAsDialog(this, saveUri.path, true) { saveBitmapToFile(result.bitmap, it) 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 6b722080a..3c59a8361 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt @@ -22,6 +22,7 @@ import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED import com.simplemobiletools.commons.helpers.SORT_BY_DATE_TAKEN import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.Release +import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.gallery.BuildConfig import com.simplemobiletools.gallery.R @@ -369,7 +370,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { } private fun setupGridLayoutManager() { - val layoutManager = directories_grid.layoutManager as GridLayoutManager + val layoutManager = directories_grid.layoutManager as MyGridLayoutManager if (config.scrollHorizontally) { layoutManager.orientation = GridLayoutManager.HORIZONTAL directories_refresh_layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT) @@ -383,7 +384,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { private fun initZoomListener() { if (config.viewTypeFolders == VIEW_TYPE_GRID) { - val layoutManager = directories_grid.layoutManager as GridLayoutManager + val layoutManager = directories_grid.layoutManager as MyGridLayoutManager mZoomListener = object : MyRecyclerView.MyZoomListener { override fun zoomIn() { if (layoutManager.spanCount > 1) { @@ -405,7 +406,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { } private fun setupListLayoutManager() { - val layoutManager = directories_grid.layoutManager as GridLayoutManager + val layoutManager = directories_grid.layoutManager as MyGridLayoutManager layoutManager.spanCount = 1 layoutManager.orientation = GridLayoutManager.VERTICAL directories_refresh_layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) @@ -424,7 +425,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { private fun increaseColumnCount() { directories_vertical_fastscroller.measureRecyclerViewOnRedraw() directories_horizontal_fastscroller.measureRecyclerViewOnRedraw() - config.dirColumnCnt = ++(directories_grid.layoutManager as GridLayoutManager).spanCount + config.dirColumnCnt = ++(directories_grid.layoutManager as MyGridLayoutManager).spanCount invalidateOptionsMenu() directories_grid.adapter?.notifyDataSetChanged() } @@ -432,7 +433,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { private fun reduceColumnCount() { directories_vertical_fastscroller.measureRecyclerViewOnRedraw() directories_horizontal_fastscroller.measureRecyclerViewOnRedraw() - config.dirColumnCnt = --(directories_grid.layoutManager as GridLayoutManager).spanCount + config.dirColumnCnt = --(directories_grid.layoutManager as MyGridLayoutManager).spanCount invalidateOptionsMenu() directories_grid.adapter?.notifyDataSetChanged() } 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 29b64841d..82d8990ad 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt @@ -9,6 +9,7 @@ import android.graphics.Bitmap import android.net.Uri import android.os.Bundle import android.os.Handler +import android.support.v4.view.MenuItemCompat import android.support.v7.widget.GridLayoutManager import android.support.v7.widget.SearchView import android.view.Menu @@ -26,6 +27,7 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE import com.simplemobiletools.commons.helpers.REQUEST_EDIT_IMAGE import com.simplemobiletools.commons.models.RadioItem +import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.adapters.MediaAdapter @@ -52,6 +54,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { private var mAllowPickingMultiple = false private var mShowAll = false private var mLoadedInitialPhotos = false + private var mIsSearchOpen = false private var mLatestMediaId = 0L private var mLastMediaHandler = Handler() private var mTempShowHiddenHandler = Handler() @@ -81,7 +84,14 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { } media_refresh_layout.setOnRefreshListener { getMedia() } - mPath = intent.getStringExtra(DIRECTORY) + try { + mPath = intent.getStringExtra(DIRECTORY) + } catch (e: Exception) { + showErrorToast(e) + finish() + return + } + storeStateVariables() if (mShowAll) supportActionBar?.setDisplayHomeAsUpEnabled(false) @@ -233,11 +243,25 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { override fun onQueryTextSubmit(query: String) = false override fun onQueryTextChange(newText: String): Boolean { - searchQueryChanged(newText) + if (mIsSearchOpen) { + searchQueryChanged(newText) + } return true } }) } + + MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, object : MenuItemCompat.OnActionExpandListener { + override fun onMenuItemActionExpand(item: MenuItem?): Boolean { + mIsSearchOpen = true + return true + } + + override fun onMenuItemActionCollapse(item: MenuItem?): Boolean { + mIsSearchOpen = false + return true + } + }) } private fun searchQueryChanged(text: String) { @@ -479,7 +503,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { } private fun setupGridLayoutManager() { - val layoutManager = media_grid.layoutManager as GridLayoutManager + val layoutManager = media_grid.layoutManager as MyGridLayoutManager if (config.scrollHorizontally) { layoutManager.orientation = GridLayoutManager.HORIZONTAL media_refresh_layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT) @@ -493,7 +517,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { private fun initZoomListener() { if (config.viewTypeFiles == VIEW_TYPE_GRID) { - val layoutManager = media_grid.layoutManager as GridLayoutManager + val layoutManager = media_grid.layoutManager as MyGridLayoutManager mZoomListener = object : MyRecyclerView.MyZoomListener { override fun zoomIn() { if (layoutManager.spanCount > 1) { @@ -515,7 +539,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { } private fun setupListLayoutManager() { - val layoutManager = media_grid.layoutManager as GridLayoutManager + val layoutManager = media_grid.layoutManager as MyGridLayoutManager layoutManager.spanCount = 1 layoutManager.orientation = GridLayoutManager.VERTICAL media_refresh_layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) @@ -525,7 +549,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { private fun increaseColumnCount() { media_vertical_fastscroller.measureRecyclerViewOnRedraw() media_horizontal_fastscroller.measureRecyclerViewOnRedraw() - config.mediaColumnCnt = ++(media_grid.layoutManager as GridLayoutManager).spanCount + config.mediaColumnCnt = ++(media_grid.layoutManager as MyGridLayoutManager).spanCount invalidateOptionsMenu() media_grid.adapter?.notifyDataSetChanged() } @@ -533,7 +557,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { private fun reduceColumnCount() { media_vertical_fastscroller.measureRecyclerViewOnRedraw() media_horizontal_fastscroller.measureRecyclerViewOnRedraw() - config.mediaColumnCnt = --(media_grid.layoutManager as GridLayoutManager).spanCount + config.mediaColumnCnt = --(media_grid.layoutManager as MyGridLayoutManager).spanCount invalidateOptionsMenu() media_grid.adapter?.notifyDataSetChanged() } @@ -633,6 +657,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { val subList = mMedia.subList(0, Math.min(SAVE_MEDIA_CNT, mMedia.size)) val json = Gson().toJson(subList) config.saveFolderMedia(mPath, json) + } catch (ignored: Exception) { } catch (ignored: OutOfMemoryError) { } }.start() 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 0e75cdddd..4d16a3980 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt @@ -33,10 +33,12 @@ class SettingsActivity : SimpleActivity() { setupCustomizeColors() setupUseEnglish() + setupAvoidWhatsNew() setupManageIncludedFolders() setupManageExcludedFolders() setupManageHiddenFolders() setupShowHiddenItems() + setupDoExtraCheck() setupAutoplayVideos() setupLoopVideos() setupAnimateGifs() @@ -50,6 +52,7 @@ class SettingsActivity : SimpleActivity() { setupPasswordProtection() setupAppPasswordProtection() setupDeleteEmptyFolders() + setupAllowPhotoGestures() setupAllowVideoGestures() setupShowMediaCount() setupKeepLastModified() @@ -88,6 +91,14 @@ class SettingsActivity : SimpleActivity() { } } + private fun setupAvoidWhatsNew() { + settings_avoid_whats_new.isChecked = config.avoidWhatsNew + settings_avoid_whats_new_holder.setOnClickListener { + settings_avoid_whats_new.toggle() + config.avoidWhatsNew = settings_avoid_whats_new.isChecked + } + } + private fun setupManageIncludedFolders() { settings_manage_included_folders_holder.setOnClickListener { startActivity(Intent(this, IncludedFoldersActivity::class.java)) @@ -126,6 +137,14 @@ class SettingsActivity : SimpleActivity() { config.showHiddenMedia = settings_show_hidden_items.isChecked } + private fun setupDoExtraCheck() { + settings_do_extra_check.isChecked = config.doExtraCheck + settings_do_extra_check_holder.setOnClickListener { + settings_do_extra_check.toggle() + config.doExtraCheck = settings_do_extra_check.isChecked + } + } + private fun setupAutoplayVideos() { settings_autoplay_videos.isChecked = config.autoplayVideos settings_autoplay_videos_holder.setOnClickListener { @@ -250,6 +269,14 @@ class SettingsActivity : SimpleActivity() { } } + private fun setupAllowPhotoGestures() { + settings_allow_photo_gestures.isChecked = config.allowPhotoGestures + settings_allow_photo_gestures_holder.setOnClickListener { + settings_allow_photo_gestures.toggle() + config.allowPhotoGestures = settings_allow_photo_gestures.isChecked + } + } + private fun setupAllowVideoGestures() { settings_allow_video_gestures.isChecked = config.allowVideoGestures settings_allow_video_gestures_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 f9a813d6d..80e41d7c5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt @@ -181,8 +181,10 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View } val file = File(mPath) - if (!file.exists()) { - deleteFromMediaStore(file) + if (!file.exists() && file.length() == 0L) { + Thread { + deleteFromMediaStore(file) + }.start() finish() return } @@ -211,7 +213,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View } refreshViewPager() - scanPath(mPath) if (config.blackBackground) { view_pager.background = ColorDrawable(Color.BLACK) @@ -642,7 +643,13 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View } private fun showOnMap() { - val exif = ExifInterface(getCurrentPath()) + val exif: ExifInterface + try { + exif = ExifInterface(getCurrentPath()) + } catch (e: Exception) { + showErrorToast(e) + return + } val lat = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) val lat_ref = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF) val lon = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE) 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 a334e344d..f6efe8972 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt @@ -349,7 +349,7 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: MutableList { - if (!context.hasPermission(PERMISSION_WRITE_STORAGE)) + if (!context.hasPermission(PERMISSION_WRITE_STORAGE)) { return ArrayList() + } val config = context.config val groupedMedia = mediaFetcher.getMediaByDirectories(isPickVideo, isPickImage) @@ -57,7 +55,7 @@ class GetDirectoriesAsynctask(val context: Context, val isPickVideo: Boolean, va val lastModified = if (config.directorySorting and SORT_DESCENDING > 0) Math.max(firstItem.modified, lastItem.modified) else Math.min(firstItem.modified, lastItem.modified) val dateTaken = if (config.directorySorting and SORT_DESCENDING > 0) Math.max(firstItem.taken, lastItem.taken) else Math.min(firstItem.taken, lastItem.taken) val size = curMedia.sumByLong { it.size } - val directory = Directory(parentDir, thumbnail, dirName, curMedia.size, lastModified, dateTaken, size) + val directory = Directory(parentDir, thumbnail, dirName, curMedia.size, lastModified, dateTaken, size, context.isPathOnSD(parentDir)) directories.add(directory) } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickDirectoryDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickDirectoryDialog.kt index cbaa30443..471237111 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickDirectoryDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickDirectoryDialog.kt @@ -8,6 +8,7 @@ import com.simplemobiletools.commons.extensions.beGoneIf import com.simplemobiletools.commons.extensions.beVisibleIf import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.adapters.DirectoryAdapter import com.simplemobiletools.gallery.asynctasks.GetDirectoriesAsynctask @@ -26,7 +27,7 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri var isGridViewType = activity.config.viewTypeFolders == VIEW_TYPE_GRID init { - (view.directories_grid.layoutManager as GridLayoutManager).apply { + (view.directories_grid.layoutManager as MyGridLayoutManager).apply { orientation = if (activity.config.scrollHorizontally && isGridViewType) GridLayoutManager.HORIZONTAL else GridLayoutManager.VERTICAL spanCount = if (isGridViewType) activity.config.dirColumnCnt else 1 } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt index b94fd0aed..fd5abf97b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt @@ -6,6 +6,7 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.beGoneIf import com.simplemobiletools.commons.extensions.beVisibleIf import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.adapters.MediaAdapter import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask @@ -22,7 +23,7 @@ class PickMediumDialog(val activity: BaseSimpleActivity, val path: String, val c var isGridViewType = activity.config.viewTypeFiles == VIEW_TYPE_GRID init { - (view.media_grid.layoutManager as GridLayoutManager).apply { + (view.media_grid.layoutManager as MyGridLayoutManager).apply { orientation = if (activity.config.scrollHorizontally && isGridViewType) GridLayoutManager.HORIZONTAL else GridLayoutManager.VERTICAL spanCount = if (isGridViewType) activity.config.mediaColumnCnt else 1 } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Activity.kt index 46a10186f..3103a84a9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Activity.kt @@ -185,7 +185,7 @@ fun BaseSimpleActivity.addTempFolderIfNeeded(dirs: ArrayList): ArrayL val directories = ArrayList() val tempFolderPath = config.tempFolderPath if (tempFolderPath.isNotEmpty()) { - val newFolder = Directory(tempFolderPath, "", tempFolderPath.getFilenameFromPath(), 0, 0, 0, 0L) + val newFolder = Directory(tempFolderPath, "", tempFolderPath.getFilenameFromPath(), 0, 0, 0, 0L, isPathOnSD(tempFolderPath)) directories.add(newFolder) } directories.addAll(dirs) 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 62c8f95c7..4d3ac9961 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/Context.kt @@ -23,6 +23,7 @@ val Context.windowManager: WindowManager get() = getSystemService(Context.WINDOW val Context.navigationBarRight: Boolean get() = usableScreenSize.x < realScreenSize.x val Context.navigationBarBottom: Boolean get() = usableScreenSize.y < realScreenSize.y val Context.navigationBarHeight: Int get() = if (navigationBarBottom) navigationBarSize.y else 0 +val Context.navigationBarWidth: Int get() = if (navigationBarRight) navigationBarSize.x else 0 internal val Context.navigationBarSize: Point get() = when { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/View.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/View.kt new file mode 100644 index 000000000..cf1459c54 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/View.kt @@ -0,0 +1,13 @@ +package com.simplemobiletools.gallery.extensions + +import android.os.SystemClock +import android.view.MotionEvent +import android.view.View + +fun View.sendFakeClick(x: Float, y: Float) { + val uptime = SystemClock.uptimeMillis() + val event = MotionEvent.obtain(uptime, uptime, MotionEvent.ACTION_DOWN, x, y, 0) + dispatchTouchEvent(event) + event.action = MotionEvent.ACTION_UP + dispatchTouchEvent(event) +} 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 1cb1d5e23..18a2d23a3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt @@ -58,6 +58,19 @@ class PhotoFragment : ViewPagerFragment() { gif_view.setOnClickListener { photoClicked() } instant_prev_item.setOnClickListener { listener?.goToPrevItem() } instant_next_item.setOnClickListener { listener?.goToNextItem() } + + instant_prev_item.parentView = container + instant_next_item.parentView = container + + photo_brightness_controller.initialize(activity!!, slide_info, true, container) { x, y -> + view.apply { + if (subsampling_view.isVisible()) { + subsampling_view.sendFakeClick(x, y) + } else { + gif_view.sendFakeClick(x, y) + } + } + } } storeStateVariables() @@ -116,9 +129,15 @@ class PhotoFragment : ViewPagerFragment() { checkExtendedDetails() } + val allowPhotoGestures = context!!.config.allowPhotoGestures val allowInstantChange = context!!.config.allowInstantChange - view.instant_prev_item.beVisibleIf(allowInstantChange) - view.instant_next_item.beVisibleIf(allowInstantChange) + + view.apply { + photo_brightness_controller.beVisibleIf(allowPhotoGestures) + instant_prev_item.beVisibleIf(allowInstantChange) + instant_next_item.beVisibleIf(allowInstantChange) + } + storeStateVariables() } 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 0ee831121..5cf2dc092 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt @@ -7,7 +7,6 @@ import android.net.Uri import android.os.Build import android.os.Bundle import android.os.Handler -import android.provider.Settings import android.support.annotation.RequiresApi import android.util.DisplayMetrics import android.view.* @@ -17,16 +16,14 @@ import android.widget.TextView import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.activities.VideoActivity -import com.simplemobiletools.gallery.activities.ViewPagerActivity import com.simplemobiletools.gallery.extensions.* import com.simplemobiletools.gallery.helpers.MEDIUM +import com.simplemobiletools.gallery.helpers.MediaSideScroll import com.simplemobiletools.gallery.models.Medium import kotlinx.android.synthetic.main.pager_video_item.view.* import java.io.IOException class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSeekBarChangeListener { - private val CLICK_MAX_DURATION = 150 - private val SLIDE_INFO_FADE_DELAY = 1000L private val PROGRESS = "progress" private var mMediaPlayer: MediaPlayer? = null @@ -50,21 +47,13 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee private var mDuration = 0 private var mEncodedPath = "" - private var mTouchDownX = 0f - private var mTouchDownY = 0f - private var mTouchDownTime = 0L - private var mTouchDownVolume = 0 - private var mTouchDownBrightness = -1 - private var mTempBrightness = 0 - private var mLastTouchY = 0f - - private var mSlideInfoText = "" - private var mSlideInfoFadeHandler = Handler() - private var mStoredShowExtendedDetails = false private var mStoredHideExtendedDetails = false private var mStoredExtendedDetails = 0 + private lateinit var brightnessSideScroll: MediaSideScroll + private lateinit var volumeSideScroll: MediaSideScroll + lateinit var medium: Medium override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -91,6 +80,21 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee checkFullscreen() wasInit = true + mView!!.apply { + brightnessSideScroll = video_brightness_controller + brightnessSideScroll.initialize(activity!!, slide_info, true, container) { x, y -> + video_holder.performClick() + } + + volumeSideScroll = video_volume_controller + volumeSideScroll.initialize(activity!!, slide_info, false, container) { x, y -> + video_holder.performClick() + } + + video_curr_time.setOnClickListener { skip(false) } + video_duration.setOnClickListener { skip(true) } + } + return mView } @@ -145,15 +149,6 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee mSurfaceHolder!!.addCallback(this) mSurfaceView!!.setOnClickListener { toggleFullscreen() } mView!!.video_holder.setOnClickListener { toggleFullscreen() } - mView!!.video_volume_controller.setOnTouchListener { v, event -> - handleVolumeTouched(event) - true - } - - mView!!.video_brightness_controller.setOnTouchListener { v, event -> - handleBrightnessTouched(event) - true - } initTimeHolder() checkExtendedDetails() @@ -186,142 +181,19 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee listener?.fragmentClicked() } - private fun handleVolumeTouched(event: MotionEvent) { - when (event.action) { - MotionEvent.ACTION_DOWN -> { - mTouchDownX = event.x - mTouchDownY = event.y - mLastTouchY = event.y - mTouchDownTime = System.currentTimeMillis() - mTouchDownVolume = getCurrentVolume() - mSlideInfoText = "${getString(R.string.volume)}:\n" - } - MotionEvent.ACTION_MOVE -> { - val diffX = mTouchDownX - event.x - val diffY = mTouchDownY - event.y - - if (Math.abs(diffY) > 20 && Math.abs(diffY) > Math.abs(diffX)) { - var percent = ((diffY / ViewPagerActivity.screenHeight) * 100).toInt() * 3 - percent = Math.min(100, Math.max(-100, percent)) - - if ((percent == 100 && event.y > mLastTouchY) || (percent == -100 && event.y < mLastTouchY)) { - mTouchDownY = event.y - mTouchDownVolume = getCurrentVolume() - } - - volumePercentChanged(percent) - } - mLastTouchY = event.y - } - MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { - val diffX = Math.abs(event.x - mTouchDownX) - val diffY = Math.abs(event.y - mTouchDownY) - if (System.currentTimeMillis() - mTouchDownTime < CLICK_MAX_DURATION && diffX < 20 && diffY < 20) { - mView!!.video_holder.performClick() - } - } - } - } - - private fun handleBrightnessTouched(event: MotionEvent) { - when (event.action) { - MotionEvent.ACTION_DOWN -> { - mTouchDownX = event.x - mTouchDownY = event.y - mLastTouchY = event.y - mTouchDownTime = System.currentTimeMillis() - mSlideInfoText = "${getString(R.string.brightness)}:\n" - if (mTouchDownBrightness == -1) - mTouchDownBrightness = getCurrentBrightness() - } - MotionEvent.ACTION_MOVE -> { - val diffX = mTouchDownX - event.x - val diffY = mTouchDownY - event.y - - if (Math.abs(diffY) > 20 && Math.abs(diffY) > Math.abs(diffX)) { - var percent = ((diffY / ViewPagerActivity.screenHeight) * 100).toInt() * 3 - percent = Math.min(100, Math.max(-100, percent)) - - if ((percent == 100 && event.y > mLastTouchY) || (percent == -100 && event.y < mLastTouchY)) { - mTouchDownY = event.y - mTouchDownBrightness = mTempBrightness - } - - brightnessPercentChanged(percent) - } - mLastTouchY = event.y - } - MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { - val diffX = Math.abs(event.x - mTouchDownX) - val diffY = Math.abs(event.y - mTouchDownY) - if (System.currentTimeMillis() - mTouchDownTime < CLICK_MAX_DURATION && diffX < 20 && diffY < 20) { - mView!!.video_holder.performClick() - } - mTouchDownBrightness = mTempBrightness - } - } - mView!!.video_holder - } - - private fun getCurrentVolume() = context!!.audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) - - private fun getCurrentBrightness() = Settings.System.getInt(activity!!.contentResolver, Settings.System.SCREEN_BRIGHTNESS) - - private fun volumePercentChanged(percent: Int) { - val stream = AudioManager.STREAM_MUSIC - val maxVolume = context!!.audioManager.getStreamMaxVolume(stream) - val percentPerPoint = 100 / maxVolume - val addPoints = percent / percentPerPoint - val newVolume = Math.min(maxVolume, Math.max(0, mTouchDownVolume + addPoints)) - context!!.audioManager.setStreamVolume(stream, newVolume, 0) - - val absolutePercent = ((newVolume / maxVolume.toFloat()) * 100).toInt() - mView!!.slide_info.apply { - text = "$mSlideInfoText$absolutePercent%" - alpha = 1f - } - - mSlideInfoFadeHandler.removeCallbacksAndMessages(null) - mSlideInfoFadeHandler.postDelayed({ - mView!!.slide_info.animate().alpha(0f) - }, SLIDE_INFO_FADE_DELAY) - } - - private fun brightnessPercentChanged(percent: Int) { - val maxBrightness = 255f - var newBrightness = (mTouchDownBrightness + 2.55 * percent).toFloat() - newBrightness = Math.min(maxBrightness, Math.max(0f, newBrightness)) - mTempBrightness = newBrightness.toInt() - - val absolutePercent = ((newBrightness / maxBrightness) * 100).toInt() - mView!!.slide_info.apply { - text = "$mSlideInfoText$absolutePercent%" - alpha = 1f - } - - val attributes = activity!!.window.attributes - attributes.screenBrightness = absolutePercent / 100f - activity!!.window.attributes = attributes - - mSlideInfoFadeHandler.removeCallbacksAndMessages(null) - mSlideInfoFadeHandler.postDelayed({ - mView!!.slide_info.animate().alpha(0f) - }, SLIDE_INFO_FADE_DELAY) - } - private fun initTimeHolder() { val res = resources val height = context!!.navigationBarHeight val left = mTimeHolder!!.paddingLeft val top = mTimeHolder!!.paddingTop - var right = res.getDimension(R.dimen.timer_padding).toInt() + var right = mTimeHolder!!.paddingRight var bottom = 0 if (hasNavBar()) { if (res.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { - bottom += height + bottom += context!!.navigationBarHeight } else { - right += height + right += context!!.navigationBarWidth bottom += context!!.navigationBarHeight } mTimeHolder!!.setPadding(left, top, right, bottom) @@ -331,8 +203,9 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee mSeekBar = mView!!.video_seekbar mSeekBar!!.setOnSeekBarChangeListener(this) - if (mIsFullscreen) + if (mIsFullscreen) { mTimeHolder!!.beInvisible() + } } private fun hasNavBar(): Boolean { @@ -386,8 +259,9 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee } private fun checkFullscreen() { - if (activity == null) + if (activity == null) { return + } var anim = android.R.anim.fade_in if (mIsFullscreen) { @@ -596,6 +470,16 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee } } + private fun skip(forward: Boolean) { + val curr = mMediaPlayer!!.currentPosition + val twoPercents = mMediaPlayer!!.duration / 50 + val newProgress = if (forward) curr + twoPercents else curr - twoPercents + setProgress(Math.round(newProgress / 1000f)) + if (!mIsPlaying) { + togglePlayPause() + } + } + override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { if (mMediaPlayer != null && fromUser) { setProgress(progress) 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 9f10cbaa1..333937de6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Config.kt @@ -253,6 +253,10 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getBoolean(DELETE_EMPTY_FOLDERS, false) set(deleteEmptyFolders) = prefs.edit().putBoolean(DELETE_EMPTY_FOLDERS, deleteEmptyFolders).apply() + var allowPhotoGestures: Boolean + get() = prefs.getBoolean(ALLOW_PHOTO_GESTURES, false) + set(allowPhotoGestures) = prefs.edit().putBoolean(ALLOW_PHOTO_GESTURES, allowPhotoGestures).apply() + var allowVideoGestures: Boolean get() = prefs.getBoolean(ALLOW_VIDEO_GESTURES, true) set(allowVideoGestures) = prefs.edit().putBoolean(ALLOW_VIDEO_GESTURES, allowVideoGestures).apply() @@ -316,4 +320,8 @@ class Config(context: Context) : BaseConfig(context) { var extendedDetails: Int get() = prefs.getInt(EXTENDED_DETAILS, EXT_RESOLUTION or EXT_LAST_MODIFIED or EXT_EXIF_PROPERTIES) set(extendedDetails) = prefs.edit().putInt(EXTENDED_DETAILS, extendedDetails).apply() + + var doExtraCheck: Boolean + get() = prefs.getBoolean(DO_EXTRA_CHECK, false) + set(doExtraCheck) = prefs.edit().putBoolean(DO_EXTRA_CHECK, doExtraCheck).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 33a95e350..b4ecd1a6d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt @@ -35,6 +35,7 @@ const val SCROLL_HORIZONTALLY = "scroll_horizontally" 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" const val SHOW_MEDIA_COUNT = "show_media_count" const val TEMP_FOLDER_PATH = "temp_folder_path" @@ -46,6 +47,7 @@ const val HIDE_EXTENDED_DETAILS = "hide_extended_details" const val ONE_FINGER_ZOOM = "one_finger_zoom" const val ALLOW_INSTANT_CHANGE = "allow_instant_change" const val REPLACE_ZOOMABLE_IMAGES = "replace_zoomable_images" +const val DO_EXTRA_CHECK = "do_extra_check" // slideshow const val SLIDESHOW_INTERVAL = "slideshow_interval" @@ -62,6 +64,8 @@ const val SLIDESHOW_SCROLL_DURATION = 500L const val NOMEDIA = ".nomedia" const val MAX_COLUMN_COUNT = 20 const val SHOW_TEMP_HIDDEN_DURATION = 600000L +const val CLICK_MAX_DURATION = 150 +const val DRAG_THRESHOLD = 8 const val DIRECTORY = "directory" const val MEDIUM = "medium" 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 f941b8f03..6df8fc016 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt @@ -40,9 +40,42 @@ class MediaFetcher(val context: Context) { directories.remove(it) } + searchNewFiles(directories, showHidden) return directories } + // search for undiscovered media files in the folders, from which we already have some media files + private fun searchNewFiles(directories: Map>, showHidden: Boolean) { + Thread { + // try not to delay the main media file loading + Thread.sleep(3000) + for ((path, dirMedia) in directories) { + if (path.contains("/.thumbnails/", true)) { + continue + } + + // get the file parent this way, "path" is lowercased + val folder = File(dirMedia.first().path).parentFile + val files = folder.listFiles() ?: continue + val fileCnt = files.filter { it.isFile }.size + val newPaths = ArrayList() + + if (dirMedia.size != fileCnt) { + val dirPaths = dirMedia.map { it.path } + files.forEach { + val filePath = it.absolutePath + if ((showHidden || !it.name.startsWith(".")) && !dirPaths.contains(filePath)) { + if (it.exists() && it.length() > 0 && it.isImageVideoGif()) { + newPaths.add(it.absolutePath) + } + } + } + } + context.scanPaths(newPaths) + } + }.start() + } + fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean): ArrayList { val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.DISPLAY_NAME, @@ -99,6 +132,7 @@ class MediaFetcher(val context: Context) { val filterMedia = config.filterMedia val showHidden = config.shouldShowHidden val isThirdPartyIntent = config.isThirdPartyIntent + val doExtraCheck = config.doExtraCheck cur.use { if (cur.moveToFirst()) { @@ -137,7 +171,7 @@ class MediaFetcher(val context: Context) { size = file.length() } - if (size <= 0L) + if (size <= 0L || (doExtraCheck && !file.exists())) continue val dateTaken = cur.getLongValue(MediaStore.Images.Media.DATE_TAKEN) diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaSideScroll.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaSideScroll.kt new file mode 100644 index 000000000..91c5f0a3c --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaSideScroll.kt @@ -0,0 +1,175 @@ +package com.simplemobiletools.gallery.helpers + +import android.app.Activity +import android.content.Context +import android.media.AudioManager +import android.os.Handler +import android.provider.Settings +import android.util.AttributeSet +import android.view.MotionEvent +import android.view.ViewGroup +import android.widget.RelativeLayout +import android.widget.TextView +import com.simplemobiletools.gallery.R +import com.simplemobiletools.gallery.activities.ViewPagerActivity +import com.simplemobiletools.gallery.extensions.audioManager + +// allow horizontal swipes through the layout, else it can cause glitches at zoomed in images +class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs) { + private val SLIDE_INFO_FADE_DELAY = 1000L + private var mTouchDownX = 0f + private var mTouchDownY = 0f + private var mTouchDownTime = 0L + private var mTouchDownValue = -1 + private var mTempBrightness = 0 + private var mLastTouchY = 0f + private var mIsBrightnessScroll = false + private var mPassTouches = false + private var dragThreshold = DRAG_THRESHOLD * context.resources.displayMetrics.density + + private var mSlideInfoText = "" + private var mSlideInfoFadeHandler = Handler() + private var mParentView: ViewGroup? = null + + private lateinit var activity: Activity + private lateinit var slideInfoView: TextView + private lateinit var callback: (Float, Float) -> Unit + + fun initialize(activity: Activity, slideInfoView: TextView, isBrightness: Boolean, parentView: ViewGroup?, callback: (x: Float, y: Float) -> Unit) { + this.activity = activity + this.slideInfoView = slideInfoView + this.callback = callback + mParentView = parentView + mIsBrightnessScroll = isBrightness + mSlideInfoText = activity.getString(if (isBrightness) R.string.brightness else R.string.volume) + } + + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + if (mPassTouches) { + if (ev.actionMasked == MotionEvent.ACTION_DOWN) { + mPassTouches = false + } + return false + } + return super.dispatchTouchEvent(ev) + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + if (mPassTouches) { + return false + } + + when (event.actionMasked) { + MotionEvent.ACTION_DOWN -> { + mTouchDownX = event.x + mTouchDownY = event.y + mLastTouchY = event.y + mTouchDownTime = System.currentTimeMillis() + if (mIsBrightnessScroll) { + if (mTouchDownValue == -1) { + mTouchDownValue = getCurrentBrightness() + } + } else { + mTouchDownValue = getCurrentVolume() + } + } + MotionEvent.ACTION_MOVE -> { + val diffX = mTouchDownX - event.x + val diffY = mTouchDownY - event.y + + if (Math.abs(diffY) > dragThreshold && Math.abs(diffY) > Math.abs(diffX)) { + var percent = ((diffY / ViewPagerActivity.screenHeight) * 100).toInt() * 3 + percent = Math.min(100, Math.max(-100, percent)) + + if ((percent == 100 && event.y > mLastTouchY) || (percent == -100 && event.y < mLastTouchY)) { + mTouchDownY = event.y + mTouchDownValue = if (mIsBrightnessScroll) mTempBrightness else getCurrentVolume() + } + + percentChanged(percent) + } else if (Math.abs(diffX) > dragThreshold || Math.abs(diffY) > dragThreshold) { + if (!mPassTouches) { + event.action = MotionEvent.ACTION_DOWN + event.setLocation(event.rawX, event.y) + mParentView?.dispatchTouchEvent(event) + } + mPassTouches = true + mParentView?.dispatchTouchEvent(event) + return false + } + mLastTouchY = event.y + } + MotionEvent.ACTION_UP -> { + if (System.currentTimeMillis() - mTouchDownTime < CLICK_MAX_DURATION) { + callback(event.rawX, event.rawY) + } + + if (mIsBrightnessScroll) { + mTouchDownValue = mTempBrightness + } + } + } + return true + } + + private fun getCurrentVolume() = activity.audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) + + private fun getCurrentBrightness(): Int { + return try { + Settings.System.getInt(activity.contentResolver, Settings.System.SCREEN_BRIGHTNESS) + } catch (e: Settings.SettingNotFoundException) { + 70 + } + } + + private fun percentChanged(percent: Int) { + if (mIsBrightnessScroll) { + brightnessPercentChanged(percent) + } else { + volumePercentChanged(percent) + } + } + + private fun volumePercentChanged(percent: Int) { + val stream = AudioManager.STREAM_MUSIC + val maxVolume = activity.audioManager.getStreamMaxVolume(stream) + val percentPerPoint = 100 / maxVolume + val addPoints = percent / percentPerPoint + val newVolume = Math.min(maxVolume, Math.max(0, mTouchDownValue + addPoints)) + activity.audioManager.setStreamVolume(stream, newVolume, 0) + + val absolutePercent = ((newVolume / maxVolume.toFloat()) * 100).toInt() + showValue(absolutePercent) + + mSlideInfoFadeHandler.removeCallbacksAndMessages(null) + mSlideInfoFadeHandler.postDelayed({ + slideInfoView.animate().alpha(0f) + }, SLIDE_INFO_FADE_DELAY) + } + + private fun brightnessPercentChanged(percent: Int) { + val maxBrightness = 255f + var newBrightness = (mTouchDownValue + 2.55 * percent).toFloat() + newBrightness = Math.min(maxBrightness, Math.max(0f, newBrightness)) + mTempBrightness = newBrightness.toInt() + + val absolutePercent = ((newBrightness / maxBrightness) * 100).toInt() + showValue(absolutePercent) + + val attributes = activity.window.attributes + attributes.screenBrightness = absolutePercent / 100f + activity.window.attributes = attributes + + mSlideInfoFadeHandler.removeCallbacksAndMessages(null) + mSlideInfoFadeHandler.postDelayed({ + slideInfoView.animate().alpha(0f) + }, SLIDE_INFO_FADE_DELAY) + } + + private fun showValue(percent: Int) { + slideInfoView.apply { + text = "$mSlideInfoText:\n$percent%" + alpha = 1f + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/models/Directory.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/models/Directory.kt index 271f065ed..a3a54fb5a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/models/Directory.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/models/Directory.kt @@ -6,7 +6,7 @@ import com.simplemobiletools.commons.helpers.* import java.io.Serializable data class Directory(val path: String, val tmb: String, val name: String, var mediaCnt: Int, val modified: Long, val taken: Long, - val size: Long) : Serializable, Comparable { + val size: Long, val isOnSDCard: Boolean) : Serializable, Comparable { companion object { private val serialVersionUID = -6553345863555455L var sorting: Int = 0 diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/views/InstantItemSwitch.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/views/InstantItemSwitch.kt new file mode 100644 index 000000000..bdfe1264a --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/views/InstantItemSwitch.kt @@ -0,0 +1,68 @@ +package com.simplemobiletools.gallery.views + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import android.view.ViewGroup +import android.widget.RelativeLayout +import com.simplemobiletools.gallery.helpers.CLICK_MAX_DURATION +import com.simplemobiletools.gallery.helpers.DRAG_THRESHOLD + +// handle only one finger clicks, pass other events to the parent view and ignore it when received again +class InstantItemSwitch(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs) { + private var mTouchDownTime = 0L + private var mTouchDownX = 0f + private var mTouchDownY = 0f + private var passTouches = false + private var dragThreshold = DRAG_THRESHOLD * context.resources.displayMetrics.density + + var parentView: ViewGroup? = null + + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + if (passTouches) { + if (ev.actionMasked == MotionEvent.ACTION_DOWN) { + passTouches = false + } + return false + } + return super.dispatchTouchEvent(ev) + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + if (passTouches) { + return false + } + + when (event.actionMasked) { + MotionEvent.ACTION_DOWN -> { + mTouchDownX = event.x + mTouchDownY = event.y + mTouchDownTime = System.currentTimeMillis() + } + MotionEvent.ACTION_UP -> { + if (System.currentTimeMillis() - mTouchDownTime < CLICK_MAX_DURATION) { + performClick() + } + } + MotionEvent.ACTION_MOVE -> { + if (passTouches) { + return false + } + + val diffX = mTouchDownX - event.x + val diffY = mTouchDownY - event.y + if (Math.abs(diffX) > dragThreshold || Math.abs(diffY) > dragThreshold) { + if (!passTouches) { + event.action = MotionEvent.ACTION_DOWN + event.setLocation(event.rawX, event.y) + parentView?.dispatchTouchEvent(event) + } + passTouches = true + parentView?.dispatchTouchEvent(event) + return false + } + } + } + return true + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 033563bb1..e3aad745a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -38,7 +38,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none" - app:layoutManager="android.support.v7.widget.GridLayoutManager" + app:layoutManager="com.simplemobiletools.commons.views.MyGridLayoutManager" app:spanCount="@integer/directory_columns_vertical_scroll"/> + app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager"/> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + + + + + + + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + + + + + + + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + + + + + + + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin" + android:paddingLeft="@dimen/normal_margin" + android:paddingRight="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin"> - + + + + - - - - - + android:background="@drawable/gradient_background"> + android:paddingLeft="@dimen/activity_margin" + android:paddingRight="@dimen/activity_margin" + android:textColor="@android:color/white" + tools:text="00:00"/> + android:paddingLeft="@dimen/activity_margin" + android:paddingRight="@dimen/activity_margin" + android:textColor="@android:color/white" + tools:text="00:00"/> diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 580b02f68..f75a61d8c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -130,6 +130,7 @@ قم بتمرير الصور المصغرة أفقيا إخفاء واجهة النظام تلقائيا عند العرض في وضع ملء الشاشة احذف المجلدات الفارغة بعد حذف محتواها + Allow controlling photo brightness with vertical gestures السماح بالتحكم في صوت الفيديو والسطوع بالإيماءات العمودية إظهار عدد لوسائط المجلد على طريقة العرض الرئيسية استبدال خيار المشاركة مع خيار تدوير في القائمة ملء الشاشة @@ -139,6 +140,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index fae7b6b0a..37c20d263 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -126,6 +126,7 @@ Desplaçar miniatures horizontalment Ocultar automàticament la interficie de usuari del sistema a pantalla complerta Eliminar carpetes buides després d\'esborrar el seu contingut + Permet controlar la brillantor amb gestos verticals Permet controlar el volum i la brillantor del vídeo amb gestos verticals Mostrar el número de mitjans de les carpetes a la vista principal Reemplaçar Compartir per Girar al menú de pantalla complerta @@ -134,7 +135,8 @@ Permet fer zoom amb un sol dit a pantalla complerta Permet canviar els mitjans de manera instantània fent clic als costats de la pantalla Substituïr imatges ampliades per les de millor quialitat - Amaga els detalls estesos quan la barra d'estat està amagada + Amaga els detalls estesos quan la barra d\'estat està amagada + Fer una verificació addicional per evitar que es mostrin fitxers no vàlids Miniatures diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 859adbd5f..16b76fe49 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -126,6 +126,7 @@ Scroll thumbnails horizontally Automatically hide system UI at fullscreen media Delete empty folders after deleting their content + Allow controlling photo brightness with vertical gestures Allow controlling video volume and brightness with vertical gestures Show folder media count on the main view Replace Share with Rotate at fullscreen menu @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 39b4d3634..b02e45e42 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -126,6 +126,7 @@ Kacheln horizontal scrollen Systemleiste im Vollbild ausblenden Nach Löschen leere Ordner löschen + Fotohelligkeit mit vertikalen Gesten ändern Gesten für Videolautstärke/Helligkeit zulassen Medienanzahl bei Ordnern anzeigen Teilen/Drehen im Vollbild-Menü vertauschen @@ -135,6 +136,7 @@ Beim Tippen auf eine Bildschirmseite sofort zwischen Medien wechseln 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 Thumbnails diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 031a2c97d..a6889d070 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -126,6 +126,7 @@ Desplazar miniaturas horizontalmente Ocultar automáticamente la interfaz de usuario del sistema en medios de pantalla completa Eliminar carpetas vacias despues de borrar su contenido + Permite controlar el brillo con gestos verticales Permite controlar el volumen y el brillo del video con gestos verticales Mostrar el conteo de medios de las carpetas en la vista principal Reemplazar Compartir con Girar en el menú de pantalla completa @@ -135,6 +136,7 @@ Permitir el cambio instantáneo de medios haciendo clic en los lados de la pantalla 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 Miniaturas diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 45386c324..5db309a6c 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -126,6 +126,7 @@ Vieritä pienoiskuvia vaakasuorassa Piilota järjestelmän UI automaattisesti koko näytön mediassa Poista tyhjät kansiot kansion tyhjennyksen jälkeen + Allow controlling photo brightness with vertical gestures Salli videon äänenvoimakkuuden ja kirkkauden säätö pystysuorilla eleillä Show folder media count on the main view Korvaa jakaminen kääntämisellä koko näytön tilassa @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 51702b67f..2163d8031 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -51,7 +51,7 @@ Dossiers inclus Gérer les dossiers inclus Ajouter un dossier - Si vous avez des dossiers contenant des médias et qui ne sont pas reconnus par l\'application alors, vous pouvez les ajouter manuellement ici. + Si vous avez des dossiers contenant des médias et qu\'ils ne sont pas reconnus par l\'application, vous pouvez les ajouter manuellement ici. Redimensionner @@ -122,24 +122,26 @@ Paramètres système Rotation de l\'appareil Ratio d\'aspect - Fond et barre de statur noir en plein écran + Fond et barre de statut noir en plein écran Défilement des miniatures horizontalement - Masquer automatiquement l\'interface utilisateur si média plein écran + Masquer automatiquement l\'interface utilisateur si média en plein écran Supprimer les dossiers vides après avoir supprimé leur contenu + Allow controlling photo brightness with vertical gestures Permettre le contrôle du volume vidéo et de la luminosité avec des gestes verticaux Afficher le nombre de fichiers dans les dossiers sur l\'écran principal Remplacer Partager par Pivoter si menu en plein écran Afficher les détails supplémentaires par dessus le média en plein écran Gérer les détails supplémentaires - Allow one finger zoom at fullscreen media - Allow instantly changing media by clicking on screen sides - Replace deep zoomable images with better quality ones - Hide extended details when status bar is hidden + Autoriser le zoom avec un doigt sur un média en plein écran + Autoriser le changement instantané de média en cliquant sur les côtés de l\'écran + 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 - Thumbnails - Fullscreen media - Extended details + Vignettes + Média plein écran + Détails supplémentaires @@ -147,11 +149,11 @@ Un simple outil pour visionner les photos et les vidéos. Elles peuvent être triées par dates, tailles, noms dans les deux sens (alphabétique comme désalphabétique), il est possible de zoomer sur les photos. Les fichiers sont affichés sur de multiple colonnes en fonction de la taille de l\'écran, vous pouvez changer le nombre de colonnes par pincement. Elles peuvent être renommées, partagées, supprimées, copiées et déplacées. Les images peuvent en plus être tournées, rognées ou être définies comme fond d\'écran directement depuis l\'application. - La galerie est également proposée pour une utilisation comme tierce partie pour la prévisualisation des images/vidéos, ajouter des pièces jointes aux clients email etc. C\'est parfait pour un usage au quotidien. + La galerie est également proposée pour une utilisation comme tierce partie pour la prévisualisation des images/vidéos, ajouter des pièces jointes aux clients email, etc... C\'est parfait pour un usage au quotidien. L\'autorisation d\'empreinte digitale est nécessaire pour verrouiller les dossiers cachés et/ou l\'application. - L\'application ne contient ni publicité ni autorisation inutile. Elle est totalement opensource et est aussi fournie avec des couleurs personnalisables. + L\'application ne contient ni publicité ni autorisation inutile. Elle est totalement opensource et est également fournie avec des couleurs personnalisables. Cette application fait partie d\'une plus grande suite. Vous pouvez trouver les autres applications sur http://www.simplemobiletools.com diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 31b8eb039..ae64e382a 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -126,6 +126,7 @@ Desplazar iconas horizontalmente Agochar controis do sistema cando visualice a pantalla completa Borrar cartafoles baldeiros cando elmine o seu contido + Allow controlling photo brightness with vertical gestures Permitir controlar o volume do vídeo e o brillo con xestos verticáis Mostrar a conta de medios do cartafol na vista principal Substituír Compartir con Rotar no menú de pantalla completa @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 9de39af66..36fb734fb 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -126,6 +126,7 @@ Listaj sličice horizontalno Automatski sakrij UI sustava pri pregledu datoteka Izbriži prazne direktorije nakon brisanja njihovog sadržaja + Allow controlling photo brightness with vertical gestures Omogući kontrolu glasnoće videa i svjetline pomoću vertikalnih gesti Prikaži broj datoteka u direktoriju na glavnom zaslonu Zamjeni Dijeli s Rotiraj pri pregledu datoteka @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index d2ff7481a..f6ee30b59 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -126,6 +126,7 @@ Scroll thumbnails horizontally Automatically hide system UI at fullscreen media Delete empty folders after deleting their content + Allow controlling photo brightness with vertical gestures Allow controlling video volume and brightness with vertical gestures Show folder media count on the main view Replace Share with Rotate at fullscreen menu @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index a040ee80d..a0bb6b6bd 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -126,20 +126,22 @@ Scorri le miniature orizzontalmente Nascondi UI di sistema con media a schermo intero Elimina cartelle vuote dopo averne eliminato il contenuto + Controlla la luminosità delle foto con gesti verticali Gestisci il volume e la luminosità dei video con gesti verticali Mostra numero elementi nella cartella Sostituisci Condividi con Ruota a schermo intero Mostra informazioni estese su media a schermo intero Gestisci le informazioni estese Abilita zoom con un dito su media a schermo intero - Allow instantly changing media by clicking on screen sides - Replace deep zoomable images with better quality ones - Hide extended details when status bar is hidden + Cambia media istantaneamente toccando sui lati dello schermo + 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 - Thumbnails - Fullscreen media - Extended details + Miniature + Media a schermo intero + Dettagli estesi diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index c2d4de191..540a8f242 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -126,6 +126,7 @@ サムネイル画面を横方向にスクロール フルスクリーン時にシステムUIを非表示にする メディアの削除後にフォルダーが空になった場合、そのフォルダーを削除する + Allow controlling photo brightness with vertical gestures ビデオ再生中に、音量と明るさを縦方向のジェスチャーで変更する Show folder media count on the main view フルスクリーンメニューの「共有」を「回転」に置き換える @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 03a188346..813ff8565 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -126,6 +126,7 @@ 섬네일 수평스크롤 전체화면 모드에서 시스템 UI 숨김 콘텐츠 삭제 후 빈폴더 삭제 + Allow controlling photo brightness with vertical gestures 수직 제스처로 비디오 볼륨 및 밝기 제어 폴더에 포함된 미디어파일 수 표시 전체화면 메뉴의 공유 아이콘을 회전 아이콘으로 변경 @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 342bb2f27..cf7e1d702 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -126,6 +126,7 @@ Horisontal rulling av minibilder Skjul automatisk systemlinjer ved mediavisning Slett tomme mapper etter sletting av deres innhold + Tillat å styre fotolysstyrke med vertikale bevegelser Tillat å styre videovolum og lysstyrke med vertikale bevegelser Vis mediaantallet i mapper på hovedvisningen Erstatt Del med Roter i meny ved mediavisning @@ -135,6 +136,7 @@ Tillat å skifte media øyeblikkelig ved å trykke på kanten av skjermen 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 Minibilder diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index be82781f7..b966fa1f6 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -126,6 +126,7 @@ Horizontaal scrollen Statusbalk automatisch verbergen in volledig scherm Lege mappen verwijderen na leegmaken + Allow controlling photo brightness with vertical gestures Volume en helderheid aanpassen met verticale gebaren Aantallen in mappen tonen Menu-item Draaien vastzetten in volledig scherm (in plaats van Delen) @@ -135,6 +136,7 @@ Direct naar vorige/volgende door op de zijkanten van het scherm te tikken In hoge kwaliteit weergeven (ten koste van ver inzoomen) Uitgebreide informatie niet tonen als de statusbalk is verborgen + Do an extra check to avoid showing invalid files Miniatuurvoorbeelden diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 5b5505b85..1ba92b71f 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -7,7 +7,7 @@ (ukryty) Przypnij folder Wypakuj folder - Pin to the top +    Przypnij na górze Pokaż wszystko Wszystkie foldery Przełącz na widok folderów @@ -126,20 +126,22 @@ Przewijaj miniatury poziomo Ukrywaj interfejs przy pełnoekranowym podglądzie Usuwaj puste foldery po usunięciu ich zawartości + Allow controlling photo brightness with vertical gestures Zezwalaj na kontrolę jasności i głośności filmów pionowymi gestami Pokazuj liczbę elementów w folderach w głównym widoku Zamień funkcję udostępniania na obracanie w menu pełnoekranowym Dodatkowe szczegóły przy podglądzie pełnoekranowym Zarządzaj dodatkowymi szczegółami - Allow one finger zoom at fullscreen media - Allow instantly changing media by clicking on screen sides - Replace deep zoomable images with better quality ones - Hide extended details when status bar is hidden +    Zezwalaj na powiększanie jednym palcem w widoku pełnoekranowym +    Zezwalaj na natychmiastową zmianę multimediów po kliknięciu boków ekranu +    Zamieniaj powiększalne obrazy na te o lepszej jakości +    Ukrywaj dodatkowe szczegóły gdy pasek stanu jest ukryty + Do an extra check to avoid showing invalid files - Thumbnails - Fullscreen media - Extended details +    Miniatury +    Widok pełnoekranowy +    Dodatkowe szczegóły diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index bb2cdec30..14d8ea1f3 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -126,6 +126,7 @@ Rolar miniaturas horizontalmente Esconder interface do sistema automaticamente quando em tela cheia Apagar pastas vazias após deleter seu conteúdo + Allow controlling photo brightness with vertical gestures Permitir controle do volume e brilho com gestos na vertical Mostrar quantidade de arquivos das pastas Substituir botão "Compartilhar" por "Rotação de tela" quando em tela cheia @@ -135,6 +136,7 @@ Permitir alternância instantânia de mídia clicando nas laterais da tela 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 Miniaturas diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 8afac4e8d..c158d291d 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -29,7 +29,7 @@ Filtrar multimédia Imagens Vídeos - GIFs + GIF Não foram encontrados ficheiros que cumpram os requisitos. Alterar filtros @@ -98,7 +98,7 @@ Intervalo (segundos): Incluir fotos Incluir vídeos - Incluir GIFs + Incluir GIF Ordem aleatória Usar animações Mover para trás @@ -115,7 +115,7 @@ Reproduzir vídeos automaticamente Mostrar/ocultar nome do ficheiro Vídeos em ciclo - Animação de GIFs nas miniaturas + Animação de GIF nas miniaturas Brilho máximo permitido Recortar miniaturas em quadrados Rodar em ecrã completo por @@ -126,20 +126,22 @@ Deslocação horizontal de miniaturas Ocultar interface do sistema se em ecrã completo Apagar as pastas vazias depois de remover o seu conteúdo - Permitir controlo do volume e brilho dos vídeos através de gestos verticais + Permitir controlo do brilho das fotos com gestos verticais + Permitir controlo do volume e do brilho dos vídeos através de gestos verticais Mostrar número de ficheiros na vista principal Substituir a opção Partilhar pela opção Rodar se em ecrã completo Mostrar detalhes se em ecrã completo Gerir detalhes exibidos - Allow one finger zoom at fullscreen media - Allow instantly changing media by clicking on screen sides + Permitir ampliação com um dedo se em ecrã completo + Permitir troca imediata de ficheiro ao tocar nas margens do ecrã Replace deep zoomable images with better quality ones - Hide extended details when status bar is hidden + Ocultar detalhes extra se a barra de estado estiver oculta + Efetuar uma dupla verificação para evitar mostrar os ficheiros inválidos - Thumbnails - Fullscreen media - Extended details + Miniaturas + Multimédia em ecrã completo + Detalhes extra diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 69b3df690..468e48cca 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -126,6 +126,7 @@ Прокрутка эскизов по горизонтали Автоматически скрывать системный интерфейс в полноэкранном режиме Удалять пустые папки после удаления их содержимого + Управлять яркостью фото с помощью вертикальных жестов Управлять громкостью и яркостью видео с помощью вертикальных жестов Показывать количество файлов в папках Заменить \"Поделиться\" на \"Повернуть\" в меню полноэкранного режима @@ -135,6 +136,7 @@ Мгновенное переключение медиафайлов нажатием по краю экрана Заменить масштабируемые изображения высококачественными Не показывать подробности, если скрыта строка состояния + Делать дополнительную проверку, чтобы избежать показа неверных файлов Миниатюры diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index aeb067881..21dd19109 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -126,6 +126,7 @@ Prehliadať miniatúry vodorovne Automaticky skrývať systémové lišty pri celoobrazovkových médiách Odstrániť prázdne priečinky po vymazaní ich obsahu + Allow controlling photo brightness with vertical gestures Povoliť ovládanie hlasitosti a jasu videí vertikálnymi ťahmi Zobraziť počet médií v priečinku na hlavnej obrazovke Nahradiť Zdieľanie s Otočením v celoobrazovkovom menu @@ -135,6 +136,7 @@ Povoliť instantné prepínanie médií kliknutím na okraj obrazovky 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 Náhľady diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index a4c380455..b65c23c2d 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -126,6 +126,7 @@ Rulla horisontellt genom miniatyrer Dölj systemanvändargränssnittet automatiskt när media visas i helskärmsläge Ta bort tomma mappar när deras innehåll tas bort + Allow controlling photo brightness with vertical gestures Tillåt styrning av videovolym och videoljusstyrka med vertikala gester Visa antalet mediefiler i varje mapp i huvudvyn Ersätt Dela med Rotera i helskärmsmenyn @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml index 595bc8570..5ce6c1c68 100644 --- a/app/src/main/res/values-sw600dp/dimens.xml +++ b/app/src/main/res/values-sw600dp/dimens.xml @@ -5,7 +5,5 @@ 30dp 38dp 230dp - 32dp 60dp - 250dp diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index fdb8ddf11..834639abb 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -126,6 +126,7 @@ Scroll thumbnails horizontally Automatically hide system UI at fullscreen media Delete empty folders after deleting their content + Allow controlling photo brightness with vertical gestures Allow controlling video volume and brightness with vertical gestures Show folder media count on the main view Replace Share with Rotate at fullscreen menu @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9989b6f9d..f4439d761 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -126,6 +126,7 @@ 水平滚动缩略图 全屏时自动隐藏状态栏 删除没有内容的空文件夹 + 使用纵向滑动手势控制照片亮度 使用纵向滑动手势控制视频音量和亮度 在主界面显示文件夹媒体计数 替换全屏时菜单栏的“分享”为“旋转” @@ -135,6 +136,7 @@ 通过单击屏幕边缘来切换媒体 用质量更好的图像替换可深度缩放的图像 当状态栏隐藏时隐藏扩展详情 + 额外检查以避免显示无效的文件 缩略图 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index a00a943a1..db09cd9f1 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -126,6 +126,7 @@ 橫向滑動縮圖 全螢幕時自動隱藏系統介面 刪除內容後刪除空白資料夾 + 允許用上下手勢來控制相片的亮度 允許用上下手勢來控制影片的音量和亮度 主畫面顯示資料夾內媒體檔案數量 將全螢幕選單的分享取代為旋轉 @@ -135,6 +136,7 @@ 允許點擊螢幕邊緣來快速切換媒體檔案 可深度縮放的圖片用品質更佳的來取代 狀態欄隱藏時,同時隱藏詳細資訊 + 進行額外檢查,避免顯示無效的檔案 縮圖 @@ -149,7 +151,7 @@ 這相簿也支援第三方應用,像是預覽圖片/影片、添加電子信箱附件...等功能,日常使用上相當適合。 - The fingerprint permission is needed for locking either hidden item visibility, or the whole app. + 指紋權限用來鎖定隱藏的項目或是整個程式。 優點包含沒廣告,也沒非必要的權限,而且完全開放原始碼,並提供自訂顏色。 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index cca10a70f..0a0cdcd24 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -6,9 +6,8 @@ 22dp 26dp 150dp - 24dp - 50dp - 150dp - 60dp + 60dp + 60dp + 30dp 72dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5cea74dfe..abf2cb0ca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -126,6 +126,7 @@ Scroll thumbnails horizontally Automatically hide system UI at fullscreen media Delete empty folders after deleting their content + Allow controlling photo brightness with vertical gestures Allow controlling video volume and brightness with vertical gestures Show folder media count on the main view Replace Share with Rotate at fullscreen menu @@ -135,6 +136,7 @@ Allow instantly changing media by clicking on screen sides 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 Thumbnails