23
CHANGELOG.md
|
@ -1,6 +1,29 @@
|
||||||
Changelog
|
Changelog
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
Version 4.1.1 *(2018-05-26)*
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
* Always set folder thumbnail based on folder content sorting
|
||||||
|
* Make sure hidden folders have the "(hidden)" appended
|
||||||
|
|
||||||
|
Version 4.1.0 *(2018-05-25)*
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
* Added sorting by Date Taken
|
||||||
|
* Fixed file renaming on Android Oreo
|
||||||
|
* Fixed some scrollbar glitches
|
||||||
|
* Fixed broken "Use english language" in some cases
|
||||||
|
* Make sure only the proper files are shown at "Show all folders content"
|
||||||
|
* Many other smaller UX, stability improvements and bugfixes
|
||||||
|
|
||||||
|
Version 4.0.0 *(2018-05-13)*
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
* Allow customizing the app launcher color
|
||||||
|
* Remove the top spinning circle at initial launch
|
||||||
|
* Many other bugfixes and UX/stability improvements
|
||||||
|
|
||||||
Version 3.8.2 *(2018-04-26)*
|
Version 3.8.2 *(2018-04-26)*
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ android {
|
||||||
applicationId "com.simplemobiletools.gallery"
|
applicationId "com.simplemobiletools.gallery"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
versionCode 176
|
versionCode 179
|
||||||
versionName "3.8.2"
|
versionName "4.1.1"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
setProperty("archivesBaseName", "gallery")
|
setProperty("archivesBaseName", "gallery")
|
||||||
}
|
}
|
||||||
|
@ -47,16 +47,16 @@ ext {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.simplemobiletools:commons:3.19.21'
|
implementation 'com.simplemobiletools:commons:4.1.4'
|
||||||
implementation 'com.theartofdev.edmodo:android-image-cropper:2.7.0'
|
implementation 'com.theartofdev.edmodo:android-image-cropper:2.7.0'
|
||||||
implementation 'com.android.support:multidex:1.0.3'
|
implementation 'com.android.support:multidex:1.0.3'
|
||||||
implementation 'it.sephiroth.android.exif:library:1.0.1'
|
implementation 'it.sephiroth.android.exif:library:1.0.1'
|
||||||
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.12'
|
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.12'
|
||||||
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
|
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
|
||||||
|
|
||||||
kapt "android.arch.persistence.room:compiler:1.0.0"
|
kapt "android.arch.persistence.room:compiler:1.1.0"
|
||||||
implementation "android.arch.persistence.room:runtime:1.0.0"
|
implementation "android.arch.persistence.room:runtime:1.1.0"
|
||||||
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
|
annotationProcessor "android.arch.persistence.room:compiler:1.1.0"
|
||||||
|
|
||||||
//implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.9.0'
|
//implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.9.0'
|
||||||
implementation 'com.github.tibbi:subsampling-scale-image-view:v3.10.0-fork'
|
implementation 'com.github.tibbi:subsampling-scale-image-view:v3.10.0-fork'
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
android:name=".activities.SplashActivity"
|
android:name=".activities.SplashActivity"
|
||||||
android:theme="@style/SplashTheme">
|
android:theme="@style/SplashTheme">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
@ -212,5 +210,252 @@
|
||||||
<action android:name="com.simplemobiletools.REFRESH_MEDIA"/>
|
<action android:name="com.simplemobiletools.REFRESH_MEDIA"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<!-- Do not append ".Orange" to the default alias "name", it would remove the old homescreen launcher of users at upgrade -->
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity"
|
||||||
|
android:enabled="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Red"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_red"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_red"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Pink"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_pink"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_pink"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Purple"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_purple"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_purple"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Deep_purple"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_deep_purple"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_deep_purple"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Indigo"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_indigo"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_indigo"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Blue"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_blue"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_blue"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Light_blue"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_light_blue"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_light_blue"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Cyan"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_cyan"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_cyan"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Teal"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_teal"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_teal"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Green"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_green"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_green"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Light_green"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_light_green"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_light_green"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Lime"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_lime"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_lime"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Yellow"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_yellow"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_yellow"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Amber"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_amber"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_amber"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Deep_orange"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_deep_orange"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_deep_orange"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Brown"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_brown"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_brown"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Blue_grey"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_blue_grey"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_blue_grey"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".activities.SplashActivity.Grey_black"
|
||||||
|
android:enabled="false"
|
||||||
|
android:icon="@mipmap/ic_launcher_grey_black"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_grey_black"
|
||||||
|
android:targetActivity=".activities.SplashActivity">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -176,6 +176,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
|
||||||
}
|
}
|
||||||
|
|
||||||
Intent().apply {
|
Intent().apply {
|
||||||
|
data = saveUri
|
||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
setResult(RESULT_OK, this)
|
setResult(RESULT_OK, this)
|
||||||
}
|
}
|
||||||
|
@ -260,7 +261,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scanFinalPath(path: String) {
|
private fun scanFinalPath(path: String) {
|
||||||
scanPath(path) {
|
scanPathRecursively(path) {
|
||||||
setResult(Activity.RESULT_OK, intent)
|
setResult(Activity.RESULT_OK, intent)
|
||||||
toast(R.string.file_saved)
|
toast(R.string.file_saved)
|
||||||
finish()
|
finish()
|
||||||
|
|
|
@ -5,7 +5,7 @@ import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
||||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||||
import com.simplemobiletools.commons.extensions.scanPath
|
import com.simplemobiletools.commons.extensions.scanPathRecursively
|
||||||
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
||||||
import com.simplemobiletools.gallery.R
|
import com.simplemobiletools.gallery.R
|
||||||
import com.simplemobiletools.gallery.adapters.ManageFoldersAdapter
|
import com.simplemobiletools.gallery.adapters.ManageFoldersAdapter
|
||||||
|
@ -55,7 +55,7 @@ class IncludedFoldersActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
||||||
config.addIncludedFolder(it)
|
config.addIncludedFolder(it)
|
||||||
updateFolders()
|
updateFolders()
|
||||||
Thread {
|
Thread {
|
||||||
scanPath(it)
|
scanPathRecursively(it)
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
import com.simplemobiletools.gallery.BuildConfig
|
import com.simplemobiletools.gallery.BuildConfig
|
||||||
import com.simplemobiletools.gallery.R
|
import com.simplemobiletools.gallery.R
|
||||||
import com.simplemobiletools.gallery.adapters.DirectoryAdapter
|
import com.simplemobiletools.gallery.adapters.DirectoryAdapter
|
||||||
import com.simplemobiletools.gallery.databases.GalleryDataBase
|
import com.simplemobiletools.gallery.databases.GalleryDatabase
|
||||||
import com.simplemobiletools.gallery.dialogs.ChangeSortingDialog
|
import com.simplemobiletools.gallery.dialogs.ChangeSortingDialog
|
||||||
import com.simplemobiletools.gallery.dialogs.FilterMediaDialog
|
import com.simplemobiletools.gallery.dialogs.FilterMediaDialog
|
||||||
import com.simplemobiletools.gallery.extensions.*
|
import com.simplemobiletools.gallery.extensions.*
|
||||||
|
@ -72,7 +72,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
appLaunched()
|
appLaunched(BuildConfig.APPLICATION_ID)
|
||||||
|
|
||||||
mIsPickImageIntent = isPickImageIntent(intent)
|
mIsPickImageIntent = isPickImageIntent(intent)
|
||||||
mIsPickVideoIntent = isPickVideoIntent(intent)
|
mIsPickVideoIntent = isPickVideoIntent(intent)
|
||||||
|
@ -188,10 +188,11 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
config.temporarilyShowHidden = false
|
config.temporarilyShowHidden = false
|
||||||
|
config.tempSkipDeleteConfirmation = false
|
||||||
mTempShowHiddenHandler.removeCallbacksAndMessages(null)
|
mTempShowHiddenHandler.removeCallbacksAndMessages(null)
|
||||||
removeTempFolder()
|
removeTempFolder()
|
||||||
if (!isChangingConfigurations) {
|
if (!isChangingConfigurations) {
|
||||||
GalleryDataBase.destroyInstance()
|
GalleryDatabase.destroyInstance()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,11 +295,6 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
val getVideosOnly = mIsPickVideoIntent || mIsGetVideoContentIntent
|
val getVideosOnly = mIsPickVideoIntent || mIsGetVideoContentIntent
|
||||||
|
|
||||||
getCachedDirectories(getVideosOnly, getImagesOnly) {
|
getCachedDirectories(getVideosOnly, getImagesOnly) {
|
||||||
if (!mLoadedInitialPhotos) {
|
|
||||||
runOnUiThread {
|
|
||||||
directories_refresh_layout.isRefreshing = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gotDirectories(addTempFolderIfNeeded(it))
|
gotDirectories(addTempFolderIfNeeded(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -542,7 +538,8 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillIntentPath(resultData: Intent, resultIntent: Intent) {
|
private fun fillIntentPath(resultData: Intent, resultIntent: Intent) {
|
||||||
val path = resultData.data.path
|
val data = resultData.data
|
||||||
|
val path = if (data.toString().startsWith("/")) data.toString() else data.path
|
||||||
val uri = getFilePublicUri(File(path), BuildConfig.APPLICATION_ID)
|
val uri = getFilePublicUri(File(path), BuildConfig.APPLICATION_ID)
|
||||||
val type = path.getMimeType()
|
val type = path.getMimeType()
|
||||||
resultIntent.setDataAndTypeAndNormalize(uri, type)
|
resultIntent.setDataAndTypeAndNormalize(uri, type)
|
||||||
|
@ -595,9 +592,10 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
val isSortingAscending = config.directorySorting and SORT_DESCENDING == 0
|
val isSortingAscending = config.directorySorting and SORT_DESCENDING == 0
|
||||||
val mediumDao = galleryDB.MediumDao()
|
val mediumDao = galleryDB.MediumDao()
|
||||||
val directoryDao = galleryDB.DirectoryDao()
|
val directoryDao = galleryDB.DirectoryDao()
|
||||||
|
val getProperDateTaken = config.directorySorting and SORT_BY_DATE_TAKEN != 0
|
||||||
|
|
||||||
for (directory in dirs) {
|
for (directory in dirs) {
|
||||||
val curMedia = mediaFetcher.getFilesFrom(directory.path, getImagesOnly, getVideosOnly)
|
val curMedia = mediaFetcher.getFilesFrom(directory.path, getImagesOnly, getVideosOnly, getProperDateTaken)
|
||||||
val newDir = if (curMedia.isEmpty()) {
|
val newDir = if (curMedia.isEmpty()) {
|
||||||
directory
|
directory
|
||||||
} else {
|
} else {
|
||||||
|
@ -611,6 +609,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
|
|
||||||
directory.apply {
|
directory.apply {
|
||||||
tmb = newDir.tmb
|
tmb = newDir.tmb
|
||||||
|
name = newDir.name
|
||||||
mediaCnt = newDir.mediaCnt
|
mediaCnt = newDir.mediaCnt
|
||||||
modified = newDir.modified
|
modified = newDir.modified
|
||||||
taken = newDir.taken
|
taken = newDir.taken
|
||||||
|
@ -632,13 +631,14 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val foldersToScan = mediaFetcher.getFoldersToScan("")
|
val foldersToScan = mediaFetcher.getFoldersToScan()
|
||||||
dirs.forEach {
|
dirs.forEach {
|
||||||
foldersToScan.remove(it.path)
|
foldersToScan.remove(it.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check the remaining folders which were not cached at all yet
|
||||||
for (folder in foldersToScan) {
|
for (folder in foldersToScan) {
|
||||||
val newMedia = mediaFetcher.getFilesFrom(folder, getImagesOnly, getVideosOnly)
|
val newMedia = mediaFetcher.getFilesFrom(folder, getImagesOnly, getVideosOnly, getProperDateTaken)
|
||||||
if (newMedia.isEmpty()) {
|
if (newMedia.isEmpty()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -779,7 +779,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
|
|
||||||
private fun getCurrentlyDisplayedDirs() = getRecyclerAdapter()?.dirs ?: ArrayList()
|
private fun getCurrentlyDisplayedDirs() = getRecyclerAdapter()?.dirs ?: ArrayList()
|
||||||
|
|
||||||
private fun getBubbleTextItem(index: Int) = getRecyclerAdapter()?.dirs?.getOrNull(index)?.getBubbleText() ?: ""
|
private fun getBubbleTextItem(index: Int) = getRecyclerAdapter()?.dirs?.getOrNull(index)?.getBubbleText(config.directorySorting) ?: ""
|
||||||
|
|
||||||
private fun setupLatestMediaId() {
|
private fun setupLatestMediaId() {
|
||||||
Thread {
|
Thread {
|
||||||
|
@ -873,6 +873,8 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
add(Release(158, R.string.release_158))
|
add(Release(158, R.string.release_158))
|
||||||
add(Release(159, R.string.release_159))
|
add(Release(159, R.string.release_159))
|
||||||
add(Release(163, R.string.release_163))
|
add(Release(163, R.string.release_163))
|
||||||
|
add(Release(177, R.string.release_177))
|
||||||
|
add(Release(178, R.string.release_178))
|
||||||
checkWhatsNew(this, BuildConfig.VERSION_CODE)
|
checkWhatsNew(this, BuildConfig.VERSION_CODE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,6 +175,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
if (config.showAll) {
|
if (config.showAll) {
|
||||||
config.temporarilyShowHidden = false
|
config.temporarilyShowHidden = false
|
||||||
|
config.tempSkipDeleteConfirmation = false
|
||||||
}
|
}
|
||||||
|
|
||||||
mTempShowHiddenHandler.removeCallbacksAndMessages(null)
|
mTempShowHiddenHandler.removeCallbacksAndMessages(null)
|
||||||
|
@ -333,20 +334,22 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
|
||||||
media_horizontal_fastscroller.isHorizontal = true
|
media_horizontal_fastscroller.isHorizontal = true
|
||||||
media_horizontal_fastscroller.beVisibleIf(allowHorizontalScroll)
|
media_horizontal_fastscroller.beVisibleIf(allowHorizontalScroll)
|
||||||
|
|
||||||
|
val sorting = config.getFileSorting(mPath)
|
||||||
|
|
||||||
if (allowHorizontalScroll) {
|
if (allowHorizontalScroll) {
|
||||||
media_horizontal_fastscroller.allowBubbleDisplay = config.showInfoBubble
|
media_horizontal_fastscroller.allowBubbleDisplay = config.showInfoBubble
|
||||||
media_horizontal_fastscroller.setViews(media_grid, media_refresh_layout) {
|
media_horizontal_fastscroller.setViews(media_grid, media_refresh_layout) {
|
||||||
media_horizontal_fastscroller.updateBubbleText(getBubbleTextItem(it))
|
media_horizontal_fastscroller.updateBubbleText(getBubbleTextItem(it, sorting))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
media_vertical_fastscroller.allowBubbleDisplay = config.showInfoBubble
|
media_vertical_fastscroller.allowBubbleDisplay = config.showInfoBubble
|
||||||
media_vertical_fastscroller.setViews(media_grid, media_refresh_layout) {
|
media_vertical_fastscroller.setViews(media_grid, media_refresh_layout) {
|
||||||
media_vertical_fastscroller.updateBubbleText(getBubbleTextItem(it))
|
media_vertical_fastscroller.updateBubbleText(getBubbleTextItem(it, sorting))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getBubbleTextItem(index: Int) = getMediaAdapter()?.media?.getOrNull(index)?.getBubbleText() ?: ""
|
private fun getBubbleTextItem(index: Int, sorting: Int) = getMediaAdapter()?.media?.getOrNull(index)?.getBubbleText(sorting) ?: ""
|
||||||
|
|
||||||
private fun checkLastMediaChanged() {
|
private fun checkLastMediaChanged() {
|
||||||
if (isActivityDestroyed())
|
if (isActivityDestroyed())
|
||||||
|
@ -479,6 +482,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
|
||||||
mCurrAsyncTask = GetMediaAsynctask(applicationContext, mPath, mIsGetImageIntent, mIsGetVideoIntent, mShowAll) {
|
mCurrAsyncTask = GetMediaAsynctask(applicationContext, mPath, mIsGetImageIntent, mIsGetVideoIntent, mShowAll) {
|
||||||
gotMedia(it)
|
gotMedia(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrAsyncTask!!.execute()
|
mCurrAsyncTask!!.execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,14 +67,14 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
|
||||||
|
|
||||||
mIsFromGallery = intent.getBooleanExtra(IS_FROM_GALLERY, false)
|
mIsFromGallery = intent.getBooleanExtra(IS_FROM_GALLERY, false)
|
||||||
if (mUri!!.scheme == "file") {
|
if (mUri!!.scheme == "file") {
|
||||||
scanPath(mUri!!.path)
|
scanPathRecursively(mUri!!.path)
|
||||||
sendViewPagerIntent(mUri!!.path)
|
sendViewPagerIntent(mUri!!.path)
|
||||||
finish()
|
finish()
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
val path = applicationContext.getRealPathFromURI(mUri!!) ?: ""
|
val path = applicationContext.getRealPathFromURI(mUri!!) ?: ""
|
||||||
if (path != mUri.toString() && path.isNotEmpty() && mUri!!.authority != "mms") {
|
if (path != mUri.toString() && path.isNotEmpty() && mUri!!.authority != "mms") {
|
||||||
scanPath(mUri!!.path)
|
scanPathRecursively(mUri!!.path)
|
||||||
sendViewPagerIntent(path)
|
sendViewPagerIntent(path)
|
||||||
finish()
|
finish()
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,5 +1,30 @@
|
||||||
package com.simplemobiletools.gallery.activities
|
package com.simplemobiletools.gallery.activities
|
||||||
|
|
||||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
|
import com.simplemobiletools.gallery.R
|
||||||
|
|
||||||
open class SimpleActivity : BaseSimpleActivity()
|
open class SimpleActivity : BaseSimpleActivity() {
|
||||||
|
override fun getAppIconIDs() = arrayListOf(
|
||||||
|
R.mipmap.ic_launcher_red,
|
||||||
|
R.mipmap.ic_launcher_pink,
|
||||||
|
R.mipmap.ic_launcher_purple,
|
||||||
|
R.mipmap.ic_launcher_deep_purple,
|
||||||
|
R.mipmap.ic_launcher_indigo,
|
||||||
|
R.mipmap.ic_launcher_blue,
|
||||||
|
R.mipmap.ic_launcher_light_blue,
|
||||||
|
R.mipmap.ic_launcher_cyan,
|
||||||
|
R.mipmap.ic_launcher_teal,
|
||||||
|
R.mipmap.ic_launcher_green,
|
||||||
|
R.mipmap.ic_launcher_light_green,
|
||||||
|
R.mipmap.ic_launcher_lime,
|
||||||
|
R.mipmap.ic_launcher_yellow,
|
||||||
|
R.mipmap.ic_launcher_amber,
|
||||||
|
R.mipmap.ic_launcher,
|
||||||
|
R.mipmap.ic_launcher_deep_orange,
|
||||||
|
R.mipmap.ic_launcher_brown,
|
||||||
|
R.mipmap.ic_launcher_blue_grey,
|
||||||
|
R.mipmap.ic_launcher_grey_black
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getAppLauncherName() = getString(R.string.app_launcher_name)
|
||||||
|
}
|
||||||
|
|
|
@ -58,7 +58,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
||||||
private var mPos = -1
|
private var mPos = -1
|
||||||
private var mShowAll = false
|
private var mShowAll = false
|
||||||
private var mIsSlideshowActive = false
|
private var mIsSlideshowActive = false
|
||||||
private var mSkipConfirmationDialog = false
|
|
||||||
private var mRotationDegrees = 0
|
private var mRotationDegrees = 0
|
||||||
private var mPrevHashcode = 0
|
private var mPrevHashcode = 0
|
||||||
|
|
||||||
|
@ -182,7 +181,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
||||||
|
|
||||||
if (!getDoesFilePathExist(mPath)) {
|
if (!getDoesFilePathExist(mPath)) {
|
||||||
Thread {
|
Thread {
|
||||||
scanPath(mPath)
|
scanPathRecursively(mPath)
|
||||||
}.start()
|
}.start()
|
||||||
finish()
|
finish()
|
||||||
return
|
return
|
||||||
|
@ -554,7 +553,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
||||||
}
|
}
|
||||||
|
|
||||||
copyFile(tmpPath, newPath)
|
copyFile(tmpPath, newPath)
|
||||||
scanPath(newPath)
|
scanPathRecursively(newPath)
|
||||||
toast(R.string.file_saved)
|
toast(R.string.file_saved)
|
||||||
|
|
||||||
if (config.keepLastModified) {
|
if (config.keepLastModified) {
|
||||||
|
@ -728,7 +727,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkDeleteConfirmation() {
|
private fun checkDeleteConfirmation() {
|
||||||
if (mSkipConfirmationDialog || config.skipDeleteConfirmation) {
|
if (config.tempSkipDeleteConfirmation || config.skipDeleteConfirmation) {
|
||||||
deleteConfirmed()
|
deleteConfirmed()
|
||||||
} else {
|
} else {
|
||||||
askConfirmDelete()
|
askConfirmDelete()
|
||||||
|
@ -737,7 +736,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
||||||
|
|
||||||
private fun askConfirmDelete() {
|
private fun askConfirmDelete() {
|
||||||
DeleteWithRememberDialog(this, getString(R.string.proceed_with_deletion)) {
|
DeleteWithRememberDialog(this, getString(R.string.proceed_with_deletion)) {
|
||||||
mSkipConfirmationDialog = it
|
config.tempSkipDeleteConfirmation = it
|
||||||
deleteConfirmed()
|
deleteConfirmed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,7 +832,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
||||||
tryDeleteFileDirItem(fileDirItem, true)
|
tryDeleteFileDirItem(fileDirItem, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
scanPath(mDirectory)
|
scanPathRecursively(mDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkOrientation() {
|
private fun checkOrientation() {
|
||||||
|
|
|
@ -61,8 +61,8 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
|
||||||
val dir = dirs[position]
|
val dir = dirs.getOrNull(position) ?: return
|
||||||
val view = holder.bindView(dir, !isPickIntent) { itemView, layoutPosition ->
|
val view = holder.bindView(dir, !isPickIntent) { itemView, adapterPosition ->
|
||||||
setupView(itemView, dir)
|
setupView(itemView, dir)
|
||||||
}
|
}
|
||||||
bindViewHolder(holder, position, view)
|
bindViewHolder(holder, position, view)
|
||||||
|
@ -169,7 +169,10 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
|
||||||
tmb = File(it, tmb.getFilenameFromPath()).absolutePath
|
tmb = File(it, tmb.getFilenameFromPath()).absolutePath
|
||||||
}
|
}
|
||||||
updateDirs(dirs)
|
updateDirs(dirs)
|
||||||
listener?.updateDirectories(dirs.toList() as ArrayList)
|
Thread {
|
||||||
|
activity.galleryDB.DirectoryDao().updateDirectoryAfterRename(firstDir.tmb, firstDir.name, firstDir.path, sourcePath)
|
||||||
|
listener?.refreshItems()
|
||||||
|
}.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,6 +403,7 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
|
||||||
dirs = newDirs.clone() as ArrayList<Directory>
|
dirs = newDirs.clone() as ArrayList<Directory>
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
finishActMode()
|
finishActMode()
|
||||||
|
fastScroller?.measureRecyclerView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class ManageFoldersAdapter(activity: BaseSimpleActivity, var folders: ArrayList<
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val folder = folders[position]
|
val folder = folders[position]
|
||||||
val view = holder.bindView(folder) { itemView, layoutPosition ->
|
val view = holder.bindView(folder) { itemView, adapterPosition ->
|
||||||
setupView(itemView, folder)
|
setupView(itemView, folder)
|
||||||
}
|
}
|
||||||
bindViewHolder(holder, position, view)
|
bindViewHolder(holder, position, view)
|
||||||
|
|
|
@ -45,7 +45,7 @@ class ManageHiddenFoldersAdapter(activity: BaseSimpleActivity, var folders: Arra
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val folder = folders[position]
|
val folder = folders[position]
|
||||||
val view = holder.bindView(folder) { itemView, layoutPosition ->
|
val view = holder.bindView(folder) { itemView, adapterPosition ->
|
||||||
setupView(itemView, folder)
|
setupView(itemView, folder)
|
||||||
}
|
}
|
||||||
bindViewHolder(holder, position, view)
|
bindViewHolder(holder, position, view)
|
||||||
|
|
|
@ -31,7 +31,6 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Medium>,
|
||||||
|
|
||||||
private val config = activity.config
|
private val config = activity.config
|
||||||
private val isListViewType = config.viewTypeFiles == VIEW_TYPE_LIST
|
private val isListViewType = config.viewTypeFiles == VIEW_TYPE_LIST
|
||||||
private var skipConfirmationDialog = false
|
|
||||||
private var visibleItemPaths = ArrayList<String>()
|
private var visibleItemPaths = ArrayList<String>()
|
||||||
private var loadImageInstantly = false
|
private var loadImageInstantly = false
|
||||||
private var delayHandler = Handler(Looper.getMainLooper())
|
private var delayHandler = Handler(Looper.getMainLooper())
|
||||||
|
@ -64,9 +63,9 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Medium>,
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
|
||||||
val medium = media[position]
|
val medium = media.getOrNull(position) ?: return
|
||||||
visibleItemPaths.add(medium.path)
|
visibleItemPaths.add(medium.path)
|
||||||
val view = holder.bindView(medium, !allowMultiplePicks) { itemView, layoutPosition ->
|
val view = holder.bindView(medium, !allowMultiplePicks) { itemView, adapterPosition ->
|
||||||
setupView(itemView, medium)
|
setupView(itemView, medium)
|
||||||
}
|
}
|
||||||
bindViewHolder(holder, position, view)
|
bindViewHolder(holder, position, view)
|
||||||
|
@ -152,12 +151,13 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Medium>,
|
||||||
RenameItemDialog(activity, oldPath) {
|
RenameItemDialog(activity, oldPath) {
|
||||||
Thread {
|
Thread {
|
||||||
activity.updateDBMediaPath(oldPath, it)
|
activity.updateDBMediaPath(oldPath, it)
|
||||||
}.start()
|
|
||||||
|
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
|
enableInstantLoad()
|
||||||
listener?.refreshItems()
|
listener?.refreshItems()
|
||||||
finishActMode()
|
finishActMode()
|
||||||
}
|
}
|
||||||
|
}.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Medium>,
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkDeleteConfirmation() {
|
private fun checkDeleteConfirmation() {
|
||||||
if (skipConfirmationDialog || config.skipDeleteConfirmation) {
|
if (config.tempSkipDeleteConfirmation || config.skipDeleteConfirmation) {
|
||||||
deleteFiles()
|
deleteFiles()
|
||||||
} else {
|
} else {
|
||||||
askConfirmDelete()
|
askConfirmDelete()
|
||||||
|
@ -212,7 +212,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Medium>,
|
||||||
val items = resources.getQuantityString(R.plurals.delete_items, selectedPositions.size, selectedPositions.size)
|
val items = resources.getQuantityString(R.plurals.delete_items, selectedPositions.size, selectedPositions.size)
|
||||||
val question = String.format(resources.getString(R.string.deletion_confirmation), items)
|
val question = String.format(resources.getString(R.string.deletion_confirmation), items)
|
||||||
DeleteWithRememberDialog(activity, question) {
|
DeleteWithRememberDialog(activity, question) {
|
||||||
skipConfirmationDialog = it
|
config.tempSkipDeleteConfirmation = it
|
||||||
deleteFiles()
|
deleteFiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Medium>,
|
||||||
enableInstantLoad()
|
enableInstantLoad()
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
finishActMode()
|
finishActMode()
|
||||||
|
fastScroller?.measureRecyclerView()
|
||||||
}, 100L)
|
}, 100L)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ class MyPagerAdapter(val activity: ViewPagerActivity, fm: FragmentManager, val m
|
||||||
// try fixing TransactionTooLargeException crash on Android Nougat, tip from https://stackoverflow.com/a/43193425/1967672
|
// try fixing TransactionTooLargeException crash on Android Nougat, tip from https://stackoverflow.com/a/43193425/1967672
|
||||||
override fun saveState(): Parcelable? {
|
override fun saveState(): Parcelable? {
|
||||||
val bundle = super.saveState() as Bundle?
|
val bundle = super.saveState() as Bundle?
|
||||||
bundle!!.putParcelableArray("states", null)
|
bundle?.putParcelableArray("states", null)
|
||||||
return bundle
|
return bundle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package com.simplemobiletools.gallery.asynctasks
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
|
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_TAKEN
|
||||||
|
import com.simplemobiletools.commons.models.FileDirItem.Companion.sorting
|
||||||
import com.simplemobiletools.gallery.extensions.config
|
import com.simplemobiletools.gallery.extensions.config
|
||||||
import com.simplemobiletools.gallery.helpers.MediaFetcher
|
import com.simplemobiletools.gallery.helpers.MediaFetcher
|
||||||
import com.simplemobiletools.gallery.models.Medium
|
import com.simplemobiletools.gallery.models.Medium
|
||||||
|
@ -13,19 +15,19 @@ class GetMediaAsynctask(val context: Context, val mPath: String, val isPickImage
|
||||||
private val mediaFetcher = MediaFetcher(context)
|
private val mediaFetcher = MediaFetcher(context)
|
||||||
|
|
||||||
override fun doInBackground(vararg params: Void): ArrayList<Medium> {
|
override fun doInBackground(vararg params: Void): ArrayList<Medium> {
|
||||||
|
val getProperDateTaken = sorting and SORT_BY_DATE_TAKEN != 0
|
||||||
return if (showAll) {
|
return if (showAll) {
|
||||||
val foldersToScan = mediaFetcher.getFoldersToScan("")
|
val foldersToScan = mediaFetcher.getFoldersToScan()
|
||||||
val media = ArrayList<Medium>()
|
val media = ArrayList<Medium>()
|
||||||
for (folder in foldersToScan) {
|
foldersToScan.forEach {
|
||||||
val newMedia = mediaFetcher.getFilesFrom(folder, isPickImage, isPickVideo)
|
val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken)
|
||||||
media.addAll(newMedia)
|
media.addAll(newMedia)
|
||||||
}
|
}
|
||||||
|
|
||||||
Medium.sorting = context.config.getFileSorting("")
|
MediaFetcher(context).sortMedia(media, context.config.getFileSorting(""))
|
||||||
media.sort()
|
|
||||||
media
|
media
|
||||||
} else {
|
} else {
|
||||||
mediaFetcher.getFilesFrom(mPath, isPickImage, isPickVideo)
|
mediaFetcher.getFilesFrom(mPath, isPickImage, isPickVideo, getProperDateTaken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,28 +10,30 @@ import com.simplemobiletools.gallery.models.Directory
|
||||||
import com.simplemobiletools.gallery.models.Medium
|
import com.simplemobiletools.gallery.models.Medium
|
||||||
|
|
||||||
@Database(entities = [(Directory::class), (Medium::class)], version = 2)
|
@Database(entities = [(Directory::class), (Medium::class)], version = 2)
|
||||||
abstract class GalleryDataBase : RoomDatabase() {
|
abstract class GalleryDatabase : RoomDatabase() {
|
||||||
|
|
||||||
abstract fun DirectoryDao(): DirectoryDao
|
abstract fun DirectoryDao(): DirectoryDao
|
||||||
|
|
||||||
abstract fun MediumDao(): MediumDao
|
abstract fun MediumDao(): MediumDao
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var INSTANCE: GalleryDataBase? = null
|
private var db: GalleryDatabase? = null
|
||||||
|
|
||||||
fun getInstance(context: Context): GalleryDataBase {
|
fun getInstance(context: Context): GalleryDatabase {
|
||||||
if (INSTANCE == null) {
|
if (db == null) {
|
||||||
synchronized(GalleryDataBase::class) {
|
synchronized(GalleryDatabase::class) {
|
||||||
INSTANCE = Room.databaseBuilder(context.applicationContext, GalleryDataBase::class.java, "gallery.db")
|
if (db == null) {
|
||||||
|
db = Room.databaseBuilder(context.applicationContext, GalleryDatabase::class.java, "gallery.db")
|
||||||
.fallbackToDestructiveMigration()
|
.fallbackToDestructiveMigration()
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return INSTANCE!!
|
}
|
||||||
|
return db!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun destroyInstance() {
|
fun destroyInstance() {
|
||||||
INSTANCE = null
|
db = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -44,6 +44,7 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, val isDirectorySorti
|
||||||
currSorting and SORT_BY_PATH != 0 -> sortingRadio.sorting_dialog_radio_path
|
currSorting and SORT_BY_PATH != 0 -> sortingRadio.sorting_dialog_radio_path
|
||||||
currSorting and SORT_BY_SIZE != 0 -> sortingRadio.sorting_dialog_radio_size
|
currSorting and SORT_BY_SIZE != 0 -> sortingRadio.sorting_dialog_radio_size
|
||||||
currSorting and SORT_BY_DATE_MODIFIED != 0 -> sortingRadio.sorting_dialog_radio_last_modified
|
currSorting and SORT_BY_DATE_MODIFIED != 0 -> sortingRadio.sorting_dialog_radio_last_modified
|
||||||
|
currSorting and SORT_BY_DATE_TAKEN != 0 -> sortingRadio.sorting_dialog_radio_date_taken
|
||||||
else -> sortingRadio.sorting_dialog_radio_name
|
else -> sortingRadio.sorting_dialog_radio_name
|
||||||
}
|
}
|
||||||
sortBtn.isChecked = true
|
sortBtn.isChecked = true
|
||||||
|
@ -65,7 +66,8 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, val isDirectorySorti
|
||||||
R.id.sorting_dialog_radio_name -> SORT_BY_NAME
|
R.id.sorting_dialog_radio_name -> SORT_BY_NAME
|
||||||
R.id.sorting_dialog_radio_path -> SORT_BY_PATH
|
R.id.sorting_dialog_radio_path -> SORT_BY_PATH
|
||||||
R.id.sorting_dialog_radio_size -> SORT_BY_SIZE
|
R.id.sorting_dialog_radio_size -> SORT_BY_SIZE
|
||||||
else -> SORT_BY_DATE_MODIFIED
|
R.id.sorting_dialog_radio_last_modified -> SORT_BY_DATE_MODIFIED
|
||||||
|
else -> SORT_BY_DATE_TAKEN
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view.sorting_dialog_radio_order.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) {
|
if (view.sorting_dialog_radio_order.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) {
|
||||||
|
|
|
@ -72,6 +72,7 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
|
||||||
}
|
}
|
||||||
|
|
||||||
val scrollHorizontally = activity.config.scrollHorizontally && isGridViewType
|
val scrollHorizontally = activity.config.scrollHorizontally && isGridViewType
|
||||||
|
val sorting = activity.config.directorySorting
|
||||||
view.apply {
|
view.apply {
|
||||||
directories_grid.adapter = adapter
|
directories_grid.adapter = adapter
|
||||||
|
|
||||||
|
@ -84,12 +85,12 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
|
||||||
if (scrollHorizontally) {
|
if (scrollHorizontally) {
|
||||||
directories_horizontal_fastscroller.allowBubbleDisplay = activity.config.showInfoBubble
|
directories_horizontal_fastscroller.allowBubbleDisplay = activity.config.showInfoBubble
|
||||||
directories_horizontal_fastscroller.setViews(directories_grid) {
|
directories_horizontal_fastscroller.setViews(directories_grid) {
|
||||||
directories_horizontal_fastscroller.updateBubbleText(dirs[it].getBubbleText())
|
directories_horizontal_fastscroller.updateBubbleText(dirs[it].getBubbleText(sorting))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
directories_vertical_fastscroller.allowBubbleDisplay = activity.config.showInfoBubble
|
directories_vertical_fastscroller.allowBubbleDisplay = activity.config.showInfoBubble
|
||||||
directories_vertical_fastscroller.setViews(directories_grid) {
|
directories_vertical_fastscroller.setViews(directories_grid) {
|
||||||
directories_vertical_fastscroller.updateBubbleText(dirs[it].getBubbleText())
|
directories_vertical_fastscroller.updateBubbleText(dirs[it].getBubbleText(sorting))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ class PickMediumDialog(val activity: BaseSimpleActivity, val path: String, val c
|
||||||
}
|
}
|
||||||
|
|
||||||
val scrollHorizontally = activity.config.scrollHorizontally && isGridViewType
|
val scrollHorizontally = activity.config.scrollHorizontally && isGridViewType
|
||||||
|
val sorting = activity.config.getFileSorting(path)
|
||||||
view.apply {
|
view.apply {
|
||||||
media_grid.adapter = adapter
|
media_grid.adapter = adapter
|
||||||
|
|
||||||
|
@ -80,12 +81,12 @@ class PickMediumDialog(val activity: BaseSimpleActivity, val path: String, val c
|
||||||
if (scrollHorizontally) {
|
if (scrollHorizontally) {
|
||||||
media_horizontal_fastscroller.allowBubbleDisplay = activity.config.showInfoBubble
|
media_horizontal_fastscroller.allowBubbleDisplay = activity.config.showInfoBubble
|
||||||
media_horizontal_fastscroller.setViews(media_grid) {
|
media_horizontal_fastscroller.setViews(media_grid) {
|
||||||
media_horizontal_fastscroller.updateBubbleText(media[it].getBubbleText())
|
media_horizontal_fastscroller.updateBubbleText(media[it].getBubbleText(sorting))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
media_vertical_fastscroller.allowBubbleDisplay = activity.config.showInfoBubble
|
media_vertical_fastscroller.allowBubbleDisplay = activity.config.showInfoBubble
|
||||||
media_vertical_fastscroller.setViews(media_grid) {
|
media_vertical_fastscroller.setViews(media_grid) {
|
||||||
media_vertical_fastscroller.updateBubbleText(media[it].getBubbleText())
|
media_vertical_fastscroller.updateBubbleText(media[it].getBubbleText(sorting))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ fun BaseSimpleActivity.addNoMedia(path: String, callback: () -> Unit) {
|
||||||
val fileDocument = getDocumentFile(path)
|
val fileDocument = getDocumentFile(path)
|
||||||
if (fileDocument?.exists() == true && fileDocument.isDirectory) {
|
if (fileDocument?.exists() == true && fileDocument.isDirectory) {
|
||||||
fileDocument.createFile("", NOMEDIA)
|
fileDocument.createFile("", NOMEDIA)
|
||||||
applicationContext.scanFile(file) {
|
applicationContext.scanFileRecursively(file) {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -117,7 +117,7 @@ fun BaseSimpleActivity.addNoMedia(path: String, callback: () -> Unit) {
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
file.createNewFile()
|
file.createNewFile()
|
||||||
applicationContext.scanFile(file) {
|
applicationContext.scanFileRecursively(file) {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -16,11 +16,11 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.OTG_PATH
|
import com.simplemobiletools.commons.helpers.*
|
||||||
import com.simplemobiletools.gallery.R
|
import com.simplemobiletools.gallery.R
|
||||||
import com.simplemobiletools.gallery.activities.SettingsActivity
|
import com.simplemobiletools.gallery.activities.SettingsActivity
|
||||||
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
|
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
|
||||||
import com.simplemobiletools.gallery.databases.GalleryDataBase
|
import com.simplemobiletools.gallery.databases.GalleryDatabase
|
||||||
import com.simplemobiletools.gallery.helpers.*
|
import com.simplemobiletools.gallery.helpers.*
|
||||||
import com.simplemobiletools.gallery.interfaces.DirectoryDao
|
import com.simplemobiletools.gallery.interfaces.DirectoryDao
|
||||||
import com.simplemobiletools.gallery.models.Directory
|
import com.simplemobiletools.gallery.models.Directory
|
||||||
|
@ -70,7 +70,7 @@ fun Context.launchSettings() {
|
||||||
|
|
||||||
val Context.config: Config get() = Config.newInstance(applicationContext)
|
val Context.config: Config get() = Config.newInstance(applicationContext)
|
||||||
|
|
||||||
val Context.galleryDB: GalleryDataBase get() = GalleryDataBase.getInstance(applicationContext)
|
val Context.galleryDB: GalleryDatabase get() = GalleryDatabase.getInstance(applicationContext)
|
||||||
|
|
||||||
fun Context.movePinnedDirectoriesToFront(dirs: ArrayList<Directory>): ArrayList<Directory> {
|
fun Context.movePinnedDirectoriesToFront(dirs: ArrayList<Directory>): ArrayList<Directory> {
|
||||||
val foundFolders = ArrayList<Directory>()
|
val foundFolders = ArrayList<Directory>()
|
||||||
|
@ -96,9 +96,26 @@ fun Context.movePinnedDirectoriesToFront(dirs: ArrayList<Directory>): ArrayList<
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun Context.getSortedDirectories(source: ArrayList<Directory>): ArrayList<Directory> {
|
fun Context.getSortedDirectories(source: ArrayList<Directory>): ArrayList<Directory> {
|
||||||
Directory.sorting = config.directorySorting
|
val sorting = config.directorySorting
|
||||||
val dirs = source.clone() as ArrayList<Directory>
|
val dirs = source.clone() as ArrayList<Directory>
|
||||||
dirs.sort()
|
|
||||||
|
dirs.sortWith(Comparator { o1, o2 ->
|
||||||
|
o1 as Directory
|
||||||
|
o2 as Directory
|
||||||
|
var result = when {
|
||||||
|
sorting and SORT_BY_NAME != 0 -> AlphanumericComparator().compare(o1.name.toLowerCase(), o2.name.toLowerCase())
|
||||||
|
sorting and SORT_BY_PATH != 0 -> AlphanumericComparator().compare(o1.path.toLowerCase(), o2.path.toLowerCase())
|
||||||
|
sorting and SORT_BY_SIZE != 0 -> o1.size.compareTo(o2.size)
|
||||||
|
sorting and SORT_BY_DATE_MODIFIED != 0 -> o1.modified.compareTo(o2.modified)
|
||||||
|
else -> o1.taken.compareTo(o2.taken)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sorting and SORT_DESCENDING != 0) {
|
||||||
|
result *= -1
|
||||||
|
}
|
||||||
|
result
|
||||||
|
})
|
||||||
|
|
||||||
return movePinnedDirectoriesToFront(dirs)
|
return movePinnedDirectoriesToFront(dirs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,34 +293,51 @@ fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly:
|
||||||
}
|
}
|
||||||
}) as ArrayList<Directory>
|
}) as ArrayList<Directory>
|
||||||
|
|
||||||
callback(filteredDirectories.distinctBy { it.path.getDistinctPath() } as ArrayList<Directory>)
|
val hiddenString = resources.getString(R.string.hidden)
|
||||||
|
filteredDirectories.forEach {
|
||||||
|
it.name = if (File(it.path).doesThisOrParentHaveNoMedia() && !it.path.isThisOrParentIncluded(includedPaths)) {
|
||||||
|
"${it.name.removeSuffix(hiddenString).trim()} $hiddenString"
|
||||||
|
} else {
|
||||||
|
it.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
removeInvalidDBDirectories(directories, directoryDao)
|
val clone = filteredDirectories.clone() as ArrayList<Directory>
|
||||||
|
callback(clone.distinctBy { it.path.getDistinctPath() } as ArrayList<Directory>)
|
||||||
|
|
||||||
|
removeInvalidDBDirectories(filteredDirectories, directoryDao)
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, callback: (ArrayList<Medium>) -> Unit) {
|
fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, callback: (ArrayList<Medium>) -> Unit) {
|
||||||
Thread {
|
Thread {
|
||||||
val mediumDao = galleryDB.MediumDao()
|
val mediumDao = galleryDB.MediumDao()
|
||||||
val media = (if (path == "/") mediumDao.getAll() else mediumDao.getMediaFromPath(path)) as ArrayList<Medium>
|
val foldersToScan = if (path == "/") MediaFetcher(this).getFoldersToScan() else arrayListOf(path)
|
||||||
|
var media = ArrayList<Medium>()
|
||||||
val shouldShowHidden = config.shouldShowHidden
|
val shouldShowHidden = config.shouldShowHidden
|
||||||
var filteredMedia = media
|
foldersToScan.forEach {
|
||||||
|
val currMedia = mediumDao.getMediaFromPath(it)
|
||||||
|
media.addAll(currMedia)
|
||||||
|
}
|
||||||
|
|
||||||
if (!shouldShowHidden) {
|
if (!shouldShowHidden) {
|
||||||
filteredMedia = media.filter { !it.name.startsWith('.') } as ArrayList<Medium>
|
media = media.filter { !it.path.contains("/.") } as ArrayList<Medium>
|
||||||
}
|
}
|
||||||
|
|
||||||
val filterMedia = config.filterMedia
|
val filterMedia = config.filterMedia
|
||||||
filteredMedia = (when {
|
media = (when {
|
||||||
getVideosOnly -> filteredMedia.filter { it.type == TYPE_VIDEOS }
|
getVideosOnly -> media.filter { it.type == TYPE_VIDEOS }
|
||||||
getImagesOnly -> filteredMedia.filter { it.type == TYPE_IMAGES }
|
getImagesOnly -> media.filter { it.type == TYPE_IMAGES }
|
||||||
else -> filteredMedia.filter {
|
else -> media.filter {
|
||||||
(filterMedia and TYPE_IMAGES != 0 && it.type == TYPE_IMAGES) ||
|
(filterMedia and TYPE_IMAGES != 0 && it.type == TYPE_IMAGES) ||
|
||||||
(filterMedia and TYPE_VIDEOS != 0 && it.type == TYPE_VIDEOS) ||
|
(filterMedia and TYPE_VIDEOS != 0 && it.type == TYPE_VIDEOS) ||
|
||||||
(filterMedia and TYPE_GIFS != 0 && it.type == TYPE_GIFS)
|
(filterMedia and TYPE_GIFS != 0 && it.type == TYPE_GIFS)
|
||||||
}
|
}
|
||||||
}) as ArrayList<Medium>
|
}) as ArrayList<Medium>
|
||||||
|
|
||||||
callback(filteredMedia)
|
MediaFetcher(this).sortMedia(media, config.getFileSorting(path))
|
||||||
|
callback(media.clone() as ArrayList<Medium>)
|
||||||
|
|
||||||
media.filter { !getDoesFilePathExist(it.path) }.forEach {
|
media.filter { !getDoesFilePathExist(it.path) }.forEach {
|
||||||
mediumDao.deleteMediumPath(it.path)
|
mediumDao.deleteMediumPath(it.path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import com.google.gson.Gson
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
import com.simplemobiletools.commons.helpers.BaseConfig
|
import com.simplemobiletools.commons.helpers.BaseConfig
|
||||||
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
|
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
|
||||||
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_TAKEN
|
|
||||||
import com.simplemobiletools.commons.helpers.SORT_DESCENDING
|
import com.simplemobiletools.commons.helpers.SORT_DESCENDING
|
||||||
import com.simplemobiletools.gallery.R
|
import com.simplemobiletools.gallery.R
|
||||||
import com.simplemobiletools.gallery.models.AlbumCover
|
import com.simplemobiletools.gallery.models.AlbumCover
|
||||||
|
@ -18,13 +17,7 @@ class Config(context: Context) : BaseConfig(context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var directorySorting: Int
|
var directorySorting: Int
|
||||||
get(): Int {
|
get(): Int = prefs.getInt(DIRECTORY_SORT_ORDER, SORT_BY_DATE_MODIFIED or SORT_DESCENDING)
|
||||||
var sort = prefs.getInt(DIRECTORY_SORT_ORDER, SORT_BY_DATE_MODIFIED or SORT_DESCENDING)
|
|
||||||
if (sort and SORT_BY_DATE_TAKEN != 0) {
|
|
||||||
sort = sort - SORT_BY_DATE_TAKEN + SORT_BY_DATE_MODIFIED
|
|
||||||
}
|
|
||||||
return sort
|
|
||||||
}
|
|
||||||
set(order) = prefs.edit().putInt(DIRECTORY_SORT_ORDER, order).apply()
|
set(order) = prefs.edit().putInt(DIRECTORY_SORT_ORDER, order).apply()
|
||||||
|
|
||||||
fun saveFileSorting(path: String, value: Int) {
|
fun saveFileSorting(path: String, value: Int) {
|
||||||
|
@ -35,13 +28,7 @@ class Config(context: Context) : BaseConfig(context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFileSorting(path: String): Int {
|
fun getFileSorting(path: String) = prefs.getInt(SORT_FOLDER_PREFIX + path.toLowerCase(), sorting)
|
||||||
var sort = prefs.getInt(SORT_FOLDER_PREFIX + path.toLowerCase(), sorting)
|
|
||||||
if (sort and SORT_BY_DATE_TAKEN != 0) {
|
|
||||||
sort = sort - SORT_BY_DATE_TAKEN + SORT_BY_DATE_MODIFIED
|
|
||||||
}
|
|
||||||
return sort
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeFileSorting(path: String) {
|
fun removeFileSorting(path: String) {
|
||||||
prefs.edit().remove(SORT_FOLDER_PREFIX + path.toLowerCase()).apply()
|
prefs.edit().remove(SORT_FOLDER_PREFIX + path.toLowerCase()).apply()
|
||||||
|
@ -331,4 +318,8 @@ class Config(context: Context) : BaseConfig(context) {
|
||||||
var wasOTGHandled: Boolean
|
var wasOTGHandled: Boolean
|
||||||
get() = prefs.getBoolean(WAS_OTG_HANDLED, false)
|
get() = prefs.getBoolean(WAS_OTG_HANDLED, false)
|
||||||
set(wasOTGHandled) = prefs.edit().putBoolean(WAS_OTG_HANDLED, wasOTGHandled).apply()
|
set(wasOTGHandled) = prefs.edit().putBoolean(WAS_OTG_HANDLED, wasOTGHandled).apply()
|
||||||
|
|
||||||
|
var tempSkipDeleteConfirmation: Boolean
|
||||||
|
get() = prefs.getBoolean(TEMP_SKIP_DELETE_CONFIRMATION, false)
|
||||||
|
set(tempSkipDeleteConfirmation) = prefs.edit().putBoolean(TEMP_SKIP_DELETE_CONFIRMATION, tempSkipDeleteConfirmation).apply()
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ const val DO_EXTRA_CHECK = "do_extra_check"
|
||||||
const val WAS_NEW_APP_SHOWN = "was_new_app_shown_clock"
|
const val WAS_NEW_APP_SHOWN = "was_new_app_shown_clock"
|
||||||
const val LAST_FILEPICKER_PATH = "last_filepicker_path"
|
const val LAST_FILEPICKER_PATH = "last_filepicker_path"
|
||||||
const val WAS_OTG_HANDLED = "was_otg_handled"
|
const val WAS_OTG_HANDLED = "was_otg_handled"
|
||||||
|
const val TEMP_SKIP_DELETE_CONFIRMATION = "temp_skip_delete_confirmation"
|
||||||
|
|
||||||
// slideshow
|
// slideshow
|
||||||
const val SLIDESHOW_INTERVAL = "slideshow_interval"
|
const val SLIDESHOW_INTERVAL = "slideshow_interval"
|
||||||
|
|
|
@ -5,9 +5,7 @@ import android.database.Cursor
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.OTG_PATH
|
import com.simplemobiletools.commons.helpers.*
|
||||||
import com.simplemobiletools.commons.helpers.photoExtensions
|
|
||||||
import com.simplemobiletools.commons.helpers.videoExtensions
|
|
||||||
import com.simplemobiletools.gallery.extensions.config
|
import com.simplemobiletools.gallery.extensions.config
|
||||||
import com.simplemobiletools.gallery.extensions.getDistinctPath
|
import com.simplemobiletools.gallery.extensions.getDistinctPath
|
||||||
import com.simplemobiletools.gallery.extensions.getOTGFolderChildren
|
import com.simplemobiletools.gallery.extensions.getOTGFolderChildren
|
||||||
|
@ -18,7 +16,7 @@ import java.io.File
|
||||||
class MediaFetcher(val context: Context) {
|
class MediaFetcher(val context: Context) {
|
||||||
var shouldStop = false
|
var shouldStop = false
|
||||||
|
|
||||||
fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean): ArrayList<Medium> {
|
fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean, getProperDateTaken: Boolean): ArrayList<Medium> {
|
||||||
val filterMedia = context.config.filterMedia
|
val filterMedia = context.config.filterMedia
|
||||||
if (filterMedia == 0) {
|
if (filterMedia == 0) {
|
||||||
return ArrayList()
|
return ArrayList()
|
||||||
|
@ -29,37 +27,32 @@ class MediaFetcher(val context: Context) {
|
||||||
val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia)
|
val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia)
|
||||||
curMedia.addAll(newMedia)
|
curMedia.addAll(newMedia)
|
||||||
} else {
|
} else {
|
||||||
val newMedia = fetchFolderContent(curPath, isPickImage, isPickVideo, filterMedia)
|
val newMedia = getMediaInFolder(curPath, isPickImage, isPickVideo, filterMedia, getProperDateTaken)
|
||||||
curMedia.addAll(newMedia)
|
curMedia.addAll(newMedia)
|
||||||
}
|
}
|
||||||
|
|
||||||
Medium.sorting = context.config.getFileSorting(curPath)
|
sortMedia(curMedia, context.config.getFileSorting(curPath))
|
||||||
curMedia.sort()
|
|
||||||
return curMedia
|
return curMedia
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFoldersToScan(path: String): ArrayList<String> {
|
fun getFoldersToScan(): ArrayList<String> {
|
||||||
val filterMedia = context.config.filterMedia
|
val filterMedia = context.config.filterMedia
|
||||||
val projection = arrayOf(MediaStore.Images.Media.DATA)
|
val projection = arrayOf(MediaStore.Images.Media.DATA)
|
||||||
val uri = MediaStore.Files.getContentUri("external")
|
val uri = MediaStore.Files.getContentUri("external")
|
||||||
|
|
||||||
val selection = "${getSelectionQuery(path, filterMedia)} ${MediaStore.Images.ImageColumns.BUCKET_ID} IS NOT NULL) GROUP BY (${MediaStore.Images.ImageColumns.BUCKET_ID}"
|
val selection = "${getSelectionQuery(filterMedia)} ${MediaStore.Images.ImageColumns.BUCKET_ID} IS NOT NULL) GROUP BY (${MediaStore.Images.ImageColumns.BUCKET_ID}"
|
||||||
val selectionArgs = getSelectionArgsQuery(path, filterMedia).toTypedArray()
|
val selectionArgs = getSelectionArgsQuery(filterMedia).toTypedArray()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
|
val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
|
||||||
parseCursor(cursor, path)
|
parseCursor(cursor)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
ArrayList()
|
ArrayList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSelectionQuery(path: String, filterMedia: Int): String {
|
private fun getSelectionQuery(filterMedia: Int): String {
|
||||||
val query = StringBuilder()
|
val query = StringBuilder()
|
||||||
if (path.isNotEmpty()) {
|
|
||||||
query.append("${MediaStore.Images.Media.DATA} LIKE ? AND ${MediaStore.Images.Media.DATA} NOT LIKE ? AND ")
|
|
||||||
}
|
|
||||||
|
|
||||||
query.append("(")
|
query.append("(")
|
||||||
if (filterMedia and TYPE_IMAGES != 0) {
|
if (filterMedia and TYPE_IMAGES != 0) {
|
||||||
photoExtensions.forEach {
|
photoExtensions.forEach {
|
||||||
|
@ -82,13 +75,8 @@ class MediaFetcher(val context: Context) {
|
||||||
return selectionQuery
|
return selectionQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSelectionArgsQuery(path: String, filterMedia: Int): ArrayList<String> {
|
private fun getSelectionArgsQuery(filterMedia: Int): ArrayList<String> {
|
||||||
val args = ArrayList<String>()
|
val args = ArrayList<String>()
|
||||||
if (path.isNotEmpty()) {
|
|
||||||
args.add("$path/%")
|
|
||||||
args.add("$path/%/%")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filterMedia and TYPE_IMAGES != 0) {
|
if (filterMedia and TYPE_IMAGES != 0) {
|
||||||
photoExtensions.forEach {
|
photoExtensions.forEach {
|
||||||
args.add("%$it")
|
args.add("%$it")
|
||||||
|
@ -108,7 +96,7 @@ class MediaFetcher(val context: Context) {
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseCursor(cursor: Cursor, curPath: String): ArrayList<String> {
|
private fun parseCursor(cursor: Cursor): ArrayList<String> {
|
||||||
val config = context.config
|
val config = context.config
|
||||||
val includedFolders = config.includedFolders
|
val includedFolders = config.includedFolders
|
||||||
var foldersToScan = ArrayList<String>()
|
var foldersToScan = ArrayList<String>()
|
||||||
|
@ -126,20 +114,12 @@ class MediaFetcher(val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
includedFolders.forEach {
|
includedFolders.forEach {
|
||||||
if (curPath.isEmpty()) {
|
|
||||||
addFolder(foldersToScan, it)
|
addFolder(foldersToScan, it)
|
||||||
} else if (curPath == it) {
|
|
||||||
foldersToScan.add(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val showHidden = config.shouldShowHidden
|
val showHidden = config.shouldShowHidden
|
||||||
val excludedFolders = config.excludedFolders
|
val excludedFolders = config.excludedFolders
|
||||||
foldersToScan = foldersToScan.filter { it.shouldFolderBeVisible(excludedFolders, includedFolders, showHidden) } as ArrayList<String>
|
foldersToScan = foldersToScan.filter { it.shouldFolderBeVisible(excludedFolders, includedFolders, showHidden) } as ArrayList<String>
|
||||||
if (config.isThirdPartyIntent && curPath.isNotEmpty()) {
|
|
||||||
foldersToScan.add(curPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
return foldersToScan.distinctBy { it.getDistinctPath() } as ArrayList<String>
|
return foldersToScan.distinctBy { it.getDistinctPath() } as ArrayList<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,19 +143,12 @@ class MediaFetcher(val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchFolderContent(path: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int): ArrayList<Medium> {
|
private fun getMediaInFolder(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int, getProperDateTaken: Boolean): ArrayList<Medium> {
|
||||||
return if (path.startsWith(OTG_PATH)) {
|
|
||||||
getMediaOnOTG(path, isPickImage, isPickVideo, filterMedia)
|
|
||||||
} else {
|
|
||||||
getMediaInFolder(path, isPickImage, isPickVideo, filterMedia)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getMediaInFolder(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int): ArrayList<Medium> {
|
|
||||||
val media = ArrayList<Medium>()
|
val media = ArrayList<Medium>()
|
||||||
val files = File(folder).listFiles() ?: return media
|
val files = File(folder).listFiles() ?: return media
|
||||||
val doExtraCheck = context.config.doExtraCheck
|
val doExtraCheck = context.config.doExtraCheck
|
||||||
val showHidden = context.config.shouldShowHidden
|
val showHidden = context.config.shouldShowHidden
|
||||||
|
val dateTakens = if (getProperDateTaken) getFolderDateTakens(folder) else HashMap()
|
||||||
|
|
||||||
for (file in files) {
|
for (file in files) {
|
||||||
if (shouldStop) {
|
if (shouldStop) {
|
||||||
|
@ -206,8 +179,12 @@ class MediaFetcher(val context: Context) {
|
||||||
if (size <= 0L || (doExtraCheck && !file.exists()))
|
if (size <= 0L || (doExtraCheck && !file.exists()))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
val dateTaken = file.lastModified()
|
val lastModified = file.lastModified()
|
||||||
val dateModified = file.lastModified()
|
var dateTaken = lastModified
|
||||||
|
|
||||||
|
if (getProperDateTaken) {
|
||||||
|
dateTaken = dateTakens.remove(filename) ?: lastModified
|
||||||
|
}
|
||||||
|
|
||||||
val type = when {
|
val type = when {
|
||||||
isImage -> TYPE_IMAGES
|
isImage -> TYPE_IMAGES
|
||||||
|
@ -215,7 +192,7 @@ class MediaFetcher(val context: Context) {
|
||||||
else -> TYPE_GIFS
|
else -> TYPE_GIFS
|
||||||
}
|
}
|
||||||
|
|
||||||
val medium = Medium(null, filename, file.absolutePath, folder, dateModified, dateTaken, size, type)
|
val medium = Medium(null, filename, file.absolutePath, folder, lastModified, dateTaken, size, type)
|
||||||
media.add(medium)
|
media.add(medium)
|
||||||
}
|
}
|
||||||
return media
|
return media
|
||||||
|
@ -272,4 +249,51 @@ class MediaFetcher(val context: Context) {
|
||||||
|
|
||||||
return media
|
return media
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getFolderDateTakens(folder: String): HashMap<String, Long> {
|
||||||
|
val projection = arrayOf(
|
||||||
|
MediaStore.Images.Media.DISPLAY_NAME,
|
||||||
|
MediaStore.Images.Media.DATE_TAKEN
|
||||||
|
)
|
||||||
|
|
||||||
|
val uri = MediaStore.Files.getContentUri("external")
|
||||||
|
val selection = "${MediaStore.Images.Media.DATA} LIKE ? AND ${MediaStore.Images.Media.DATA} NOT LIKE ?"
|
||||||
|
val selectionArgs = arrayOf("$folder/%", "$folder/%/%")
|
||||||
|
|
||||||
|
val dateTakens = HashMap<String, Long>()
|
||||||
|
val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
|
||||||
|
cursor.use {
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
val path = cursor.getStringValue(MediaStore.Images.Media.DISPLAY_NAME)
|
||||||
|
val dateTaken = cursor.getLongValue(MediaStore.Images.Media.DATE_TAKEN)
|
||||||
|
dateTakens[path] = dateTaken
|
||||||
|
} catch (e: Exception) {
|
||||||
|
}
|
||||||
|
} while (cursor.moveToNext())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateTakens
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sortMedia(media: ArrayList<Medium>, sorting: Int) {
|
||||||
|
media.sortWith(Comparator { o1, o2 ->
|
||||||
|
o1 as Medium
|
||||||
|
o2 as Medium
|
||||||
|
var result = when {
|
||||||
|
sorting and SORT_BY_NAME != 0 -> AlphanumericComparator().compare(o1.name.toLowerCase(), o2.name.toLowerCase())
|
||||||
|
sorting and SORT_BY_PATH != 0 -> AlphanumericComparator().compare(o1.path.toLowerCase(), o2.path.toLowerCase())
|
||||||
|
sorting and SORT_BY_SIZE != 0 -> o1.size.compareTo(o2.size)
|
||||||
|
sorting and SORT_BY_DATE_MODIFIED != 0 -> o1.modified.compareTo(o2.modified)
|
||||||
|
else -> o1.taken.compareTo(o2.taken)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sorting and SORT_DESCENDING != 0) {
|
||||||
|
result *= -1
|
||||||
|
}
|
||||||
|
result
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,7 @@ interface DirectoryDao {
|
||||||
|
|
||||||
@Query("UPDATE OR REPLACE directories SET thumbnail = :thumbnail, media_count = :mediaCnt, last_modified = :lastModified, date_taken = :dateTaken, size = :size, media_types = :mediaTypes WHERE path = :path")
|
@Query("UPDATE OR REPLACE directories SET thumbnail = :thumbnail, media_count = :mediaCnt, last_modified = :lastModified, date_taken = :dateTaken, size = :size, media_types = :mediaTypes WHERE path = :path")
|
||||||
fun updateDirectory(path: String, thumbnail: String, mediaCnt: Int, lastModified: Long, dateTaken: Long, size: Long, mediaTypes: Int)
|
fun updateDirectory(path: String, thumbnail: String, mediaCnt: Int, lastModified: Long, dateTaken: Long, size: Long, mediaTypes: Int)
|
||||||
|
|
||||||
|
@Query("UPDATE directories SET thumbnail = :thumbnail, filename = :name, path = :newPath WHERE path = :oldPath")
|
||||||
|
fun updateDirectoryAfterRename(thumbnail: String, name: String, newPath: String, oldPath: String)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,6 @@ import com.simplemobiletools.gallery.models.Medium
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface MediumDao {
|
interface MediumDao {
|
||||||
@Query("SELECT * FROM media")
|
|
||||||
fun getAll(): List<Medium>
|
|
||||||
|
|
||||||
@Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type FROM media WHERE parent_path = :path")
|
@Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type FROM media WHERE parent_path = :path")
|
||||||
fun getMediaFromPath(path: String): List<Medium>
|
fun getMediaFromPath(path: String): List<Medium>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,10 @@ import android.arch.persistence.room.Index
|
||||||
import android.arch.persistence.room.PrimaryKey
|
import android.arch.persistence.room.PrimaryKey
|
||||||
import com.simplemobiletools.commons.extensions.formatDate
|
import com.simplemobiletools.commons.extensions.formatDate
|
||||||
import com.simplemobiletools.commons.extensions.formatSize
|
import com.simplemobiletools.commons.extensions.formatSize
|
||||||
import com.simplemobiletools.commons.helpers.*
|
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
|
||||||
|
import com.simplemobiletools.commons.helpers.SORT_BY_NAME
|
||||||
|
import com.simplemobiletools.commons.helpers.SORT_BY_PATH
|
||||||
|
import com.simplemobiletools.commons.helpers.SORT_BY_SIZE
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
@Entity(tableName = "directories", indices = [Index(value = "path", unique = true)])
|
@Entity(tableName = "directories", indices = [Index(value = "path", unique = true)])
|
||||||
|
@ -20,42 +23,13 @@ data class Directory(
|
||||||
@ColumnInfo(name = "date_taken") var taken: Long,
|
@ColumnInfo(name = "date_taken") var taken: Long,
|
||||||
@ColumnInfo(name = "size") var size: Long,
|
@ColumnInfo(name = "size") var size: Long,
|
||||||
@ColumnInfo(name = "location") val location: Int,
|
@ColumnInfo(name = "location") val location: Int,
|
||||||
@ColumnInfo(name = "media_types") var types: Int) : Serializable, Comparable<Directory> {
|
@ColumnInfo(name = "media_types") var types: Int) : Serializable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val serialVersionUID = -6553345863555455L
|
private const val serialVersionUID = -6553345863555455L
|
||||||
var sorting: Int = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun compareTo(other: Directory): Int {
|
fun getBubbleText(sorting: Int) = when {
|
||||||
var result: Int
|
|
||||||
when {
|
|
||||||
sorting and SORT_BY_NAME != 0 -> result = AlphanumericComparator().compare(name.toLowerCase(), other.name.toLowerCase())
|
|
||||||
sorting and SORT_BY_PATH != 0 -> result = AlphanumericComparator().compare(path.toLowerCase(), other.path.toLowerCase())
|
|
||||||
sorting and SORT_BY_SIZE != 0 -> result = when {
|
|
||||||
size == other.size -> 0
|
|
||||||
size > other.size -> 1
|
|
||||||
else -> -1
|
|
||||||
}
|
|
||||||
sorting and SORT_BY_DATE_MODIFIED != 0 -> result = when {
|
|
||||||
modified == other.modified -> 0
|
|
||||||
modified > other.modified -> 1
|
|
||||||
else -> -1
|
|
||||||
}
|
|
||||||
else -> result = when {
|
|
||||||
taken == other.taken -> 0
|
|
||||||
taken > other.taken -> 1
|
|
||||||
else -> -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sorting and SORT_DESCENDING != 0) {
|
|
||||||
result *= -1
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getBubbleText() = when {
|
|
||||||
sorting and SORT_BY_NAME != 0 -> name
|
sorting and SORT_BY_NAME != 0 -> name
|
||||||
sorting and SORT_BY_PATH != 0 -> path
|
sorting and SORT_BY_PATH != 0 -> path
|
||||||
sorting and SORT_BY_SIZE != 0 -> size.formatSize()
|
sorting and SORT_BY_SIZE != 0 -> size.formatSize()
|
||||||
|
|
|
@ -7,7 +7,10 @@ import android.arch.persistence.room.PrimaryKey
|
||||||
import com.simplemobiletools.commons.extensions.formatDate
|
import com.simplemobiletools.commons.extensions.formatDate
|
||||||
import com.simplemobiletools.commons.extensions.formatSize
|
import com.simplemobiletools.commons.extensions.formatSize
|
||||||
import com.simplemobiletools.commons.extensions.isDng
|
import com.simplemobiletools.commons.extensions.isDng
|
||||||
import com.simplemobiletools.commons.helpers.*
|
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
|
||||||
|
import com.simplemobiletools.commons.helpers.SORT_BY_NAME
|
||||||
|
import com.simplemobiletools.commons.helpers.SORT_BY_PATH
|
||||||
|
import com.simplemobiletools.commons.helpers.SORT_BY_SIZE
|
||||||
import com.simplemobiletools.gallery.helpers.TYPE_GIFS
|
import com.simplemobiletools.gallery.helpers.TYPE_GIFS
|
||||||
import com.simplemobiletools.gallery.helpers.TYPE_IMAGES
|
import com.simplemobiletools.gallery.helpers.TYPE_IMAGES
|
||||||
import com.simplemobiletools.gallery.helpers.TYPE_VIDEOS
|
import com.simplemobiletools.gallery.helpers.TYPE_VIDEOS
|
||||||
|
@ -20,13 +23,12 @@ data class Medium(
|
||||||
@ColumnInfo(name = "full_path") var path: String,
|
@ColumnInfo(name = "full_path") var path: String,
|
||||||
@ColumnInfo(name = "parent_path") var parentPath: String,
|
@ColumnInfo(name = "parent_path") var parentPath: String,
|
||||||
@ColumnInfo(name = "last_modified") val modified: Long,
|
@ColumnInfo(name = "last_modified") val modified: Long,
|
||||||
@ColumnInfo(name = "date_taken") val taken: Long,
|
@ColumnInfo(name = "date_taken") var taken: Long,
|
||||||
@ColumnInfo(name = "size") val size: Long,
|
@ColumnInfo(name = "size") val size: Long,
|
||||||
@ColumnInfo(name = "type") val type: Int) : Serializable, Comparable<Medium> {
|
@ColumnInfo(name = "type") val type: Int) : Serializable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val serialVersionUID = -6553149366975455L
|
private const val serialVersionUID = -6553149366975455L
|
||||||
var sorting: Int = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isGif() = type == TYPE_GIFS
|
fun isGif() = type == TYPE_GIFS
|
||||||
|
@ -37,35 +39,7 @@ data class Medium(
|
||||||
|
|
||||||
fun isDng() = path.isDng()
|
fun isDng() = path.isDng()
|
||||||
|
|
||||||
override fun compareTo(other: Medium): Int {
|
fun getBubbleText(sorting: Int) = when {
|
||||||
var result: Int
|
|
||||||
when {
|
|
||||||
sorting and SORT_BY_NAME != 0 -> result = AlphanumericComparator().compare(name.toLowerCase(), other.name.toLowerCase())
|
|
||||||
sorting and SORT_BY_PATH != 0 -> result = AlphanumericComparator().compare(path.toLowerCase(), other.path.toLowerCase())
|
|
||||||
sorting and SORT_BY_SIZE != 0 -> result = when {
|
|
||||||
size == other.size -> 0
|
|
||||||
size > other.size -> 1
|
|
||||||
else -> -1
|
|
||||||
}
|
|
||||||
sorting and SORT_BY_DATE_MODIFIED != 0 -> result = when {
|
|
||||||
modified == other.modified -> 0
|
|
||||||
modified > other.modified -> 1
|
|
||||||
else -> -1
|
|
||||||
}
|
|
||||||
else -> result = when {
|
|
||||||
taken == other.taken -> 0
|
|
||||||
taken > other.taken -> 1
|
|
||||||
else -> -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sorting and SORT_DESCENDING != 0) {
|
|
||||||
result *= -1
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getBubbleText() = when {
|
|
||||||
sorting and SORT_BY_NAME != 0 -> name
|
sorting and SORT_BY_NAME != 0 -> name
|
||||||
sorting and SORT_BY_PATH != 0 -> path
|
sorting and SORT_BY_PATH != 0 -> path
|
||||||
sorting and SORT_BY_SIZE != 0 -> size.formatSize()
|
sorting and SORT_BY_SIZE != 0 -> size.formatSize()
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
<vector
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportHeight="108"
|
|
||||||
android:viewportWidth="108">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:pathData="M63.58,40.16m-5.73,0a5.73,5.73 0,1 1,11.47 0a5.73,5.73 0,1 1,-11.47 0"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:pathData="M47.37,46.64l-17.45,25.43l45.46,0l-9.89,-16.21l-5.9,8.39z"/>
|
|
||||||
</vector>
|
|
|
@ -52,6 +52,14 @@
|
||||||
android:paddingTop="@dimen/medium_margin"
|
android:paddingTop="@dimen/medium_margin"
|
||||||
android:text="@string/last_modified"/>
|
android:text="@string/last_modified"/>
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyCompatRadioButton
|
||||||
|
android:id="@+id/sorting_dialog_radio_date_taken"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="@dimen/medium_margin"
|
||||||
|
android:paddingTop="@dimen/medium_margin"
|
||||||
|
android:text="@string/date_taken"/>
|
||||||
|
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
||||||
<include
|
<include
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@color/color_primary"/>
|
<background android:drawable="@color/md_orange_700"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
|
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_amber.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_amber_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_blue.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_blue_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_blue_grey_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_brown.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_brown_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_cyan.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_cyan_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_deep_orange_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_deep_purple_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_green.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_green_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_grey_black"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_indigo_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_light_blue_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_light_green_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_lime.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_lime_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_pink.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_pink_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_purple_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_red.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_red_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_teal.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_teal_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/md_yellow_700"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_amber.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_blue.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_blue_grey.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_brown.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_cyan.png
Normal file
After Width: | Height: | Size: 4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_deep_orange.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_deep_purple.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_green.png
Normal file
After Width: | Height: | Size: 4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_grey_black.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_indigo.png
Normal file
After Width: | Height: | Size: 4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_light_blue.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_light_green.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_lime.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_pink.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_purple.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_red.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_teal.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_yellow.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_amber.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_blue.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_blue_grey.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_brown.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_cyan.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_deep_orange.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_deep_purple.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_green.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_grey_black.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_indigo.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_light_blue.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_light_green.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_lime.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_pink.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_purple.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_red.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_teal.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_yellow.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 6.1 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_amber.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_blue.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_blue_grey.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_brown.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_cyan.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_deep_orange.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_deep_purple.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_green.png
Normal file
After Width: | Height: | Size: 5.8 KiB |