diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58136d1a8..feff7768b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,19 @@
Changelog
==========
+Version 6.1.3 *(2018-12-26)*
+----------------------------
+
+ * Fixed a glitch at zooming fullscreen images with double tap
+ * Hide favorite items from hidden folders, if showing hidden items is disabled
+
+Version 6.1.2 *(2018-12-24)*
+----------------------------
+
+ * Done a few performance improvements here and there
+ * Allow changing view type individually per folder
+ * Merry Christmas!
+
Version 6.1.1 *(2018-12-18)*
----------------------------
diff --git a/app/build.gradle b/app/build.gradle
index d3c104ce3..b31ee9a6c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -15,8 +15,8 @@ android {
applicationId "com.simplemobiletools.gallery.pro"
minSdkVersion 21
targetSdkVersion 28
- versionCode 214
- versionName "6.1.1"
+ versionCode 216
+ versionName "6.1.3"
multiDexEnabled true
setProperty("archivesBaseName", "gallery")
}
@@ -57,12 +57,12 @@ android {
}
dependencies {
- implementation 'com.simplemobiletools:commons:5.5.18'
+ implementation 'com.simplemobiletools:commons:5.6.3'
implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
- implementation 'androidx.multidex:multidex:2.0.0'
+ implementation 'androidx.multidex:multidex:2.0.1'
implementation 'it.sephiroth.android.exif:library:1.0.1'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.16'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.2'
implementation 'com.google.vr:sdk-panowidget:1.180.0'
implementation 'com.google.vr:sdk-videowidget:1.180.0'
@@ -78,7 +78,7 @@ dependencies {
//implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'
//implementation 'com.github.tibbi:subsampling-scale-image-view:v3.10.1-fork'
- implementation 'com.github.tibbi:subsampling-scale-image-view:fcb724fb0a'
+ implementation 'com.github.tibbi:subsampling-scale-image-view:4.0.2'
// implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.github.tibbi:PhotoView:2.3.0-fork'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b00e56d71..8b41fb872 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -122,6 +122,11 @@
android:name=".activities.PhotoVideoActivity"
android:configChanges="orientation|keyboardHidden|screenSize"/>
+
+
)
}
// cached folders have been loaded, recheck folders one by one starting with the first displayed
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
index 536e05245..fdca85100 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
@@ -22,23 +22,18 @@ import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
-import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.OTG_PATH
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
import com.simplemobiletools.commons.helpers.REQUEST_EDIT_IMAGE
import com.simplemobiletools.commons.models.FileDirItem
-import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.views.MyGridLayoutManager
import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.adapters.MediaAdapter
import com.simplemobiletools.gallery.pro.asynctasks.GetMediaAsynctask
import com.simplemobiletools.gallery.pro.databases.GalleryDatabase
-import com.simplemobiletools.gallery.pro.dialogs.ChangeGroupingDialog
-import com.simplemobiletools.gallery.pro.dialogs.ChangeSortingDialog
-import com.simplemobiletools.gallery.pro.dialogs.ExcludeFolderDialog
-import com.simplemobiletools.gallery.pro.dialogs.FilterMediaDialog
+import com.simplemobiletools.gallery.pro.dialogs.*
import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.helpers.*
import com.simplemobiletools.gallery.pro.interfaces.DirectoryDao
@@ -224,10 +219,10 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
findItem(R.id.temporarily_show_hidden).isVisible = !config.shouldShowHidden
findItem(R.id.stop_showing_hidden).isVisible = config.temporarilyShowHidden
- findItem(R.id.increase_column_count).isVisible = config.viewTypeFiles == VIEW_TYPE_GRID && config.mediaColumnCnt < MAX_COLUMN_COUNT
- findItem(R.id.reduce_column_count).isVisible = config.viewTypeFiles == VIEW_TYPE_GRID && config.mediaColumnCnt > 1
-
- findItem(R.id.toggle_filename).isVisible = config.viewTypeFiles == VIEW_TYPE_GRID
+ val viewType = config.getFolderViewType(if (mShowAll) SHOW_ALL else mPath)
+ findItem(R.id.increase_column_count).isVisible = viewType == VIEW_TYPE_GRID && config.mediaColumnCnt < MAX_COLUMN_COUNT
+ findItem(R.id.reduce_column_count).isVisible = viewType == VIEW_TYPE_GRID && config.mediaColumnCnt > 1
+ findItem(R.id.toggle_filename).isVisible = viewType == VIEW_TYPE_GRID
}
setupSearch(menu)
@@ -367,7 +362,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
initZoomListener()
val fastscroller = if (config.scrollHorizontally) media_horizontal_fastscroller else media_vertical_fastscroller
MediaAdapter(this, mMedia.clone() as ArrayList, this, mIsGetImageIntent || mIsGetVideoIntent || mIsGetAnyIntent,
- mAllowPickingMultiple, media_grid, fastscroller) {
+ mAllowPickingMultiple, mPath, media_grid, fastscroller) {
if (it is Medium) {
itemClicked(it.path)
}
@@ -385,7 +380,8 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
private fun setupScrollDirection() {
- val allowHorizontalScroll = config.scrollHorizontally && config.viewTypeFiles == VIEW_TYPE_GRID
+ val viewType = config.getFolderViewType(if (mShowAll) SHOW_ALL else mPath)
+ val allowHorizontalScroll = config.scrollHorizontally && viewType == VIEW_TYPE_GRID
media_vertical_fastscroller.isHorizontal = false
media_vertical_fastscroller.beGoneIf(allowHorizontalScroll)
@@ -493,12 +489,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
private fun changeViewType() {
- val items = arrayListOf(
- RadioItem(VIEW_TYPE_GRID, getString(R.string.grid)),
- RadioItem(VIEW_TYPE_LIST, getString(R.string.list)))
-
- RadioGroupDialog(this, items, config.viewTypeFiles) {
- config.viewTypeFiles = it as Int
+ ChangeViewTypeDialog(this, false, mPath) {
invalidateOptionsMenu()
setupLayoutManager()
media_grid.adapter = null
@@ -646,7 +637,8 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
private fun setupLayoutManager() {
- if (config.viewTypeFiles == VIEW_TYPE_GRID) {
+ val viewType = config.getFolderViewType(if (mShowAll) SHOW_ALL else mPath)
+ if (viewType == VIEW_TYPE_GRID) {
setupGridLayoutManager()
} else {
setupListLayoutManager()
@@ -722,7 +714,8 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
private fun initZoomListener() {
- if (config.viewTypeFiles == VIEW_TYPE_GRID) {
+ val viewType = config.getFolderViewType(if (mShowAll) SHOW_ALL else mPath)
+ if (viewType == VIEW_TYPE_GRID) {
val layoutManager = media_grid.layoutManager as MyGridLayoutManager
mZoomListener = object : MyRecyclerView.MyZoomListener {
override fun zoomIn() {
@@ -840,7 +833,8 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
media_empty_text.beVisibleIf(media.isEmpty() && !isFromCache)
media_grid.beVisibleIf(media_empty_text_label.isGone())
- val allowHorizontalScroll = config.scrollHorizontally && config.viewTypeFiles == VIEW_TYPE_GRID
+ val viewType = config.getFolderViewType(if (mShowAll) SHOW_ALL else mPath)
+ val allowHorizontalScroll = config.scrollHorizontally && viewType == VIEW_TYPE_GRID
media_vertical_fastscroller.beVisibleIf(media_grid.isVisible() && !allowHorizontalScroll)
media_horizontal_fastscroller.beVisibleIf(media_grid.isVisible() && allowHorizontalScroll)
setupAdapter()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PanoramaVideoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PanoramaVideoActivity.kt
index 7518add3c..8183613d4 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PanoramaVideoActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PanoramaVideoActivity.kt
@@ -8,23 +8,17 @@ import android.os.Handler
import android.view.View
import android.view.Window
import android.view.WindowManager
-import android.view.animation.AnimationUtils
import android.widget.RelativeLayout
import android.widget.SeekBar
import com.google.vr.sdk.widgets.video.VrVideoEventListener
import com.google.vr.sdk.widgets.video.VrVideoView
-import com.simplemobiletools.commons.extensions.getFormattedDuration
-import com.simplemobiletools.commons.extensions.onGlobalLayout
-import com.simplemobiletools.commons.extensions.showErrorToast
-import com.simplemobiletools.commons.extensions.toast
+import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
import com.simplemobiletools.commons.helpers.isPiePlus
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.*
-import com.simplemobiletools.gallery.pro.helpers.HIDE_PLAY_PAUSE_DELAY
import com.simplemobiletools.gallery.pro.helpers.MIN_SKIP_LENGTH
import com.simplemobiletools.gallery.pro.helpers.PATH
-import com.simplemobiletools.gallery.pro.helpers.PLAY_PAUSE_VISIBLE_ALPHA
import kotlinx.android.synthetic.main.activity_panorama_video.*
import kotlinx.android.synthetic.main.bottom_video_time_holder.*
import java.io.File
@@ -41,7 +35,6 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
private var mDuration = 0
private var mCurrTime = 0
- private var mHidePlayPauseHandler = Handler()
private var mTimerHandler = Handler()
public override fun onCreate(savedInstanceState: Bundle?) {
@@ -56,18 +49,6 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
}
- setupButtons()
-
- cardboard.setOnClickListener {
- vr_video_view.displayMode = CARDBOARD_DISPLAY_MODE
- }
-
- explore.setOnClickListener {
- mIsExploreEnabled = !mIsExploreEnabled
- vr_video_view.setPureTouchTracking(mIsExploreEnabled)
- explore.setImageResource(if (mIsExploreEnabled) R.drawable.ic_explore else R.drawable.ic_explore_off)
- }
-
handlePermission(PERMISSION_WRITE_STORAGE) {
if (it) {
checkIntent()
@@ -102,7 +83,6 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
}
if (!isChangingConfigurations) {
- mHidePlayPauseHandler.removeCallbacksAndMessages(null)
mTimerHandler.removeCallbacksAndMessages(null)
}
}
@@ -115,6 +95,7 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
return
}
+ setupButtons()
intent.removeExtra(PATH)
video_curr_time.setOnClickListener { skip(false) }
@@ -152,10 +133,14 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
setupTimer()
}
- if (mPlayOnReady) {
+ if (mPlayOnReady || config.autoplayVideos) {
mPlayOnReady = false
- playVideo()
+ mIsPlaying = true
+ resumeVideo()
+ } else {
+ video_toggle_play_pause.setImageResource(R.drawable.ic_play_outline)
}
+ video_toggle_play_pause.beVisible()
}
override fun onCompletion() {
@@ -164,7 +149,7 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
})
}
- video_play_outline.setOnClickListener {
+ video_toggle_play_pause.setOnClickListener {
togglePlayPause()
}
} catch (e: Exception) {
@@ -205,18 +190,15 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
private fun togglePlayPause() {
mIsPlaying = !mIsPlaying
- video_play_outline.alpha = PLAY_PAUSE_VISIBLE_ALPHA
- mHidePlayPauseHandler.removeCallbacksAndMessages(null)
if (mIsPlaying) {
- playVideo()
+ resumeVideo()
} else {
pauseVideo()
}
- schedulePlayPauseFadeOut()
}
- private fun playVideo() {
- video_play_outline.setImageResource(R.drawable.ic_pause)
+ private fun resumeVideo() {
+ video_toggle_play_pause.setImageResource(R.drawable.ic_pause_outline)
if (mCurrTime == mDuration) {
setVideoProgress(0)
mPlayOnReady = true
@@ -229,7 +211,7 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
private fun pauseVideo() {
vr_video_view.pauseVideo()
- video_play_outline.setImageResource(R.drawable.ic_play)
+ video_toggle_play_pause.setImageResource(R.drawable.ic_play_outline)
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
@@ -246,55 +228,57 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
video_seekbar.progress = video_seekbar.max
video_curr_time.text = mDuration.getFormattedDuration()
pauseVideo()
- video_play_outline.alpha = PLAY_PAUSE_VISIBLE_ALPHA
- }
-
- private fun schedulePlayPauseFadeOut() {
- mHidePlayPauseHandler.removeCallbacksAndMessages(null)
- mHidePlayPauseHandler.postDelayed({
- video_play_outline.animate().alpha(0f).start()
- }, HIDE_PLAY_PAUSE_DELAY)
}
private fun setupButtons() {
- val navBarHeight = navigationBarHeight
- video_time_holder.apply {
- (layoutParams as RelativeLayout.LayoutParams).bottomMargin = navBarHeight
- setPadding(paddingLeft, paddingTop, navigationBarWidth, paddingBottom)
+ var right = 0
+ var bottom = 0
+
+ if (hasNavBar()) {
+ if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
+ bottom += navigationBarHeight
+ } else {
+ right += navigationBarWidth
+ bottom += navigationBarHeight
+ }
}
+ video_time_holder.setPadding(0, 0, right, bottom)
video_time_holder.onGlobalLayout {
- (explore.layoutParams as RelativeLayout.LayoutParams).bottomMargin = navBarHeight + video_time_holder.height
+ val newBottomMargin = video_time_holder.height - resources.getDimension(R.dimen.video_player_play_pause_size).toInt() - resources.getDimension(R.dimen.activity_margin).toInt()
+ (explore.layoutParams as RelativeLayout.LayoutParams).bottomMargin = newBottomMargin
(cardboard.layoutParams as RelativeLayout.LayoutParams).apply {
- bottomMargin = navBarHeight + video_time_holder.height
+ bottomMargin = newBottomMargin
rightMargin = navigationBarWidth
}
- vr_view_gradient_background.layoutParams.height = navBarHeight + video_time_holder.height + explore.height
explore.requestLayout()
}
+ video_toggle_play_pause.setImageResource(R.drawable.ic_play_outline)
+
+ cardboard.setOnClickListener {
+ vr_video_view.displayMode = CARDBOARD_DISPLAY_MODE
+ }
+
+ explore.setOnClickListener {
+ mIsExploreEnabled = !mIsExploreEnabled
+ vr_video_view.setPureTouchTracking(mIsExploreEnabled)
+ explore.setImageResource(if (mIsExploreEnabled) R.drawable.ic_explore else R.drawable.ic_explore_off)
+ }
}
private fun toggleButtonVisibility() {
val newAlpha = if (mIsFullscreen) 0f else 1f
- arrayOf(cardboard, explore, vr_view_gradient_background).forEach {
+ arrayOf(cardboard, explore).forEach {
it.animate().alpha(newAlpha)
+ }
+
+ arrayOf(cardboard, explore, video_toggle_play_pause, video_curr_time, video_duration).forEach {
it.isClickable = !mIsFullscreen
}
- var anim = android.R.anim.fade_in
- if (mIsFullscreen) {
- anim = android.R.anim.fade_out
- video_seekbar.setOnSeekBarChangeListener(null)
- } else {
- video_seekbar.setOnSeekBarChangeListener(this)
- }
-
- AnimationUtils.loadAnimation(this, anim).apply {
- duration = 150
- fillAfter = true
- video_time_holder.startAnimation(this)
- }
+ video_seekbar.setOnSeekBarChangeListener(if (mIsFullscreen) null else this)
+ video_time_holder.animate().alpha(newAlpha).start()
}
private fun handleClick() {
@@ -336,8 +320,7 @@ open class PanoramaVideoActivity : SimpleActivity(), SeekBar.OnSeekBarChangeList
override fun onStopTrackingTouch(seekBar: SeekBar?) {
mIsPlaying = true
- playVideo()
+ resumeVideo()
mIsDragged = false
- schedulePlayPauseFadeOut()
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt
index 6ab3b2478..b5b1c0fff 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt
@@ -16,6 +16,7 @@ import com.simplemobiletools.commons.helpers.IS_FROM_GALLERY
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
import com.simplemobiletools.commons.helpers.REAL_FILE_PATH
import com.simplemobiletools.commons.helpers.isPiePlus
+import com.simplemobiletools.gallery.pro.BuildConfig
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.fragments.PhotoFragment
@@ -26,6 +27,7 @@ import com.simplemobiletools.gallery.pro.models.Medium
import kotlinx.android.synthetic.main.bottom_actions.*
import kotlinx.android.synthetic.main.fragment_holder.*
import java.io.File
+import java.io.FileInputStream
open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentListener {
@@ -63,6 +65,12 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
private fun checkIntent(savedInstanceState: Bundle? = null) {
mUri = intent.data ?: return
var filename = getFilenameFromUri(mUri!!)
+ mIsFromGallery = intent.getBooleanExtra(IS_FROM_GALLERY, false)
+ if (mIsFromGallery && filename.isVideoFast()) {
+ launchVideoPlayer()
+ return
+ }
+
if (intent.extras?.containsKey(REAL_FILE_PATH) == true) {
val realPath = intent.extras.getString(REAL_FILE_PATH)
if (realPath != null) {
@@ -76,7 +84,6 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
}
}
- mIsFromGallery = intent.getBooleanExtra(IS_FROM_GALLERY, false)
if (mUri!!.scheme == "file") {
if (filename.contains('.')) {
scanPathRecursively(mUri!!.path)
@@ -134,6 +141,41 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
initBottomActions()
}
+ private fun launchVideoPlayer() {
+ val newUri = getFinalUriFromPath(mUri.toString(), BuildConfig.APPLICATION_ID)
+ if (newUri == null) {
+ toast(R.string.unknown_error_occurred)
+ return
+ }
+
+ var isPanorama = false
+ val realPath = intent?.extras?.getString(REAL_FILE_PATH) ?: ""
+ try {
+ if (realPath.isNotEmpty()) {
+ val fis = FileInputStream(File(realPath))
+ parseFileChannel(realPath, fis.channel, 0, 0, 0) {
+ isPanorama = true
+ }
+ }
+ } catch (ignored: Exception) {
+ } catch (ignored: OutOfMemoryError) {
+ }
+
+ if (isPanorama) {
+ Intent(applicationContext, PanoramaVideoActivity::class.java).apply {
+ putExtra(PATH, realPath)
+ startActivity(this)
+ }
+ } else {
+ val mimeType = getUriMimeType(mUri.toString(), newUri)
+ Intent(applicationContext, VideoPlayerActivity::class.java).apply {
+ setDataAndType(newUri, mimeType)
+ startActivity(this)
+ }
+ }
+ finish()
+ }
+
override fun onConfigurationChanged(newConfig: Configuration?) {
super.onConfigurationChanged(newConfig)
initBottomActionsLayout()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/VideoPlayerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/VideoPlayerActivity.kt
new file mode 100644
index 000000000..d4ea4fb25
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/VideoPlayerActivity.kt
@@ -0,0 +1,522 @@
+package com.simplemobiletools.gallery.pro.activities
+
+import android.content.pm.ActivityInfo
+import android.content.res.Configuration
+import android.graphics.Color
+import android.graphics.Point
+import android.graphics.SurfaceTexture
+import android.graphics.drawable.ColorDrawable
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.util.DisplayMetrics
+import android.view.*
+import android.widget.SeekBar
+import com.google.android.exoplayer2.*
+import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
+import com.google.android.exoplayer2.source.ExtractorMediaSource
+import com.google.android.exoplayer2.source.TrackGroupArray
+import com.google.android.exoplayer2.trackselection.TrackSelectionArray
+import com.google.android.exoplayer2.upstream.ContentDataSource
+import com.google.android.exoplayer2.upstream.DataSource
+import com.google.android.exoplayer2.upstream.DataSpec
+import com.google.android.exoplayer2.video.VideoListener
+import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
+import com.simplemobiletools.commons.helpers.isPiePlus
+import com.simplemobiletools.gallery.pro.R
+import com.simplemobiletools.gallery.pro.extensions.*
+import com.simplemobiletools.gallery.pro.helpers.MIN_SKIP_LENGTH
+import kotlinx.android.synthetic.main.activity_video_player.*
+import kotlinx.android.synthetic.main.bottom_video_time_holder.*
+
+open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, TextureView.SurfaceTextureListener {
+ private var mIsFullscreen = false
+ private var mIsPlaying = false
+ private var mWasVideoStarted = false
+ private var mIsDragged = false
+ private var mCurrTime = 0
+ private var mDuration = 0
+ private var mVideoSize = Point(0, 0)
+
+ private var mUri: Uri? = null
+ private var mExoPlayer: SimpleExoPlayer? = null
+ private var mTimerHandler = Handler()
+
+ private var mTouchDownX = 0f
+ private var mTouchDownY = 0f
+ private var mCloseDownThreshold = 100f
+ private var mIgnoreCloseDown = false
+
+ public override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_video_player)
+
+ handlePermission(PERMISSION_WRITE_STORAGE) {
+ if (it) {
+ initPlayer()
+ } else {
+ toast(R.string.no_storage_permissions)
+ finish()
+ }
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ top_shadow.layoutParams.height = statusBarHeight + actionBarHeight
+ supportActionBar?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ window.statusBarColor = Color.TRANSPARENT
+ window.navigationBarColor = Color.TRANSPARENT
+ if (config.blackBackground) {
+ video_player_holder.background = ColorDrawable(Color.BLACK)
+ }
+
+ if (config.maxBrightness) {
+ val attributes = window.attributes
+ attributes.screenBrightness = 1f
+ window.attributes = attributes
+ }
+
+ updateTextColors(video_player_holder)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ pauseVideo()
+
+ if (config.rememberLastVideoPosition && mWasVideoStarted) {
+ saveVideoProgress()
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ if (!isChangingConfigurations) {
+ cleanup()
+ }
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.menu_video_player, menu)
+ return true
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ R.id.menu_change_orientation -> changeOrientation()
+ else -> return super.onOptionsItemSelected(item)
+ }
+ return true
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ setVideoSize()
+ initTimeHolder()
+ }
+
+ private fun initPlayer() {
+ mUri = intent.data ?: return
+ supportActionBar?.title = getFilenameFromUri(mUri!!)
+ initTimeHolder()
+
+ if (isPiePlus()) {
+ window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
+ window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
+ }
+
+ showSystemUI(true)
+ window.decorView.setOnSystemUiVisibilityChangeListener { visibility ->
+ val isFullscreen = visibility and View.SYSTEM_UI_FLAG_FULLSCREEN != 0
+ fullscreenToggled(isFullscreen)
+ }
+
+ // adding an empty click listener just to avoid ripple animation at toggling fullscreen
+ video_seekbar.setOnClickListener { }
+ video_curr_time.setOnClickListener { skip(false) }
+ video_duration.setOnClickListener { skip(true) }
+ video_toggle_play_pause.setOnClickListener { togglePlayPause() }
+ video_player_holder.setOnClickListener {
+ fullscreenToggled(!mIsFullscreen)
+ }
+
+ if (config.allowDownGesture) {
+ video_player_holder.setOnTouchListener { v, event ->
+ handleEvent(event)
+ false
+ }
+
+ video_surface.setOnTouchListener { v, event ->
+ handleEvent(event)
+ false
+ }
+ }
+
+ initExoPlayer()
+ video_surface.surfaceTextureListener = this
+ video_surface.setOnClickListener {
+ fullscreenToggled(!mIsFullscreen)
+ }
+
+ if (config.allowVideoGestures) {
+ video_brightness_controller.initialize(this, slide_info, true, video_player_holder) { x, y ->
+ video_player_holder.performClick()
+ }
+
+ video_volume_controller.initialize(this, slide_info, false, video_player_holder) { x, y ->
+ video_player_holder.performClick()
+ }
+ } else {
+ video_brightness_controller.beGone()
+ video_volume_controller.beGone()
+ }
+
+ if (config.hideSystemUI) {
+ Handler().postDelayed({
+ fullscreenToggled(true)
+ }, 500)
+ }
+ }
+
+ private fun initExoPlayer() {
+ val dataSpec = DataSpec(mUri)
+ val fileDataSource = ContentDataSource(applicationContext)
+ try {
+ fileDataSource.open(dataSpec)
+ } catch (e: Exception) {
+ showErrorToast(e)
+ }
+
+ val factory = DataSource.Factory { fileDataSource }
+ val audioSource = ExtractorMediaSource(fileDataSource.uri, factory, DefaultExtractorsFactory(), null, null)
+ mExoPlayer = ExoPlayerFactory.newSimpleInstance(applicationContext).apply {
+ seekParameters = SeekParameters.CLOSEST_SYNC
+ audioStreamType = C.STREAM_TYPE_MUSIC
+ prepare(audioSource)
+ }
+ initExoPlayerListeners()
+ }
+
+ private fun initExoPlayerListeners() {
+ mExoPlayer!!.addListener(object : Player.EventListener {
+ override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {}
+
+ override fun onSeekProcessed() {}
+
+ override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {}
+
+ override fun onPlayerError(error: ExoPlaybackException?) {}
+
+ override fun onLoadingChanged(isLoading: Boolean) {}
+
+ override fun onPositionDiscontinuity(reason: Int) {}
+
+ override fun onRepeatModeChanged(repeatMode: Int) {}
+
+ override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {}
+
+ override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {}
+
+ override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
+ when (playbackState) {
+ Player.STATE_READY -> videoPrepared()
+ Player.STATE_ENDED -> videoCompleted()
+ }
+ }
+ })
+
+ mExoPlayer!!.addVideoListener(object : VideoListener {
+ override fun onVideoSizeChanged(width: Int, height: Int, unappliedRotationDegrees: Int, pixelWidthHeightRatio: Float) {
+ mVideoSize.x = width
+ mVideoSize.y = height
+ setVideoSize()
+ }
+
+ override fun onRenderedFirstFrame() {}
+ })
+ }
+
+ private fun videoPrepared() {
+ if (!mWasVideoStarted) {
+ video_toggle_play_pause.beVisible()
+ mDuration = (mExoPlayer!!.duration / 1000).toInt()
+ video_seekbar.max = mDuration
+ video_duration.text = mDuration.getFormattedDuration()
+ setPosition(mCurrTime)
+
+ if (config.rememberLastVideoPosition) {
+ setLastVideoSavedPosition()
+ }
+
+ if (config.autoplayVideos) {
+ resumeVideo()
+ } else {
+ video_toggle_play_pause.setImageResource(R.drawable.ic_play_outline)
+ }
+ }
+ }
+
+ private fun resumeVideo() {
+ video_toggle_play_pause.setImageResource(R.drawable.ic_pause_outline)
+ if (mExoPlayer == null) {
+ return
+ }
+
+ val wasEnded = didVideoEnd()
+ if (wasEnded) {
+ setPosition(0)
+ }
+
+ mWasVideoStarted = true
+ mIsPlaying = true
+ mExoPlayer?.playWhenReady = true
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ }
+
+ private fun pauseVideo() {
+ video_toggle_play_pause.setImageResource(R.drawable.ic_play_outline)
+ if (mExoPlayer == null) {
+ return
+ }
+
+ mIsPlaying = false
+ if (!didVideoEnd()) {
+ mExoPlayer?.playWhenReady = false
+ }
+
+ window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ }
+
+ private fun togglePlayPause() {
+ mIsPlaying = !mIsPlaying
+ if (mIsPlaying) {
+ resumeVideo()
+ } else {
+ pauseVideo()
+ }
+ }
+
+ private fun setPosition(seconds: Int) {
+ mExoPlayer?.seekTo(seconds * 1000L)
+ video_seekbar.progress = seconds
+ video_curr_time.text = seconds.getFormattedDuration()
+ }
+
+ private fun setLastVideoSavedPosition() {
+ if (config.lastVideoPath == mUri.toString() && config.lastVideoPosition > 0) {
+ setPosition(config.lastVideoPosition)
+ }
+ }
+
+ private fun videoCompleted() {
+ if (mExoPlayer == null) {
+ return
+ }
+
+ clearLastVideoSavedProgress()
+ mCurrTime = (mExoPlayer!!.duration / 1000).toInt()
+ if (config.loopVideos) {
+ resumeVideo()
+ } else {
+ video_seekbar.progress = video_seekbar.max
+ video_curr_time.text = mDuration.getFormattedDuration()
+ pauseVideo()
+ }
+ }
+
+ private fun didVideoEnd(): Boolean {
+ val currentPos = mExoPlayer?.currentPosition ?: 0
+ val duration = mExoPlayer?.duration ?: 0
+ return currentPos != 0L && currentPos >= duration
+ }
+
+ private fun saveVideoProgress() {
+ if (!didVideoEnd()) {
+ config.apply {
+ lastVideoPosition = mExoPlayer!!.currentPosition.toInt() / 1000
+ lastVideoPath = mUri.toString()
+ }
+ }
+ }
+
+ private fun clearLastVideoSavedProgress() {
+ config.apply {
+ lastVideoPosition = 0
+ lastVideoPath = ""
+ }
+ }
+
+ private fun setVideoSize() {
+ val videoProportion = mVideoSize.x.toFloat() / mVideoSize.y.toFloat()
+ val display = windowManager.defaultDisplay
+ val screenWidth: Int
+ val screenHeight: Int
+
+ val realMetrics = DisplayMetrics()
+ display.getRealMetrics(realMetrics)
+ screenWidth = realMetrics.widthPixels
+ screenHeight = realMetrics.heightPixels
+
+ val screenProportion = screenWidth.toFloat() / screenHeight.toFloat()
+
+ video_surface.layoutParams.apply {
+ if (videoProportion > screenProportion) {
+ width = screenWidth
+ height = (screenWidth.toFloat() / videoProportion).toInt()
+ } else {
+ width = (videoProportion * screenHeight.toFloat()).toInt()
+ height = screenHeight
+ }
+ video_surface.layoutParams = this
+ }
+ }
+
+ private fun changeOrientation() {
+ requestedOrientation = if (resources.configuration.orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
+ ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ } else {
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ }
+ }
+
+ private fun fullscreenToggled(isFullScreen: Boolean) {
+ mIsFullscreen = isFullScreen
+ if (isFullScreen) {
+ hideSystemUI(true)
+ } else {
+ showSystemUI(true)
+ }
+
+ val newAlpha = if (isFullScreen) 0f else 1f
+ top_shadow.animate().alpha(newAlpha).start()
+ video_time_holder.animate().alpha(newAlpha).start()
+ video_seekbar.setOnSeekBarChangeListener(if (mIsFullscreen) null else this)
+ arrayOf(video_toggle_play_pause, video_curr_time, video_duration).forEach {
+ it.isClickable = !mIsFullscreen
+ }
+ }
+
+ private fun initTimeHolder() {
+ var right = 0
+ var bottom = 0
+
+ if (hasNavBar()) {
+ if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
+ bottom += navigationBarHeight
+ } else {
+ right += navigationBarWidth
+ bottom += navigationBarHeight
+ }
+ }
+
+ video_time_holder.setPadding(0, 0, right, bottom)
+ video_seekbar.setOnSeekBarChangeListener(this)
+ video_seekbar!!.max = mDuration
+ video_duration.text = mDuration.getFormattedDuration()
+ video_curr_time.text = mCurrTime.getFormattedDuration()
+ setupTimer()
+ }
+
+ private fun setupTimer() {
+ runOnUiThread(object : Runnable {
+ override fun run() {
+ if (mExoPlayer != null && !mIsDragged && mIsPlaying) {
+ mCurrTime = (mExoPlayer!!.currentPosition / 1000).toInt()
+ video_seekbar.progress = mCurrTime
+ video_curr_time.text = mCurrTime.getFormattedDuration()
+ }
+
+ mTimerHandler.postDelayed(this, 1000)
+ }
+ })
+ }
+
+ private fun skip(forward: Boolean) {
+ if (mExoPlayer == null) {
+ return
+ }
+
+ val curr = mExoPlayer!!.currentPosition
+ val twoPercents = Math.max((mExoPlayer!!.duration / 50).toInt(), MIN_SKIP_LENGTH)
+ val newProgress = if (forward) curr + twoPercents else curr - twoPercents
+ val roundProgress = Math.round(newProgress / 1000f)
+ val limitedProgress = Math.max(Math.min(mExoPlayer!!.duration.toInt(), roundProgress), 0)
+ setPosition(limitedProgress)
+ if (!mIsPlaying) {
+ togglePlayPause()
+ }
+ }
+
+ private fun handleEvent(event: MotionEvent) {
+ when (event.actionMasked) {
+ MotionEvent.ACTION_DOWN -> {
+ mTouchDownX = event.x
+ mTouchDownY = event.y
+ }
+ MotionEvent.ACTION_POINTER_DOWN -> mIgnoreCloseDown = true
+ MotionEvent.ACTION_UP -> {
+ val diffX = mTouchDownX - event.x
+ val diffY = mTouchDownY - event.y
+
+ if (!mIgnoreCloseDown && Math.abs(diffY) > Math.abs(diffX) && diffY < -mCloseDownThreshold) {
+ supportFinishAfterTransition()
+ }
+ mIgnoreCloseDown = false
+ }
+ }
+ }
+
+ private fun cleanup() {
+ pauseVideo()
+ video_curr_time.text = 0.getFormattedDuration()
+ releaseExoPlayer()
+ video_seekbar.progress = 0
+ mTimerHandler.removeCallbacksAndMessages(null)
+ }
+
+ private fun releaseExoPlayer() {
+ mExoPlayer?.stop()
+ Thread {
+ mExoPlayer?.release()
+ mExoPlayer = null
+ }.start()
+ }
+
+ override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
+ if (mExoPlayer != null && fromUser) {
+ setPosition(progress)
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {
+ mIsDragged = true
+ }
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ if (mExoPlayer == null)
+ return
+
+ if (mIsPlaying) {
+ mExoPlayer!!.playWhenReady = true
+ } else {
+ togglePlayPause()
+ }
+
+ mIsDragged = false
+ }
+
+ override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {
+ }
+
+ override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?) = false
+
+ override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
+ Thread {
+ mExoPlayer?.setVideoSurface(Surface(video_surface!!.surfaceTexture))
+ }.start()
+ }
+
+ override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
index 9c96ec30e..7225ab6ab 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
@@ -41,7 +41,6 @@ import com.simplemobiletools.gallery.pro.dialogs.SaveAsDialog
import com.simplemobiletools.gallery.pro.dialogs.SlideshowDialog
import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.fragments.PhotoFragment
-import com.simplemobiletools.gallery.pro.fragments.VideoFragment
import com.simplemobiletools.gallery.pro.fragments.ViewPagerFragment
import com.simplemobiletools.gallery.pro.helpers.*
import com.simplemobiletools.gallery.pro.models.Medium
@@ -129,10 +128,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
setupRotation()
invalidateOptionsMenu()
- if (config.blackBackground) {
- updateStatusbarColor(Color.BLACK)
- }
-
supportActionBar?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
window.statusBarColor = Color.TRANSPARENT
}
@@ -500,8 +495,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
swipeToNextMedium()
}
}, mSlideshowInterval * 1000L)
- } else {
- (getCurrentFragment() as? VideoFragment)!!.playVideo()
}
}
}
@@ -511,18 +504,9 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
private fun getMediaForSlideshow(): Boolean {
- mSlideshowMedia = mMediaFiles.toMutableList()
- if (!config.slideshowIncludePhotos) {
- mSlideshowMedia = mSlideshowMedia.filter { !it.isImage() } as MutableList
- }
-
- if (!config.slideshowIncludeVideos) {
- mSlideshowMedia = mSlideshowMedia.filter { it.isImage() || it.isGIF() } as MutableList
- }
-
- if (!config.slideshowIncludeGIFs) {
- mSlideshowMedia = mSlideshowMedia.filter { !it.isGIF() } as MutableList
- }
+ mSlideshowMedia = mMediaFiles.filter {
+ it.isImage() || (config.slideshowIncludeGIFs && it.isGIF())
+ }.toMutableList()
if (config.slideshowRandomOrder) {
mSlideshowMedia.shuffle()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt
index e20ea1351..0206d451e 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt
@@ -24,6 +24,7 @@ import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.dialogs.DeleteWithRememberDialog
import com.simplemobiletools.gallery.pro.extensions.*
+import com.simplemobiletools.gallery.pro.helpers.SHOW_ALL
import com.simplemobiletools.gallery.pro.helpers.VIEW_TYPE_LIST
import com.simplemobiletools.gallery.pro.interfaces.MediaOperationsListener
import com.simplemobiletools.gallery.pro.models.Medium
@@ -35,7 +36,7 @@ import java.text.SimpleDateFormat
import java.util.*
class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList, val listener: MediaOperationsListener?, val isAGetIntent: Boolean,
- val allowMultiplePicks: Boolean, recyclerView: MyRecyclerView, fastScroller: FastScroller? = null, itemClick: (Any) -> Unit) :
+ val allowMultiplePicks: Boolean, val path: String, recyclerView: MyRecyclerView, fastScroller: FastScroller? = null, itemClick: (Any) -> Unit) :
MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
private val INSTANT_LOAD_DURATION = 2000L
@@ -45,7 +46,8 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList()
private var loadImageInstantly = false
private var delayHandler = Handler(Looper.getMainLooper())
@@ -347,7 +349,12 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList()
foldersToScan.forEach {
- val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken, favoritePaths, getVideoDurations)
+ val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken, favoritePaths, getVideoDurations, false)
media.addAll(newMedia)
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ChangeViewTypeDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ChangeViewTypeDialog.kt
index b534b5c3e..78537069a 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ChangeViewTypeDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ChangeViewTypeDialog.kt
@@ -3,22 +3,47 @@ package com.simplemobiletools.gallery.pro.dialogs
import android.view.View
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
+import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.config
+import com.simplemobiletools.gallery.pro.helpers.SHOW_ALL
import com.simplemobiletools.gallery.pro.helpers.VIEW_TYPE_GRID
import com.simplemobiletools.gallery.pro.helpers.VIEW_TYPE_LIST
import kotlinx.android.synthetic.main.dialog_change_view_type.view.*
-class ChangeViewTypeDialog(val activity: BaseSimpleActivity, val callback: () -> Unit) {
+class ChangeViewTypeDialog(val activity: BaseSimpleActivity, val fromFoldersView: Boolean, val path: String = "", val callback: () -> Unit) {
private var view: View
private var config = activity.config
+ private var pathToUse = if (path.isEmpty()) SHOW_ALL else path
init {
view = activity.layoutInflater.inflate(R.layout.dialog_change_view_type, null).apply {
- val viewToCheck = if (config.viewTypeFolders == VIEW_TYPE_GRID) change_view_type_dialog_radio_grid.id else change_view_type_dialog_radio_list.id
+ val viewToCheck = if (fromFoldersView) {
+ if (config.viewTypeFolders == VIEW_TYPE_GRID) {
+ change_view_type_dialog_radio_grid.id
+ } else {
+ change_view_type_dialog_radio_list.id
+ }
+ } else {
+ val currViewType = config.getFolderViewType(pathToUse)
+ if (currViewType == VIEW_TYPE_GRID) {
+ change_view_type_dialog_radio_grid.id
+ } else {
+ change_view_type_dialog_radio_list.id
+ }
+ }
+
change_view_type_dialog_radio.check(viewToCheck)
- change_view_type_dialog_group_direct_subfolders.isChecked = config.groupDirectSubfolders
+ change_view_type_dialog_group_direct_subfolders.apply {
+ beVisibleIf(fromFoldersView)
+ isChecked = config.groupDirectSubfolders
+ }
+
+ change_view_type_dialog_use_for_this_folder.apply {
+ beVisibleIf(!fromFoldersView)
+ isChecked = config.hasCustomViewType(pathToUse)
+ }
}
AlertDialog.Builder(activity)
@@ -31,8 +56,18 @@ class ChangeViewTypeDialog(val activity: BaseSimpleActivity, val callback: () ->
private fun dialogConfirmed() {
val viewType = if (view.change_view_type_dialog_radio.checkedRadioButtonId == view.change_view_type_dialog_radio_grid.id) VIEW_TYPE_GRID else VIEW_TYPE_LIST
- config.viewTypeFolders = viewType
- config.groupDirectSubfolders = view.change_view_type_dialog_group_direct_subfolders.isChecked
+ if (fromFoldersView) {
+ config.viewTypeFolders = viewType
+ config.groupDirectSubfolders = view.change_view_type_dialog_group_direct_subfolders.isChecked
+ } else {
+ if (view.change_view_type_dialog_use_for_this_folder.isChecked) {
+ config.saveFolderViewType(pathToUse, viewType)
+ } else {
+ config.removeFolderViewType(pathToUse)
+ config.viewTypeFiles = viewType
+ }
+ }
+
callback()
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickMediumDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickMediumDialog.kt
index b1f83527b..f75a8f301 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickMediumDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickMediumDialog.kt
@@ -22,7 +22,8 @@ class PickMediumDialog(val activity: BaseSimpleActivity, val path: String, val c
var dialog: AlertDialog
var shownMedia = ArrayList()
val view = activity.layoutInflater.inflate(R.layout.dialog_medium_picker, null)
- var isGridViewType = activity.config.viewTypeFiles == VIEW_TYPE_GRID
+ val viewType = activity.config.getFolderViewType(if (activity.config.showAll) SHOW_ALL else path)
+ var isGridViewType = viewType == VIEW_TYPE_GRID
init {
(view.media_grid.layoutManager as MyGridLayoutManager).apply {
@@ -64,7 +65,7 @@ class PickMediumDialog(val activity: BaseSimpleActivity, val path: String, val c
return
shownMedia = media
- val adapter = MediaAdapter(activity, shownMedia.clone() as ArrayList, null, true, false, view.media_grid, null) {
+ val adapter = MediaAdapter(activity, shownMedia.clone() as ArrayList, null, true, false, path, view.media_grid, null) {
if (it is Medium) {
callback(it.path)
dialog.dismiss()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/SlideshowDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/SlideshowDialog.kt
index 486b8886d..5e3c5f198 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/SlideshowDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/SlideshowDialog.kt
@@ -5,7 +5,6 @@ import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.hideKeyboard
import com.simplemobiletools.commons.extensions.setupDialogStuff
-import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.config
import com.simplemobiletools.gallery.pro.helpers.SLIDESHOW_DEFAULT_INTERVAL
@@ -29,16 +28,6 @@ class SlideshowDialog(val activity: BaseSimpleActivity, val callback: () -> Unit
activity.hideKeyboard(v)
}
- include_photos_holder.setOnClickListener {
- interval_value.clearFocus()
- include_photos.toggle()
- }
-
- include_videos_holder.setOnClickListener {
- interval_value.clearFocus()
- include_videos.toggle()
- }
-
include_gifs_holder.setOnClickListener {
interval_value.clearFocus()
include_gifs.toggle()
@@ -73,11 +62,6 @@ class SlideshowDialog(val activity: BaseSimpleActivity, val callback: () -> Unit
activity.setupDialogStuff(view, this) {
hideKeyboard()
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
- if (!view.include_photos.isChecked && !view.include_videos.isChecked && !view.include_gifs.isChecked) {
- activity.toast(R.string.no_media_for_slideshow)
- return@setOnClickListener
- }
-
storeValues()
callback()
dismiss()
@@ -90,8 +74,6 @@ class SlideshowDialog(val activity: BaseSimpleActivity, val callback: () -> Unit
val config = activity.config
view.apply {
interval_value.setText(config.slideshowInterval.toString())
- include_photos.isChecked = config.slideshowIncludePhotos
- include_videos.isChecked = config.slideshowIncludeVideos
include_gifs.isChecked = config.slideshowIncludeGIFs
random_order.isChecked = config.slideshowRandomOrder
use_fade.isChecked = config.slideshowUseFade
@@ -107,8 +89,6 @@ class SlideshowDialog(val activity: BaseSimpleActivity, val callback: () -> Unit
activity.config.apply {
slideshowInterval = interval.toInt()
- slideshowIncludePhotos = view.include_photos.isChecked
- slideshowIncludeVideos = view.include_videos.isChecked
slideshowIncludeGIFs = view.include_gifs.isChecked
slideshowRandomOrder = view.random_order.isChecked
slideshowUseFade = view.use_fade.isChecked
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
index 0c8458d92..a8103b206 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
@@ -3,6 +3,7 @@ package com.simplemobiletools.gallery.pro.extensions
import android.app.Activity
import android.content.Intent
import android.provider.MediaStore
+import android.util.DisplayMetrics
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.simplemobiletools.commons.activities.BaseSimpleActivity
@@ -79,7 +80,8 @@ fun SimpleActivity.launchAbout() {
FAQItem(R.string.faq_12_title, R.string.faq_12_text),
FAQItem(R.string.faq_13_title, R.string.faq_13_text),
FAQItem(R.string.faq_14_title, R.string.faq_14_text),
- FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons))
+ FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons),
+ FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons))
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, true)
}
@@ -291,3 +293,15 @@ fun BaseSimpleActivity.updateFavoritePaths(fileDirItems: ArrayList,
}
}.start()
}
+
+fun Activity.hasNavBar(): Boolean {
+ val display = windowManager.defaultDisplay
+
+ val realDisplayMetrics = DisplayMetrics()
+ display.getRealMetrics(realDisplayMetrics)
+
+ val displayMetrics = DisplayMetrics()
+ display.getMetrics(displayMetrics)
+
+ return (realDisplayMetrics.widthPixels - displayMetrics.widthPixels > 0) || (realDisplayMetrics.heightPixels - displayMetrics.heightPixels > 0)
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
index c8a7f5b58..3f6b336de 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
@@ -35,6 +35,9 @@ import com.simplemobiletools.gallery.pro.svg.SvgSoftwareLayerSetter
import com.simplemobiletools.gallery.pro.views.MySquareImageView
import pl.droidsonroids.gif.GifDrawable
import java.io.File
+import java.io.FileInputStream
+import java.nio.ByteBuffer
+import java.nio.channels.FileChannel
import java.util.HashSet
import java.util.LinkedHashSet
import kotlin.Comparator
@@ -170,10 +173,6 @@ fun Context.getSortedDirectories(source: ArrayList): ArrayList o1.taken.compareTo(o2.taken)
}
- if (result == 0) {
- result = AlphanumericComparator().compare(o1.path.toLowerCase(), o2.path.toLowerCase())
- }
-
if (sorting and SORT_DESCENDING != 0) {
result *= -1
}
@@ -627,3 +626,60 @@ fun Context.updateWidgets() {
}
}
}
+
+// based on https://github.com/sannies/mp4parser/blob/master/examples/src/main/java/com/google/code/mp4parser/example/PrintStructure.java
+fun Context.parseFileChannel(path: String, fc: FileChannel, level: Int, start: Long, end: Long, callback: () -> Unit) {
+ val FILE_CHANNEL_CONTAINERS = arrayListOf("moov", "trak", "mdia", "minf", "udta", "stbl")
+ try {
+ var iteration = 0
+ var currEnd = end
+ fc.position(start)
+ if (currEnd <= 0) {
+ currEnd = start + fc.size()
+ }
+
+ while (currEnd - fc.position() > 8) {
+ // just a check to avoid deadloop at some videos
+ if (iteration++ > 50) {
+ return
+ }
+
+ val begin = fc.position()
+ val byteBuffer = ByteBuffer.allocate(8)
+ fc.read(byteBuffer)
+ byteBuffer.rewind()
+ val size = IsoTypeReader.readUInt32(byteBuffer)
+ val type = IsoTypeReader.read4cc(byteBuffer)
+ val newEnd = begin + size
+
+ if (type == "uuid") {
+ val fis = FileInputStream(File(path))
+ fis.skip(begin)
+
+ val sb = StringBuilder()
+ val buffer = ByteArray(1024)
+ while (true) {
+ val n = fis.read(buffer)
+ if (n != -1) {
+ sb.append(String(buffer, 0, n))
+ } else {
+ break
+ }
+ }
+
+ val xmlString = sb.toString().toLowerCase()
+ if (xmlString.contains("gspherical:projectiontype>equirectangular") || xmlString.contains("gspherical:projectiontype=\"equirectangular\"")) {
+ callback.invoke()
+ }
+ return
+ }
+
+ if (FILE_CHANNEL_CONTAINERS.contains(type)) {
+ parseFileChannel(path, fc, level + 1, begin + 8, newEnd, callback)
+ }
+
+ fc.position(newEnd)
+ }
+ } catch (ignored: Exception) {
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
index 372bc7b0c..847d5f95a 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
@@ -18,12 +18,12 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.Glide
-import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
+import com.bumptech.glide.request.target.Target
import com.davemorrissey.labs.subscaleview.ImageSource
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.davemorrissey.labs.subscaleview.decoder.DecoderFactory
@@ -55,7 +55,7 @@ import java.util.*
class PhotoFragment : ViewPagerFragment() {
private val DEFAULT_DOUBLE_TAP_ZOOM = 2f
- private val ZOOMABLE_VIEW_LOAD_DELAY = 300L
+ private val ZOOMABLE_VIEW_LOAD_DELAY = 150L
// devices with good displays, but the rest of the hardware not good enough for them
private val WEIRD_DEVICES = arrayListOf(
@@ -119,10 +119,7 @@ class PhotoFragment : ViewPagerFragment() {
}
}
- if (ViewPagerActivity.screenWidth == 0 || ViewPagerActivity.screenHeight == 0) {
- measureScreen()
- }
-
+ checkScreenDimensions()
storeStateVariables()
if (!isFragmentVisible && activity is PhotoActivity) {
isFragmentVisible = true
@@ -227,6 +224,12 @@ class PhotoFragment : ViewPagerFragment() {
}
}
+ private fun checkScreenDimensions() {
+ if (ViewPagerActivity.screenWidth == 0 || ViewPagerActivity.screenHeight == 0) {
+ measureScreen()
+ }
+ }
+
private fun measureScreen() {
val metrics = DisplayMetrics()
activity!!.windowManager.defaultDisplay.getRealMetrics(metrics)
@@ -297,6 +300,7 @@ class PhotoFragment : ViewPagerFragment() {
}
private fun loadBitmap(degrees: Int = 0) {
+ checkScreenDimensions()
var pathToLoad = if (medium.path.startsWith("content://")) medium.path else "file://${medium.path}"
pathToLoad = pathToLoad.replace("%", "%25").replace("#", "%23")
@@ -350,7 +354,7 @@ class PhotoFragment : ViewPagerFragment() {
.listener(object : RequestListener {
override fun onLoadFailed(e: GlideException?, model: Any?, target: com.bumptech.glide.request.target.Target?, isFirstResource: Boolean) = false
- override fun onResourceReady(resource: Bitmap?, model: Any?, target: com.bumptech.glide.request.target.Target?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
+ override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target?, dataSource: com.bumptech.glide.load.DataSource?, isFirstResource: Boolean): Boolean {
if (isFragmentVisible) {
scheduleZoomableView()
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt
index 5d28ff477..586edfaa4 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt
@@ -2,75 +2,33 @@ package com.simplemobiletools.gallery.pro.fragments
import android.content.Intent
import android.content.res.Configuration
-import android.graphics.Point
-import android.graphics.SurfaceTexture
-import android.net.Uri
import android.os.Bundle
-import android.os.Handler
-import android.util.DisplayMetrics
-import android.view.*
-import android.view.animation.AnimationUtils
-import android.widget.SeekBar
-import android.widget.TextView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
import com.bumptech.glide.Glide
-import com.google.android.exoplayer2.*
-import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
-import com.google.android.exoplayer2.source.ExtractorMediaSource
-import com.google.android.exoplayer2.source.TrackGroupArray
-import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
-import com.google.android.exoplayer2.trackselection.TrackSelectionArray
-import com.google.android.exoplayer2.upstream.ContentDataSource
-import com.google.android.exoplayer2.upstream.DataSource
-import com.google.android.exoplayer2.upstream.DataSpec
-import com.google.android.exoplayer2.upstream.FileDataSource
-import com.google.android.exoplayer2.video.VideoListener
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.PanoramaVideoActivity
-import com.simplemobiletools.gallery.pro.activities.VideoActivity
import com.simplemobiletools.gallery.pro.extensions.*
-import com.simplemobiletools.gallery.pro.helpers.*
+import com.simplemobiletools.gallery.pro.helpers.MEDIUM
+import com.simplemobiletools.gallery.pro.helpers.PATH
import com.simplemobiletools.gallery.pro.models.Medium
import com.simplemobiletools.gallery.pro.views.MediaSideScroll
-import kotlinx.android.synthetic.main.bottom_video_time_holder.view.*
import kotlinx.android.synthetic.main.pager_video_item.view.*
import java.io.File
import java.io.FileInputStream
-import java.nio.ByteBuffer
-import java.nio.channels.FileChannel
-class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, SeekBar.OnSeekBarChangeListener {
- private val PROGRESS = "progress"
- private val FILE_CHANNEL_CONTAINERS = arrayListOf("moov", "trak", "mdia", "minf", "udta", "stbl")
-
- private var mTextureView: TextureView? = null
- private var mCurrTimeView: TextView? = null
- private var mSeekBar: SeekBar? = null
- private var mExoPlayer: SimpleExoPlayer? = null
- private var mVideoSize = Point(0, 0)
- private var mTimerHandler = Handler()
- private var mHidePlayPauseHandler = Handler()
-
- private var mIsPlaying = false
- private var mIsDragged = false
+class VideoFragment : ViewPagerFragment() {
private var mIsFullscreen = false
- private var mIsFragmentVisible = false
private var mWasFragmentInit = false
- private var mIsExoPlayerInitialized = false
private var mIsPanorama = false
- private var mWasVideoStarted = false
- private var mCurrTime = 0
- private var mDuration = 0
private var mStoredShowExtendedDetails = false
private var mStoredHideExtendedDetails = false
private var mStoredBottomActions = true
private var mStoredExtendedDetails = 0
- private var mStoredRememberLastVideoPosition = false
- private var mStoredLastVideoPath = ""
- private var mStoredLastVideoPosition = 0
- private lateinit var mTimeHolder: View
private lateinit var mBrightnessSideScroll: MediaSideScroll
private lateinit var mVolumeSideScroll: MediaSideScroll
@@ -81,30 +39,19 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
mView = inflater.inflate(R.layout.pager_video_item, container, false).apply {
instant_prev_item.setOnClickListener { listener?.goToPrevItem() }
instant_next_item.setOnClickListener { listener?.goToNextItem() }
- video_curr_time.setOnClickListener { skip(false) }
- video_duration.setOnClickListener { skip(true) }
video_holder.setOnClickListener { toggleFullscreen() }
video_preview.setOnClickListener { toggleFullscreen() }
panorama_outline.setOnClickListener { openPanorama() }
+ video_play_outline.setOnClickListener { launchVideoPlayer() }
- // adding an empty click listener just to avoid ripple animation at toggling fullscreen
- video_seekbar.setOnClickListener { }
-
- mTimeHolder = video_time_holder
mBrightnessSideScroll = video_brightness_controller
mVolumeSideScroll = video_volume_controller
- mCurrTimeView = video_curr_time
if (context.config.allowDownGesture) {
video_preview.setOnTouchListener { v, event ->
handleEvent(event)
false
}
-
- video_surface.setOnTouchListener { v, event ->
- handleEvent(event)
- false
- }
}
}
@@ -112,46 +59,22 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
medium = arguments!!.getSerializable(MEDIUM) as Medium
Glide.with(context!!).load(medium.path).into(mView.video_preview)
- // setMenuVisibility is not called at VideoActivity (third party intent)
- if (!mIsFragmentVisible && activity is VideoActivity) {
- mIsFragmentVisible = true
- }
-
mIsFullscreen = activity!!.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN
- initTimeHolder()
checkIfPanorama()
- medium.path.getVideoResolution()?.apply {
- mVideoSize.x = x
- mVideoSize.y = y
- if (mIsPanorama) {
- mView.apply {
- panorama_outline.beVisible()
- video_play_outline.beGone()
- mVolumeSideScroll.beGone()
- mBrightnessSideScroll.beGone()
- Glide.with(context!!).load(medium.path).into(video_preview)
- }
+ if (mIsPanorama) {
+ mView.apply {
+ panorama_outline.beVisible()
+ video_play_outline.beGone()
+ mVolumeSideScroll.beGone()
+ mBrightnessSideScroll.beGone()
+ Glide.with(context!!).load(medium.path).into(video_preview)
}
}
if (!mIsPanorama) {
- setupPlayer()
- if (savedInstanceState != null) {
- mCurrTime = savedInstanceState.getInt(PROGRESS)
- }
-
- checkFullscreen()
mWasFragmentInit = true
- mExoPlayer = ExoPlayerFactory.newSimpleInstance(context)
- mExoPlayer!!.seekParameters = SeekParameters.CLOSEST_SYNC
- initExoPlayerListeners()
-
- if (mVideoSize.x != 0 && mVideoSize.y != 0) {
- setVideoSize()
- }
-
mView.apply {
mBrightnessSideScroll.initialize(activity!!, slide_info, true, container) { x, y ->
video_holder.performClick()
@@ -160,22 +83,10 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
mVolumeSideScroll.initialize(activity!!, slide_info, false, container) { x, y ->
video_holder.performClick()
}
-
- video_surface.onGlobalLayout {
- if (mIsFragmentVisible && context?.config?.autoplayVideos == true) {
- playVideo()
- }
- }
}
}
- setupVideoDuration()
- if (mStoredRememberLastVideoPosition) {
- setLastVideoSavedPosition()
- }
-
updateInstantSwitchWidths()
-
return mView
}
@@ -197,47 +108,16 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
checkExtendedDetails()
}
- if (config.bottomActions != mStoredBottomActions) {
- initTimeHolder()
- }
-
- mTimeHolder.setBackgroundResource(if (config.bottomActions) 0 else R.drawable.gradient_background)
storeStateVariables()
}
override fun onPause() {
super.onPause()
- pauseVideo()
- if (mStoredRememberLastVideoPosition && mIsFragmentVisible && mWasVideoStarted) {
- saveVideoProgress()
- }
-
storeStateVariables()
}
- override fun onDestroy() {
- super.onDestroy()
- if (activity?.isChangingConfigurations == false) {
- cleanup()
- }
- }
-
- override fun setMenuVisibility(menuVisible: Boolean) {
- super.setMenuVisibility(menuVisible)
- if (mIsFragmentVisible && !menuVisible) {
- pauseVideo()
- }
-
- mIsFragmentVisible = menuVisible
- if (mWasFragmentInit && menuVisible && context?.config?.autoplayVideos == true) {
- playVideo()
- }
- }
-
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
- setVideoSize()
- initTimeHolder()
checkExtendedDetails()
updateInstantSwitchWidths()
}
@@ -248,365 +128,17 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
mStoredHideExtendedDetails = hideExtendedDetails
mStoredExtendedDetails = extendedDetails
mStoredBottomActions = bottomActions
- mStoredRememberLastVideoPosition = rememberLastVideoPosition
- mStoredLastVideoPath = lastVideoPath
- mStoredLastVideoPosition = lastVideoPosition
}
}
- private fun setupPlayer() {
- if (activity == null)
- return
-
- mView.video_play_outline.setOnClickListener { togglePlayPause() }
-
- mTextureView = mView.video_surface
- mTextureView!!.setOnClickListener { toggleFullscreen() }
- mTextureView!!.surfaceTextureListener = this
-
- checkExtendedDetails()
- }
-
- private fun saveVideoProgress() {
- if (!videoEnded()) {
- mStoredLastVideoPosition = mExoPlayer!!.currentPosition.toInt() / 1000
- mStoredLastVideoPath = medium.path
- }
-
- context!!.config.apply {
- lastVideoPosition = mStoredLastVideoPosition
- lastVideoPath = mStoredLastVideoPath
- }
- }
-
- private fun initExoPlayer() {
- val isContentUri = medium.path.startsWith("content://")
- val uri = if (isContentUri) Uri.parse(medium.path) else Uri.fromFile(File(medium.path))
- val dataSpec = DataSpec(uri)
- val fileDataSource = if (isContentUri) ContentDataSource(context) else FileDataSource()
- try {
- fileDataSource.open(dataSpec)
- } catch (e: Exception) {
- activity?.showErrorToast(e)
- }
-
- val factory = DataSource.Factory { fileDataSource }
- val audioSource = ExtractorMediaSource(fileDataSource.uri, factory, DefaultExtractorsFactory(), null, null)
- mExoPlayer!!.audioStreamType = C.STREAM_TYPE_MUSIC
- mExoPlayer!!.prepare(audioSource)
- }
-
- private fun initExoPlayerListeners() {
- mExoPlayer!!.addListener(object : Player.EventListener {
- override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {}
-
- override fun onSeekProcessed() {}
-
- override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {}
-
- override fun onPlayerError(error: ExoPlaybackException?) {
- mIsExoPlayerInitialized = false
- }
-
- override fun onLoadingChanged(isLoading: Boolean) {}
-
- override fun onPositionDiscontinuity(reason: Int) {}
-
- override fun onRepeatModeChanged(repeatMode: Int) {}
-
- override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {}
-
- override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {}
-
- override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
- mIsExoPlayerInitialized = playbackState == Player.STATE_READY || playbackState == Player.STATE_ENDED
- when (playbackState) {
- Player.STATE_READY -> videoPrepared()
- Player.STATE_ENDED -> videoCompleted()
- }
- }
- })
-
- mExoPlayer!!.addVideoListener(object : VideoListener {
- override fun onVideoSizeChanged(width: Int, height: Int, unappliedRotationDegrees: Int, pixelWidthHeightRatio: Float) {
- mVideoSize.x = width
- mVideoSize.y = height
- setVideoSize()
- }
-
- override fun onRenderedFirstFrame() {}
- })
+ private fun launchVideoPlayer() {
+ activity!!.openPath(medium.path, false)
}
private fun toggleFullscreen() {
listener?.fragmentClicked()
}
- private fun setLastVideoSavedPosition() {
- if (mStoredLastVideoPath == medium.path && mStoredLastVideoPosition > 0) {
- setPosition(mStoredLastVideoPosition)
- }
- }
-
- private fun initTimeHolder() {
- val left = 0
- val top = 0
- var right = 0
- var bottom = 0
-
- if (hasNavBar()) {
- if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
- bottom += context!!.navigationBarHeight
- } else {
- right += context!!.navigationBarWidth
- bottom += context!!.navigationBarHeight
- }
- }
-
- if (context!!.config.bottomActions) {
- bottom += resources.getDimension(R.dimen.bottom_actions_height).toInt()
- }
-
- mTimeHolder.setPadding(left, top, right, bottom)
-
- mSeekBar = mView.video_seekbar
- mSeekBar!!.setOnSeekBarChangeListener(this)
- mTimeHolder.beInvisibleIf(mIsFullscreen)
- }
-
- private fun hasNavBar(): Boolean {
- val display = context!!.windowManager.defaultDisplay
-
- val realDisplayMetrics = DisplayMetrics()
- display.getRealMetrics(realDisplayMetrics)
-
- val displayMetrics = DisplayMetrics()
- display.getMetrics(displayMetrics)
-
- return (realDisplayMetrics.widthPixels - displayMetrics.widthPixels > 0) || (realDisplayMetrics.heightPixels - displayMetrics.heightPixels > 0)
- }
-
- private fun setupTimeHolder() {
- mSeekBar!!.max = mDuration
- mView.video_duration.text = mDuration.getFormattedDuration()
- setupTimer()
- }
-
- private fun setupTimer() {
- activity!!.runOnUiThread(object : Runnable {
- override fun run() {
- if (mExoPlayer != null && !mIsDragged && mIsPlaying) {
- mCurrTime = (mExoPlayer!!.currentPosition / 1000).toInt()
- mSeekBar!!.progress = mCurrTime
- mCurrTimeView!!.text = mCurrTime.getFormattedDuration()
- }
-
- mTimerHandler.postDelayed(this, 1000)
- }
- })
- }
-
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- outState.putInt(PROGRESS, mCurrTime)
- }
-
- private fun checkFullscreen() {
- if (activity == null) {
- return
- }
-
- var anim = android.R.anim.fade_in
- if (mIsFullscreen) {
- anim = android.R.anim.fade_out
- mSeekBar!!.setOnSeekBarChangeListener(null)
- } else {
- mSeekBar!!.setOnSeekBarChangeListener(this)
- }
-
- AnimationUtils.loadAnimation(activity, anim).apply {
- duration = 150
- fillAfter = true
- mTimeHolder.startAnimation(this)
- }
- }
-
- private fun togglePlayPause() {
- if (activity == null || !isAdded)
- return
-
- mIsPlaying = !mIsPlaying
- mHidePlayPauseHandler.removeCallbacksAndMessages(null)
- if (mIsPlaying) {
- playVideo()
- } else {
- pauseVideo()
- }
- }
-
- fun playVideo() {
- if (mExoPlayer == null) {
- return
- }
-
- if (mView.video_preview.isVisible()) {
- mView.video_preview.beGone()
- initExoPlayer()
- }
-
- val wasEnded = videoEnded()
- if (wasEnded) {
- setPosition(0)
- }
-
- if (mStoredRememberLastVideoPosition) {
- setLastVideoSavedPosition()
- clearLastVideoSavedProgress()
- }
-
- if (!wasEnded || context?.config?.loopVideos == false) {
- mView.video_play_outline.setImageResource(R.drawable.ic_pause)
- mView.video_play_outline.alpha = PLAY_PAUSE_VISIBLE_ALPHA
- }
-
- schedulePlayPauseFadeOut()
- mWasVideoStarted = true
- mIsPlaying = true
- mExoPlayer?.playWhenReady = true
- activity!!.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
- }
-
- private fun clearLastVideoSavedProgress() {
- mStoredLastVideoPosition = 0
- mStoredLastVideoPath = ""
- }
-
- private fun pauseVideo() {
- if (mExoPlayer == null) {
- return
- }
-
- mIsPlaying = false
- if (!videoEnded()) {
- mExoPlayer?.playWhenReady = false
- }
-
- mView.video_play_outline?.setImageResource(R.drawable.ic_play)
- mView.video_play_outline?.alpha = PLAY_PAUSE_VISIBLE_ALPHA
- schedulePlayPauseFadeOut()
- activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
- }
-
- private fun schedulePlayPauseFadeOut() {
- mHidePlayPauseHandler.removeCallbacksAndMessages(null)
- mHidePlayPauseHandler.postDelayed({
- mView.video_play_outline.animate().alpha(0f).start()
- }, HIDE_PLAY_PAUSE_DELAY)
- }
-
- private fun videoEnded(): Boolean {
- val currentPos = mExoPlayer?.currentPosition ?: 0
- val duration = mExoPlayer?.duration ?: 0
- return currentPos != 0L && currentPos >= duration
- }
-
- private fun setPosition(seconds: Int) {
- mExoPlayer?.seekTo(seconds * 1000L)
- mSeekBar!!.progress = seconds
- mCurrTimeView!!.text = seconds.getFormattedDuration()
- }
-
- private fun setupVideoDuration() {
- mDuration = medium.path.getVideoDuration()
- setupTimeHolder()
- setPosition(0)
- }
-
- private fun videoPrepared() {
- if (mDuration == 0) {
- mDuration = (mExoPlayer!!.duration / 1000).toInt()
- setupTimeHolder()
- setPosition(mCurrTime)
-
- if (mIsFragmentVisible && (context!!.config.autoplayVideos)) {
- playVideo()
- }
- }
- }
-
- private fun videoCompleted() {
- if (!isAdded || mExoPlayer == null) {
- return
- }
-
- mCurrTime = (mExoPlayer!!.duration / 1000).toInt()
- if (listener?.videoEnded() == false && context!!.config.loopVideos) {
- playVideo()
- } else {
- mSeekBar!!.progress = mSeekBar!!.max
- mCurrTimeView!!.text = mDuration.getFormattedDuration()
- pauseVideo()
- }
- }
-
- private fun cleanup() {
- pauseVideo()
- mCurrTimeView?.text = 0.getFormattedDuration()
- releaseExoPlayer()
- mSeekBar?.progress = 0
- mTimerHandler.removeCallbacksAndMessages(null)
- mHidePlayPauseHandler.removeCallbacksAndMessages(null)
- mTextureView = null
- }
-
- private fun releaseExoPlayer() {
- mExoPlayer?.stop()
- Thread {
- mExoPlayer?.release()
- mExoPlayer = null
- }.start()
- }
-
- override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {}
-
- override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {}
-
- override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?) = false
-
- override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
- Thread {
- mExoPlayer?.setVideoSurface(Surface(mTextureView!!.surfaceTexture))
- }.start()
- }
-
- private fun setVideoSize() {
- if (activity == null || mTextureView == null)
- return
-
- val videoProportion = mVideoSize.x.toFloat() / mVideoSize.y.toFloat()
- val display = activity!!.windowManager.defaultDisplay
- val screenWidth: Int
- val screenHeight: Int
-
- val realMetrics = DisplayMetrics()
- display.getRealMetrics(realMetrics)
- screenWidth = realMetrics.widthPixels
- screenHeight = realMetrics.heightPixels
-
- val screenProportion = screenWidth.toFloat() / screenHeight.toFloat()
-
- mTextureView!!.layoutParams.apply {
- if (videoProportion > screenProportion) {
- width = screenWidth
- height = (screenWidth.toFloat() / videoProportion).toInt()
- } else {
- width = (videoProportion * screenHeight.toFloat()).toInt()
- height = screenHeight
- }
- mTextureView!!.layoutParams = this
- }
- }
-
private fun checkExtendedDetails() {
if (context!!.config.showExtendedDetails) {
mView.video_details.apply {
@@ -628,118 +160,17 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
}
}
- private fun skip(forward: Boolean) {
- if (mExoPlayer == null || mIsPanorama) {
- return
- }
-
- val curr = mExoPlayer!!.currentPosition
- val twoPercents = Math.max((mExoPlayer!!.duration / 50).toInt(), MIN_SKIP_LENGTH)
- val newProgress = if (forward) curr + twoPercents else curr - twoPercents
- val roundProgress = Math.round(newProgress / 1000f)
- val limitedProgress = Math.max(Math.min(mExoPlayer!!.duration.toInt(), roundProgress), 0)
- setPosition(limitedProgress)
- if (!mIsPlaying) {
- togglePlayPause()
- }
- }
-
- override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
- if (mExoPlayer != null && fromUser) {
- setPosition(progress)
- }
- }
-
- override fun onStartTrackingTouch(seekBar: SeekBar) {
- if (mExoPlayer == null)
- return
-
- mExoPlayer!!.playWhenReady = false
- mIsDragged = true
- }
-
- override fun onStopTrackingTouch(seekBar: SeekBar) {
- if (mIsPanorama) {
- openPanorama()
- return
- }
-
- if (mExoPlayer == null)
- return
-
- if (mIsPlaying) {
- mExoPlayer!!.playWhenReady = true
- } else {
- togglePlayPause()
- }
-
- mIsDragged = false
- }
-
private fun checkIfPanorama() {
try {
val fis = FileInputStream(File(medium.path))
- parseFileChannel(fis.channel, 0, 0, 0)
+ context!!.parseFileChannel(medium.path, fis.channel, 0, 0, 0) {
+ mIsPanorama = true
+ }
} catch (ignored: Exception) {
} catch (ignored: OutOfMemoryError) {
}
}
- // based on https://github.com/sannies/mp4parser/blob/master/examples/src/main/java/com/google/code/mp4parser/example/PrintStructure.java
- private fun parseFileChannel(fc: FileChannel, level: Int, start: Long, end: Long) {
- try {
- var iteration = 0
- var currEnd = end
- fc.position(start)
- if (currEnd <= 0) {
- currEnd = start + fc.size()
- }
-
- while (currEnd - fc.position() > 8) {
- // just a check to avoid deadloop at some videos
- if (iteration++ > 50) {
- return
- }
-
- val begin = fc.position()
- val byteBuffer = ByteBuffer.allocate(8)
- fc.read(byteBuffer)
- byteBuffer.rewind()
- val size = IsoTypeReader.readUInt32(byteBuffer)
- val type = IsoTypeReader.read4cc(byteBuffer)
- val newEnd = begin + size
-
- if (type == "uuid") {
- val fis = FileInputStream(File(medium.path))
- fis.skip(begin)
-
- val sb = StringBuilder()
- val buffer = ByteArray(1024)
- while (true) {
- val n = fis.read(buffer)
- if (n != -1) {
- sb.append(String(buffer, 0, n))
- } else {
- break
- }
- }
-
- val xmlString = sb.toString().toLowerCase()
- mIsPanorama = xmlString.contains("gspherical:projectiontype>equirectangular") ||
- xmlString.contains("gspherical:projectiontype=\"equirectangular\"")
- return
- }
-
- if (FILE_CHANNEL_CONTAINERS.contains(type)) {
- parseFileChannel(fc, level + 1, begin + 8, newEnd)
- }
-
- fc.position(newEnd)
- }
- } catch (ignored: Exception) {
- }
- }
-
private fun openPanorama() {
Intent(context, PanoramaVideoActivity::class.java).apply {
putExtra(PATH, medium.path)
@@ -755,7 +186,6 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
override fun fullscreenToggled(isFullscreen: Boolean) {
mIsFullscreen = isFullscreen
- checkFullscreen()
mView.video_details.apply {
if (mStoredShowExtendedDetails && isVisible()) {
animate().y(getExtendedDetailsY(height))
@@ -769,7 +199,6 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private fun getExtendedDetailsY(height: Int): Float {
val smallMargin = resources.getDimension(R.dimen.small_margin)
- val fullscreenOffset = smallMargin + if (mIsFullscreen) 0 else mTimeHolder.height
- return context!!.realScreenSize.y.toFloat() - height - fullscreenOffset
+ return context!!.realScreenSize.y.toFloat() - height - smallMargin
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
index cdb7ef840..1b479de80 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
@@ -59,6 +59,22 @@ class Config(context: Context) : BaseConfig(context) {
fun hasCustomGrouping(path: String) = prefs.contains(GROUP_FOLDER_PREFIX + path.toLowerCase())
+ fun saveFolderViewType(path: String, value: Int) {
+ if (path.isEmpty()) {
+ viewTypeFiles = value
+ } else {
+ prefs.edit().putInt(VIEW_TYPE_PREFIX + path.toLowerCase(), value).apply()
+ }
+ }
+
+ fun getFolderViewType(path: String) = prefs.getInt(VIEW_TYPE_PREFIX + path.toLowerCase(), viewTypeFiles)
+
+ fun removeFolderViewType(path: String) {
+ prefs.edit().remove(VIEW_TYPE_PREFIX + path.toLowerCase()).apply()
+ }
+
+ fun hasCustomViewType(path: String) = prefs.contains(VIEW_TYPE_PREFIX + path.toLowerCase())
+
var wasHideFolderTooltipShown: Boolean
get() = prefs.getBoolean(HIDE_FOLDER_TOOLTIP_SHOWN, false)
set(wasShown) = prefs.edit().putBoolean(HIDE_FOLDER_TOOLTIP_SHOWN, wasShown).apply()
@@ -137,7 +153,7 @@ class Config(context: Context) : BaseConfig(context) {
set(includedFolders) = prefs.edit().remove(INCLUDED_FOLDERS).putStringSet(INCLUDED_FOLDERS, includedFolders).apply()
var autoplayVideos: Boolean
- get() = prefs.getBoolean(AUTOPLAY_VIDEOS, false)
+ get() = prefs.getBoolean(AUTOPLAY_VIDEOS, true)
set(autoplay) = prefs.edit().putBoolean(AUTOPLAY_VIDEOS, autoplay).apply()
var animateGifs: Boolean
@@ -265,14 +281,6 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getInt(SLIDESHOW_INTERVAL, SLIDESHOW_DEFAULT_INTERVAL)
set(slideshowInterval) = prefs.edit().putInt(SLIDESHOW_INTERVAL, slideshowInterval).apply()
- var slideshowIncludePhotos: Boolean
- get() = prefs.getBoolean(SLIDESHOW_INCLUDE_PHOTOS, true)
- set(slideshowIncludePhotos) = prefs.edit().putBoolean(SLIDESHOW_INCLUDE_PHOTOS, slideshowIncludePhotos).apply()
-
- var slideshowIncludeVideos: Boolean
- get() = prefs.getBoolean(SLIDESHOW_INCLUDE_VIDEOS, false)
- set(slideshowIncludeVideos) = prefs.edit().putBoolean(SLIDESHOW_INCLUDE_VIDEOS, slideshowIncludeVideos).apply()
-
var slideshowIncludeGIFs: Boolean
get() = prefs.getBoolean(SLIDESHOW_INCLUDE_GIFS, false)
set(slideshowIncludeGIFs) = prefs.edit().putBoolean(SLIDESHOW_INCLUDE_GIFS, slideshowIncludeGIFs).apply()
@@ -384,8 +392,10 @@ class Config(context: Context) : BaseConfig(context) {
fun getEverShownFolders() = hashSetOf(
internalStoragePath,
- Environment.DIRECTORY_DCIM,
- Environment.DIRECTORY_PICTURES
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).absolutePath,
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath,
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).absolutePath,
+ "${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).absolutePath}/Screenshots"
)
var showRecycleBinAtFolders: Boolean
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
index 95a068eb0..16e61ddc8 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
@@ -6,6 +6,7 @@ import com.simplemobiletools.commons.helpers.MONTH_SECONDS
const val DIRECTORY_SORT_ORDER = "directory_sort_order"
const val SORT_FOLDER_PREFIX = "sort_folder_"
const val GROUP_FOLDER_PREFIX = "group_folder_"
+const val VIEW_TYPE_PREFIX = "view_type_folder_"
const val SHOW_HIDDEN_MEDIA = "show_hidden_media"
const val TEMPORARILY_SHOW_HIDDEN = "temporarily_show_hidden"
const val IS_THIRD_PARTY_INTENT = "is_third_party_intent"
@@ -76,8 +77,6 @@ const val SHOW_WIDGET_FOLDER_NAME = "show_widget_folder_name"
// slideshow
const val SLIDESHOW_INTERVAL = "slideshow_interval"
-const val SLIDESHOW_INCLUDE_PHOTOS = "slideshow_include_photos"
-const val SLIDESHOW_INCLUDE_VIDEOS = "slideshow_include_videos"
const val SLIDESHOW_INCLUDE_GIFS = "slideshow_include_gifs"
const val SLIDESHOW_RANDOM_ORDER = "slideshow_random_order"
const val SLIDESHOW_USE_FADE = "slideshow_use_fade"
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
index b57e37c70..3978d0a49 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
@@ -19,22 +19,27 @@ class MediaFetcher(val context: Context) {
var shouldStop = false
fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean, getProperDateTaken: Boolean, favoritePaths: ArrayList,
- getVideoDurations: Boolean): ArrayList {
+ getVideoDurations: Boolean, sortMedia: Boolean = true): ArrayList {
val filterMedia = context.config.filterMedia
if (filterMedia == 0) {
return ArrayList()
}
val curMedia = ArrayList()
- if (curPath.startsWith(OTG_PATH)) {
- val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia, favoritePaths, getVideoDurations)
- curMedia.addAll(newMedia)
+ if (curPath.startsWith(OTG_PATH, true)) {
+ if (context.hasOTGConnected()) {
+ val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia, favoritePaths, getVideoDurations)
+ curMedia.addAll(newMedia)
+ }
} else {
val newMedia = getMediaInFolder(curPath, isPickImage, isPickVideo, filterMedia, getProperDateTaken, favoritePaths, getVideoDurations)
curMedia.addAll(newMedia)
}
- sortMedia(curMedia, context.config.getFileSorting(curPath))
+ if (sortMedia) {
+ sortMedia(curMedia, context.config.getFileSorting(curPath))
+ }
+
return curMedia
}
@@ -177,27 +182,27 @@ class MediaFetcher(val context: Context) {
ArrayList()
}
+ val doExtraCheck = context.config.doExtraCheck
+ val showHidden = context.config.shouldShowHidden
+ val dateTakens = if (getProperDateTaken && folder != FAVORITES && folder != RECYCLE_BIN) getFolderDateTakens(folder) else HashMap()
+
val files = when (folder) {
- FAVORITES -> favoritePaths.map { File(it) }.toTypedArray()
+ FAVORITES -> favoritePaths.filter { showHidden || !it.contains("/.") }.map { File(it) }.toTypedArray()
RECYCLE_BIN -> deletedMedia.map { File(it.path) }.toTypedArray()
else -> File(folder).listFiles() ?: return media
}
- val doExtraCheck = context.config.doExtraCheck
- val showHidden = context.config.shouldShowHidden
- val dateTakens = if (getProperDateTaken) getFolderDateTakens(folder) else HashMap()
-
for (file in files) {
if (shouldStop) {
break
}
- val filename = file.name
- 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()
- val isSvg = if (isImage || isVideo || isGif || isRaw) false else filename.isSvg()
+ val path = file.absolutePath
+ val isImage = path.isImageFast()
+ val isVideo = if (isImage) false else path.isVideoFast()
+ val isGif = if (isImage || isVideo) false else path.isGif()
+ val isRaw = if (isImage || isVideo || isGif) false else path.isRawFast()
+ val isSvg = if (isImage || isVideo || isGif || isRaw) false else path.isSvg()
if (!isImage && !isVideo && !isGif && !isRaw && !isSvg)
continue
@@ -217,6 +222,7 @@ class MediaFetcher(val context: Context) {
if (isSvg && filterMedia and TYPE_SVGS == 0)
continue
+ val filename = file.name
if (!showHidden && filename.startsWith('.'))
continue
@@ -224,7 +230,6 @@ class MediaFetcher(val context: Context) {
if (size <= 0L || (doExtraCheck && !file.exists()))
continue
- val path = file.absolutePath
if (folder == RECYCLE_BIN) {
deletedMedia.firstOrNull { it.path == path }?.apply {
media.add(this)
@@ -364,8 +369,9 @@ class MediaFetcher(val context: Context) {
else -> o1.taken.compareTo(o2.taken)
}
- if (result == 0) {
- result = AlphanumericComparator().compare(o1.path.toLowerCase(), o2.path.toLowerCase())
+ // do just a quick extra sorting if the original sorting is equal, does not need to be accurate in all cases
+ if (result == 0 && sorting and SORT_BY_NAME == 0 && sorting and SORT_BY_PATH == 0) {
+ result = o1.name.compareTo(o2.name)
}
if (sorting and SORT_DESCENDING != 0) {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/views/MediaSideScroll.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/views/MediaSideScroll.kt
index 916550f21..0c424b631 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/views/MediaSideScroll.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/views/MediaSideScroll.kt
@@ -10,8 +10,8 @@ import android.view.MotionEvent
import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.TextView
+import com.simplemobiletools.commons.extensions.onGlobalLayout
import com.simplemobiletools.gallery.pro.R
-import com.simplemobiletools.gallery.pro.activities.ViewPagerActivity
import com.simplemobiletools.gallery.pro.extensions.audioManager
import com.simplemobiletools.gallery.pro.helpers.CLICK_MAX_DURATION
import com.simplemobiletools.gallery.pro.helpers.DRAG_THRESHOLD
@@ -25,6 +25,7 @@ class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(co
private var mTouchDownValue = -1
private var mTempBrightness = 0
private var mLastTouchY = 0f
+ private var mViewHeight = 0
private var mIsBrightnessScroll = false
private var mPassTouches = false
private var dragThreshold = DRAG_THRESHOLD * context.resources.displayMetrics.density
@@ -44,6 +45,9 @@ class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(co
mParentView = parentView
mIsBrightnessScroll = isBrightness
mSlideInfoText = activity.getString(if (isBrightness) R.string.brightness else R.string.volume)
+ onGlobalLayout {
+ mViewHeight = height
+ }
}
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
@@ -80,7 +84,7 @@ class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(co
val diffY = mTouchDownY - event.y
if (Math.abs(diffY) > dragThreshold && Math.abs(diffY) > Math.abs(diffX)) {
- var percent = ((diffY / ViewPagerActivity.screenHeight) * 100).toInt() * 3
+ var percent = ((diffY / mViewHeight) * 100).toInt() * 3
percent = Math.min(100, Math.max(-100, percent))
if ((percent == 100 && event.y > mLastTouchY) || (percent == -100 && event.y < mLastTouchY)) {
diff --git a/app/src/main/res/drawable-hdpi/ic_panorama.png b/app/src/main/res/drawable-hdpi/ic_panorama.png
deleted file mode 100644
index 513420277..000000000
Binary files a/app/src/main/res/drawable-hdpi/ic_panorama.png and /dev/null differ
diff --git a/app/src/main/res/drawable-hdpi/ic_panorama_outline.png b/app/src/main/res/drawable-hdpi/ic_panorama_outline.png
new file mode 100644
index 000000000..c932dcd78
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_panorama_outline.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_pause_outline.png b/app/src/main/res/drawable-hdpi/ic_pause_outline.png
new file mode 100644
index 000000000..d6d51bfc9
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_pause_outline.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_play_outline.png b/app/src/main/res/drawable-hdpi/ic_play_outline.png
new file mode 100644
index 000000000..12be0724f
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_play_outline.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_panorama.png b/app/src/main/res/drawable-xhdpi/ic_panorama.png
deleted file mode 100644
index c7f48d89c..000000000
Binary files a/app/src/main/res/drawable-xhdpi/ic_panorama.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_panorama_outline.png b/app/src/main/res/drawable-xhdpi/ic_panorama_outline.png
new file mode 100644
index 000000000..70e0274ec
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_panorama_outline.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_pause_outline.png b/app/src/main/res/drawable-xhdpi/ic_pause_outline.png
new file mode 100644
index 000000000..11d8d1698
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_pause_outline.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_play_outline.png b/app/src/main/res/drawable-xhdpi/ic_play_outline.png
new file mode 100644
index 000000000..f99911f6c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_play_outline.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_panorama.png b/app/src/main/res/drawable-xxhdpi/ic_panorama.png
deleted file mode 100644
index 17e7cde47..000000000
Binary files a/app/src/main/res/drawable-xxhdpi/ic_panorama.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_panorama_outline.png b/app/src/main/res/drawable-xxhdpi/ic_panorama_outline.png
new file mode 100644
index 000000000..8ba832ca8
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_panorama_outline.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_pause_outline.png b/app/src/main/res/drawable-xxhdpi/ic_pause_outline.png
new file mode 100644
index 000000000..d6f0c72ce
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_pause_outline.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_play_outline.png b/app/src/main/res/drawable-xxhdpi/ic_play_outline.png
new file mode 100644
index 000000000..156d6ca62
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_play_outline.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_panorama.png b/app/src/main/res/drawable-xxxhdpi/ic_panorama.png
deleted file mode 100644
index deaad2e1c..000000000
Binary files a/app/src/main/res/drawable-xxxhdpi/ic_panorama.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_panorama_outline.png b/app/src/main/res/drawable-xxxhdpi/ic_panorama_outline.png
new file mode 100644
index 000000000..c7a48896b
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_panorama_outline.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_pause_outline.png b/app/src/main/res/drawable-xxxhdpi/ic_pause_outline.png
new file mode 100644
index 000000000..162ed84d1
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_pause_outline.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_play_outline.png b/app/src/main/res/drawable-xxxhdpi/ic_play_outline.png
new file mode 100644
index 000000000..77370d426
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_play_outline.png differ
diff --git a/app/src/main/res/drawable/circle_black_background_with_inset.xml b/app/src/main/res/drawable/circle_black_background_with_inset.xml
deleted file mode 100644
index 6bab48721..000000000
--- a/app/src/main/res/drawable/circle_black_background_with_inset.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
diff --git a/app/src/main/res/layout/activity_panorama_video.xml b/app/src/main/res/layout/activity_panorama_video.xml
index 7b7919887..343496d24 100644
--- a/app/src/main/res/layout/activity_panorama_video.xml
+++ b/app/src/main/res/layout/activity_panorama_video.xml
@@ -11,12 +11,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
-
+
-
-
-
-
diff --git a/app/src/main/res/layout/activity_video_player.xml b/app/src/main/res/layout/activity_video_player.xml
new file mode 100644
index 000000000..8a0efeeb3
--- /dev/null
+++ b/app/src/main/res/layout/activity_video_player.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/bottom_video_time_holder.xml b/app/src/main/res/layout/bottom_video_time_holder.xml
index cdf1e0c53..69acead92 100644
--- a/app/src/main/res/layout/bottom_video_time_holder.xml
+++ b/app/src/main/res/layout/bottom_video_time_holder.xml
@@ -5,12 +5,25 @@
android:id="@+id/video_time_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentBottom="true">
+ android:layout_alignParentBottom="true"
+ android:background="@drawable/gradient_background">
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_slideshow.xml b/app/src/main/res/layout/dialog_slideshow.xml
index 48da05572..7915aa5dc 100644
--- a/app/src/main/res/layout/dialog_slideshow.xml
+++ b/app/src/main/res/layout/dialog_slideshow.xml
@@ -36,53 +36,11 @@
android:textCursorDrawable="@null"
android:textSize="@dimen/normal_text_size"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:padding="20dp"
+ android:src="@drawable/ic_play_outline"/>
-
diff --git a/app/src/main/res/menu/menu_video_player.xml b/app/src/main/res/menu/menu_video_player.xml
new file mode 100644
index 000000000..00e818ca3
--- /dev/null
+++ b/app/src/main/res/menu/menu_video_player.xml
@@ -0,0 +1,18 @@
+
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 4f9e5a2c7..2f15a3572 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -218,7 +218,7 @@
- استوديو لعرض الصور والفيديو بدون اعلانات.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index 372505031..e12e2ee27 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -149,7 +149,7 @@
System setting
Device rotation
Aspect ratio
- Black background and status bar at fullscreen media
+ Black background and at fullscreen media
Scroll thumbnails horizontally
Automatically hide system UI at fullscreen media
Delete empty folders after deleting their content
@@ -216,7 +216,7 @@
- Şəkil və videolara baxmaq üçün reklamsız qalereya.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index df1bbe48b..555fd7dbd 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -216,7 +216,7 @@
- Una galeria per veure imatges i vídeos sense publicitat.
+ An offline gallery for managing your files without ads, respecting your privacy.
Una galeria molt personalitzable capaç de mostrar molts tipus d\'imatge i de vídeo diferents, inclosos SVGs, RAWs, fotos panoràmiques i vídeos.
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index e8706c85b..b27b77b50 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -133,8 +133,8 @@
Přípony
- Folder shown on the widget:
- Show folder name
+ Složka zobrazená na widgetu:
+ Zobrazit název složky
Automaticky přehrávat videa
@@ -144,12 +144,12 @@
Animovat náhledy souborů GIF
Nastavit jas obrazovky na max při zobrazení médií
Oříznout náhledy na čtverce
- Show video durations
+ Zobrazit dobu trvání videí
Otočit média podle
Systémového nastavení
Otočení zařízení
Poměru stran
- Černé pozadí a stavová lišta při médiích na celou obrazovku
+ Černé pozadí při médiích na celou obrazovku
Prohlížet miniatury vodorovně
Automaticky skrývat systémové lišty při celoobrazovkových médiích
Odstranit prázdné složky po smazání jejich obsahu
@@ -175,7 +175,7 @@
Náhledy
Celoobrazovkový režim
Rozšířené vlastnosti
- Spodní skční tlačítka
+ Spodní akční tlačítka
Upravit viditelné spodní akční tlačítka
@@ -216,7 +216,7 @@
- Galerie na prohlížení obrázků a videí bez reklam.
+ An offline gallery for managing your files without ads, respecting your privacy.
Přizpůsobitelná galerie na zobrazování množství rozličných druhů obrázků a videí, včetně SVG, RAW souborů, panoramatických fotek a videí.
@@ -227,7 +227,7 @@
2. Prezentace
3. Podpora pro výřez v displeji
4. Připínání složek na vrch
- 5. Filtování médií podle typu
+ 5. Filtrování médií podle typu
6. Odpadkový koš pro snadnou obnovu souborů
7. Uzamykání orientace celoobrazovkového režimu
8. Označování oblíbených položek pro snadný přístup
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index 0557e2732..059977161 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -30,15 +30,15 @@
Brug standard orientering
Fiks Dato Taget værdi
Fikser…
- Dates fixed successfully
+ Datoer fikset med succes
- Filtrer medier
+ Filtrér medier
Billeder
Videoer
GIF\'er
- RAW images
- SVGs
+ RAW billeder
+ SVG\'er
Der blev ikke fundet nogen filer med det valgte filter.
Skift filter
@@ -67,7 +67,7 @@
Skalér valgte elementer og gem
Bredde
Højde
- Bevar billedeforhold
+ Bevar billedforhold
Indtast en gyldig opløsning
@@ -88,8 +88,8 @@
Spejlvend vandret
Spejlvend lodret
Rediger med
- Free
- Other
+ Fri
+ Andet
Simple Wallpaper
@@ -111,7 +111,7 @@
Inkluder videoer
Inkluder GIF\'er
Tilfældig rækkefølge
- Use fade animations
+ Brug udtonende animationer
Kør baglæns
Endeløs kørsel
Slideshowet endte
@@ -216,7 +216,7 @@
- Et galleri til visning af billeder og videoer uden reklamer.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 0237128fb..ddae898bf 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -215,7 +215,7 @@
- Eine schlichte Galerie zum Betrachten von Bildern und Videos, ganz ohne Werbung.
+ An offline gallery for managing your files without ads, respecting your privacy.
Eine stark anpassbare Galerie fähig zur Anzeige von diversen Bild- und Videoarten u. a. SVG, RAW, Panoramafotos und -videos.
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 3c29ab646..bec488bcf 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -216,7 +216,7 @@
- Μία Gallery για την προβολή φωτογραφιών και βίντεο χωρίς διαφημίσεις.
+ An offline gallery for managing your files without ads, respecting your privacy.
Μια εξαιρετικά προσαρμόσιμη Gallery ικανή να εμφανίζει πολλούς διαφορετικούς τύπους εικόνας και βίντεο, όπως SVGs, RAWs, πανοραμικές φωτογραφίες και βίντεο.
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index b10955ebc..16787f52d 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -216,7 +216,7 @@
- Una galería para ver fotos y vídeos sin publicidad.
+ An offline gallery for managing your files without ads, respecting your privacy.
Una galería altamente personalizable capaz de mostrar diferentes tipos de imágenes y videos, incluyendo SVG, RAW, fotos panorámicas y videos.
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 0ebaef866..5575db260 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -216,7 +216,7 @@
- Galleria kuvien ja videoiden katsomiseen ilman mainoksia.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 5af44b0a6..89d4c2a6c 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -144,7 +144,7 @@
GIFs animés sur les miniatures
Luminosité maximale
Recadrer les miniatures en carrés
- Show video durations
+ Montrer la durée de la vidéo
Pivoter l\'affichage selon
Paramètres système
Rotation de l\'appareil
@@ -214,7 +214,7 @@
- Une galerie pour visionner photos et vidéos sans publicité.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index 79e7592bc..919d02c66 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -216,7 +216,7 @@
- Unha galería para ver fotos e videos, pero non publicidade.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 8fee29889..b7452023b 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -216,7 +216,7 @@
- Galerija za gledanje fotografija i videozapisa bez oglasa.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index bdfeb0610..0d2833293 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -150,7 +150,7 @@
Rendszer beállítások
Eszköz elforgatás
Képarány
- Fekete háttérszín és állapotsáv teljes képernyős médiánál
+ Fekete háttérszín teljes képernyős médiánál
Miniatűrök görgetése vízszintesen
Automatikusan elrejti a rendszer UI-t teljes képernyőn
Az üres mappák törlése a tartalom törlése után
@@ -217,7 +217,7 @@ Ezzel csak a kiválasztott mappák láthatók, mivel a kizárás és a befoglal
- Galéria a fotók és videók hirdetések nélküli megtekintéséhez.
+ An offline gallery for managing your files without ads, respecting your privacy.
Nagyon testreszabható galéria, amely alkalmas számos különböző kép- és videotípus megjelenítésére, beleértve az SVG-ket, RAW-t, panorámaképeket és videókat.
diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml
index 319a68155..9bf419404 100644
--- a/app/src/main/res/values-id/strings.xml
+++ b/app/src/main/res/values-id/strings.xml
@@ -216,7 +216,7 @@
- Aplikasi galeri untuk melihat foto dan video tanpa iklan.
+ An offline gallery for managing your files without ads, respecting your privacy.
Aplikasi galeri dengan banyak kustomisasi dan mampu menampilkan banyak jenis gambar dan video termasuk SVG, RAW, panorama foto dan video.
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index fc126811d..ba7f48e3b 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -1,6 +1,6 @@
- Simple Gallery
+ Semplice Galleria
Galleria
Modifica
Apri fotocamera
@@ -29,38 +29,38 @@
Forza orizzontale
Usa l\'orientamento predefinito
Correggi valore Data acquisizione
- Correzione…
+ Correzione in corso…
Date aggiornate correttamente
- Filtra i media
+ Filtra i file
Immagini
Video
GIF
Immagini RAW
SVG
- Nessun file trovato per il filtro selezionato.
+ Nessun file trovato con il filtro selezionato.
Cambia filtro
- Questa funzione nasconde la cartella aggiungendo un file \'.nomedia\' all\'interno, nasconderà anche tutte le sottocartelle. Puoi vederle attivando l\'opzione \'Mostra cartelle nascoste\' nelle impostazioni. Continuare?
+ Questa funzione nasconde la cartella aggiungendo un file \'.nomedia\' all\'interno, nasconderà anche tutte le sottocartelle. Si possono vedere attivando l\'opzione \'Mostra cartelle nascoste\' nelle impostazioni. Continuare?
Escludi
Cartelle escluse
Gestisci le cartelle escluse
- Questo escluderà la selezione e le relative sottocartelle solo da Simple Gallery. Puoi gestire le cartelle escluse nelle impostazioni.
+ Questo escluderà la selezione e le relative sottocartelle solo da Semplice Galleria. Si possono gestire le cartelle escluse nelle impostazioni.
Vuoi invece escluderne una superiore?
- L\'esclusione delle cartelle e delle sottocartelle le renderà nascoste solo in Simple Gallery, saranno ancora visibili in altre applicazioni.\\n\\nSe desideri nasconderle anche nelle altre app, usa la funzione Nascondi.
+ L\'esclusione delle cartelle e delle sottocartelle le renderà nascoste solo in Semplice Galleria, saranno ancora visibili in altre applicazioni.\\n\\nSe si desidera nasconderle anche nelle altre app, usa la funzione Nascondi.
Rimuovi tutte
Rimuovere tutte le cartelle dalla lista delle esclusioni? Ciò non eliminerà le cartelle.
Cartelle nascoste
Gestisci le cartelle nascoste
- Pare che tu non abbia alcuna cartella nascosta con un file \".nomedia\".
+ Non si ha alcuna cartella nascosta con un file \".nomedia\".
Includi cartelle
Gestisci le cartelle incluse
Aggiungi cartella
- Se hai alcune cartelle che contengono media, ma non sono state riconosciute dall\'app, puoi aggiungerle manualmente qui.
+ Se si hanno alcune cartelle che contengono media, ma non sono state riconosciute dall\'app, si possono aggiungerle manualmente qui.
Ridimensiona
@@ -75,11 +75,11 @@
Salva
Ruota
Percorso
- Percorso immagine non valido
- Modifica immagine fallita
+ Percorso dell\'immagine non valido
+ Modifica dell\'immagine fallita
Modifica immagine con:
- Editor immagini non trovato
- Posizione file sconosciuta
+ Editor delle immagini non trovato
+ Posizione del file sconosciuta
Impossibile sovrascrivere il file originale
Ruota a sinistra
Ruota a destra
@@ -137,7 +137,7 @@
Mostra il nome della cartella
- Riproduci i video automaticamente
+ Riproduci automaticamente i video
Ricorda l\'ultimo stato di riproduzione dei video
Visibilità nome del file
Ripeti i video
@@ -149,9 +149,9 @@
Impostazione di sistema
Rotazione dispositivo
Proporzioni
- Sfondo e barra di stato neri con media a schermo intero
+ Sfondo e barra di stato neri con i file a schermo intero
Scorri le miniature orizzontalmente
- Nascondi UI di sistema con media a schermo intero
+ Nascondi l\'interfaccia utente di sistema con i file 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
@@ -172,7 +172,7 @@
Chiudi la visuale a schermo intero con un gesto verso il basso
- Miniature
+ Anteprime
Media a schermo intero
Dettagli estesi
Azioni inferiori
@@ -183,68 +183,68 @@
Attiva / disattiva la visibilità dei file
- Come posso impostare Simple Gallery come galleria predefinita del dispositivo?
- Prima devi trovare l\'attuale galleria predefinita nella sezione App delle impostazioni di sistema, cerca un pulsante che dice qualcosa come \"App predefinite\", cliccalo, poi seleziona \"Ripristina predefiniti\".
- La prossima volta che proverai ad aprire un\'immagine o video dovresti vedere un selettore di app, dove puoi scegliere Simple Gallery e renderla l\'app predefinita.
+ Come posso impostare Semplice Galleria come la galleria predefinita del dispositivo?
+ Si deve prima trovare l\'attuale galleria predefinita nella sezione App delle impostazioni di sistema, cercare un pulsante che dice qualcosa come \"App predefinite\", cliccarlo e poi selezionare \"Ripristina predefiniti\".
+ La prossima volta che proverai ad aprire un\'immagine o video si dovrebbe vedere un selettore di app, dove si può scegliere Semplice Galleria e renderla l\'app predefinita.
Ho bloccato l\'app con una password, ma l\'ho dimenticata. Cosa posso fare?
- Puoi risolvere in 2 modi. Puoi reinstallare l\'app, oppure trova l\'app nelle impostazioni del dispositivo e seleziona \"Cancella dati\". Tutte le impostazioni verranno ripristinate, nessun file multimediale verrà rimosso.
+ Si può risolvere in 2 modi: reinstallare l\'app, oppure trovare l\'app nelle impostazioni del dispositivo e seleziona \"Cancella dati\". Tutte le impostazioni verranno ripristinate, nessun file verrà rimosso.
Come posso fare apparire un album sempre in cima?
- Puoi toccare a lungo l\'album desiderato e selezionare l\'icona puntina nel menù azioni, ciò lo fisserà in cima. Puoi anche fissare varie cartelle, gli elementi fissati verranno ordinati dal metodo di ordinamento predefinito.
+ Si può toccare a lungo l\'album desiderato e selezionare l\'icona puntina nel menù azioni, ciò lo fisserà in cima. Si possono anche fissare varie cartelle, gli elementi fissati saranno ordinati dal metodo di ordinamento predefinito.
Come avanzo velocemente nei video?
- Puoi cliccare sui testi di durata attuale o massima vicino alla barra di avanzamento, ciò avanzerà o riavvolgerà il video.
+ Si può cliccare sui testi di durata attuale o massima vicino alla barra di avanzamento, ciò avanzerà o riavvolgerà il video.
Che differenza c\'è tra nascondere ed escludere una cartella?
- Escludere impedisce la visualizzazione della cartella solo in Simple Gallery, mentre nascondere ha effetto in tutto il sistema e nasconde la cartella anche alle altre gallerie. Funziona creando un file vuoto \".nomedia\" nella cartella in questione, che puoi anche rimuovere successivamente con qualsiasi gestore di file.
+ Escludere impedisce la visualizzazione della cartella solo in Semplice Galleria, mentre nascondere ha effetto in tutto il sistema e nasconde la cartella anche alle altre gallerie. Funziona creando un file vuoto \".nomedia\" nella cartella in questione, si possono anche rimuovere successivamente con qualsiasi gestore dei file.
Perchè vengono mostrate cartelle con copertine o adesivi di musica?
- Può succedere che tu veda apparire alcuni album insoliti. Puoi escluderli facilmente toccandoli a lungo e selezionando Escludi. Nella finestra successiva puoi quindi selezionare la cartella superiore, con la possibilità di impedire la visualizzazione anche di altri album correlati.
+ Può succedere che si vedano apparire alcuni album insoliti. Si possono escluderli facilmente toccandoli a lungo e selezionando Escludi. Nella finestra successiva si possono quindi selezionare la cartella superiore, con la possibilità di impedire la visualizzazione anche di altri album correlati.
Una cartella con immagini non viene mostrata, cosa posso fare?
Può succedere per vari motivi, ma la soluzione è semplice. Vai in Impostazioni -> Gestisci le cartelle incluse, tocca il tasto Più e naviga verso la cartella desiderata.
Che fare se voglio rendere visibili solo poche particolari cartelle?
- Aggiungere una cartella nelle Cartelle Incluse non esclude automaticamente nulla. Quello che puoi fare è andare in Impostazioni -> Gestisci le cartelle escluse, escludi la cartella root \"/\", poi aggiungi le cartelle desiderate in Impostazioni -> Gestisci le cartelle incluse.
+ Aggiungere una cartella nelle Cartelle Incluse non esclude automaticamente nulla. Quello che puoi fare è andare in Impostazioni → Gestisci le cartelle escluse, escludi la cartella root \"/\", poi aggiungi le cartelle desiderate in Impostazioni → Gestisci le cartelle incluse.
Ciò renderà visibili solo le cartelle selezionate, dato che sia l\'esclusione che l\'inclusione sono ricorsive e se una cartella è sia esclusa che inclusa, verrà mostrata.
Le immagini a schermo intero hanno strani artefatti, posso migliorarne la qualità in qualche modo?
- Sì, c\'è un\'opzione nelle impostazioni che dice \"Sostituisci le immagini ingrandibili a fondo con altre di migliore qualità\", puoi usare quella. Ciò migliorerà la qualità delle immagini, ma saranno sfuocate quando proverai a ingrandirle troppo.
+ Sì, c\'è un\'opzione nelle impostazioni che dice \"Sostituisci le immagini ingrandibili a fondo con altre di migliore qualità\". Ciò migliorerà la qualità delle immagini, ma saranno sfuocate quando si proverà a ingrandirle troppo.
Posso ritagliare le immagini con questa app?
- Sì, puoi ritagliare le immagini nell\'editor, trascinando gli angoli dell\'immagine. Puoi usare l\'editor sia premendo a lungo la miniatura di un\'immagine e selezionando Modifica, o selezionando Modifica mentre la vedi a schermo intero.
+ Sì, si possono ritagliare le immagini nell\'editor, trascinando gli angoli dell\'immagine. Si può accedere all\'editor sia premendo a lungo la miniatura di un\'immagine e selezionando Modifica, oppure selezionando Modifica mentre si vede una foto a schermo intero.
Posso raggruppare in qualche modo le miniature dei file?
- Certo, usa il menu \"Raggruppa per\" mentre visualizzi le miniature. Puoi raggruppare i file con diversi criteri, incluso la data di creazione. Se utilizzi la funzione \"Mostra tutti i contenuti\" puoi anche raggrupparli per cartelle.
+ Certo, si può usare il menu \"Raggruppa per\" mentre si visualizzano le miniature. Il raggruppamento può avvenire per diversi criteri, incluso la data di creazione. Se si utilizza la funzione \"Mostra tutti i contenuti\" si può anche raggrupparli per cartelle.
L\'ordinamento per data acquisizione sembra non funzionare bene, come posso risolvere?
- Probabilmente è causato dai file copiati da altre parti. Puoi risolvere selezionando le miniature dei file e scegliendo \"Correggi valore Data acquisizione\".
+ Probabilmente è causato dai file copiati da altre parti. Si può risolvere selezionando le miniature dei file e scegliendo \"Correggi valore Data acquisizione\".
Vedo curvature di colore nelle immagini. Come posso migliorarne la qualità?
- L\'attuale soluzione per visualizzare immagini funziona bene nella maggior parte dei casi, ma se vuoi una qualità ancora maggiore, puoi attivare \"Mostra le immagini alla massima qualità possibile\" nelle impostazioni dell\'app, nella sezione \"Immagini ingrandibili a fondo\".
+ L\'attuale soluzione per visualizzare immagini funziona bene nella maggior parte dei casi, ma se si vuole una qualità ancora maggiore, si può attivare \"Mostra le immagini alla massima qualità possibile\" nelle impostazioni dell\'app, nella sezione \"Immagini ingrandibili a fondo\".
Ho nascosto un file/una cartella. Come posso mostrarlo/a di nuovo?
- Puoi premere \"Mostra temporaneamente nascosti\" nel menu della schermata principale, oppure attivare \"Mostra gli elementi nascosti\" nelle impostazioni dell\'app per vedere l\'elemento nascosto. Se vuoi che resti visibile, premilo a lungo e seleziona \"Non nascondere\". Le cartelle vengono nascoste aggiungendo un file nascosto \".nomedia\" all\'interno di esse, puoi anche eliminare il file con qualsiasi gestore di file.
+ Si può premere \"Mostra temporaneamente nascosti\" nel menu della schermata principale, oppure attivare \"Mostra gli elementi nascosti\" nelle impostazioni dell\'app per vedere l\'elemento nascosto. Per farla rimanere visibile, premere a lungo e selezionare \"Non nascondere\". Le cartelle vengono nascoste aggiungendo un file nascosto \".nomedia\" all\'interno di esse, si può eliminare il file con qualsiasi gestore di file.
- Una galleria per visualizzare foto e video senza pubblicità.
+ Una galleria per gestire i propri file senza pubblicità che rispetta la privacy.
Una galleria altamente personalizzabile e capace di visualizzare tipi di file immagini e video differenti, fra cui SVG, RAW, foto panoramiche e video.
- È open source, non contiene pubblicità e autorizzazioni superflue.
+ L\'applicazione non contiene pubblicità o permessi non necessari; è completamente opensource e la si può personalizzare con i propri colori preferiti.
+
Alcune funzionalità che vale la pena accennare:
1. Ricerca
2. Presentazione
3. Supporto al notch
4. Fissare le cartelle in alto
- 5. Filtro dei file per tipo
+ 5. Filtro dei file per tipologia
6. Cestino per un recupero facile dei file
7. Blocco dell\'orientamento nella vista a schermo intero
- 8. Selezionare file preferiti per un accesso facile
- 9. Chisura rapida della vista schermo intero con un movimento verso il basso
- 10. Un editor per modificare le immagini ed applicare filtri
+ 8. Selezione dei file preferiti per un accesso immediato
+ 9. Chisura rapida della vista a schermo intero con un movimento verso il basso
+ 10. Un editor per modificare le immagini e applicare filtri
11. Protezione con password per proteggere elementi nascosti o l\'intera applicazione
12. Cambio delle colonne delle anteprime con un movimento o tramite dei pulsanti nel menu
- 13. Pulsanti rapidi per azioni personalizzabili nella vista schermo intero
+ 13. Pulsanti rapidi per azioni personalizzabili nella vista a schermo intero
14. Visualizzazione di determinati dettagli aggiuntivi nella vista a schermo intero
15. Molti modi per ordinare o raggruppare gli elementi, sia in ordine crescente che decrescente
- 16. Cartelle nascoste (anche per altre applicazioni), cartelle escluse (solo per Simple Gallery)
+ 16. Cartelle nascoste (anche per altre applicazioni), cartelle escluse (solo per Semplice Galleria)
- L\'autorizzazione per leggere le impronte digitali è necessaria per il blocco della visibilità degli elementi, dell\'intera applicazione o per proteggere alcuni file dalla loro eliminazione.
-
- Questa applicazione è solamente una di una serie più grande. Si possono trovare le altre su https://www.simplemobiletools.com
+ L\'autorizzazione per leggere le impronte digitali è necessaria per il blocco della visibilità, dell\'intera applicazione o per proteggere alcuni file dalla loro eliminazione.
+
+ Questa è solamente una delle tante applicazioni della serie Simple Mobile Tools. Si possono trovare le altre su https://www.simplemobiletools.com
-
- 写真やビデオを見るためのギャラリー。広告はありません。
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index aef49c472..440a533b6 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -216,7 +216,7 @@
- 광고없이 사진과 동영상을 볼 수 있는 갤러리.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index d791865cf..bdaefa6bb 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -216,7 +216,7 @@
- Galerija, skirta peržiūrėti nuotraukas ir vaizdo įrašus be reklamų.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index 6b42ebde8..04ff031ca 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -216,7 +216,7 @@
- A gallery for viewing photos and videos without ads.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index df6819783..efab9aca5 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -216,7 +216,7 @@
- Een galerij voor afbeeldingen en video\'s, zonder advertenties.
+ Een privacyvriendelijke advertentievrije galerij voor afbeeldingen en video\'s.
Een zeer goed aan te passen galerij voor afbeeldingen en video\'s in vele bestandsformaten, waaronder SVG, RAW, panoramafoto\'s en -video\'s.
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 42ba52f06..fa1b6654f 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -89,7 +89,7 @@
Przewróć w pionie
Edytuj w:
Wolne
- Other
+ Inny
Tapeta
@@ -133,8 +133,8 @@
Rozszerzenia
- Folder shown on the widget:
- Show folder name
+ Folder wyświetlany na widżecie:
+ Pokaż nazwę folderu
Odtwarzaj filmy automatycznie
@@ -214,7 +214,7 @@
- Prosta galeria bez reklam do przeglądania obrazów i filmów.
+ An offline gallery for managing your files without ads, respecting your privacy.
Wysoce konfigurowalna galeria obsługująca wiele formatów obrazów i filmów, w tym SVG, RAW oraz multimedia panoramiczne.
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index cb971ca18..cb3587889 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -216,7 +216,7 @@
- Um aplicativo para visualizar fotos e vídeos.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index bff249a51..c3932e292 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -216,7 +216,7 @@
- Uma aplicação para ver fotografias e vídeos.
+ An offline gallery for managing your files without ads, respecting your privacy.
Um aplicação capaz de mostrar diversos tipos de imagens e vídeos incluíndo SVG, RAW, fotos panorâmicas e vídeos.
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index b2f1c0ec2..3541f561f 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -216,7 +216,7 @@
- Галерея для просмотра изображений и видео. Без рекламы.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index f6592eb1d..604d715f8 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -149,7 +149,7 @@
Systémového nastavenia
Otočenia zariadenia
Pomeru strán
- Čierne pozadie a stavová lišta pri médiách na celú obrazovku
+ Čierne pozadie pri médiách na celú obrazovku
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
@@ -216,7 +216,7 @@
- Galéria na prezeranie obrázkov a videí bez reklám.
+ Offline galéria na správu vašich súborov, rešpektujúca vaše súkromie.
Nastaviteľná galéria na zobrazovanie množstva rozličných druhov obrázkov a videí, vrátane SVG, RAW súborov, panoramatických fotiek a videí.
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index e8b8941e8..fe0e6a3f4 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -215,7 +215,7 @@
Lahko uporabite funkcijo \"Začasno prikaži skrite elemente\", ki se nahaja v meniju na glavnem zaslonu ali preklopite \"Prikaži skrite elemente\" v Nastavitvah aplikacije. Če želite element označiti kot viden, z dolgim pritiskom nanj prikličite meni in izberite \"Prikaži\". Skrivanje map deluje tako, da se kreira prazno \".nomedia\" datoteko v izbrani mapi, ki jo lahko odstranite tudi s katerimkoli urejevalnikom datotek.
- Galerija za ogled fotografij in videoposnetkov brez reklam.
+ An offline gallery for managing your files without ads, respecting your privacy.
Visoko prilagodljiva galerija, zmožna prikazovanja različnih tipov fotografij in videoposnetkov, vključno s SVGji, RAWi, panoramskimi fotografijami in videoposnetki.
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 45da7bafb..bfa6dc3dc 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -216,7 +216,7 @@
- Ett galleri för att visa foton och videor utan reklam.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 33bdcfecb..bbd08e2fe 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -216,7 +216,7 @@
- Reklamsız fotoğrafları ve videoları görüntülemek için bir galeri.
+ An offline gallery for managing your files without ads, respecting your privacy.
SVG\'ler, RAW\'lar, panoramik fotoğraflar ve videolar dahil olmak üzere birçok farklı resim ve video türünü gösterebilen son derece özelleştirilebilir bir galeri.
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 24bd7ead0..e8d0a3f17 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -216,7 +216,7 @@
- Галерея для перегляду фото та відео без реклами.
+ Офлайн-галерея для керування файлами: без реклами та з повагою до приватності.
Тонко налаштовувана галерея, здатна відображати зображення та відео різноманітних типів, включаючи SVG-зображення, RAW-зображення,панорамні фото і відео.
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index e77503681..a266a88de 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -133,8 +133,8 @@
扩展
- Folder shown on the widget:
- Show folder name
+ 要在小部件上显示的文件夹:
+ 显示文件夹名称
自动播放
@@ -214,7 +214,7 @@
- 一个没有广告,用来观看照片及视频的相册。
+ An offline gallery for managing your files without ads, respecting your privacy.
一个高度可定制的图库,支持很多的图像和视频类型,包括SVG,RAW,全景照片和视频。
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index d6304564d..08c7be32b 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -216,7 +216,7 @@
- 一個用來瀏覽相片和影片,且沒有廣告的相簿。
+ 一個沒有廣告的離線相簿,用來管理你的檔案,並且尊重您的隱私。
一個高自訂性的相簿,能夠顯示許多不同的圖片和影片類型,包含SVGs、RAWs、全景相片和影片。
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 89072fb3e..b2135537c 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -8,6 +8,7 @@
96dp
60dp
60dp
+ 60dp
50dp
72dp
64dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 808d89d8b..6fa8f41a3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -149,7 +149,7 @@
System setting
Device rotation
Aspect ratio
- Black background and status bar at fullscreen media
+ Black background and at fullscreen media
Scroll thumbnails horizontally
Automatically hide system UI at fullscreen media
Delete empty folders after deleting their content
@@ -216,7 +216,7 @@
- A gallery for viewing photos and videos without ads.
+ An offline gallery for managing your files without ads, respecting your privacy.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_6.jpg b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_6.jpg
index a0f0752fe..db4b66408 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_6.jpg and b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_6.jpg differ