Merge branch 'develop'
This commit is contained in:
commit
00681cbaee
208 changed files with 2132 additions and 1877 deletions
2
.flutter
2
.flutter
|
@ -1 +1 @@
|
||||||
Subproject commit b0850beeb25f6d5b10426284f506557f66181b36
|
Subproject commit 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
@ -53,6 +53,8 @@ jobs:
|
||||||
./flutterw build apk -t lib/main_izzy.dart --flavor izzy --split-per-abi
|
./flutterw build apk -t lib/main_izzy.dart --flavor izzy --split-per-abi
|
||||||
cp build/app/outputs/apk/izzy/release/*.apk outputs
|
cp build/app/outputs/apk/izzy/release/*.apk outputs
|
||||||
scripts/apply_flavor_libre.sh
|
scripts/apply_flavor_libre.sh
|
||||||
|
./flutterw build appbundle -t lib/main_libre.dart --flavor libre
|
||||||
|
cp build/app/outputs/bundle/libreRelease/*.aab outputs
|
||||||
./flutterw build apk -t lib/main_libre.dart --flavor libre --split-per-abi
|
./flutterw build apk -t lib/main_libre.dart --flavor libre --split-per-abi
|
||||||
cp build/app/outputs/apk/libre/release/*.apk outputs
|
cp build/app/outputs/apk/libre/release/*.apk outputs
|
||||||
rm $AVES_STORE_FILE
|
rm $AVES_STORE_FILE
|
||||||
|
|
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## <a id="unreleased"></a>[Unreleased]
|
## <a id="unreleased"></a>[Unreleased]
|
||||||
|
|
||||||
|
## <a id="v1.11.9"></a>[v1.11.9] - 2024-08-07
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Viewer: display more items in tag/copy/move quick action choosers
|
||||||
|
- Viewer: long descriptions are scrollable when overlay is expanded by tap
|
||||||
|
- Collection: sort by duration
|
||||||
|
- Map: open external map app from map views
|
||||||
|
- Explorer: stats
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Accessibility: more animations and effects are suppressed when animations are disabled
|
||||||
|
- upgraded Flutter to stable v3.24.0
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- opening app from launcher always showing home page
|
||||||
|
- collection quick actions not showing in the top bar nor the menu
|
||||||
|
- multiple widget setup after device reboot
|
||||||
|
|
||||||
## <a id="v1.11.8"></a>[v1.11.8] - 2024-07-19
|
## <a id="v1.11.8"></a>[v1.11.8] - 2024-07-19
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -189,7 +189,7 @@ dependencies {
|
||||||
|
|
||||||
implementation "androidx.appcompat:appcompat:1.7.0"
|
implementation "androidx.appcompat:appcompat:1.7.0"
|
||||||
implementation 'androidx.core:core-ktx:1.13.1'
|
implementation 'androidx.core:core-ktx:1.13.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-process:2.8.3'
|
implementation 'androidx.lifecycle:lifecycle-process:2.8.4'
|
||||||
implementation 'androidx.media:media:1.7.0'
|
implementation 'androidx.media:media:1.7.0'
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
|
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
|
||||||
|
@ -201,7 +201,7 @@ dependencies {
|
||||||
implementation "com.github.bumptech.glide:glide:$glide_version"
|
implementation "com.github.bumptech.glide:glide:$glide_version"
|
||||||
implementation 'com.google.android.material:material:1.12.0'
|
implementation 'com.google.android.material:material:1.12.0'
|
||||||
// SLF4J implementation for `mp4parser`
|
// SLF4J implementation for `mp4parser`
|
||||||
implementation 'org.slf4j:slf4j-simple:2.0.13'
|
implementation 'org.slf4j:slf4j-simple:2.0.14'
|
||||||
|
|
||||||
// forked, built by JitPack:
|
// forked, built by JitPack:
|
||||||
// - https://jitpack.io/p/deckerst/Android-TiffBitmapFactory
|
// - https://jitpack.io/p/deckerst/Android-TiffBitmapFactory
|
||||||
|
@ -213,9 +213,9 @@ dependencies {
|
||||||
implementation 'com.github.deckerst:pixymeta-android:9ec7097f17'
|
implementation 'com.github.deckerst:pixymeta-android:9ec7097f17'
|
||||||
implementation project(':exifinterface')
|
implementation project(':exifinterface')
|
||||||
|
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.2'
|
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.3'
|
||||||
|
|
||||||
kapt 'androidx.annotation:annotation:1.8.0'
|
kapt 'androidx.annotation:annotation:1.8.1'
|
||||||
ksp "com.github.bumptech.glide:ksp:$glide_version"
|
ksp "com.github.bumptech.glide:ksp:$glide_version"
|
||||||
|
|
||||||
compileOnly rootProject.findProject(':streams_channel')
|
compileOnly rootProject.findProject(':streams_channel')
|
||||||
|
|
|
@ -323,8 +323,10 @@
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
<!-- as of Flutter v3.22.0 (stable),
|
<!--
|
||||||
Impeller fails to render videos (via `ffmpegkit`), and has random glitches -->
|
Impeller is not supported by `media_kit` v1.1.10+1:
|
||||||
|
https://github.com/media-kit/media-kit/issues/707
|
||||||
|
-->
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.flutter.embedding.android.EnableImpeller"
|
android:name="io.flutter.embedding.android.EnableImpeller"
|
||||||
android:value="false" />
|
android:value="false" />
|
||||||
|
|
|
@ -11,12 +11,18 @@ import android.graphics.Bitmap
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.SizeF
|
import android.util.SizeF
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import app.loup.streams_channel.StreamsChannel
|
import app.loup.streams_channel.StreamsChannel
|
||||||
import deckers.thibault.aves.channel.AvesByteSendingMethodCodec
|
import deckers.thibault.aves.channel.AvesByteSendingMethodCodec
|
||||||
import deckers.thibault.aves.channel.calls.*
|
import deckers.thibault.aves.channel.calls.DeviceHandler
|
||||||
|
import deckers.thibault.aves.channel.calls.MediaFetchBytesHandler
|
||||||
|
import deckers.thibault.aves.channel.calls.MediaFetchObjectHandler
|
||||||
|
import deckers.thibault.aves.channel.calls.MediaStoreHandler
|
||||||
|
import deckers.thibault.aves.channel.calls.StorageHandler
|
||||||
import deckers.thibault.aves.channel.streams.ImageByteStreamHandler
|
import deckers.thibault.aves.channel.streams.ImageByteStreamHandler
|
||||||
import deckers.thibault.aves.channel.streams.MediaStoreStreamHandler
|
import deckers.thibault.aves.channel.streams.MediaStoreStreamHandler
|
||||||
import deckers.thibault.aves.model.FieldMap
|
import deckers.thibault.aves.model.FieldMap
|
||||||
|
@ -26,8 +32,14 @@ import io.flutter.FlutterInjector
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
import io.flutter.embedding.engine.dart.DartExecutor
|
import io.flutter.embedding.engine.dart.DartExecutor
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
|
import kotlin.coroutines.Continuation
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.resumeWithException
|
import kotlin.coroutines.resumeWithException
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
@ -108,14 +120,7 @@ class HomeWidgetProvider : AppWidgetProvider() {
|
||||||
|
|
||||||
val isNightModeOn = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
val isNightModeOn = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
||||||
|
|
||||||
initFlutterEngine(context)
|
val params = hashMapOf(
|
||||||
val messenger = flutterEngine!!.dartExecutor
|
|
||||||
val channel = MethodChannel(messenger, WIDGET_DRAW_CHANNEL)
|
|
||||||
try {
|
|
||||||
val props = suspendCoroutine<Any?> { cont ->
|
|
||||||
defaultScope.launch {
|
|
||||||
FlutterUtils.runOnUiThread {
|
|
||||||
channel.invokeMethod("drawWidget", hashMapOf(
|
|
||||||
"widgetId" to widgetId,
|
"widgetId" to widgetId,
|
||||||
"sizesDip" to sizesDip,
|
"sizesDip" to sizesDip,
|
||||||
"devicePixelRatio" to getDevicePixelRatio(),
|
"devicePixelRatio" to getDevicePixelRatio(),
|
||||||
|
@ -126,19 +131,14 @@ class HomeWidgetProvider : AppWidgetProvider() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
put("cornerRadiusPx", context.resources.getDimension(android.R.dimen.system_app_widget_background_radius))
|
put("cornerRadiusPx", context.resources.getDimension(android.R.dimen.system_app_widget_background_radius))
|
||||||
}
|
}
|
||||||
}, object : MethodChannel.Result {
|
|
||||||
override fun success(result: Any?) {
|
|
||||||
cont.resume(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
initFlutterEngine(context)
|
||||||
cont.resumeWithException(Exception("$errorCode: $errorMessage\n$errorDetails"))
|
try {
|
||||||
}
|
val props = suspendCoroutine { cont ->
|
||||||
|
defaultScope.launch {
|
||||||
override fun notImplemented() {
|
FlutterUtils.runOnUiThread {
|
||||||
cont.resumeWithException(Exception("not implemented"))
|
tryDrawWidget(params, cont, 0)
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,30 @@ class HomeWidgetProvider : AppWidgetProvider() {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun tryDrawWidget(params: HashMap<String, Any>, cont: Continuation<Any?>, drawRetry: Int) {
|
||||||
|
val messenger = flutterEngine!!.dartExecutor
|
||||||
|
val channel = MethodChannel(messenger, WIDGET_DRAW_CHANNEL)
|
||||||
|
channel.invokeMethod("drawWidget", params, object : MethodChannel.Result {
|
||||||
|
override fun success(result: Any?) {
|
||||||
|
cont.resume(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
||||||
|
cont.resumeWithException(Exception("$errorCode: $errorMessage\n$errorDetails"))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun notImplemented() {
|
||||||
|
if (drawRetry > DRAW_RETRY_MAX) {
|
||||||
|
cont.resumeWithException(Exception("not implemented"))
|
||||||
|
} else {
|
||||||
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
|
tryDrawWidget(params, cont, drawRetry + 1)
|
||||||
|
}, 2000L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateWidgetImage(
|
private fun updateWidgetImage(
|
||||||
context: Context,
|
context: Context,
|
||||||
appWidgetManager: AppWidgetManager,
|
appWidgetManager: AppWidgetManager,
|
||||||
|
@ -271,6 +295,7 @@ class HomeWidgetProvider : AppWidgetProvider() {
|
||||||
private val LOG_TAG = LogUtils.createTag<HomeWidgetProvider>()
|
private val LOG_TAG = LogUtils.createTag<HomeWidgetProvider>()
|
||||||
private const val WIDGET_DART_ENTRYPOINT = "widgetMain"
|
private const val WIDGET_DART_ENTRYPOINT = "widgetMain"
|
||||||
private const val WIDGET_DRAW_CHANNEL = "deckers.thibault/aves/widget_draw"
|
private const val WIDGET_DRAW_CHANNEL = "deckers.thibault/aves/widget_draw"
|
||||||
|
private const val DRAW_RETRY_MAX = 5
|
||||||
|
|
||||||
private var flutterEngine: FlutterEngine? = null
|
private var flutterEngine: FlutterEngine? = null
|
||||||
private var imageByteFetchJob: Job? = null
|
private var imageByteFetchJob: Job? = null
|
||||||
|
|
|
@ -59,7 +59,14 @@ class MediaStoreHandler(private val context: Context) : MethodCallHandler {
|
||||||
|
|
||||||
private fun getGeneration(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
private fun getGeneration(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
||||||
val generation = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
val generation = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
try {
|
||||||
MediaStore.getGeneration(context, MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
MediaStore.getGeneration(context, MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// may yield `IllegalArgumentException: Volume external_primary not found`
|
||||||
|
val volumes = MediaStore.getExternalVolumeNames(context).joinToString(", ")
|
||||||
|
result.error("getGeneration-primary", e.message + " (available volumes are $volumes)", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<string name="search_shortcut_short_label">Zoeken</string>
|
<string name="search_shortcut_short_label">Zoeken</string>
|
||||||
<string name="videos_shortcut_short_label">Video’s</string>
|
<string name="videos_shortcut_short_label">Video’s</string>
|
||||||
<string name="analysis_channel_name">Media indexeren</string>
|
<string name="analysis_channel_name">Media indexeren</string>
|
||||||
<string name="analysis_notification_default_title">Indexeren van media</string>
|
<string name="analysis_notification_default_title">Media indexeren</string>
|
||||||
<string name="analysis_notification_action_stop">Stoppen</string>
|
<string name="analysis_notification_action_stop">Stoppen</string>
|
||||||
<string name="safe_mode_shortcut_short_label">Veilige modus</string>
|
<string name="safe_mode_shortcut_short_label">Veilige modus</string>
|
||||||
</resources>
|
</resources>
|
|
@ -7,6 +7,6 @@
|
||||||
<string name="videos_shortcut_short_label">Videor</string>
|
<string name="videos_shortcut_short_label">Videor</string>
|
||||||
<string name="analysis_channel_name">Media scanning</string>
|
<string name="analysis_channel_name">Media scanning</string>
|
||||||
<string name="analysis_notification_default_title">Scannar media</string>
|
<string name="analysis_notification_default_title">Scannar media</string>
|
||||||
<string name="analysis_notification_action_stop">Stop</string>
|
<string name="analysis_notification_action_stop">Stopp</string>
|
||||||
<string name="search_shortcut_short_label">Sök</string>
|
<string name="search_shortcut_short_label">Sök</string>
|
||||||
</resources>
|
</resources>
|
|
@ -1,4 +0,0 @@
|
||||||
In v1.11.1:
|
|
||||||
- watch videos with SRT subtitle files
|
|
||||||
- enjoy the app in Persian
|
|
||||||
Full changelog available on GitHub
|
|
|
@ -1,4 +0,0 @@
|
||||||
In v1.11.1:
|
|
||||||
- watch videos with SRT subtitle files
|
|
||||||
- enjoy the app in Persian
|
|
||||||
Full changelog available on GitHub
|
|
|
@ -1,3 +0,0 @@
|
||||||
In v1.11.2:
|
|
||||||
- show selected albums together in Collection
|
|
||||||
Full changelog available on GitHub
|
|
|
@ -1,3 +0,0 @@
|
||||||
In v1.11.2:
|
|
||||||
- show selected albums together in Collection
|
|
||||||
Full changelog available on GitHub
|
|
|
@ -1,3 +0,0 @@
|
||||||
In v1.11.3:
|
|
||||||
- show selected albums together in Collection
|
|
||||||
Full changelog available on GitHub
|
|
|
@ -1,3 +0,0 @@
|
||||||
In v1.11.3:
|
|
||||||
- show selected albums together in Collection
|
|
||||||
Full changelog available on GitHub
|
|
|
@ -1,4 +0,0 @@
|
||||||
In v1.11.4:
|
|
||||||
- explore your collection with the... explorer
|
|
||||||
- convert your motion photos to stills in bulk
|
|
||||||
Full changelog available on GitHub
|
|
|
@ -1,4 +0,0 @@
|
||||||
In v1.11.4:
|
|
||||||
- explore your collection with the... explorer
|
|
||||||
- convert your motion photos to stills in bulk
|
|
||||||
Full changelog available on GitHub
|
|
5
fastlane/metadata/android/en-US/changelogs/128.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/128.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
In v1.11.9:
|
||||||
|
- peruse more options to tag or move via quick actions
|
||||||
|
- read long descriptions right from the overlay
|
||||||
|
- sort videos by duration
|
||||||
|
Full changelog available on GitHub
|
5
fastlane/metadata/android/en-US/changelogs/12801.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/12801.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
In v1.11.9:
|
||||||
|
- peruse more options to tag or move via quick actions
|
||||||
|
- read long descriptions right from the overlay
|
||||||
|
- sort videos by duration
|
||||||
|
Full changelog available on GitHub
|
|
@ -1536,5 +1536,17 @@
|
||||||
"chipActionGoToExplorerPage": "عرض في المستكشف",
|
"chipActionGoToExplorerPage": "عرض في المستكشف",
|
||||||
"@chipActionGoToExplorerPage": {},
|
"@chipActionGoToExplorerPage": {},
|
||||||
"explorerPageTitle": "المستكشف",
|
"explorerPageTitle": "المستكشف",
|
||||||
"@explorerPageTitle": {}
|
"@explorerPageTitle": {},
|
||||||
|
"explorerActionSelectStorageVolume": "حدد التخزين",
|
||||||
|
"@explorerActionSelectStorageVolume": {},
|
||||||
|
"setHomeCustom": "مخصص",
|
||||||
|
"@setHomeCustom": {},
|
||||||
|
"selectStorageVolumeDialogTitle": "حدد التَخزين",
|
||||||
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"sortOrderShortestFirst": "الأقصر أولاً",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "الأطول أولاً",
|
||||||
|
"@sortOrderLongestFirst": {},
|
||||||
|
"sortByDuration": "حسب المدة",
|
||||||
|
"@sortByDuration": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1536,5 +1536,17 @@
|
||||||
"chipActionGoToExplorerPage": "Паказаць у Правадыру",
|
"chipActionGoToExplorerPage": "Паказаць у Правадыру",
|
||||||
"@chipActionGoToExplorerPage": {},
|
"@chipActionGoToExplorerPage": {},
|
||||||
"explorerPageTitle": "Правадыр",
|
"explorerPageTitle": "Правадыр",
|
||||||
"@explorerPageTitle": {}
|
"@explorerPageTitle": {},
|
||||||
|
"sortByDuration": "Па працягласці",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderShortestFirst": "Спачатку самы кароткі",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "Спачатку самы доўгі",
|
||||||
|
"@sortOrderLongestFirst": {},
|
||||||
|
"explorerActionSelectStorageVolume": "Выбраць сховішча",
|
||||||
|
"@explorerActionSelectStorageVolume": {},
|
||||||
|
"selectStorageVolumeDialogTitle": "Выбраць сховішча",
|
||||||
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"setHomeCustom": "Па-свойму",
|
||||||
|
"@setHomeCustom": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -723,6 +723,7 @@
|
||||||
"sortBySize": "By size",
|
"sortBySize": "By size",
|
||||||
"sortByAlbumFileName": "By album & file name",
|
"sortByAlbumFileName": "By album & file name",
|
||||||
"sortByRating": "By rating",
|
"sortByRating": "By rating",
|
||||||
|
"sortByDuration": "By duration",
|
||||||
|
|
||||||
"sortOrderNewestFirst": "Newest first",
|
"sortOrderNewestFirst": "Newest first",
|
||||||
"sortOrderOldestFirst": "Oldest first",
|
"sortOrderOldestFirst": "Oldest first",
|
||||||
|
@ -732,6 +733,8 @@
|
||||||
"sortOrderLowestFirst": "Lowest first",
|
"sortOrderLowestFirst": "Lowest first",
|
||||||
"sortOrderLargestFirst": "Largest first",
|
"sortOrderLargestFirst": "Largest first",
|
||||||
"sortOrderSmallestFirst": "Smallest first",
|
"sortOrderSmallestFirst": "Smallest first",
|
||||||
|
"sortOrderShortestFirst": "Shortest first",
|
||||||
|
"sortOrderLongestFirst": "Longest first",
|
||||||
|
|
||||||
"albumGroupTier": "By tier",
|
"albumGroupTier": "By tier",
|
||||||
"albumGroupType": "By type",
|
"albumGroupType": "By type",
|
||||||
|
|
|
@ -1384,5 +1384,11 @@
|
||||||
"setHomeCustom": "Personalizado",
|
"setHomeCustom": "Personalizado",
|
||||||
"@setHomeCustom": {},
|
"@setHomeCustom": {},
|
||||||
"explorerActionSelectStorageVolume": "Seleccionar almacenamiento",
|
"explorerActionSelectStorageVolume": "Seleccionar almacenamiento",
|
||||||
"@explorerActionSelectStorageVolume": {}
|
"@explorerActionSelectStorageVolume": {},
|
||||||
|
"sortByDuration": "Por duración",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderShortestFirst": "El más corto primero",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "El más largo primero",
|
||||||
|
"@sortOrderLongestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1384,5 +1384,11 @@
|
||||||
"explorerActionSelectStorageVolume": "Choisir le stockage",
|
"explorerActionSelectStorageVolume": "Choisir le stockage",
|
||||||
"@explorerActionSelectStorageVolume": {},
|
"@explorerActionSelectStorageVolume": {},
|
||||||
"selectStorageVolumeDialogTitle": "Volumes de stockage",
|
"selectStorageVolumeDialogTitle": "Volumes de stockage",
|
||||||
"@selectStorageVolumeDialogTitle": {}
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"sortByDuration": "par durée",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderShortestFirst": "Plus courts d’abord",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "Plus longs d’abord",
|
||||||
|
"@sortOrderLongestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,5 +101,448 @@
|
||||||
"chipActionGoToCountryPage": "देशों में दिखाएं",
|
"chipActionGoToCountryPage": "देशों में दिखाएं",
|
||||||
"@chipActionGoToCountryPage": {},
|
"@chipActionGoToCountryPage": {},
|
||||||
"chipActionHide": "छिपाए",
|
"chipActionHide": "छिपाए",
|
||||||
"@chipActionHide": {}
|
"@chipActionHide": {},
|
||||||
|
"chipActionShowCollection": "कोलेक्शन में दिखाए",
|
||||||
|
"@chipActionShowCollection": {},
|
||||||
|
"chipActionFilterOut": "फिल्टर करें",
|
||||||
|
"@chipActionFilterOut": {},
|
||||||
|
"chipActionLock": "लॉक",
|
||||||
|
"@chipActionLock": {},
|
||||||
|
"chipActionPin": "शीर्ष पर पिन करें",
|
||||||
|
"@chipActionPin": {},
|
||||||
|
"chipActionGoToExplorerPage": "एक्सप्लोरर में दिखाए",
|
||||||
|
"@chipActionGoToExplorerPage": {},
|
||||||
|
"entryActionRotateCW": "दक्षिणावर्त घुमाएं",
|
||||||
|
"@entryActionRotateCW": {},
|
||||||
|
"entryActionViewSource": "सोर्स देखें",
|
||||||
|
"@entryActionViewSource": {},
|
||||||
|
"entryActionShowGeoTiffOnMap": "मैप ओवरले के रूप में देखे",
|
||||||
|
"@entryActionShowGeoTiffOnMap": {},
|
||||||
|
"entryActionViewMotionPhotoVideo": "वीडियो खोलें",
|
||||||
|
"@entryActionViewMotionPhotoVideo": {},
|
||||||
|
"entryActionOpen": "के साथ खोलें",
|
||||||
|
"@entryActionOpen": {},
|
||||||
|
"entryActionRemoveFavourite": "पसंदीदा से निकालें",
|
||||||
|
"@entryActionRemoveFavourite": {},
|
||||||
|
"entryInfoActionRemoveMetadata": "मेटाडाटा हटाएं",
|
||||||
|
"@entryInfoActionRemoveMetadata": {},
|
||||||
|
"entryInfoActionRemoveLocation": "लोकेशन हटाएं",
|
||||||
|
"@entryInfoActionRemoveLocation": {},
|
||||||
|
"entryActionFlip": "क्षैतिज फ्लिप करे",
|
||||||
|
"@entryActionFlip": {},
|
||||||
|
"entryActionShareVideoOnly": "केवल वीडियो शेयर करें",
|
||||||
|
"@entryActionShareVideoOnly": {},
|
||||||
|
"entryActionConvertMotionPhotoToStillImage": "स्थिर छवि में परिवर्तित करें",
|
||||||
|
"@entryActionConvertMotionPhotoToStillImage": {},
|
||||||
|
"entryActionOpenMap": "मैप एप में दिखाएं",
|
||||||
|
"@entryActionOpenMap": {},
|
||||||
|
"entryActionSetAs": "के रूप में सेट करें",
|
||||||
|
"@entryActionSetAs": {},
|
||||||
|
"entryActionRotateScreen": "स्क्रीन घुमाएँ",
|
||||||
|
"@entryActionRotateScreen": {},
|
||||||
|
"videoActionCaptureFrame": "फ्रेम कैप्चर करें",
|
||||||
|
"@videoActionCaptureFrame": {},
|
||||||
|
"chipActionCreateAlbum": "एल्बम बनाएं",
|
||||||
|
"@chipActionCreateAlbum": {},
|
||||||
|
"chipActionCreateVault": "वॉल्ट बनाएं",
|
||||||
|
"@chipActionCreateVault": {},
|
||||||
|
"videoActionPlay": "चलाएं",
|
||||||
|
"@videoActionPlay": {},
|
||||||
|
"videoActionReplay10": "10 सेकंड्स पीछे ले",
|
||||||
|
"@videoActionReplay10": {},
|
||||||
|
"videoActionSkip10": "10 सेकंड्स आगे लें",
|
||||||
|
"@videoActionSkip10": {},
|
||||||
|
"videoActionUnmute": "अनम्यूट करे",
|
||||||
|
"@videoActionUnmute": {},
|
||||||
|
"slideshowActionShowInCollection": "संग्रह में दिखाएं",
|
||||||
|
"@slideshowActionShowInCollection": {},
|
||||||
|
"slideshowActionResume": "रिज्यूम करें",
|
||||||
|
"@slideshowActionResume": {},
|
||||||
|
"filterTypeAnimatedLabel": "एनिमेटेड",
|
||||||
|
"@filterTypeAnimatedLabel": {},
|
||||||
|
"filterTypeMotionPhotoLabel": "मोशन फोटो",
|
||||||
|
"@filterTypeMotionPhotoLabel": {},
|
||||||
|
"filterTypePanoramaLabel": "पैनोरमा",
|
||||||
|
"@filterTypePanoramaLabel": {},
|
||||||
|
"sourceStateLocatingCountries": "देश खोज रहे हैं",
|
||||||
|
"@sourceStateLocatingCountries": {},
|
||||||
|
"sourceStateLocatingPlaces": "स्थान खोज रहें हैं",
|
||||||
|
"@sourceStateLocatingPlaces": {},
|
||||||
|
"chipActionFilterIn": "में फिल्टर करें",
|
||||||
|
"@chipActionFilterIn": {},
|
||||||
|
"chipActionRename": "नाम बदले",
|
||||||
|
"@chipActionRename": {},
|
||||||
|
"chipActionUnpin": "शीर्ष से अनपिन करें",
|
||||||
|
"@chipActionUnpin": {},
|
||||||
|
"entryActionEdit": "एडिट करें",
|
||||||
|
"@entryActionEdit": {},
|
||||||
|
"videoActionMute": "म्यूट करे",
|
||||||
|
"@videoActionMute": {},
|
||||||
|
"videoActionPause": "रोके",
|
||||||
|
"@videoActionPause": {},
|
||||||
|
"entryInfoActionEditTags": "टैग्स एडिट करे",
|
||||||
|
"@entryInfoActionEditTags": {},
|
||||||
|
"filterOnThisDayLabel": "इस दिन पर",
|
||||||
|
"@filterOnThisDayLabel": {},
|
||||||
|
"filterTypeSphericalVideoLabel": "360° वीडियो",
|
||||||
|
"@filterTypeSphericalVideoLabel": {},
|
||||||
|
"filterMimeVideoLabel": "वीडियो",
|
||||||
|
"@filterMimeVideoLabel": {},
|
||||||
|
"viewerActionSettings": "सैटिंग",
|
||||||
|
"@viewerActionSettings": {},
|
||||||
|
"entryActionCast": "कास्ट करें",
|
||||||
|
"@entryActionCast": {},
|
||||||
|
"entryInfoActionExportMetadata": "मेटाडाटा एक्सपोर्ट करें",
|
||||||
|
"@entryInfoActionExportMetadata": {},
|
||||||
|
"chipActionSetCover": "कवर सेट करें",
|
||||||
|
"@chipActionSetCover": {},
|
||||||
|
"entryActionCopyToClipboard": "क्लिपबोर्ड पर कॉपी करें",
|
||||||
|
"@entryActionCopyToClipboard": {},
|
||||||
|
"entryActionDelete": "मिटाएं",
|
||||||
|
"@entryActionDelete": {},
|
||||||
|
"entryActionExport": "एक्सपोर्ट करें",
|
||||||
|
"@entryActionExport": {},
|
||||||
|
"entryActionInfo": "जानकारी",
|
||||||
|
"@entryActionInfo": {},
|
||||||
|
"entryActionConvert": "बदले",
|
||||||
|
"@entryActionConvert": {},
|
||||||
|
"entryActionRename": "नाम बदलें",
|
||||||
|
"@entryActionRename": {},
|
||||||
|
"entryActionRestore": "रिस्टोर करे",
|
||||||
|
"@entryActionRestore": {},
|
||||||
|
"entryActionRotateCCW": "वामावर्त स्थिति में घुमाएं",
|
||||||
|
"@entryActionRotateCCW": {},
|
||||||
|
"entryActionPrint": "प्रिंट करे",
|
||||||
|
"@entryActionPrint": {},
|
||||||
|
"entryActionShare": "शेयर करे",
|
||||||
|
"@entryActionShare": {},
|
||||||
|
"entryActionShareImageOnly": "केवल इमेज शेयर करें",
|
||||||
|
"@entryActionShareImageOnly": {},
|
||||||
|
"entryActionAddFavourite": "पसंदीदा में जोड़े",
|
||||||
|
"@entryActionAddFavourite": {},
|
||||||
|
"videoActionSelectStreams": "ट्रैक्स को चुने",
|
||||||
|
"@videoActionSelectStreams": {},
|
||||||
|
"videoActionSetSpeed": "चलाने की गति",
|
||||||
|
"@videoActionSetSpeed": {},
|
||||||
|
"entryInfoActionEditDate": "दिनांक व समय एडिट करे",
|
||||||
|
"@entryInfoActionEditDate": {},
|
||||||
|
"entryInfoActionEditLocation": "लोकेशन एडिट करे",
|
||||||
|
"@entryInfoActionEditLocation": {},
|
||||||
|
"entryInfoActionEditRating": "रेटिंग एडिट करे",
|
||||||
|
"@entryInfoActionEditRating": {},
|
||||||
|
"editorTransformRotate": "घुमाएं",
|
||||||
|
"@editorTransformRotate": {},
|
||||||
|
"cropAspectRatioOriginal": "ओरिजनल",
|
||||||
|
"@cropAspectRatioOriginal": {},
|
||||||
|
"filterFavouriteLabel": "पसंदीदा",
|
||||||
|
"@filterFavouriteLabel": {},
|
||||||
|
"filterRecentlyAddedLabel": "हाल ही में शामिल की गई",
|
||||||
|
"@filterRecentlyAddedLabel": {},
|
||||||
|
"filterMimeImageLabel": "इमेज",
|
||||||
|
"@filterMimeImageLabel": {},
|
||||||
|
"keepScreenOnVideoPlayback": "वीडियो प्लेबैक के दौरान",
|
||||||
|
"@keepScreenOnVideoPlayback": {},
|
||||||
|
"displayRefreshRatePreferLowest": "न्यूनतम दर",
|
||||||
|
"@displayRefreshRatePreferLowest": {},
|
||||||
|
"nameConflictStrategyRename": "नाम बदलें",
|
||||||
|
"@nameConflictStrategyRename": {},
|
||||||
|
"unitSystemMetric": "Metric",
|
||||||
|
"@unitSystemMetric": {},
|
||||||
|
"viewerTransitionSlide": "स्लाइड",
|
||||||
|
"@viewerTransitionSlide": {},
|
||||||
|
"viewerTransitionFade": "फेड",
|
||||||
|
"@viewerTransitionFade": {},
|
||||||
|
"newAlbumDialogStorageLabel": "स्टोरेज:",
|
||||||
|
"@newAlbumDialogStorageLabel": {},
|
||||||
|
"newVaultDialogTitle": "नया वॉल्ट",
|
||||||
|
"@newVaultDialogTitle": {},
|
||||||
|
"vaultDialogLockModeWhenScreenOff": "लॉक करे,जब स्क्रीन बंद हो जाती है",
|
||||||
|
"@vaultDialogLockModeWhenScreenOff": {},
|
||||||
|
"filterTaggedLabel": "टैग किया गया",
|
||||||
|
"@filterTaggedLabel": {},
|
||||||
|
"mapStyleGoogleTerrain": "गूगल मैप्स (टेरेन)",
|
||||||
|
"@mapStyleGoogleTerrain": {},
|
||||||
|
"themeBrightnessDark": "Dark",
|
||||||
|
"@themeBrightnessDark": {},
|
||||||
|
"themeBrightnessBlack": "Black",
|
||||||
|
"@themeBrightnessBlack": {},
|
||||||
|
"videoControlsPlaySeek": "पिछड़े / आगे की तलाश करें",
|
||||||
|
"@videoControlsPlaySeek": {},
|
||||||
|
"mapStyleOsmHot": "Humanitarian OSM",
|
||||||
|
"@mapStyleOsmHot": {},
|
||||||
|
"filterAspectRatioPortraitLabel": "पोर्ट्रेट",
|
||||||
|
"@filterAspectRatioPortraitLabel": {},
|
||||||
|
"filterNoAddressLabel": "एड्रेस रहित",
|
||||||
|
"@filterNoAddressLabel": {},
|
||||||
|
"filterNoRatingLabel": "रेट नहीं किया गया",
|
||||||
|
"@filterNoRatingLabel": {},
|
||||||
|
"filterRatingRejectedLabel": "अस्वीकृत",
|
||||||
|
"@filterRatingRejectedLabel": {},
|
||||||
|
"mapStyleGoogleNormal": "गूगल मैप्स",
|
||||||
|
"@mapStyleGoogleNormal": {},
|
||||||
|
"mapStyleGoogleHybrid": "गूगल मैप्स (हाइब्रिड)",
|
||||||
|
"@mapStyleGoogleHybrid": {},
|
||||||
|
"mapStyleStamenWatercolor": "Stamen Watercolor",
|
||||||
|
"@mapStyleStamenWatercolor": {},
|
||||||
|
"unitSystemImperial": "Imperial",
|
||||||
|
"@unitSystemImperial": {},
|
||||||
|
"passwordDialogEnter": "पासवर्ड दर्ज करें",
|
||||||
|
"@passwordDialogEnter": {},
|
||||||
|
"filterBinLabel": "रीसाइकल बिन",
|
||||||
|
"@filterBinLabel": {},
|
||||||
|
"filterTypeRawLabel": "Raw",
|
||||||
|
"@filterTypeRawLabel": {},
|
||||||
|
"albumTierVaults": "संदूक",
|
||||||
|
"@albumTierVaults": {},
|
||||||
|
"albumTierRegular": "अन्य",
|
||||||
|
"@albumTierRegular": {},
|
||||||
|
"coordinateFormatDms": "DMS",
|
||||||
|
"@coordinateFormatDms": {},
|
||||||
|
"coordinateFormatDecimal": "Decimal degrees",
|
||||||
|
"@coordinateFormatDecimal": {},
|
||||||
|
"coordinateDms": "{coordinate} {direction}",
|
||||||
|
"@coordinateDms": {
|
||||||
|
"placeholders": {
|
||||||
|
"coordinate": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "38° 41′ 47.72″"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "S"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"coordinateDmsSouth": "द",
|
||||||
|
"@coordinateDmsSouth": {},
|
||||||
|
"coordinateDmsWest": "प",
|
||||||
|
"@coordinateDmsWest": {},
|
||||||
|
"displayRefreshRatePreferHighest": "उच्चतम दर",
|
||||||
|
"@displayRefreshRatePreferHighest": {},
|
||||||
|
"lengthUnitPixel": "px",
|
||||||
|
"@lengthUnitPixel": {},
|
||||||
|
"subtitlePositionTop": "शीर्ष",
|
||||||
|
"@subtitlePositionTop": {},
|
||||||
|
"subtitlePositionBottom": "नीचे",
|
||||||
|
"@subtitlePositionBottom": {},
|
||||||
|
"videoLoopModeNever": "कभी नहीं",
|
||||||
|
"@videoLoopModeNever": {},
|
||||||
|
"videoPlaybackMuted": "बिना ध्वनि के चलाएं",
|
||||||
|
"@videoPlaybackMuted": {},
|
||||||
|
"viewerTransitionNone": "कोई नहीं",
|
||||||
|
"@viewerTransitionNone": {},
|
||||||
|
"nameConflictDialogSingleSourceMessage": "गंतव्य फ़ोल्डर में कुछ फ़ाइलों का नाम समान है।।",
|
||||||
|
"@nameConflictDialogSingleSourceMessage": {},
|
||||||
|
"noMatchingAppDialogMessage": "इसमें कोई ऐप नहीं है जो इसे संभाल सकता है।।",
|
||||||
|
"@noMatchingAppDialogMessage": {},
|
||||||
|
"binEntriesConfirmationDialogMessage": "{count, plural, =1{Move this item to the recycle bin?} other{Move these {count} items to the recycle bin?}}",
|
||||||
|
"@binEntriesConfirmationDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"count": {
|
||||||
|
"format": "decimalPattern"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deleteEntriesConfirmationDialogMessage": "{count, plural, =1{Delete this item?} other{Delete these {count} items?}}",
|
||||||
|
"@deleteEntriesConfirmationDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"count": {
|
||||||
|
"format": "decimalPattern"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"newAlbumDialogTitle": "नया एल्बम",
|
||||||
|
"@newAlbumDialogTitle": {},
|
||||||
|
"newAlbumDialogNameLabel": "एल्बम का नाम",
|
||||||
|
"@newAlbumDialogNameLabel": {},
|
||||||
|
"pinDialogEnter": "पिन दर्ज करें",
|
||||||
|
"@pinDialogEnter": {},
|
||||||
|
"pinDialogConfirm": "पिन कन्फर्म करें",
|
||||||
|
"@pinDialogConfirm": {},
|
||||||
|
"passwordDialogConfirm": "पासवर्ड कन्फर्म करें",
|
||||||
|
"@passwordDialogConfirm": {},
|
||||||
|
"videoLoopModeAlways": "हमेशा",
|
||||||
|
"@videoLoopModeAlways": {},
|
||||||
|
"videoPlaybackSkip": "छोड़े",
|
||||||
|
"@videoPlaybackSkip": {},
|
||||||
|
"newAlbumDialogNameLabelAlreadyExistsHelper": "डायरेक्टरी पहले से मौजूद",
|
||||||
|
"@newAlbumDialogNameLabelAlreadyExistsHelper": {},
|
||||||
|
"coordinateDmsEast": "पू",
|
||||||
|
"@coordinateDmsEast": {},
|
||||||
|
"moveUndatedConfirmationDialogSetDate": "तारीख सहेजें",
|
||||||
|
"@moveUndatedConfirmationDialogSetDate": {},
|
||||||
|
"notEnoughSpaceDialogMessage": "इस ऑपरेशन को पूरा करने के लिए \"{volume}\" पर “{neededSize}” खाली जगह की आवश्यकता है, लेकिन केवल {freeSize} जगह है।।",
|
||||||
|
"@notEnoughSpaceDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"neededSize": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "314 MB"
|
||||||
|
},
|
||||||
|
"freeSize": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "123 MB"
|
||||||
|
},
|
||||||
|
"volume": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "SD card",
|
||||||
|
"description": "the name of a storage volume"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"renameAlbumDialogLabel": "नया नाम",
|
||||||
|
"@renameAlbumDialogLabel": {},
|
||||||
|
"wallpaperTargetLock": "लॉक स्क्रीन",
|
||||||
|
"@wallpaperTargetLock": {},
|
||||||
|
"unsupportedTypeDialogMessage": "{count, plural, =1{This operation is not supported for items of the following type: {types}.} other{This operation is not supported for items of the following types: {types}.}}",
|
||||||
|
"@unsupportedTypeDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"count": {},
|
||||||
|
"types": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "GIF, TIFF, MP4",
|
||||||
|
"description": "a list of unsupported types"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"restrictedAccessDialogMessage": "इस एप्लिकेशन को \"{volume}\" की {directory} में फ़ाइलों को संशोधित करने की अनुमति नहीं है।\n\nकृपया किसी अन्य directory में आइटम स्थानांतरित करने के लिए एक पूर्व-स्थापित फ़ाइल प्रबंधक या गैलरी ऐप का उपयोग करें।।",
|
||||||
|
"@restrictedAccessDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"directory": {
|
||||||
|
"type": "String",
|
||||||
|
"description": "the name of a directory, using the output of `rootDirectoryDescription` or `otherDirectoryDescription`"
|
||||||
|
},
|
||||||
|
"volume": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "SD card",
|
||||||
|
"description": "the name of a storage volume"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"videoResumeDialogMessage": "क्या आप {time} पर पुन: चलाना चाहते हैं?",
|
||||||
|
"@videoResumeDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"time": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "13:37"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"videoStartOverButtonLabel": "पुन: प्रारंभ करें",
|
||||||
|
"@videoStartOverButtonLabel": {},
|
||||||
|
"vaultDialogLockTypeLabel": "लॉक प्रकार",
|
||||||
|
"@vaultDialogLockTypeLabel": {},
|
||||||
|
"patternDialogConfirm": "पैटर्न कन्फर्म करे",
|
||||||
|
"@patternDialogConfirm": {},
|
||||||
|
"patternDialogEnter": "पैटर्न दर्ज करें",
|
||||||
|
"@patternDialogEnter": {},
|
||||||
|
"authenticateToUnlockVault": "वॉल्ट को अनलॉक करने के लिए प्रमाणीकरण करें",
|
||||||
|
"@authenticateToUnlockVault": {},
|
||||||
|
"settingsVideoEnablePip": "पिक्चर-इन-पिक्चर",
|
||||||
|
"@settingsVideoEnablePip": {},
|
||||||
|
"videoControlsPlay": "चलाएं",
|
||||||
|
"@videoControlsPlay": {},
|
||||||
|
"videoControlsPlayOutside": "अन्य प्लेयर के साथ खोलें",
|
||||||
|
"@videoControlsPlayOutside": {},
|
||||||
|
"videoControlsNone": "कोई नहीं",
|
||||||
|
"@videoControlsNone": {},
|
||||||
|
"videoLoopModeShortOnly": "केवल लघु वीडियो",
|
||||||
|
"@videoLoopModeShortOnly": {},
|
||||||
|
"videoPlaybackWithSound": "ध्वनि के साथ चलाए",
|
||||||
|
"@videoPlaybackWithSound": {},
|
||||||
|
"viewerTransitionParallax": "पैरालैक्स",
|
||||||
|
"@viewerTransitionParallax": {},
|
||||||
|
"viewerTransitionZoomIn": "ज़ूम इन",
|
||||||
|
"@viewerTransitionZoomIn": {},
|
||||||
|
"wallpaperTargetHome": "होम स्क्रीन",
|
||||||
|
"@wallpaperTargetHome": {},
|
||||||
|
"widgetDisplayedItemRandom": "यादृच्छिक",
|
||||||
|
"@widgetDisplayedItemRandom": {},
|
||||||
|
"videoResumeButtonLabel": "पुन: चलाएं",
|
||||||
|
"@videoResumeButtonLabel": {},
|
||||||
|
"filterNoTitleLabel": "शीर्षकहीन",
|
||||||
|
"@filterNoTitleLabel": {},
|
||||||
|
"stopTooltip": "रोके",
|
||||||
|
"@stopTooltip": {},
|
||||||
|
"vaultLockTypePin": "पिन",
|
||||||
|
"@vaultLockTypePin": {},
|
||||||
|
"wallpaperTargetHomeLock": "होम और लॉक स्क्रीन",
|
||||||
|
"@wallpaperTargetHomeLock": {},
|
||||||
|
"widgetDisplayedItemMostRecent": "हाल ही के",
|
||||||
|
"@widgetDisplayedItemMostRecent": {},
|
||||||
|
"filterAspectRatioLandscapeLabel": "लैंडस्केप",
|
||||||
|
"@filterAspectRatioLandscapeLabel": {},
|
||||||
|
"filterNoDateLabel": "अदिनांकित",
|
||||||
|
"@filterNoDateLabel": {},
|
||||||
|
"filterNoTagLabel": "टैग नहीं किया गया",
|
||||||
|
"@filterNoTagLabel": {},
|
||||||
|
"filterTypeGeotiffLabel": "GeoTIFF",
|
||||||
|
"@filterTypeGeotiffLabel": {},
|
||||||
|
"accessibilityAnimationsKeep": "स्क्रीन प्रभाव रखें",
|
||||||
|
"@accessibilityAnimationsKeep": {},
|
||||||
|
"vaultLockTypePattern": "पैटर्न",
|
||||||
|
"@vaultLockTypePattern": {},
|
||||||
|
"coordinateDmsNorth": "उ",
|
||||||
|
"@coordinateDmsNorth": {},
|
||||||
|
"albumTierNew": "नया",
|
||||||
|
"@albumTierNew": {},
|
||||||
|
"albumTierApps": "ऐप्स",
|
||||||
|
"@albumTierApps": {},
|
||||||
|
"lengthUnitPercent": "%",
|
||||||
|
"@lengthUnitPercent": {},
|
||||||
|
"nameConflictStrategyReplace": "बदलें",
|
||||||
|
"@nameConflictStrategyReplace": {},
|
||||||
|
"themeBrightnessLight": "Light",
|
||||||
|
"@themeBrightnessLight": {},
|
||||||
|
"vaultLockTypePassword": "पासवर्ड",
|
||||||
|
"@vaultLockTypePassword": {},
|
||||||
|
"storageVolumeDescriptionFallbackNonPrimary": "एसडी कार्ड",
|
||||||
|
"@storageVolumeDescriptionFallbackNonPrimary": {},
|
||||||
|
"storageAccessDialogMessage": "अगले स्क्रीन में \"{volume}\" के {directory} का चयन करें ताकि यह ऐप इसके लिए पहुंच सके।।",
|
||||||
|
"@storageAccessDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"directory": {
|
||||||
|
"type": "String",
|
||||||
|
"description": "the name of a directory, using the output of `rootDirectoryDescription` or `otherDirectoryDescription`"
|
||||||
|
},
|
||||||
|
"volume": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "SD card",
|
||||||
|
"description": "the name of a storage volume"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rootDirectoryDescription": "root directory",
|
||||||
|
"@rootDirectoryDescription": {},
|
||||||
|
"otherDirectoryDescription": "“{name}” directory",
|
||||||
|
"@otherDirectoryDescription": {
|
||||||
|
"placeholders": {
|
||||||
|
"name": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "Pictures",
|
||||||
|
"description": "the name of a specific directory"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"missingSystemFilePickerDialogMessage": "सिस्टम फ़ाइल पिकर लापता या अक्षम है। कृपया इसे सक्षम करें और फिर से प्रयास करें।।",
|
||||||
|
"@missingSystemFilePickerDialogMessage": {},
|
||||||
|
"nameConflictDialogMultipleSourceMessage": "कुछ फ़ाइलों का नाम समान है।।",
|
||||||
|
"@nameConflictDialogMultipleSourceMessage": {},
|
||||||
|
"addShortcutDialogLabel": "शॉर्टकट लेबल",
|
||||||
|
"@addShortcutDialogLabel": {},
|
||||||
|
"newVaultWarningDialogMessage": "वॉल्ट में आइटम केवल इस ऐप के लिए व अन्य के लिए नहीं उपलब्ध हैं।\n\nयदि आप इस ऐप को अनइंस्टॉल करते हैं, या इस ऐप डेटा को साफ़ करते हैं, तो आप इन सभी आइटम को खो देंगे।।",
|
||||||
|
"@newVaultWarningDialogMessage": {},
|
||||||
|
"configureVaultDialogTitle": "वॉल्ट को कॉन्फ़िगर करना",
|
||||||
|
"@configureVaultDialogTitle": {},
|
||||||
|
"moveUndatedConfirmationDialogMessage": "आगे बढ़ने से पहले आइटम की तारीख सेव करे?",
|
||||||
|
"@moveUndatedConfirmationDialogMessage": {},
|
||||||
|
"setCoverDialogLatest": "नवीनतम आइटम",
|
||||||
|
"@setCoverDialogLatest": {},
|
||||||
|
"hideFilterConfirmationDialogMessage": "मैचिंग तस्वीरें और वीडियो आपके कलेक्शन से छिपे होंगे। आप उन्हें फिर से \"गोपनीयता\" सेटिंग्स से दिखा सकते हैं।\n\nक्या आप उन्हें छिपाना चाहते हैं?",
|
||||||
|
"@hideFilterConfirmationDialogMessage": {},
|
||||||
|
"renameEntrySetPageTitle": "नाम बदलें",
|
||||||
|
"@renameEntrySetPageTitle": {},
|
||||||
|
"authenticateToConfigureVault": "वॉल्ट को कॉन्फ़िगर करने के लिए प्रमाणीकरण करें",
|
||||||
|
"@authenticateToConfigureVault": {},
|
||||||
|
"renameAlbumDialogLabelAlreadyExistsHelper": "डायरेक्टरी पहले से मौजूद",
|
||||||
|
"@renameAlbumDialogLabelAlreadyExistsHelper": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1374,5 +1374,11 @@
|
||||||
"renameProcessorHash": "Hash",
|
"renameProcessorHash": "Hash",
|
||||||
"@renameProcessorHash": {},
|
"@renameProcessorHash": {},
|
||||||
"chipActionShowCollection": "Tampilkan di Koleksi",
|
"chipActionShowCollection": "Tampilkan di Koleksi",
|
||||||
"@chipActionShowCollection": {}
|
"@chipActionShowCollection": {},
|
||||||
|
"explorerActionSelectStorageVolume": "Pilih penyimpanan",
|
||||||
|
"@explorerActionSelectStorageVolume": {},
|
||||||
|
"selectStorageVolumeDialogTitle": "Pilih Penyimpanan",
|
||||||
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"setHomeCustom": "Kustom",
|
||||||
|
"@setHomeCustom": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1384,5 +1384,11 @@
|
||||||
"explorerActionSelectStorageVolume": "저장공간 선택",
|
"explorerActionSelectStorageVolume": "저장공간 선택",
|
||||||
"@explorerActionSelectStorageVolume": {},
|
"@explorerActionSelectStorageVolume": {},
|
||||||
"selectStorageVolumeDialogTitle": "저장공간",
|
"selectStorageVolumeDialogTitle": "저장공간",
|
||||||
"@selectStorageVolumeDialogTitle": {}
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"sortByDuration": "길이",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderShortestFirst": "짧은 순",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "긴 순",
|
||||||
|
"@sortOrderLongestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,11 +65,11 @@
|
||||||
"@sourceStateLocatingPlaces": {},
|
"@sourceStateLocatingPlaces": {},
|
||||||
"chipActionDelete": "Verwijderen",
|
"chipActionDelete": "Verwijderen",
|
||||||
"@chipActionDelete": {},
|
"@chipActionDelete": {},
|
||||||
"chipActionGoToAlbumPage": "Tonen Albums",
|
"chipActionGoToAlbumPage": "In Albums tonen",
|
||||||
"@chipActionGoToAlbumPage": {},
|
"@chipActionGoToAlbumPage": {},
|
||||||
"chipActionGoToCountryPage": "Tonen in Landen",
|
"chipActionGoToCountryPage": "In Landen tonen",
|
||||||
"@chipActionGoToCountryPage": {},
|
"@chipActionGoToCountryPage": {},
|
||||||
"chipActionGoToTagPage": "Tonen in Labels",
|
"chipActionGoToTagPage": "In Labels tonen",
|
||||||
"@chipActionGoToTagPage": {},
|
"@chipActionGoToTagPage": {},
|
||||||
"chipActionFilterOut": "Uitfilteren",
|
"chipActionFilterOut": "Uitfilteren",
|
||||||
"@chipActionFilterOut": {},
|
"@chipActionFilterOut": {},
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
"@entryActionShare": {},
|
"@entryActionShare": {},
|
||||||
"entryActionViewSource": "Bron bekijken",
|
"entryActionViewSource": "Bron bekijken",
|
||||||
"@entryActionViewSource": {},
|
"@entryActionViewSource": {},
|
||||||
"entryActionShowGeoTiffOnMap": "Tonen als map overlay",
|
"entryActionShowGeoTiffOnMap": "Als kaart-overlay tonen",
|
||||||
"@entryActionShowGeoTiffOnMap": {},
|
"@entryActionShowGeoTiffOnMap": {},
|
||||||
"entryActionConvertMotionPhotoToStillImage": "Converteren naar stilstaand beeld",
|
"entryActionConvertMotionPhotoToStillImage": "Converteren naar stilstaand beeld",
|
||||||
"@entryActionConvertMotionPhotoToStillImage": {},
|
"@entryActionConvertMotionPhotoToStillImage": {},
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
"@entryActionOpen": {},
|
"@entryActionOpen": {},
|
||||||
"entryActionSetAs": "Instellen als",
|
"entryActionSetAs": "Instellen als",
|
||||||
"@entryActionSetAs": {},
|
"@entryActionSetAs": {},
|
||||||
"entryActionOpenMap": "Tonen in map app",
|
"entryActionOpenMap": "In Kaarten-app tonen",
|
||||||
"@entryActionOpenMap": {},
|
"@entryActionOpenMap": {},
|
||||||
"entryActionRotateScreen": "Scherm roteren",
|
"entryActionRotateScreen": "Scherm roteren",
|
||||||
"@entryActionRotateScreen": {},
|
"@entryActionRotateScreen": {},
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
"@videoActionReplay10": {},
|
"@videoActionReplay10": {},
|
||||||
"videoActionSkip10": "10 seconden vooruit",
|
"videoActionSkip10": "10 seconden vooruit",
|
||||||
"@videoActionSkip10": {},
|
"@videoActionSkip10": {},
|
||||||
"videoActionSelectStreams": "Tracks selecteren",
|
"videoActionSelectStreams": "Sporen selecteren",
|
||||||
"@videoActionSelectStreams": {},
|
"@videoActionSelectStreams": {},
|
||||||
"videoActionSetSpeed": "Afspeelsnelheid",
|
"videoActionSetSpeed": "Afspeelsnelheid",
|
||||||
"@videoActionSetSpeed": {},
|
"@videoActionSetSpeed": {},
|
||||||
|
@ -155,13 +155,13 @@
|
||||||
"@viewerActionSettings": {},
|
"@viewerActionSettings": {},
|
||||||
"slideshowActionResume": "Hervatten",
|
"slideshowActionResume": "Hervatten",
|
||||||
"@slideshowActionResume": {},
|
"@slideshowActionResume": {},
|
||||||
"slideshowActionShowInCollection": "Tonen in Collectie",
|
"slideshowActionShowInCollection": "In Collectie tonen",
|
||||||
"@slideshowActionShowInCollection": {},
|
"@slideshowActionShowInCollection": {},
|
||||||
"entryInfoActionEditDate": "Bewerk datum & tijd",
|
"entryInfoActionEditDate": "Datum & tijd bewerken",
|
||||||
"@entryInfoActionEditDate": {},
|
"@entryInfoActionEditDate": {},
|
||||||
"entryInfoActionEditLocation": "Bewerk locatie",
|
"entryInfoActionEditLocation": "Locatie bewerken",
|
||||||
"@entryInfoActionEditLocation": {},
|
"@entryInfoActionEditLocation": {},
|
||||||
"entryInfoActionEditTitleDescription": "Wijzig titel & omschrijving",
|
"entryInfoActionEditTitleDescription": "Titel & beschrijving bewerken",
|
||||||
"@entryInfoActionEditTitleDescription": {},
|
"@entryInfoActionEditTitleDescription": {},
|
||||||
"entryInfoActionEditRating": "Waardering bewerken",
|
"entryInfoActionEditRating": "Waardering bewerken",
|
||||||
"@entryInfoActionEditRating": {},
|
"@entryInfoActionEditRating": {},
|
||||||
|
@ -221,11 +221,11 @@
|
||||||
"@coordinateDmsWest": {},
|
"@coordinateDmsWest": {},
|
||||||
"unitSystemMetric": "Metrisch",
|
"unitSystemMetric": "Metrisch",
|
||||||
"@unitSystemMetric": {},
|
"@unitSystemMetric": {},
|
||||||
"unitSystemImperial": "Imperiaal",
|
"unitSystemImperial": "Brits-Amerikaans",
|
||||||
"@unitSystemImperial": {},
|
"@unitSystemImperial": {},
|
||||||
"videoLoopModeNever": "Nooit",
|
"videoLoopModeNever": "Nooit",
|
||||||
"@videoLoopModeNever": {},
|
"@videoLoopModeNever": {},
|
||||||
"videoLoopModeShortOnly": "Enkel korte videos",
|
"videoLoopModeShortOnly": "Alleen korte video's",
|
||||||
"@videoLoopModeShortOnly": {},
|
"@videoLoopModeShortOnly": {},
|
||||||
"videoLoopModeAlways": "Altijd",
|
"videoLoopModeAlways": "Altijd",
|
||||||
"@videoLoopModeAlways": {},
|
"@videoLoopModeAlways": {},
|
||||||
|
@ -233,7 +233,7 @@
|
||||||
"@videoControlsPlay": {},
|
"@videoControlsPlay": {},
|
||||||
"videoControlsPlaySeek": "Speel & zoek terug/vooruit",
|
"videoControlsPlaySeek": "Speel & zoek terug/vooruit",
|
||||||
"@videoControlsPlaySeek": {},
|
"@videoControlsPlaySeek": {},
|
||||||
"videoControlsPlayOutside": "Openen met andere speler",
|
"videoControlsPlayOutside": "Met andere speler openen",
|
||||||
"@videoControlsPlayOutside": {},
|
"@videoControlsPlayOutside": {},
|
||||||
"videoControlsNone": "Geen",
|
"videoControlsNone": "Geen",
|
||||||
"@videoControlsNone": {},
|
"@videoControlsNone": {},
|
||||||
|
@ -255,13 +255,13 @@
|
||||||
"@nameConflictStrategySkip": {},
|
"@nameConflictStrategySkip": {},
|
||||||
"keepScreenOnNever": "Nooit",
|
"keepScreenOnNever": "Nooit",
|
||||||
"@keepScreenOnNever": {},
|
"@keepScreenOnNever": {},
|
||||||
"keepScreenOnViewerOnly": "Enkel Viewer pagina",
|
"keepScreenOnViewerOnly": "Alleen Viewerpagina",
|
||||||
"@keepScreenOnViewerOnly": {},
|
"@keepScreenOnViewerOnly": {},
|
||||||
"keepScreenOnAlways": "Altijd",
|
"keepScreenOnAlways": "Altijd",
|
||||||
"@keepScreenOnAlways": {},
|
"@keepScreenOnAlways": {},
|
||||||
"accessibilityAnimationsRemove": "Scherm effecten uitschakelen",
|
"accessibilityAnimationsRemove": "Schermeffecten uitschakelen",
|
||||||
"@accessibilityAnimationsRemove": {},
|
"@accessibilityAnimationsRemove": {},
|
||||||
"accessibilityAnimationsKeep": "Scherm effecten houden",
|
"accessibilityAnimationsKeep": "Schermeffecten behouden",
|
||||||
"@accessibilityAnimationsKeep": {},
|
"@accessibilityAnimationsKeep": {},
|
||||||
"displayRefreshRatePreferHighest": "Hoogste waardering",
|
"displayRefreshRatePreferHighest": "Hoogste waardering",
|
||||||
"@displayRefreshRatePreferHighest": {},
|
"@displayRefreshRatePreferHighest": {},
|
||||||
|
@ -269,7 +269,7 @@
|
||||||
"@displayRefreshRatePreferLowest": {},
|
"@displayRefreshRatePreferLowest": {},
|
||||||
"videoPlaybackSkip": "Overslaan",
|
"videoPlaybackSkip": "Overslaan",
|
||||||
"@videoPlaybackSkip": {},
|
"@videoPlaybackSkip": {},
|
||||||
"videoPlaybackMuted": "Gedempte afspelen",
|
"videoPlaybackMuted": "Gedempt afspelen",
|
||||||
"@videoPlaybackMuted": {},
|
"@videoPlaybackMuted": {},
|
||||||
"videoPlaybackWithSound": "Met geluid afspelen",
|
"videoPlaybackWithSound": "Met geluid afspelen",
|
||||||
"@videoPlaybackWithSound": {},
|
"@videoPlaybackWithSound": {},
|
||||||
|
@ -289,13 +289,13 @@
|
||||||
"@viewerTransitionZoomIn": {},
|
"@viewerTransitionZoomIn": {},
|
||||||
"viewerTransitionNone": "Geen",
|
"viewerTransitionNone": "Geen",
|
||||||
"@viewerTransitionNone": {},
|
"@viewerTransitionNone": {},
|
||||||
"wallpaperTargetHome": "Home scherm",
|
"wallpaperTargetHome": "Startscherm",
|
||||||
"@wallpaperTargetHome": {},
|
"@wallpaperTargetHome": {},
|
||||||
"wallpaperTargetLock": "Vergrendel scherm",
|
"wallpaperTargetLock": "Vergrendelingsscherm",
|
||||||
"@wallpaperTargetLock": {},
|
"@wallpaperTargetLock": {},
|
||||||
"wallpaperTargetHomeLock": "Home and Vergrendel schermen",
|
"wallpaperTargetHomeLock": "Start- en vergrendelingsschermen",
|
||||||
"@wallpaperTargetHomeLock": {},
|
"@wallpaperTargetHomeLock": {},
|
||||||
"widgetOpenPageHome": "Open startscherm",
|
"widgetOpenPageHome": "Startscherm openen",
|
||||||
"@widgetOpenPageHome": {},
|
"@widgetOpenPageHome": {},
|
||||||
"albumTierNew": "Nieuw",
|
"albumTierNew": "Nieuw",
|
||||||
"@albumTierNew": {},
|
"@albumTierNew": {},
|
||||||
|
@ -315,7 +315,7 @@
|
||||||
"@rootDirectoryDescription": {},
|
"@rootDirectoryDescription": {},
|
||||||
"otherDirectoryDescription": "“{name}” map",
|
"otherDirectoryDescription": "“{name}” map",
|
||||||
"@otherDirectoryDescription": {},
|
"@otherDirectoryDescription": {},
|
||||||
"storageAccessDialogMessage": "Selecteer de {directory} van “{volume}”, in het volgende scherm om deze app er toegang toe te geven.",
|
"storageAccessDialogMessage": "Selecteer in het volgende scherm de {directory} van “{volume}” om deze app er toegang toe te geven.",
|
||||||
"@storageAccessDialogMessage": {},
|
"@storageAccessDialogMessage": {},
|
||||||
"restrictedAccessDialogMessage": "Deze applicatie mag geen bestanden wijzigen in de {directory} van “{volume}”,.\n\n Gebruik een vooraf geïnstalleerde filemanager of galerij-app om de items naar een andere map te verplaatsen.",
|
"restrictedAccessDialogMessage": "Deze applicatie mag geen bestanden wijzigen in de {directory} van “{volume}”,.\n\n Gebruik een vooraf geïnstalleerde filemanager of galerij-app om de items naar een andere map te verplaatsen.",
|
||||||
"@restrictedAccessDialogMessage": {},
|
"@restrictedAccessDialogMessage": {},
|
||||||
|
@ -335,17 +335,17 @@
|
||||||
"@addShortcutButtonLabel": {},
|
"@addShortcutButtonLabel": {},
|
||||||
"noMatchingAppDialogMessage": "Er zijn geen apps die dit ondersteunen.",
|
"noMatchingAppDialogMessage": "Er zijn geen apps die dit ondersteunen.",
|
||||||
"@noMatchingAppDialogMessage": {},
|
"@noMatchingAppDialogMessage": {},
|
||||||
"binEntriesConfirmationDialogMessage": "{count, plural, =1{Dit item naar de prullenbak verplaatsen??} other{Verplaats deze {count} items naar de prullenbak?}}",
|
"binEntriesConfirmationDialogMessage": "{count, plural, =1{Dit item naar de prullenbak verplaatsen??} other{Deze {count} items naar de prullenbak verplaatsen?}}",
|
||||||
"@binEntriesConfirmationDialogMessage": {},
|
"@binEntriesConfirmationDialogMessage": {},
|
||||||
"deleteEntriesConfirmationDialogMessage": "{count, plural, =1{Verwijder dit item?} other{Verwijder deze {count} items?}}",
|
"deleteEntriesConfirmationDialogMessage": "{count, plural, =1{Dit item verwijderen?} other{Deze {count} items verwijderen?}}",
|
||||||
"@deleteEntriesConfirmationDialogMessage": {},
|
"@deleteEntriesConfirmationDialogMessage": {},
|
||||||
"moveUndatedConfirmationDialogMessage": "Datums opslaan voordat u doorgaat??",
|
"moveUndatedConfirmationDialogMessage": "Datums opslaan alvorens door te gaan?",
|
||||||
"@moveUndatedConfirmationDialogMessage": {},
|
"@moveUndatedConfirmationDialogMessage": {},
|
||||||
"moveUndatedConfirmationDialogSetDate": "Datums opslaan",
|
"moveUndatedConfirmationDialogSetDate": "Datums opslaan",
|
||||||
"@moveUndatedConfirmationDialogSetDate": {},
|
"@moveUndatedConfirmationDialogSetDate": {},
|
||||||
"videoResumeDialogMessage": "Wil je het afspelen hervatten op {time}?",
|
"videoResumeDialogMessage": "Afspelen hervatten om {time}?",
|
||||||
"@videoResumeDialogMessage": {},
|
"@videoResumeDialogMessage": {},
|
||||||
"videoStartOverButtonLabel": "OPNIEUW BEGINNEN",
|
"videoStartOverButtonLabel": "OPNIEUW AFSPELLEN",
|
||||||
"@videoStartOverButtonLabel": {},
|
"@videoStartOverButtonLabel": {},
|
||||||
"videoResumeButtonLabel": "HERVATTEN",
|
"videoResumeButtonLabel": "HERVATTEN",
|
||||||
"@videoResumeButtonLabel": {},
|
"@videoResumeButtonLabel": {},
|
||||||
|
@ -355,7 +355,7 @@
|
||||||
"@setCoverDialogAuto": {},
|
"@setCoverDialogAuto": {},
|
||||||
"setCoverDialogCustom": "Aangepast",
|
"setCoverDialogCustom": "Aangepast",
|
||||||
"@setCoverDialogCustom": {},
|
"@setCoverDialogCustom": {},
|
||||||
"hideFilterConfirmationDialogMessage": "Overeenkomende foto’s en video’s worden verborgen binnen jouw verzameling. Je kunt ze opnieuw weergeven via de “Privacy”-instellingen.\n\nWeet je zeker dat je ze wilt verbergen?",
|
"hideFilterConfirmationDialogMessage": "Overeenkomstige foto’s en video’s worden verborgen binnen jouw verzameling. Je kunt ze opnieuw weergeven via de “Privacy”-instellingen.\n\nWeet je zeker dat je ze wilt verbergen?",
|
||||||
"@hideFilterConfirmationDialogMessage": {},
|
"@hideFilterConfirmationDialogMessage": {},
|
||||||
"newAlbumDialogTitle": "Nieuw Album",
|
"newAlbumDialogTitle": "Nieuw Album",
|
||||||
"@newAlbumDialogTitle": {},
|
"@newAlbumDialogTitle": {},
|
||||||
|
@ -381,11 +381,11 @@
|
||||||
"@renameProcessorCounter": {},
|
"@renameProcessorCounter": {},
|
||||||
"renameProcessorName": "Naam",
|
"renameProcessorName": "Naam",
|
||||||
"@renameProcessorName": {},
|
"@renameProcessorName": {},
|
||||||
"deleteSingleAlbumConfirmationDialogMessage": "{count, plural, =1{Verwijder dit album en het item binnen dit album?} other{Verwijder dit album en de {count} items binnen dit album?}}",
|
"deleteSingleAlbumConfirmationDialogMessage": "{count, plural, =1{Dit album en het item erbinnen verwijderen?} other{Dit album en de {count} items erbinnen verwijderen?}}",
|
||||||
"@deleteSingleAlbumConfirmationDialogMessage": {},
|
"@deleteSingleAlbumConfirmationDialogMessage": {},
|
||||||
"deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{Verwijder deze albums en het item binnen deze albums?} other{Verwijder deze albums en de {count} items binnen deze albums?}}",
|
"deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{Deze albums en de items erbinnen verwijderen?} other{Deze albums en de {count} items erbinnen verwijderen?}}",
|
||||||
"@deleteMultiAlbumConfirmationDialogMessage": {},
|
"@deleteMultiAlbumConfirmationDialogMessage": {},
|
||||||
"exportEntryDialogFormat": "Formaat:",
|
"exportEntryDialogFormat": "Type:",
|
||||||
"@exportEntryDialogFormat": {},
|
"@exportEntryDialogFormat": {},
|
||||||
"exportEntryDialogWidth": "Breedte",
|
"exportEntryDialogWidth": "Breedte",
|
||||||
"@exportEntryDialogWidth": {},
|
"@exportEntryDialogWidth": {},
|
||||||
|
@ -397,11 +397,11 @@
|
||||||
"@editEntryDialogTargetFieldsHeader": {},
|
"@editEntryDialogTargetFieldsHeader": {},
|
||||||
"editEntryDateDialogTitle": "Datum & Tijd",
|
"editEntryDateDialogTitle": "Datum & Tijd",
|
||||||
"@editEntryDateDialogTitle": {},
|
"@editEntryDateDialogTitle": {},
|
||||||
"editEntryDateDialogSetCustom": "Stel een custom datum in",
|
"editEntryDateDialogSetCustom": "Aangepaste datum instellen",
|
||||||
"@editEntryDateDialogSetCustom": {},
|
"@editEntryDateDialogSetCustom": {},
|
||||||
"editEntryDateDialogCopyField": "Kopiëren van andere datum",
|
"editEntryDateDialogCopyField": "Van andere datum kopiëren",
|
||||||
"@editEntryDateDialogCopyField": {},
|
"@editEntryDateDialogCopyField": {},
|
||||||
"editEntryDialogCopyFromItem": "Kopiëren van ander item",
|
"editEntryDialogCopyFromItem": "Van ander item kopiëren",
|
||||||
"@editEntryDialogCopyFromItem": {},
|
"@editEntryDialogCopyFromItem": {},
|
||||||
"editEntryDateDialogExtractFromTitle": "Uit titel halen",
|
"editEntryDateDialogExtractFromTitle": "Uit titel halen",
|
||||||
"@editEntryDateDialogExtractFromTitle": {},
|
"@editEntryDateDialogExtractFromTitle": {},
|
||||||
|
@ -415,7 +415,7 @@
|
||||||
"@durationDialogMinutes": {},
|
"@durationDialogMinutes": {},
|
||||||
"editEntryLocationDialogTitle": "Locatie",
|
"editEntryLocationDialogTitle": "Locatie",
|
||||||
"@editEntryLocationDialogTitle": {},
|
"@editEntryLocationDialogTitle": {},
|
||||||
"editEntryLocationDialogChooseOnMap": "Kies op kaart",
|
"editEntryLocationDialogChooseOnMap": "Op kaart kiezen",
|
||||||
"@editEntryLocationDialogChooseOnMap": {},
|
"@editEntryLocationDialogChooseOnMap": {},
|
||||||
"editEntryLocationDialogLatitude": "Breedtegraad",
|
"editEntryLocationDialogLatitude": "Breedtegraad",
|
||||||
"@editEntryLocationDialogLatitude": {},
|
"@editEntryLocationDialogLatitude": {},
|
||||||
|
@ -443,9 +443,9 @@
|
||||||
"@videoStreamSelectionDialogText": {},
|
"@videoStreamSelectionDialogText": {},
|
||||||
"videoStreamSelectionDialogOff": "Uit",
|
"videoStreamSelectionDialogOff": "Uit",
|
||||||
"@videoStreamSelectionDialogOff": {},
|
"@videoStreamSelectionDialogOff": {},
|
||||||
"videoStreamSelectionDialogTrack": "Nummer",
|
"videoStreamSelectionDialogTrack": "Spoor",
|
||||||
"@videoStreamSelectionDialogTrack": {},
|
"@videoStreamSelectionDialogTrack": {},
|
||||||
"videoStreamSelectionDialogNoSelection": "Er zijn geen andere nummers.",
|
"videoStreamSelectionDialogNoSelection": "Er zijn geen andere sporen.",
|
||||||
"@videoStreamSelectionDialogNoSelection": {},
|
"@videoStreamSelectionDialogNoSelection": {},
|
||||||
"genericSuccessFeedback": "Klaar!",
|
"genericSuccessFeedback": "Klaar!",
|
||||||
"@genericSuccessFeedback": {},
|
"@genericSuccessFeedback": {},
|
||||||
|
@ -453,9 +453,9 @@
|
||||||
"@genericFailureFeedback": {},
|
"@genericFailureFeedback": {},
|
||||||
"menuActionConfigureView": "Beeld",
|
"menuActionConfigureView": "Beeld",
|
||||||
"@menuActionConfigureView": {},
|
"@menuActionConfigureView": {},
|
||||||
"menuActionSelect": "Selecteer",
|
"menuActionSelect": "Selecteren",
|
||||||
"@menuActionSelect": {},
|
"@menuActionSelect": {},
|
||||||
"menuActionSelectAll": "Selecteer alles",
|
"menuActionSelectAll": "Alles selecteren",
|
||||||
"@menuActionSelectAll": {},
|
"@menuActionSelectAll": {},
|
||||||
"menuActionSelectNone": "Selectie ongedaan maken",
|
"menuActionSelectNone": "Selectie ongedaan maken",
|
||||||
"@menuActionSelectNone": {},
|
"@menuActionSelectNone": {},
|
||||||
|
@ -493,17 +493,17 @@
|
||||||
"@aboutPageTitle": {},
|
"@aboutPageTitle": {},
|
||||||
"aboutLinkLicense": "Licentie",
|
"aboutLinkLicense": "Licentie",
|
||||||
"@aboutLinkLicense": {},
|
"@aboutLinkLicense": {},
|
||||||
"aboutBugSectionTitle": "Bug Reporteren",
|
"aboutBugSectionTitle": "Foutmelding",
|
||||||
"@aboutBugSectionTitle": {},
|
"@aboutBugSectionTitle": {},
|
||||||
"aboutBugSaveLogInstruction": "Sla applicatielogs op in een bestand",
|
"aboutBugSaveLogInstruction": "Sla applicatielogs op in een bestand",
|
||||||
"@aboutBugSaveLogInstruction": {},
|
"@aboutBugSaveLogInstruction": {},
|
||||||
"aboutBugCopyInfoInstruction": "Kopieer systeem informatie",
|
"aboutBugCopyInfoInstruction": "Systeeminformatie kopiëren",
|
||||||
"@aboutBugCopyInfoInstruction": {},
|
"@aboutBugCopyInfoInstruction": {},
|
||||||
"aboutBugCopyInfoButton": "Kopieer",
|
"aboutBugCopyInfoButton": "Kopieer",
|
||||||
"@aboutBugCopyInfoButton": {},
|
"@aboutBugCopyInfoButton": {},
|
||||||
"aboutBugReportInstruction": "Reporteer op GitHub met de logs en systeeminformatie",
|
"aboutBugReportInstruction": "Melden op GitHub met de logs en systeeminformatie",
|
||||||
"@aboutBugReportInstruction": {},
|
"@aboutBugReportInstruction": {},
|
||||||
"aboutBugReportButton": "Reporteer",
|
"aboutBugReportButton": "Melden",
|
||||||
"@aboutBugReportButton": {},
|
"@aboutBugReportButton": {},
|
||||||
"aboutCreditsSectionTitle": "Dankbetuiging",
|
"aboutCreditsSectionTitle": "Dankbetuiging",
|
||||||
"@aboutCreditsSectionTitle": {},
|
"@aboutCreditsSectionTitle": {},
|
||||||
|
@ -531,9 +531,9 @@
|
||||||
"@collectionPageTitle": {},
|
"@collectionPageTitle": {},
|
||||||
"collectionPickPageTitle": "Kies",
|
"collectionPickPageTitle": "Kies",
|
||||||
"@collectionPickPageTitle": {},
|
"@collectionPickPageTitle": {},
|
||||||
"collectionSelectPageTitle": "Selecteer items",
|
"collectionSelectPageTitle": "Items selecteren",
|
||||||
"@collectionSelectPageTitle": {},
|
"@collectionSelectPageTitle": {},
|
||||||
"collectionActionShowTitleSearch": "Laat titel filter zien",
|
"collectionActionShowTitleSearch": "Titelfilter weergeven",
|
||||||
"@collectionActionShowTitleSearch": {},
|
"@collectionActionShowTitleSearch": {},
|
||||||
"collectionActionHideTitleSearch": "Verberg titel filter",
|
"collectionActionHideTitleSearch": "Verberg titel filter",
|
||||||
"@collectionActionHideTitleSearch": {},
|
"@collectionActionHideTitleSearch": {},
|
||||||
|
@ -547,7 +547,7 @@
|
||||||
"@collectionActionMove": {},
|
"@collectionActionMove": {},
|
||||||
"collectionActionRescan": "Opnieuw indexeren",
|
"collectionActionRescan": "Opnieuw indexeren",
|
||||||
"@collectionActionRescan": {},
|
"@collectionActionRescan": {},
|
||||||
"collectionActionEdit": "Wijzigen",
|
"collectionActionEdit": "Bewerken",
|
||||||
"@collectionActionEdit": {},
|
"@collectionActionEdit": {},
|
||||||
"collectionSearchTitlesHintText": "Zoek op titel",
|
"collectionSearchTitlesHintText": "Zoek op titel",
|
||||||
"@collectionSearchTitlesHintText": {},
|
"@collectionSearchTitlesHintText": {},
|
||||||
|
@ -575,7 +575,7 @@
|
||||||
"@collectionMoveFailureFeedback": {},
|
"@collectionMoveFailureFeedback": {},
|
||||||
"collectionRenameFailureFeedback": "{count, plural, =1{Kan 1 item niet hernoemen} other{Kan {count} items niet hernoemen}}",
|
"collectionRenameFailureFeedback": "{count, plural, =1{Kan 1 item niet hernoemen} other{Kan {count} items niet hernoemen}}",
|
||||||
"@collectionRenameFailureFeedback": {},
|
"@collectionRenameFailureFeedback": {},
|
||||||
"collectionEditFailureFeedback": "{count, plural, =1{Kan 1 item niet wijzigen} other{Kan {count} items niet wijzigen}}",
|
"collectionEditFailureFeedback": "{count, plural, =1{Kan 1 item niet bewerken} other{Kan {count} items niet bewerken}}",
|
||||||
"@collectionEditFailureFeedback": {},
|
"@collectionEditFailureFeedback": {},
|
||||||
"collectionExportFailureFeedback": "{count, plural, =1{Kan 1 pagina niet exporteren} other{Kan {count} pagina’s niet exporteren}}",
|
"collectionExportFailureFeedback": "{count, plural, =1{Kan 1 pagina niet exporteren} other{Kan {count} pagina’s niet exporteren}}",
|
||||||
"@collectionExportFailureFeedback": {},
|
"@collectionExportFailureFeedback": {},
|
||||||
|
@ -585,7 +585,7 @@
|
||||||
"@collectionMoveSuccessFeedback": {},
|
"@collectionMoveSuccessFeedback": {},
|
||||||
"collectionRenameSuccessFeedback": "{count, plural, =1{1 item hernoemd} other{{count} items hernoemd}}",
|
"collectionRenameSuccessFeedback": "{count, plural, =1{1 item hernoemd} other{{count} items hernoemd}}",
|
||||||
"@collectionRenameSuccessFeedback": {},
|
"@collectionRenameSuccessFeedback": {},
|
||||||
"collectionEditSuccessFeedback": "{count, plural, =1{1 item gewijzigd} other{{count} items gewijzigd}}",
|
"collectionEditSuccessFeedback": "{count, plural, =1{1 item bewerkt} other{{count} items bewerkt}}",
|
||||||
"@collectionEditSuccessFeedback": {},
|
"@collectionEditSuccessFeedback": {},
|
||||||
"collectionEmptyFavourites": "Geen favourieten",
|
"collectionEmptyFavourites": "Geen favourieten",
|
||||||
"@collectionEmptyFavourites": {},
|
"@collectionEmptyFavourites": {},
|
||||||
|
@ -595,9 +595,9 @@
|
||||||
"@collectionEmptyImages": {},
|
"@collectionEmptyImages": {},
|
||||||
"collectionEmptyGrantAccessButtonLabel": "Toegang verlenen",
|
"collectionEmptyGrantAccessButtonLabel": "Toegang verlenen",
|
||||||
"@collectionEmptyGrantAccessButtonLabel": {},
|
"@collectionEmptyGrantAccessButtonLabel": {},
|
||||||
"collectionSelectSectionTooltip": "Selecteer sectie",
|
"collectionSelectSectionTooltip": "Sectie selecteren",
|
||||||
"@collectionSelectSectionTooltip": {},
|
"@collectionSelectSectionTooltip": {},
|
||||||
"collectionDeselectSectionTooltip": "Deselecteer sectie",
|
"collectionDeselectSectionTooltip": "Sectie niet selecteren",
|
||||||
"@collectionDeselectSectionTooltip": {},
|
"@collectionDeselectSectionTooltip": {},
|
||||||
"drawerAboutButton": "Over",
|
"drawerAboutButton": "Over",
|
||||||
"@drawerAboutButton": {},
|
"@drawerAboutButton": {},
|
||||||
|
@ -677,7 +677,7 @@
|
||||||
"@albumCamera": {},
|
"@albumCamera": {},
|
||||||
"albumDownload": "Opslaan",
|
"albumDownload": "Opslaan",
|
||||||
"@albumDownload": {},
|
"@albumDownload": {},
|
||||||
"albumScreenshots": "Schermafbeeldingen",
|
"albumScreenshots": "Schermopnames",
|
||||||
"@albumScreenshots": {},
|
"@albumScreenshots": {},
|
||||||
"albumScreenRecordings": "Schermopnames",
|
"albumScreenRecordings": "Schermopnames",
|
||||||
"@albumScreenRecordings": {},
|
"@albumScreenRecordings": {},
|
||||||
|
@ -751,25 +751,25 @@
|
||||||
"@settingsHomeTile": {},
|
"@settingsHomeTile": {},
|
||||||
"settingsHomeDialogTitle": "Startscherm",
|
"settingsHomeDialogTitle": "Startscherm",
|
||||||
"@settingsHomeDialogTitle": {},
|
"@settingsHomeDialogTitle": {},
|
||||||
"settingsShowBottomNavigationBar": "Laat onderste navigatiebalk zien",
|
"settingsShowBottomNavigationBar": "Onderste navigatiebalk weergeven",
|
||||||
"@settingsShowBottomNavigationBar": {},
|
"@settingsShowBottomNavigationBar": {},
|
||||||
"settingsKeepScreenOnTile": "Houd het scherm aan",
|
"settingsKeepScreenOnTile": "Scherm aan houden",
|
||||||
"@settingsKeepScreenOnTile": {},
|
"@settingsKeepScreenOnTile": {},
|
||||||
"settingsKeepScreenOnDialogTitle": "Houd het scherm aan",
|
"settingsKeepScreenOnDialogTitle": "Scherm aan houden",
|
||||||
"@settingsKeepScreenOnDialogTitle": {},
|
"@settingsKeepScreenOnDialogTitle": {},
|
||||||
"settingsDoubleBackExit": "Tik twee keer op “terug” om af te sluiten",
|
"settingsDoubleBackExit": "Twee keer op “terug” tikken om af te sluiten",
|
||||||
"@settingsDoubleBackExit": {},
|
"@settingsDoubleBackExit": {},
|
||||||
"settingsConfirmationTile": "Bevestigingsscherm",
|
"settingsConfirmationTile": "Bevestigingsdialogen",
|
||||||
"@settingsConfirmationTile": {},
|
"@settingsConfirmationTile": {},
|
||||||
"settingsConfirmationDialogTitle": "Bevestigingsschermen",
|
"settingsConfirmationDialogTitle": "Bevestigingsdialogen",
|
||||||
"@settingsConfirmationDialogTitle": {},
|
"@settingsConfirmationDialogTitle": {},
|
||||||
"settingsConfirmationBeforeDeleteItems": "Bevestig voordat je items voor altijd verwijdert",
|
"settingsConfirmationBeforeDeleteItems": "Bevestiging vragen voordat items voor altijd worden verwijderd",
|
||||||
"@settingsConfirmationBeforeDeleteItems": {},
|
"@settingsConfirmationBeforeDeleteItems": {},
|
||||||
"settingsConfirmationBeforeMoveToBinItems": "Bevestig voordat u items naar de prullenbak verplaatst",
|
"settingsConfirmationBeforeMoveToBinItems": "Bevestiging vragen voordat items naar de prullenbak worden verplaatst",
|
||||||
"@settingsConfirmationBeforeMoveToBinItems": {},
|
"@settingsConfirmationBeforeMoveToBinItems": {},
|
||||||
"settingsConfirmationBeforeMoveUndatedItems": "Bevestigvoordat u ongedateerde items verplaatst",
|
"settingsConfirmationBeforeMoveUndatedItems": "Bevestiging vragen voordat ongedateerde items worden verplaatst",
|
||||||
"@settingsConfirmationBeforeMoveUndatedItems": {},
|
"@settingsConfirmationBeforeMoveUndatedItems": {},
|
||||||
"settingsConfirmationAfterMoveToBinItems": "Toon bevestigingsbericht na het verplaatsen van items naar de prullenbak",
|
"settingsConfirmationAfterMoveToBinItems": "Bevestigingsbericht weergeven na het verplaatsen van items naar de prullenbak",
|
||||||
"@settingsConfirmationAfterMoveToBinItems": {},
|
"@settingsConfirmationAfterMoveToBinItems": {},
|
||||||
"settingsNavigationDrawerTile": "Navigatiemenu",
|
"settingsNavigationDrawerTile": "Navigatiemenu",
|
||||||
"@settingsNavigationDrawerTile": {},
|
"@settingsNavigationDrawerTile": {},
|
||||||
|
@ -791,35 +791,35 @@
|
||||||
"@settingsThumbnailOverlayTile": {},
|
"@settingsThumbnailOverlayTile": {},
|
||||||
"settingsThumbnailOverlayPageTitle": "Overlay",
|
"settingsThumbnailOverlayPageTitle": "Overlay",
|
||||||
"@settingsThumbnailOverlayPageTitle": {},
|
"@settingsThumbnailOverlayPageTitle": {},
|
||||||
"settingsThumbnailShowFavouriteIcon": "Favorieten icoon zichtbaar",
|
"settingsThumbnailShowFavouriteIcon": "Favorieten-pictogram tonen",
|
||||||
"@settingsThumbnailShowFavouriteIcon": {},
|
"@settingsThumbnailShowFavouriteIcon": {},
|
||||||
"settingsThumbnailShowTagIcon": "Label-pictogram tonen",
|
"settingsThumbnailShowTagIcon": "Label-pictogram tonen",
|
||||||
"@settingsThumbnailShowTagIcon": {},
|
"@settingsThumbnailShowTagIcon": {},
|
||||||
"settingsThumbnailShowLocationIcon": "Locatie icoon zichtbaar",
|
"settingsThumbnailShowLocationIcon": "Locatie-pictogram tonen",
|
||||||
"@settingsThumbnailShowLocationIcon": {},
|
"@settingsThumbnailShowLocationIcon": {},
|
||||||
"settingsThumbnailShowMotionPhotoIcon": "Bewegende foto icoon zichtbaar",
|
"settingsThumbnailShowMotionPhotoIcon": "Bewegende foto-pictogram tonen",
|
||||||
"@settingsThumbnailShowMotionPhotoIcon": {},
|
"@settingsThumbnailShowMotionPhotoIcon": {},
|
||||||
"settingsThumbnailShowRating": "Waardering tonen",
|
"settingsThumbnailShowRating": "Waardering tonen",
|
||||||
"@settingsThumbnailShowRating": {},
|
"@settingsThumbnailShowRating": {},
|
||||||
"settingsThumbnailShowRawIcon": "RAW icoon zichtbaar",
|
"settingsThumbnailShowRawIcon": "RAW-pictogram tonen",
|
||||||
"@settingsThumbnailShowRawIcon": {},
|
"@settingsThumbnailShowRawIcon": {},
|
||||||
"settingsThumbnailShowVideoDuration": "Videoduur zichtbaar",
|
"settingsThumbnailShowVideoDuration": "Videoduur tonen",
|
||||||
"@settingsThumbnailShowVideoDuration": {},
|
"@settingsThumbnailShowVideoDuration": {},
|
||||||
"settingsCollectionQuickActionsTile": "Snelle bewerkingen",
|
"settingsCollectionQuickActionsTile": "Snelle bewerkingen",
|
||||||
"@settingsCollectionQuickActionsTile": {},
|
"@settingsCollectionQuickActionsTile": {},
|
||||||
"settingsCollectionQuickActionEditorPageTitle": "Snelle bewerkingen",
|
"settingsCollectionQuickActionEditorPageTitle": "Snelle acties",
|
||||||
"@settingsCollectionQuickActionEditorPageTitle": {},
|
"@settingsCollectionQuickActionEditorPageTitle": {},
|
||||||
"settingsCollectionQuickActionTabBrowsing": "Blader",
|
"settingsCollectionQuickActionTabBrowsing": "Blader",
|
||||||
"@settingsCollectionQuickActionTabBrowsing": {},
|
"@settingsCollectionQuickActionTabBrowsing": {},
|
||||||
"settingsCollectionQuickActionTabSelecting": "Selecteren",
|
"settingsCollectionQuickActionTabSelecting": "Selecteren",
|
||||||
"@settingsCollectionQuickActionTabSelecting": {},
|
"@settingsCollectionQuickActionTabSelecting": {},
|
||||||
"settingsCollectionBrowsingQuickActionEditorBanner": "Houd ingedrukt om knoppen te verplaatsen en te selecteren welke acties worden weergegeven bij het bladeren door items.",
|
"settingsCollectionBrowsingQuickActionEditorBanner": "Houd knoppen ingedrukt om deze te verplaatsen en te selecteren welke acties worden weergegeven bij het bladeren door items.",
|
||||||
"@settingsCollectionBrowsingQuickActionEditorBanner": {},
|
"@settingsCollectionBrowsingQuickActionEditorBanner": {},
|
||||||
"settingsCollectionSelectionQuickActionEditorBanner": "Houd ingedrukt om knoppen te verplaatsen en te selecteren welke acties worden weergegeven bij het selecteren van items.",
|
"settingsCollectionSelectionQuickActionEditorBanner": "Houd knoppen ingedrukt om deze te verplaatsen en te selecteren welke acties worden weergegeven bij het selecteren van items.",
|
||||||
"@settingsCollectionSelectionQuickActionEditorBanner": {},
|
"@settingsCollectionSelectionQuickActionEditorBanner": {},
|
||||||
"settingsViewerSectionTitle": "Voorbeeld",
|
"settingsViewerSectionTitle": "Voorbeeld",
|
||||||
"@settingsViewerSectionTitle": {},
|
"@settingsViewerSectionTitle": {},
|
||||||
"settingsViewerGestureSideTapNext": "Druk op het scherm om het vorige/volgende item weer te geven",
|
"settingsViewerGestureSideTapNext": "Tik op het scherm om het vorige/volgende item weer te geven",
|
||||||
"@settingsViewerGestureSideTapNext": {},
|
"@settingsViewerGestureSideTapNext": {},
|
||||||
"settingsViewerUseCutout": "Uitgesneden gebied gebruiken",
|
"settingsViewerUseCutout": "Uitgesneden gebied gebruiken",
|
||||||
"@settingsViewerUseCutout": {},
|
"@settingsViewerUseCutout": {},
|
||||||
|
@ -831,9 +831,9 @@
|
||||||
"@settingsImageBackground": {},
|
"@settingsImageBackground": {},
|
||||||
"settingsViewerQuickActionsTile": "Snelle bewerkingen",
|
"settingsViewerQuickActionsTile": "Snelle bewerkingen",
|
||||||
"@settingsViewerQuickActionsTile": {},
|
"@settingsViewerQuickActionsTile": {},
|
||||||
"settingsViewerQuickActionEditorPageTitle": "Snelle bewerkingen",
|
"settingsViewerQuickActionEditorPageTitle": "Snelle acties",
|
||||||
"@settingsViewerQuickActionEditorPageTitle": {},
|
"@settingsViewerQuickActionEditorPageTitle": {},
|
||||||
"settingsViewerQuickActionEditorBanner": "Houd ingedrukt om knoppen te verplaatsen en te selecteren welke acties in de viewer worden weergegeven.",
|
"settingsViewerQuickActionEditorBanner": "Houd knoppen ingedrukt om deze te verplaatsen en te selecteren welke acties in de viewer worden weergegeven.",
|
||||||
"@settingsViewerQuickActionEditorBanner": {},
|
"@settingsViewerQuickActionEditorBanner": {},
|
||||||
"settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": "Zichtbare knoppen",
|
"settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": "Zichtbare knoppen",
|
||||||
"@settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": {},
|
"@settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": {},
|
||||||
|
@ -845,17 +845,17 @@
|
||||||
"@settingsViewerOverlayTile": {},
|
"@settingsViewerOverlayTile": {},
|
||||||
"settingsViewerOverlayPageTitle": "Overlay",
|
"settingsViewerOverlayPageTitle": "Overlay",
|
||||||
"@settingsViewerOverlayPageTitle": {},
|
"@settingsViewerOverlayPageTitle": {},
|
||||||
"settingsViewerShowOverlayOnOpening": "Zichtbaar bij openen",
|
"settingsViewerShowOverlayOnOpening": "Bij openen weergeven",
|
||||||
"@settingsViewerShowOverlayOnOpening": {},
|
"@settingsViewerShowOverlayOnOpening": {},
|
||||||
"settingsViewerShowMinimap": "Laat kleine kaart zien",
|
"settingsViewerShowMinimap": "Kleine kaart tonen",
|
||||||
"@settingsViewerShowMinimap": {},
|
"@settingsViewerShowMinimap": {},
|
||||||
"settingsViewerShowInformation": "Laat informatie zien",
|
"settingsViewerShowInformation": "Informatie tonen",
|
||||||
"@settingsViewerShowInformation": {},
|
"@settingsViewerShowInformation": {},
|
||||||
"settingsViewerShowInformationSubtitle": "Laat titel, datum, locatie, etc zien.",
|
"settingsViewerShowInformationSubtitle": "Titel, datum, locatie, etc.",
|
||||||
"@settingsViewerShowInformationSubtitle": {},
|
"@settingsViewerShowInformationSubtitle": {},
|
||||||
"settingsViewerShowShootingDetails": "Laat opnamedetails zien",
|
"settingsViewerShowShootingDetails": "Opnamedetails tonen",
|
||||||
"@settingsViewerShowShootingDetails": {},
|
"@settingsViewerShowShootingDetails": {},
|
||||||
"settingsViewerShowOverlayThumbnails": "Laat miniaturen zien",
|
"settingsViewerShowOverlayThumbnails": "Miniaturen tonen",
|
||||||
"@settingsViewerShowOverlayThumbnails": {},
|
"@settingsViewerShowOverlayThumbnails": {},
|
||||||
"settingsViewerEnableOverlayBlurEffect": "Vervagingseffect",
|
"settingsViewerEnableOverlayBlurEffect": "Vervagingseffect",
|
||||||
"@settingsViewerEnableOverlayBlurEffect": {},
|
"@settingsViewerEnableOverlayBlurEffect": {},
|
||||||
|
@ -883,9 +883,9 @@
|
||||||
"@settingsVideoPageTitle": {},
|
"@settingsVideoPageTitle": {},
|
||||||
"settingsVideoSectionTitle": "Video",
|
"settingsVideoSectionTitle": "Video",
|
||||||
"@settingsVideoSectionTitle": {},
|
"@settingsVideoSectionTitle": {},
|
||||||
"settingsVideoShowVideos": "Videos",
|
"settingsVideoShowVideos": "Video's weergeven",
|
||||||
"@settingsVideoShowVideos": {},
|
"@settingsVideoShowVideos": {},
|
||||||
"settingsVideoEnableHardwareAcceleration": "Hardware acceleratie",
|
"settingsVideoEnableHardwareAcceleration": "Hardware-versnelling",
|
||||||
"@settingsVideoEnableHardwareAcceleration": {},
|
"@settingsVideoEnableHardwareAcceleration": {},
|
||||||
"settingsVideoAutoPlay": "Automatisch afspelen",
|
"settingsVideoAutoPlay": "Automatisch afspelen",
|
||||||
"@settingsVideoAutoPlay": {},
|
"@settingsVideoAutoPlay": {},
|
||||||
|
@ -905,7 +905,7 @@
|
||||||
"@settingsSubtitleThemeTextAlignmentDialogTitle": {},
|
"@settingsSubtitleThemeTextAlignmentDialogTitle": {},
|
||||||
"settingsSubtitleThemeTextSize": "Tekstgroote",
|
"settingsSubtitleThemeTextSize": "Tekstgroote",
|
||||||
"@settingsSubtitleThemeTextSize": {},
|
"@settingsSubtitleThemeTextSize": {},
|
||||||
"settingsSubtitleThemeShowOutline": "Laat omtrek en schaduw zien",
|
"settingsSubtitleThemeShowOutline": "Omtrek en schaduw tonen",
|
||||||
"@settingsSubtitleThemeShowOutline": {},
|
"@settingsSubtitleThemeShowOutline": {},
|
||||||
"settingsSubtitleThemeTextColor": "Tekstkleur",
|
"settingsSubtitleThemeTextColor": "Tekstkleur",
|
||||||
"@settingsSubtitleThemeTextColor": {},
|
"@settingsSubtitleThemeTextColor": {},
|
||||||
|
@ -937,9 +937,9 @@
|
||||||
"@settingsAllowInstalledAppAccess": {},
|
"@settingsAllowInstalledAppAccess": {},
|
||||||
"settingsAllowInstalledAppAccessSubtitle": "Gebruikt om de albumweergave te verbeteren",
|
"settingsAllowInstalledAppAccessSubtitle": "Gebruikt om de albumweergave te verbeteren",
|
||||||
"@settingsAllowInstalledAppAccessSubtitle": {},
|
"@settingsAllowInstalledAppAccessSubtitle": {},
|
||||||
"settingsAllowErrorReporting": "Anonieme foutrapportage toestaan",
|
"settingsAllowErrorReporting": "Anonieme foutmeldingen toestaan",
|
||||||
"@settingsAllowErrorReporting": {},
|
"@settingsAllowErrorReporting": {},
|
||||||
"settingsSaveSearchHistory": "Bewaar zoekgeschiedenis",
|
"settingsSaveSearchHistory": "Zoekgeschiedenis opslaan",
|
||||||
"@settingsSaveSearchHistory": {},
|
"@settingsSaveSearchHistory": {},
|
||||||
"settingsEnableBin": "Prullenbak gebruiken",
|
"settingsEnableBin": "Prullenbak gebruiken",
|
||||||
"@settingsEnableBin": {},
|
"@settingsEnableBin": {},
|
||||||
|
@ -957,7 +957,7 @@
|
||||||
"@settingsHiddenFiltersEmpty": {},
|
"@settingsHiddenFiltersEmpty": {},
|
||||||
"settingsHiddenItemsTabPaths": "Verborgen paden",
|
"settingsHiddenItemsTabPaths": "Verborgen paden",
|
||||||
"@settingsHiddenItemsTabPaths": {},
|
"@settingsHiddenItemsTabPaths": {},
|
||||||
"settingsHiddenPathsBanner": "Foto’s en video’s in deze mappen, of een van hun submappen, verschijnen niet in je verzameling.",
|
"settingsHiddenPathsBanner": "Foto’s en video’s in deze mappen en onderliggende mappen, verschijnen niet in je verzameling.",
|
||||||
"@settingsHiddenPathsBanner": {},
|
"@settingsHiddenPathsBanner": {},
|
||||||
"addPathTooltip": "Pad toevoegen",
|
"addPathTooltip": "Pad toevoegen",
|
||||||
"@addPathTooltip": {},
|
"@addPathTooltip": {},
|
||||||
|
@ -977,7 +977,7 @@
|
||||||
"@settingsRemoveAnimationsTile": {},
|
"@settingsRemoveAnimationsTile": {},
|
||||||
"settingsRemoveAnimationsDialogTitle": "Animaties verwijderen",
|
"settingsRemoveAnimationsDialogTitle": "Animaties verwijderen",
|
||||||
"@settingsRemoveAnimationsDialogTitle": {},
|
"@settingsRemoveAnimationsDialogTitle": {},
|
||||||
"settingsTimeToTakeActionTile": "Tijd om actie te ondernemen",
|
"settingsTimeToTakeActionTile": "Reactietijd",
|
||||||
"@settingsTimeToTakeActionTile": {},
|
"@settingsTimeToTakeActionTile": {},
|
||||||
"settingsDisplaySectionTitle": "Scherm",
|
"settingsDisplaySectionTitle": "Scherm",
|
||||||
"@settingsDisplaySectionTitle": {},
|
"@settingsDisplaySectionTitle": {},
|
||||||
|
@ -985,13 +985,13 @@
|
||||||
"@settingsThemeBrightnessTile": {},
|
"@settingsThemeBrightnessTile": {},
|
||||||
"settingsThemeBrightnessDialogTitle": "Thema",
|
"settingsThemeBrightnessDialogTitle": "Thema",
|
||||||
"@settingsThemeBrightnessDialogTitle": {},
|
"@settingsThemeBrightnessDialogTitle": {},
|
||||||
"settingsThemeColorHighlights": "Kleur highlights",
|
"settingsThemeColorHighlights": "Kleurmarkeringen",
|
||||||
"@settingsThemeColorHighlights": {},
|
"@settingsThemeColorHighlights": {},
|
||||||
"settingsThemeEnableDynamicColor": "Dynamische kleur",
|
"settingsThemeEnableDynamicColor": "Dynamische kleuren",
|
||||||
"@settingsThemeEnableDynamicColor": {},
|
"@settingsThemeEnableDynamicColor": {},
|
||||||
"settingsDisplayRefreshRateModeTile": "Vernieuwingsfrequentie weergeven",
|
"settingsDisplayRefreshRateModeTile": "Vernieuwingssnelheid weergeven",
|
||||||
"@settingsDisplayRefreshRateModeTile": {},
|
"@settingsDisplayRefreshRateModeTile": {},
|
||||||
"settingsDisplayRefreshRateModeDialogTitle": "Vernieuwingsfrequentie",
|
"settingsDisplayRefreshRateModeDialogTitle": "Vernieuwingssnelheid",
|
||||||
"@settingsDisplayRefreshRateModeDialogTitle": {},
|
"@settingsDisplayRefreshRateModeDialogTitle": {},
|
||||||
"settingsLanguageSectionTitle": "Taal & landinstellingen",
|
"settingsLanguageSectionTitle": "Taal & landinstellingen",
|
||||||
"@settingsLanguageSectionTitle": {},
|
"@settingsLanguageSectionTitle": {},
|
||||||
|
@ -999,9 +999,9 @@
|
||||||
"@settingsLanguageTile": {},
|
"@settingsLanguageTile": {},
|
||||||
"settingsLanguagePageTitle": "Taal",
|
"settingsLanguagePageTitle": "Taal",
|
||||||
"@settingsLanguagePageTitle": {},
|
"@settingsLanguagePageTitle": {},
|
||||||
"settingsCoordinateFormatTile": "Coördinaten format",
|
"settingsCoordinateFormatTile": "Coördinaten-weergave",
|
||||||
"@settingsCoordinateFormatTile": {},
|
"@settingsCoordinateFormatTile": {},
|
||||||
"settingsCoordinateFormatDialogTitle": "Coördinaten format",
|
"settingsCoordinateFormatDialogTitle": "Coördinaten-weergave",
|
||||||
"@settingsCoordinateFormatDialogTitle": {},
|
"@settingsCoordinateFormatDialogTitle": {},
|
||||||
"settingsUnitSystemTile": "Eenheden",
|
"settingsUnitSystemTile": "Eenheden",
|
||||||
"@settingsUnitSystemTile": {},
|
"@settingsUnitSystemTile": {},
|
||||||
|
@ -1013,7 +1013,7 @@
|
||||||
"@settingsWidgetPageTitle": {},
|
"@settingsWidgetPageTitle": {},
|
||||||
"settingsWidgetShowOutline": "Contour",
|
"settingsWidgetShowOutline": "Contour",
|
||||||
"@settingsWidgetShowOutline": {},
|
"@settingsWidgetShowOutline": {},
|
||||||
"settingsWidgetOpenPage": "Wanneer u op de widget tikt",
|
"settingsWidgetOpenPage": "Bij het tikken op de widget",
|
||||||
"@settingsWidgetOpenPage": {},
|
"@settingsWidgetOpenPage": {},
|
||||||
"settingsCollectionTile": "Verzameling",
|
"settingsCollectionTile": "Verzameling",
|
||||||
"@settingsCollectionTile": {},
|
"@settingsCollectionTile": {},
|
||||||
|
@ -1067,7 +1067,7 @@
|
||||||
"@viewerInfoLabelAddress": {},
|
"@viewerInfoLabelAddress": {},
|
||||||
"mapStyleDialogTitle": "Kaartstijl",
|
"mapStyleDialogTitle": "Kaartstijl",
|
||||||
"@mapStyleDialogTitle": {},
|
"@mapStyleDialogTitle": {},
|
||||||
"mapStyleTooltip": "Selecteer kaart stijl",
|
"mapStyleTooltip": "Kaartstijl selecteren",
|
||||||
"@mapStyleTooltip": {},
|
"@mapStyleTooltip": {},
|
||||||
"mapZoomInTooltip": "Inzoomen",
|
"mapZoomInTooltip": "Inzoomen",
|
||||||
"@mapZoomInTooltip": {},
|
"@mapZoomInTooltip": {},
|
||||||
|
@ -1079,13 +1079,13 @@
|
||||||
"@mapAttributionOsmHot": {},
|
"@mapAttributionOsmHot": {},
|
||||||
"mapAttributionStamen": "Kaartgegevens © [OpenStreetMap](https://www.openstreetmap.org/copyright) bijdragers • Tegels door [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
|
"mapAttributionStamen": "Kaartgegevens © [OpenStreetMap](https://www.openstreetmap.org/copyright) bijdragers • Tegels door [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
|
||||||
"@mapAttributionStamen": {},
|
"@mapAttributionStamen": {},
|
||||||
"openMapPageTooltip": "Bekijk op kaartpagina",
|
"openMapPageTooltip": "Op kaartpagina tonen",
|
||||||
"@openMapPageTooltip": {},
|
"@openMapPageTooltip": {},
|
||||||
"mapEmptyRegion": "Geen afbeeldingen in de geselecteerde regio",
|
"mapEmptyRegion": "Geen afbeeldingen in dit gebied",
|
||||||
"@mapEmptyRegion": {},
|
"@mapEmptyRegion": {},
|
||||||
"viewerInfoOpenEmbeddedFailureFeedback": "Kan ingesloten gegevens niet extraheren",
|
"viewerInfoOpenEmbeddedFailureFeedback": "Kan ingesloten gegevens niet extraheren",
|
||||||
"@viewerInfoOpenEmbeddedFailureFeedback": {},
|
"@viewerInfoOpenEmbeddedFailureFeedback": {},
|
||||||
"viewerInfoOpenLinkText": "Open",
|
"viewerInfoOpenLinkText": "Openen",
|
||||||
"@viewerInfoOpenLinkText": {},
|
"@viewerInfoOpenLinkText": {},
|
||||||
"viewerInfoViewXmlLinkText": "Bekijk XML",
|
"viewerInfoViewXmlLinkText": "Bekijk XML",
|
||||||
"@viewerInfoViewXmlLinkText": {},
|
"@viewerInfoViewXmlLinkText": {},
|
||||||
|
@ -1119,19 +1119,19 @@
|
||||||
"@panoramaDisableSensorControl": {},
|
"@panoramaDisableSensorControl": {},
|
||||||
"sourceViewerPageTitle": "Source",
|
"sourceViewerPageTitle": "Source",
|
||||||
"@sourceViewerPageTitle": {},
|
"@sourceViewerPageTitle": {},
|
||||||
"filePickerShowHiddenFiles": "Verborgen bestanden laten zien",
|
"filePickerShowHiddenFiles": "Verborgen bestanden weergeven",
|
||||||
"@filePickerShowHiddenFiles": {},
|
"@filePickerShowHiddenFiles": {},
|
||||||
"filePickerDoNotShowHiddenFiles": "Verborgen bestanden niet laten zien",
|
"filePickerDoNotShowHiddenFiles": "Verborgen bestanden niet tonen",
|
||||||
"@filePickerDoNotShowHiddenFiles": {},
|
"@filePickerDoNotShowHiddenFiles": {},
|
||||||
"filePickerOpenFrom": "Openen met",
|
"filePickerOpenFrom": "Openen van",
|
||||||
"@filePickerOpenFrom": {},
|
"@filePickerOpenFrom": {},
|
||||||
"filePickerNoItems": "Geen items",
|
"filePickerNoItems": "Geen items",
|
||||||
"@filePickerNoItems": {},
|
"@filePickerNoItems": {},
|
||||||
"filePickerUseThisFolder": "Deze map gebruiken",
|
"filePickerUseThisFolder": "Deze map gebruiken",
|
||||||
"@filePickerUseThisFolder": {},
|
"@filePickerUseThisFolder": {},
|
||||||
"widgetOpenPageCollection": "Open verzameling",
|
"widgetOpenPageCollection": "Verzameling openen",
|
||||||
"@widgetOpenPageCollection": {},
|
"@widgetOpenPageCollection": {},
|
||||||
"widgetOpenPageViewer": "Open voorbeeld",
|
"widgetOpenPageViewer": "Voorbeeld openen",
|
||||||
"@widgetOpenPageViewer": {},
|
"@widgetOpenPageViewer": {},
|
||||||
"durationDialogSeconds": "Seconden",
|
"durationDialogSeconds": "Seconden",
|
||||||
"@durationDialogSeconds": {},
|
"@durationDialogSeconds": {},
|
||||||
|
@ -1167,9 +1167,9 @@
|
||||||
"@filterNoAddressLabel": {},
|
"@filterNoAddressLabel": {},
|
||||||
"filterAspectRatioPortraitLabel": "Staand",
|
"filterAspectRatioPortraitLabel": "Staand",
|
||||||
"@filterAspectRatioPortraitLabel": {},
|
"@filterAspectRatioPortraitLabel": {},
|
||||||
"widgetDisplayedItemRandom": "Willekeurige",
|
"widgetDisplayedItemRandom": "Willekeurig",
|
||||||
"@widgetDisplayedItemRandom": {},
|
"@widgetDisplayedItemRandom": {},
|
||||||
"widgetDisplayedItemMostRecent": "Meest recente",
|
"widgetDisplayedItemMostRecent": "Laatst gebruikt",
|
||||||
"@widgetDisplayedItemMostRecent": {},
|
"@widgetDisplayedItemMostRecent": {},
|
||||||
"keepScreenOnVideoPlayback": "Tijdens het afspelen van video",
|
"keepScreenOnVideoPlayback": "Tijdens het afspelen van video",
|
||||||
"@keepScreenOnVideoPlayback": {},
|
"@keepScreenOnVideoPlayback": {},
|
||||||
|
@ -1191,7 +1191,7 @@
|
||||||
"@stopTooltip": {},
|
"@stopTooltip": {},
|
||||||
"chipActionLock": "Vergrendel",
|
"chipActionLock": "Vergrendel",
|
||||||
"@chipActionLock": {},
|
"@chipActionLock": {},
|
||||||
"chipActionShowCountryStates": "Status tonen",
|
"chipActionShowCountryStates": "Staten tonen",
|
||||||
"@chipActionShowCountryStates": {},
|
"@chipActionShowCountryStates": {},
|
||||||
"chipActionGoToPlacePage": "In Plaatsen tonen",
|
"chipActionGoToPlacePage": "In Plaatsen tonen",
|
||||||
"@chipActionGoToPlacePage": {},
|
"@chipActionGoToPlacePage": {},
|
||||||
|
@ -1199,15 +1199,15 @@
|
||||||
"@subtitlePositionTop": {},
|
"@subtitlePositionTop": {},
|
||||||
"subtitlePositionBottom": "Onder",
|
"subtitlePositionBottom": "Onder",
|
||||||
"@subtitlePositionBottom": {},
|
"@subtitlePositionBottom": {},
|
||||||
"settingsThumbnailShowHdrIcon": "HDR icoon zichtbaar",
|
"settingsThumbnailShowHdrIcon": "HDR-pictogram tonen",
|
||||||
"@settingsThumbnailShowHdrIcon": {},
|
"@settingsThumbnailShowHdrIcon": {},
|
||||||
"editorTransformCrop": "Bijsnijden",
|
"editorTransformCrop": "Bijsnijden",
|
||||||
"@editorTransformCrop": {},
|
"@editorTransformCrop": {},
|
||||||
"patternDialogConfirm": "Bevestig patroon",
|
"patternDialogConfirm": "Patroon bevestigen",
|
||||||
"@patternDialogConfirm": {},
|
"@patternDialogConfirm": {},
|
||||||
"pinDialogEnter": "Voer PIN in",
|
"pinDialogEnter": "Voer PIN in",
|
||||||
"@pinDialogEnter": {},
|
"@pinDialogEnter": {},
|
||||||
"settingsAskEverytime": "Vraag elke keer",
|
"settingsAskEverytime": "Elke keer vragen",
|
||||||
"@settingsAskEverytime": {},
|
"@settingsAskEverytime": {},
|
||||||
"aboutDataUsageExternal": "Extern",
|
"aboutDataUsageExternal": "Extern",
|
||||||
"@aboutDataUsageExternal": {},
|
"@aboutDataUsageExternal": {},
|
||||||
|
@ -1217,7 +1217,7 @@
|
||||||
"@maxBrightnessAlways": {},
|
"@maxBrightnessAlways": {},
|
||||||
"patternDialogEnter": "Voer patroon in",
|
"patternDialogEnter": "Voer patroon in",
|
||||||
"@patternDialogEnter": {},
|
"@patternDialogEnter": {},
|
||||||
"settingsViewerShowDescription": "Laat beschrijving zien",
|
"settingsViewerShowDescription": "Beschrijving tonen",
|
||||||
"@settingsViewerShowDescription": {},
|
"@settingsViewerShowDescription": {},
|
||||||
"exportEntryDialogQuality": "Kwaliteit",
|
"exportEntryDialogQuality": "Kwaliteit",
|
||||||
"@exportEntryDialogQuality": {},
|
"@exportEntryDialogQuality": {},
|
||||||
|
@ -1241,13 +1241,13 @@
|
||||||
"@overlayHistogramLuminance": {},
|
"@overlayHistogramLuminance": {},
|
||||||
"videoResumptionModeNever": "Nooit",
|
"videoResumptionModeNever": "Nooit",
|
||||||
"@videoResumptionModeNever": {},
|
"@videoResumptionModeNever": {},
|
||||||
"pinDialogConfirm": "Bevestig PIN",
|
"pinDialogConfirm": "PIN bevestigen",
|
||||||
"@pinDialogConfirm": {},
|
"@pinDialogConfirm": {},
|
||||||
"passwordDialogEnter": "Voer wachtwoord in",
|
"passwordDialogEnter": "Voer wachtwoord in",
|
||||||
"@passwordDialogEnter": {},
|
"@passwordDialogEnter": {},
|
||||||
"passwordDialogConfirm": "Bevestig wachtwoord",
|
"passwordDialogConfirm": "Wachtwoord bevestigen",
|
||||||
"@passwordDialogConfirm": {},
|
"@passwordDialogConfirm": {},
|
||||||
"settingsViewerShowHistogram": "Laat histogram zien",
|
"settingsViewerShowHistogram": "Histogram weergeven",
|
||||||
"@settingsViewerShowHistogram": {},
|
"@settingsViewerShowHistogram": {},
|
||||||
"settingsVideoGestureVerticalDragBrightnessVolume": "Veeg omhoog of naar beneden om helderheid/volume aan te passen",
|
"settingsVideoGestureVerticalDragBrightnessVolume": "Veeg omhoog of naar beneden om helderheid/volume aan te passen",
|
||||||
"@settingsVideoGestureVerticalDragBrightnessVolume": {},
|
"@settingsVideoGestureVerticalDragBrightnessVolume": {},
|
||||||
|
@ -1271,7 +1271,7 @@
|
||||||
"@videoResumptionModeAlways": {},
|
"@videoResumptionModeAlways": {},
|
||||||
"exportEntryDialogWriteMetadata": "Metadata schrijven",
|
"exportEntryDialogWriteMetadata": "Metadata schrijven",
|
||||||
"@exportEntryDialogWriteMetadata": {},
|
"@exportEntryDialogWriteMetadata": {},
|
||||||
"chipActionShowCollection": "Tonen in Collectie",
|
"chipActionShowCollection": "In Collectie tonen",
|
||||||
"@chipActionShowCollection": {},
|
"@chipActionShowCollection": {},
|
||||||
"entryActionCast": "Casten",
|
"entryActionCast": "Casten",
|
||||||
"@entryActionCast": {},
|
"@entryActionCast": {},
|
||||||
|
@ -1329,7 +1329,7 @@
|
||||||
"@settingsVideoBackgroundMode": {},
|
"@settingsVideoBackgroundMode": {},
|
||||||
"configureVaultDialogTitle": "Kluis configureren",
|
"configureVaultDialogTitle": "Kluis configureren",
|
||||||
"@configureVaultDialogTitle": {},
|
"@configureVaultDialogTitle": {},
|
||||||
"settingsWidgetDisplayedItem": "Getoond item",
|
"settingsWidgetDisplayedItem": "Zichtbaar item",
|
||||||
"@settingsWidgetDisplayedItem": {},
|
"@settingsWidgetDisplayedItem": {},
|
||||||
"albumTierVaults": "Kluizen",
|
"albumTierVaults": "Kluizen",
|
||||||
"@albumTierVaults": {},
|
"@albumTierVaults": {},
|
||||||
|
@ -1367,7 +1367,7 @@
|
||||||
"@widgetTapUpdateWidget": {},
|
"@widgetTapUpdateWidget": {},
|
||||||
"authenticateToConfigureVault": "Verifieer om de kluis te configureren",
|
"authenticateToConfigureVault": "Verifieer om de kluis te configureren",
|
||||||
"@authenticateToConfigureVault": {},
|
"@authenticateToConfigureVault": {},
|
||||||
"settingsConfirmationVaultDataLoss": "Waarschuwing voor verlies van kluisgegevens weergeven",
|
"settingsConfirmationVaultDataLoss": "Waarschuwing weergeven voor verlies van kluisgegevens",
|
||||||
"@settingsConfirmationVaultDataLoss": {},
|
"@settingsConfirmationVaultDataLoss": {},
|
||||||
"newVaultDialogTitle": "Nieuwe kluis",
|
"newVaultDialogTitle": "Nieuwe kluis",
|
||||||
"@newVaultDialogTitle": {},
|
"@newVaultDialogTitle": {},
|
||||||
|
@ -1383,8 +1383,14 @@
|
||||||
"@collectionActionSetHome": {},
|
"@collectionActionSetHome": {},
|
||||||
"setHomeCustom": "Aangepast",
|
"setHomeCustom": "Aangepast",
|
||||||
"@setHomeCustom": {},
|
"@setHomeCustom": {},
|
||||||
"explorerActionSelectStorageVolume": "Selecteer opslag",
|
"explorerActionSelectStorageVolume": "Opslag selecteren",
|
||||||
"@explorerActionSelectStorageVolume": {},
|
"@explorerActionSelectStorageVolume": {},
|
||||||
"selectStorageVolumeDialogTitle": "Selecteer opslag",
|
"selectStorageVolumeDialogTitle": "Opslag selecteren",
|
||||||
"@selectStorageVolumeDialogTitle": {}
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"sortByDuration": "Op lengte",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderShortestFirst": "Kortste eerst",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "Langste eerst",
|
||||||
|
"@sortOrderLongestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1536,5 +1536,17 @@
|
||||||
"chipActionGoToExplorerPage": "Pokaż w przeglądarce",
|
"chipActionGoToExplorerPage": "Pokaż w przeglądarce",
|
||||||
"@chipActionGoToExplorerPage": {},
|
"@chipActionGoToExplorerPage": {},
|
||||||
"explorerPageTitle": "Przeglądarka",
|
"explorerPageTitle": "Przeglądarka",
|
||||||
"@explorerPageTitle": {}
|
"@explorerPageTitle": {},
|
||||||
|
"selectStorageVolumeDialogTitle": "Wybierz pamięć",
|
||||||
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"explorerActionSelectStorageVolume": "Wybierz pamięć",
|
||||||
|
"@explorerActionSelectStorageVolume": {},
|
||||||
|
"setHomeCustom": "Własny",
|
||||||
|
"@setHomeCustom": {},
|
||||||
|
"sortByDuration": "Według czasu trwania",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderShortestFirst": "Najkrótsze najpierw",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "Najdłuższe najpierw",
|
||||||
|
"@sortOrderLongestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1380,5 +1380,15 @@
|
||||||
"explorerPageTitle": "Проводник",
|
"explorerPageTitle": "Проводник",
|
||||||
"@explorerPageTitle": {},
|
"@explorerPageTitle": {},
|
||||||
"explorerActionSelectStorageVolume": "Выбрать хранилище",
|
"explorerActionSelectStorageVolume": "Выбрать хранилище",
|
||||||
"@explorerActionSelectStorageVolume": {}
|
"@explorerActionSelectStorageVolume": {},
|
||||||
|
"selectStorageVolumeDialogTitle": "Выбрать хранилище",
|
||||||
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"sortByDuration": "По продолжительности",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderLongestFirst": "Сначала самый длинный",
|
||||||
|
"@sortOrderLongestFirst": {},
|
||||||
|
"setHomeCustom": "По своему",
|
||||||
|
"@setHomeCustom": {},
|
||||||
|
"sortOrderShortestFirst": "Сначала самый короткий",
|
||||||
|
"@sortOrderShortestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"viewerActionLock": "Lås",
|
"viewerActionLock": "Lås visaren",
|
||||||
"@viewerActionLock": {},
|
"@viewerActionLock": {},
|
||||||
"entryInfoActionEditTags": "Redigera taggar",
|
"entryInfoActionEditTags": "Redigera taggar",
|
||||||
"@entryInfoActionEditTags": {},
|
"@entryInfoActionEditTags": {},
|
||||||
|
@ -7,19 +7,19 @@
|
||||||
"@videoActionPlay": {},
|
"@videoActionPlay": {},
|
||||||
"viewerActionSettings": "Inställningar",
|
"viewerActionSettings": "Inställningar",
|
||||||
"@viewerActionSettings": {},
|
"@viewerActionSettings": {},
|
||||||
"albumTierSpecial": "Vanlig",
|
"albumTierSpecial": "Vanligt förekommande",
|
||||||
"@albumTierSpecial": {},
|
"@albumTierSpecial": {},
|
||||||
"displayRefreshRatePreferLowest": "Lägsta intervall",
|
"displayRefreshRatePreferLowest": "Lägsta intervall",
|
||||||
"@displayRefreshRatePreferLowest": {},
|
"@displayRefreshRatePreferLowest": {},
|
||||||
"keepScreenOnViewerOnly": "Visningssidan bara",
|
"keepScreenOnViewerOnly": "Endast visningssidan",
|
||||||
"@keepScreenOnViewerOnly": {},
|
"@keepScreenOnViewerOnly": {},
|
||||||
"mapStyleOsmHot": "Humanitarian OSM",
|
"mapStyleOsmHot": "Humanitär OSM",
|
||||||
"@mapStyleOsmHot": {},
|
"@mapStyleOsmHot": {},
|
||||||
"videoResumptionModeAlways": "Alltid",
|
"videoResumptionModeAlways": "Alltid",
|
||||||
"@videoResumptionModeAlways": {},
|
"@videoResumptionModeAlways": {},
|
||||||
"storageVolumeDescriptionFallbackPrimary": "Intern lagring",
|
"storageVolumeDescriptionFallbackPrimary": "Intern lagring",
|
||||||
"@storageVolumeDescriptionFallbackPrimary": {},
|
"@storageVolumeDescriptionFallbackPrimary": {},
|
||||||
"widgetOpenPageCollection": "Öppen insamling",
|
"widgetOpenPageCollection": "Öppna samling",
|
||||||
"@widgetOpenPageCollection": {},
|
"@widgetOpenPageCollection": {},
|
||||||
"widgetTapUpdateWidget": "Uppdatera widgeten",
|
"widgetTapUpdateWidget": "Uppdatera widgeten",
|
||||||
"@widgetTapUpdateWidget": {},
|
"@widgetTapUpdateWidget": {},
|
||||||
|
@ -206,7 +206,7 @@
|
||||||
"@entryActionDelete": {},
|
"@entryActionDelete": {},
|
||||||
"entryActionCopyToClipboard": "Spara till urklipp",
|
"entryActionCopyToClipboard": "Spara till urklipp",
|
||||||
"@entryActionCopyToClipboard": {},
|
"@entryActionCopyToClipboard": {},
|
||||||
"viewerActionUnlock": "Öppna",
|
"viewerActionUnlock": "Lås upp visaren",
|
||||||
"@viewerActionUnlock": {},
|
"@viewerActionUnlock": {},
|
||||||
"slideshowActionResume": "Återuppta",
|
"slideshowActionResume": "Återuppta",
|
||||||
"@slideshowActionResume": {},
|
"@slideshowActionResume": {},
|
||||||
|
@ -238,9 +238,9 @@
|
||||||
"@cropAspectRatioOriginal": {},
|
"@cropAspectRatioOriginal": {},
|
||||||
"cropAspectRatioSquare": "Fyrkant",
|
"cropAspectRatioSquare": "Fyrkant",
|
||||||
"@cropAspectRatioSquare": {},
|
"@cropAspectRatioSquare": {},
|
||||||
"filterAspectRatioLandscapeLabel": "Liggande",
|
"filterAspectRatioLandscapeLabel": "Liggande bilder",
|
||||||
"@filterAspectRatioLandscapeLabel": {},
|
"@filterAspectRatioLandscapeLabel": {},
|
||||||
"filterAspectRatioPortraitLabel": "Porträtt",
|
"filterAspectRatioPortraitLabel": "Stående bilder",
|
||||||
"@filterAspectRatioPortraitLabel": {},
|
"@filterAspectRatioPortraitLabel": {},
|
||||||
"filterBinLabel": "Papperskorg",
|
"filterBinLabel": "Papperskorg",
|
||||||
"@filterBinLabel": {},
|
"@filterBinLabel": {},
|
||||||
|
@ -333,9 +333,9 @@
|
||||||
"@mapStyleGoogleNormal": {},
|
"@mapStyleGoogleNormal": {},
|
||||||
"mapStyleGoogleHybrid": "Google Maps (Hybrid)",
|
"mapStyleGoogleHybrid": "Google Maps (Hybrid)",
|
||||||
"@mapStyleGoogleHybrid": {},
|
"@mapStyleGoogleHybrid": {},
|
||||||
"mapStyleGoogleTerrain": "Google Maps (Terrain)",
|
"mapStyleGoogleTerrain": "Google Maps (Terräng)",
|
||||||
"@mapStyleGoogleTerrain": {},
|
"@mapStyleGoogleTerrain": {},
|
||||||
"mapStyleStamenWatercolor": "Stamen Watercolor",
|
"mapStyleStamenWatercolor": "Stamen Watercolor (Akvarell)",
|
||||||
"@mapStyleStamenWatercolor": {},
|
"@mapStyleStamenWatercolor": {},
|
||||||
"maxBrightnessNever": "Alldrig",
|
"maxBrightnessNever": "Alldrig",
|
||||||
"@maxBrightnessNever": {},
|
"@maxBrightnessNever": {},
|
||||||
|
@ -377,11 +377,11 @@
|
||||||
"@settingsVideoEnablePip": {},
|
"@settingsVideoEnablePip": {},
|
||||||
"videoControlsPlay": "Spela",
|
"videoControlsPlay": "Spela",
|
||||||
"@videoControlsPlay": {},
|
"@videoControlsPlay": {},
|
||||||
"videoControlsPlaySeek": "Spela & sök bakåt/framåt",
|
"videoControlsPlaySeek": "Spela & spola bakåt/framåt",
|
||||||
"@videoControlsPlaySeek": {},
|
"@videoControlsPlaySeek": {},
|
||||||
"videoControlsPlayOutside": "Öppna med annan spelare",
|
"videoControlsPlayOutside": "Öppna med annan spelare",
|
||||||
"@videoControlsPlayOutside": {},
|
"@videoControlsPlayOutside": {},
|
||||||
"videoControlsNone": "Ingen",
|
"videoControlsNone": "Inga",
|
||||||
"@videoControlsNone": {},
|
"@videoControlsNone": {},
|
||||||
"videoLoopModeNever": "Aldrig",
|
"videoLoopModeNever": "Aldrig",
|
||||||
"@videoLoopModeNever": {},
|
"@videoLoopModeNever": {},
|
||||||
|
@ -409,9 +409,9 @@
|
||||||
"@widgetDisplayedItemRandom": {},
|
"@widgetDisplayedItemRandom": {},
|
||||||
"widgetDisplayedItemMostRecent": "Alldra senast",
|
"widgetDisplayedItemMostRecent": "Alldra senast",
|
||||||
"@widgetDisplayedItemMostRecent": {},
|
"@widgetDisplayedItemMostRecent": {},
|
||||||
"widgetOpenPageHome": "Öppna hem",
|
"widgetOpenPageHome": "Öppna startsida",
|
||||||
"@widgetOpenPageHome": {},
|
"@widgetOpenPageHome": {},
|
||||||
"otherDirectoryDescription": "“{name}” map",
|
"otherDirectoryDescription": "“{name}”-katalogen",
|
||||||
"@otherDirectoryDescription": {
|
"@otherDirectoryDescription": {
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
"name": {
|
"name": {
|
||||||
|
@ -421,7 +421,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"storageAccessDialogMessage": "Var snäll och välj {directory} av“{volume}” på nästa skärm för att ge appen åtkomst till den.",
|
"storageAccessDialogMessage": "Vänligen välj {directory} i “{volume}” på nästa skärm för att ge appen åtkomst till den.",
|
||||||
"@storageAccessDialogMessage": {
|
"@storageAccessDialogMessage": {
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
"directory": {
|
"directory": {
|
||||||
|
@ -523,7 +523,7 @@
|
||||||
"@nameConflictDialogSingleSourceMessage": {},
|
"@nameConflictDialogSingleSourceMessage": {},
|
||||||
"nameConflictDialogMultipleSourceMessage": "Vissa filer har samma namn.",
|
"nameConflictDialogMultipleSourceMessage": "Vissa filer har samma namn.",
|
||||||
"@nameConflictDialogMultipleSourceMessage": {},
|
"@nameConflictDialogMultipleSourceMessage": {},
|
||||||
"noMatchingAppDialogMessage": "Det finns inga appar som kan hantera detta.",
|
"noMatchingAppDialogMessage": "Det finns inga applikationer som kan hantera detta.",
|
||||||
"@noMatchingAppDialogMessage": {},
|
"@noMatchingAppDialogMessage": {},
|
||||||
"moveUndatedConfirmationDialogSetDate": "Spara datum",
|
"moveUndatedConfirmationDialogSetDate": "Spara datum",
|
||||||
"@moveUndatedConfirmationDialogSetDate": {},
|
"@moveUndatedConfirmationDialogSetDate": {},
|
||||||
|
@ -752,7 +752,7 @@
|
||||||
"@viewerTransitionFade": {},
|
"@viewerTransitionFade": {},
|
||||||
"wallpaperTargetHomeLock": "Hem och låsskärmar",
|
"wallpaperTargetHomeLock": "Hem och låsskärmar",
|
||||||
"@wallpaperTargetHomeLock": {},
|
"@wallpaperTargetHomeLock": {},
|
||||||
"missingSystemFilePickerDialogMessage": "systemets filväljare är borta eller avstängd. Var snäll och sätt på den och försök igen.",
|
"missingSystemFilePickerDialogMessage": "Systemets filväljare saknas eller har inaktiverats. Vänligen aktivera denna och försök igen.",
|
||||||
"@missingSystemFilePickerDialogMessage": {},
|
"@missingSystemFilePickerDialogMessage": {},
|
||||||
"renameProcessorCounter": "Räknare",
|
"renameProcessorCounter": "Räknare",
|
||||||
"@renameProcessorCounter": {},
|
"@renameProcessorCounter": {},
|
||||||
|
@ -833,5 +833,66 @@
|
||||||
"chipActionUnpin": "Släpp från fästet",
|
"chipActionUnpin": "Släpp från fästet",
|
||||||
"@chipActionUnpin": {},
|
"@chipActionUnpin": {},
|
||||||
"chipActionShowCollection": "Visa i samling",
|
"chipActionShowCollection": "Visa i samling",
|
||||||
"@chipActionShowCollection": {}
|
"@chipActionShowCollection": {},
|
||||||
|
"videoActionABRepeat": "A-B återupprepa",
|
||||||
|
"@videoActionABRepeat": {},
|
||||||
|
"videoRepeatActionSetStart": "Ange start",
|
||||||
|
"@videoRepeatActionSetStart": {},
|
||||||
|
"restrictedAccessDialogMessage": "Denna applikation har ej tillåtelse att modifiera filer i {directory} i \"{volume}\".\n\nVänligen använd en förinstallerad filhanterare eller galleriapplikation för att flytta filerna till en annan katalog.",
|
||||||
|
"@restrictedAccessDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"directory": {
|
||||||
|
"type": "String",
|
||||||
|
"description": "the name of a directory, using the output of `rootDirectoryDescription` or `otherDirectoryDescription`"
|
||||||
|
},
|
||||||
|
"volume": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "SD card",
|
||||||
|
"description": "the name of a storage volume"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"widgetOpenPageViewer": "Öppna bildspel",
|
||||||
|
"@widgetOpenPageViewer": {},
|
||||||
|
"rootDirectoryDescription": "grundkatalog",
|
||||||
|
"@rootDirectoryDescription": {},
|
||||||
|
"notEnoughSpaceDialogMessage": "Denna åtgärd behöver {neededSize} ledigt utrymme på \"{volume}\" för att kunna slutföras, men det är enbart {freeSize} kvar.",
|
||||||
|
"@notEnoughSpaceDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"neededSize": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "314 MB"
|
||||||
|
},
|
||||||
|
"freeSize": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "123 MB"
|
||||||
|
},
|
||||||
|
"volume": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "SD card",
|
||||||
|
"description": "the name of a storage volume"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"addShortcutButtonLabel": "LÄGG TILL",
|
||||||
|
"@addShortcutButtonLabel": {},
|
||||||
|
"addShortcutDialogLabel": "Rubrik för genväg",
|
||||||
|
"@addShortcutDialogLabel": {},
|
||||||
|
"unsupportedTypeDialogMessage": "{count, plural, =1{Denna åtgärd stöds ej för filer av denna typ: {types}.} other{Denna åtgärd stöds ej för följande typer av filer: {types}.}}",
|
||||||
|
"@unsupportedTypeDialogMessage": {
|
||||||
|
"placeholders": {
|
||||||
|
"count": {},
|
||||||
|
"types": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "GIF, TIFF, MP4",
|
||||||
|
"description": "a list of unsupported types"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stopTooltip": "Stopp",
|
||||||
|
"@stopTooltip": {},
|
||||||
|
"chipActionGoToExplorerPage": "Visa i utforskaren",
|
||||||
|
"@chipActionGoToExplorerPage": {},
|
||||||
|
"videoRepeatActionSetEnd": "Ange slut",
|
||||||
|
"@videoRepeatActionSetEnd": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"@welcomeOptional": {},
|
"@welcomeOptional": {},
|
||||||
"welcomeTermsToggle": "Hüküm ve koşulları kabul ediyorum",
|
"welcomeTermsToggle": "Hüküm ve koşulları kabul ediyorum",
|
||||||
"@welcomeTermsToggle": {},
|
"@welcomeTermsToggle": {},
|
||||||
"itemCount": "{count, plural, other{{count} öğe}}",
|
"itemCount": "{count, plural, other{{count} öge}}",
|
||||||
"@itemCount": {},
|
"@itemCount": {},
|
||||||
"timeSeconds": "{count, plural, other{{count} saniye}}",
|
"timeSeconds": "{count, plural, other{{count} saniye}}",
|
||||||
"@timeSeconds": {},
|
"@timeSeconds": {},
|
||||||
|
@ -273,7 +273,7 @@
|
||||||
"@rootDirectoryDescription": {},
|
"@rootDirectoryDescription": {},
|
||||||
"otherDirectoryDescription": "“{name}” dizin",
|
"otherDirectoryDescription": "“{name}” dizin",
|
||||||
"@otherDirectoryDescription": {},
|
"@otherDirectoryDescription": {},
|
||||||
"storageAccessDialogMessage": "Bu uygulamaya erişim sağlamak için lütfen bir sonraki ekranda “{volume}” öğesinin {directory} dizinini seçin.",
|
"storageAccessDialogMessage": "Bir sonraki ekranda \"{volume}\" içindeki {directory} dizinini seçerek bu uygulamaya erişim izni verin.",
|
||||||
"@storageAccessDialogMessage": {},
|
"@storageAccessDialogMessage": {},
|
||||||
"restrictedAccessDialogMessage": "Bu uygulamanın “{volume}” içindeki {directory} dosyaları değiştirmesine izin verilmiyor.\n\nÖğeleri başka bir dizine taşımak için lütfen önceden yüklenmiş bir dosya yöneticisi veya galeri uygulaması kullanın.",
|
"restrictedAccessDialogMessage": "Bu uygulamanın “{volume}” içindeki {directory} dosyaları değiştirmesine izin verilmiyor.\n\nÖğeleri başka bir dizine taşımak için lütfen önceden yüklenmiş bir dosya yöneticisi veya galeri uygulaması kullanın.",
|
||||||
"@restrictedAccessDialogMessage": {},
|
"@restrictedAccessDialogMessage": {},
|
||||||
|
@ -281,7 +281,7 @@
|
||||||
"@notEnoughSpaceDialogMessage": {},
|
"@notEnoughSpaceDialogMessage": {},
|
||||||
"missingSystemFilePickerDialogMessage": "Sistem dosya seçicisi eksik veya devre dışı. Lütfen etkinleştirin ve tekrar deneyin.",
|
"missingSystemFilePickerDialogMessage": "Sistem dosya seçicisi eksik veya devre dışı. Lütfen etkinleştirin ve tekrar deneyin.",
|
||||||
"@missingSystemFilePickerDialogMessage": {},
|
"@missingSystemFilePickerDialogMessage": {},
|
||||||
"unsupportedTypeDialogMessage": "{count, plural, =1{Bu işlem aşağıdaki türdeki öğeler için desteklenmez: {types}.} other{Bu işlem aşağıdaki türlerdeki öğeler için desteklenmez: {types}.}}",
|
"unsupportedTypeDialogMessage": "{count, plural, =1{Bu işlem şu türdeki ögeler için desteklenmez: {types}.} other{Bu işlem şu türlerdeki ögeler için desteklenmez: {types}.}}",
|
||||||
"@unsupportedTypeDialogMessage": {},
|
"@unsupportedTypeDialogMessage": {},
|
||||||
"nameConflictDialogSingleSourceMessage": "Hedef klasördeki bazı dosyalar aynı ada sahip.",
|
"nameConflictDialogSingleSourceMessage": "Hedef klasördeki bazı dosyalar aynı ada sahip.",
|
||||||
"@nameConflictDialogSingleSourceMessage": {},
|
"@nameConflictDialogSingleSourceMessage": {},
|
||||||
|
@ -293,11 +293,11 @@
|
||||||
"@addShortcutButtonLabel": {},
|
"@addShortcutButtonLabel": {},
|
||||||
"noMatchingAppDialogMessage": "Bununla ilgilenebilecek bir uygulama yok.",
|
"noMatchingAppDialogMessage": "Bununla ilgilenebilecek bir uygulama yok.",
|
||||||
"@noMatchingAppDialogMessage": {},
|
"@noMatchingAppDialogMessage": {},
|
||||||
"binEntriesConfirmationDialogMessage": "{count, plural, =1{Bu öğe geri dönüşüm kutusuna taşınsın mı?} other{Bu {count} madde geri dönüşüm kutusuna atılsın mı?}}",
|
"binEntriesConfirmationDialogMessage": "{count, plural, =1{Bu öge geri dönüşüm kutusuna taşınsın mı?} other{Bu {count} öge geri dönüşüm kutusuna atılsın mı?}}",
|
||||||
"@binEntriesConfirmationDialogMessage": {},
|
"@binEntriesConfirmationDialogMessage": {},
|
||||||
"deleteEntriesConfirmationDialogMessage": "{count, plural, =1{Bu öğe silinsin mi?} other{Bu {count} öğe silinsin mi?}}",
|
"deleteEntriesConfirmationDialogMessage": "{count, plural, =1{Bu öge silinsin mi?} other{Bu {count} öge silinsin mi?}}",
|
||||||
"@deleteEntriesConfirmationDialogMessage": {},
|
"@deleteEntriesConfirmationDialogMessage": {},
|
||||||
"moveUndatedConfirmationDialogMessage": "Devam etmeden önce öğe tarihleri kaydedilsin mi?",
|
"moveUndatedConfirmationDialogMessage": "Devam etmeden önce öge tarihleri kaydedilsin mi?",
|
||||||
"@moveUndatedConfirmationDialogMessage": {},
|
"@moveUndatedConfirmationDialogMessage": {},
|
||||||
"moveUndatedConfirmationDialogSetDate": "Tarihleri kaydet",
|
"moveUndatedConfirmationDialogSetDate": "Tarihleri kaydet",
|
||||||
"@moveUndatedConfirmationDialogSetDate": {},
|
"@moveUndatedConfirmationDialogSetDate": {},
|
||||||
|
@ -307,7 +307,7 @@
|
||||||
"@videoStartOverButtonLabel": {},
|
"@videoStartOverButtonLabel": {},
|
||||||
"videoResumeButtonLabel": "SÜRDÜR",
|
"videoResumeButtonLabel": "SÜRDÜR",
|
||||||
"@videoResumeButtonLabel": {},
|
"@videoResumeButtonLabel": {},
|
||||||
"setCoverDialogLatest": "Son öğe",
|
"setCoverDialogLatest": "Son öge",
|
||||||
"@setCoverDialogLatest": {},
|
"@setCoverDialogLatest": {},
|
||||||
"setCoverDialogAuto": "Otomatik",
|
"setCoverDialogAuto": "Otomatik",
|
||||||
"@setCoverDialogAuto": {},
|
"@setCoverDialogAuto": {},
|
||||||
|
@ -359,7 +359,7 @@
|
||||||
"@editEntryDateDialogSetCustom": {},
|
"@editEntryDateDialogSetCustom": {},
|
||||||
"editEntryDateDialogCopyField": "Başka bir tarihten kopyala",
|
"editEntryDateDialogCopyField": "Başka bir tarihten kopyala",
|
||||||
"@editEntryDateDialogCopyField": {},
|
"@editEntryDateDialogCopyField": {},
|
||||||
"editEntryDialogCopyFromItem": "Başka bir öğeden kopyala",
|
"editEntryDialogCopyFromItem": "Başka bir ögeden kopyala",
|
||||||
"@editEntryDialogCopyFromItem": {},
|
"@editEntryDialogCopyFromItem": {},
|
||||||
"editEntryDateDialogExtractFromTitle": "Başlıktan ayıkla",
|
"editEntryDateDialogExtractFromTitle": "Başlıktan ayıkla",
|
||||||
"@editEntryDateDialogExtractFromTitle": {},
|
"@editEntryDateDialogExtractFromTitle": {},
|
||||||
|
@ -523,25 +523,25 @@
|
||||||
"@dateYesterday": {},
|
"@dateYesterday": {},
|
||||||
"dateThisMonth": "Bu ay",
|
"dateThisMonth": "Bu ay",
|
||||||
"@dateThisMonth": {},
|
"@dateThisMonth": {},
|
||||||
"collectionDeleteFailureFeedback": "{count, plural, =1{1 öğe silinemedi} other{{count} öğe silinemedi}}",
|
"collectionDeleteFailureFeedback": "{count, plural, =1{1 öge silinemedi} other{{count} öge silinemedi}}",
|
||||||
"@collectionDeleteFailureFeedback": {},
|
"@collectionDeleteFailureFeedback": {},
|
||||||
"collectionCopyFailureFeedback": "{count, plural, =1{1 öğe kopyalanamadı} other{{count} öğe kopyalanamadı}}",
|
"collectionCopyFailureFeedback": "{count, plural, =1{1 öge kopyalanamadı} other{{count} öge kopyalanamadı}}",
|
||||||
"@collectionCopyFailureFeedback": {},
|
"@collectionCopyFailureFeedback": {},
|
||||||
"collectionMoveFailureFeedback": "{count, plural, =1{1 öğe taşınamadı} other{{count} öğe taşınamadı}}",
|
"collectionMoveFailureFeedback": "{count, plural, =1{1 öge taşınamadı} other{{count} öge taşınamadı}}",
|
||||||
"@collectionMoveFailureFeedback": {},
|
"@collectionMoveFailureFeedback": {},
|
||||||
"collectionRenameFailureFeedback": "{count, plural, =1{1 öğenin adı değiştirilemedi} other{{count} öğenin adı değiştirilemedi}}",
|
"collectionRenameFailureFeedback": "{count, plural, =1{1 ögenin adı değiştirilemedi} other{{count} ögenin adı değiştirilemedi}}",
|
||||||
"@collectionRenameFailureFeedback": {},
|
"@collectionRenameFailureFeedback": {},
|
||||||
"collectionEditFailureFeedback": "{count, plural, =1{1 öğe düzenlenemedi} other{{count} öğe düzenlenemedi}}",
|
"collectionEditFailureFeedback": "{count, plural, =1{1 öge düzenlenemedi} other{{count} öge düzenlenemedi}}",
|
||||||
"@collectionEditFailureFeedback": {},
|
"@collectionEditFailureFeedback": {},
|
||||||
"collectionExportFailureFeedback": "{count, plural, =1{1 sayfa dışa aktarılamadı} other{{count} sayfa dışa aktarılamadı}}",
|
"collectionExportFailureFeedback": "{count, plural, =1{1 sayfa dışa aktarılamadı} other{{count} sayfa dışa aktarılamadı}}",
|
||||||
"@collectionExportFailureFeedback": {},
|
"@collectionExportFailureFeedback": {},
|
||||||
"collectionCopySuccessFeedback": "{count, plural, =1{1 öğe kopyalandı} other{{count} öğe kopyalandı}}",
|
"collectionCopySuccessFeedback": "{count, plural, =1{1 öge kopyalandı} other{{count} öge kopyalandı}}",
|
||||||
"@collectionCopySuccessFeedback": {},
|
"@collectionCopySuccessFeedback": {},
|
||||||
"collectionMoveSuccessFeedback": "{count, plural, =1{1 öğe taşındı} other{{count} öğe taşındı}}",
|
"collectionMoveSuccessFeedback": "{count, plural, =1{1 öge taşındı} other{{count} öge taşındı}}",
|
||||||
"@collectionMoveSuccessFeedback": {},
|
"@collectionMoveSuccessFeedback": {},
|
||||||
"collectionRenameSuccessFeedback": "{count, plural, =1{1 öğenin adı değiştirildi} other{{count} öğenin adı değiştirildi}}",
|
"collectionRenameSuccessFeedback": "{count, plural, =1{1 ögenin adı değiştirildi} other{{count} ögenin adı değiştirildi}}",
|
||||||
"@collectionRenameSuccessFeedback": {},
|
"@collectionRenameSuccessFeedback": {},
|
||||||
"collectionEditSuccessFeedback": "{count, plural, =1{1 öğe düzenlendi} other{{count} öğe düzenlendi}}",
|
"collectionEditSuccessFeedback": "{count, plural, =1{1 öge düzenlendi} other{{count} öge düzenlendi}}",
|
||||||
"@collectionEditSuccessFeedback": {},
|
"@collectionEditSuccessFeedback": {},
|
||||||
"collectionEmptyFavourites": "Favori yok",
|
"collectionEmptyFavourites": "Favori yok",
|
||||||
"@collectionEmptyFavourites": {},
|
"@collectionEmptyFavourites": {},
|
||||||
|
@ -705,7 +705,7 @@
|
||||||
"@settingsNavigationDrawerTile": {},
|
"@settingsNavigationDrawerTile": {},
|
||||||
"settingsNavigationDrawerEditorPageTitle": "Gezinti Menüsü",
|
"settingsNavigationDrawerEditorPageTitle": "Gezinti Menüsü",
|
||||||
"@settingsNavigationDrawerEditorPageTitle": {},
|
"@settingsNavigationDrawerEditorPageTitle": {},
|
||||||
"settingsNavigationDrawerBanner": "Menü öğelerini taşımak ve yeniden sıralamak için dokunun ve basılı tutun.",
|
"settingsNavigationDrawerBanner": "Menü ögelerini taşımak ve yeniden sıralamak için dokunun ve basılı tutun.",
|
||||||
"@settingsNavigationDrawerBanner": {},
|
"@settingsNavigationDrawerBanner": {},
|
||||||
"settingsNavigationDrawerTabTypes": "Türler",
|
"settingsNavigationDrawerTabTypes": "Türler",
|
||||||
"@settingsNavigationDrawerTabTypes": {},
|
"@settingsNavigationDrawerTabTypes": {},
|
||||||
|
@ -743,9 +743,9 @@
|
||||||
"@settingsCollectionQuickActionTabBrowsing": {},
|
"@settingsCollectionQuickActionTabBrowsing": {},
|
||||||
"settingsCollectionQuickActionTabSelecting": "Seçme",
|
"settingsCollectionQuickActionTabSelecting": "Seçme",
|
||||||
"@settingsCollectionQuickActionTabSelecting": {},
|
"@settingsCollectionQuickActionTabSelecting": {},
|
||||||
"settingsCollectionBrowsingQuickActionEditorBanner": "Düğmeleri hareket ettirmek ve öğelere göz atarken hangi eylemlerin görüntüleneceğini seçmek için dokunun ve basılı tutun.",
|
"settingsCollectionBrowsingQuickActionEditorBanner": "Düğmeleri hareket ettirmek ve ögelere göz atarken hangi eylemlerin görüntüleneceğini seçmek için dokunun ve basılı tutun.",
|
||||||
"@settingsCollectionBrowsingQuickActionEditorBanner": {},
|
"@settingsCollectionBrowsingQuickActionEditorBanner": {},
|
||||||
"settingsCollectionSelectionQuickActionEditorBanner": "Düğmeleri hareket ettirmek ve öğeleri seçerken hangi eylemlerin görüntüleneceğini seçmek için dokunun ve basılı tutun.",
|
"settingsCollectionSelectionQuickActionEditorBanner": "Düğmeleri hareket ettirmek ve ögeleri seçerken hangi eylemlerin görüntüleneceğini seçmek için dokunun ve basılı tutun.",
|
||||||
"@settingsCollectionSelectionQuickActionEditorBanner": {},
|
"@settingsCollectionSelectionQuickActionEditorBanner": {},
|
||||||
"settingsViewerSectionTitle": "Görüntüleyici",
|
"settingsViewerSectionTitle": "Görüntüleyici",
|
||||||
"@settingsViewerSectionTitle": {},
|
"@settingsViewerSectionTitle": {},
|
||||||
|
@ -851,9 +851,9 @@
|
||||||
"@settingsSaveSearchHistory": {},
|
"@settingsSaveSearchHistory": {},
|
||||||
"settingsEnableBin": "Geri dönüşüm kutusunu kullan",
|
"settingsEnableBin": "Geri dönüşüm kutusunu kullan",
|
||||||
"@settingsEnableBin": {},
|
"@settingsEnableBin": {},
|
||||||
"settingsEnableBinSubtitle": "Silinen öğeleri 30 gün boyunca saklar",
|
"settingsEnableBinSubtitle": "Silinen ögeleri 30 gün boyunca saklar",
|
||||||
"@settingsEnableBinSubtitle": {},
|
"@settingsEnableBinSubtitle": {},
|
||||||
"settingsHiddenItemsTile": "Gizli öğeler",
|
"settingsHiddenItemsTile": "Gizli ögeler",
|
||||||
"@settingsHiddenItemsTile": {},
|
"@settingsHiddenItemsTile": {},
|
||||||
"settingsHiddenItemsPageTitle": "Gizli Öğeler",
|
"settingsHiddenItemsPageTitle": "Gizli Öğeler",
|
||||||
"@settingsHiddenItemsPageTitle": {},
|
"@settingsHiddenItemsPageTitle": {},
|
||||||
|
@ -921,7 +921,7 @@
|
||||||
"@settingsCollectionTile": {},
|
"@settingsCollectionTile": {},
|
||||||
"statsPageTitle": "İstatistikler",
|
"statsPageTitle": "İstatistikler",
|
||||||
"@statsPageTitle": {},
|
"@statsPageTitle": {},
|
||||||
"statsWithGps": "{count, plural, =1{1 konuma sahip öğe} other{{count} konuma sahip öğe}}",
|
"statsWithGps": "{count, plural, =1{1 öge konuma sahip} other{{count} öge konuma sahip}}",
|
||||||
"@statsWithGps": {},
|
"@statsWithGps": {},
|
||||||
"statsTopCountriesSectionTitle": "Öne Çıkan Ülkeler",
|
"statsTopCountriesSectionTitle": "Öne Çıkan Ülkeler",
|
||||||
"@statsTopCountriesSectionTitle": {},
|
"@statsTopCountriesSectionTitle": {},
|
||||||
|
@ -1019,7 +1019,7 @@
|
||||||
"@filePickerDoNotShowHiddenFiles": {},
|
"@filePickerDoNotShowHiddenFiles": {},
|
||||||
"filePickerOpenFrom": "Şuradan aç",
|
"filePickerOpenFrom": "Şuradan aç",
|
||||||
"@filePickerOpenFrom": {},
|
"@filePickerOpenFrom": {},
|
||||||
"filePickerNoItems": "Öğe yok",
|
"filePickerNoItems": "Öge yok",
|
||||||
"@filePickerNoItems": {},
|
"@filePickerNoItems": {},
|
||||||
"filePickerUseThisFolder": "Bu klasörü kullan",
|
"filePickerUseThisFolder": "Bu klasörü kullan",
|
||||||
"@filePickerUseThisFolder": {},
|
"@filePickerUseThisFolder": {},
|
||||||
|
@ -1049,7 +1049,7 @@
|
||||||
"@sortOrderLargestFirst": {},
|
"@sortOrderLargestFirst": {},
|
||||||
"settingsConfirmationAfterMoveToBinItems": "Öğeleri geri dönüşüm kutusuna taşıdıktan sonra mesaj göster",
|
"settingsConfirmationAfterMoveToBinItems": "Öğeleri geri dönüşüm kutusuna taşıdıktan sonra mesaj göster",
|
||||||
"@settingsConfirmationAfterMoveToBinItems": {},
|
"@settingsConfirmationAfterMoveToBinItems": {},
|
||||||
"settingsViewerGestureSideTapNext": "Önceki/sonraki öğeyi göstermek için ekran kenarlarına dokunun",
|
"settingsViewerGestureSideTapNext": "Önceki/sonraki ögeyi göstermek için ekran kenarlarına dokunun",
|
||||||
"@settingsViewerGestureSideTapNext": {},
|
"@settingsViewerGestureSideTapNext": {},
|
||||||
"settingsSlideshowVideoPlaybackTile": "Video oynatma",
|
"settingsSlideshowVideoPlaybackTile": "Video oynatma",
|
||||||
"@settingsSlideshowVideoPlaybackTile": {},
|
"@settingsSlideshowVideoPlaybackTile": {},
|
||||||
|
@ -1161,7 +1161,7 @@
|
||||||
"@widgetDisplayedItemMostRecent": {},
|
"@widgetDisplayedItemMostRecent": {},
|
||||||
"settingsSubtitleThemeTextPositionTile": "Metin konumu",
|
"settingsSubtitleThemeTextPositionTile": "Metin konumu",
|
||||||
"@settingsSubtitleThemeTextPositionTile": {},
|
"@settingsSubtitleThemeTextPositionTile": {},
|
||||||
"settingsWidgetDisplayedItem": "Görüntülenen öğe",
|
"settingsWidgetDisplayedItem": "Görüntülenen öge",
|
||||||
"@settingsWidgetDisplayedItem": {},
|
"@settingsWidgetDisplayedItem": {},
|
||||||
"settingsSubtitleThemeTextPositionDialogTitle": "Metin Konumu",
|
"settingsSubtitleThemeTextPositionDialogTitle": "Metin Konumu",
|
||||||
"@settingsSubtitleThemeTextPositionDialogTitle": {},
|
"@settingsSubtitleThemeTextPositionDialogTitle": {},
|
||||||
|
@ -1378,5 +1378,17 @@
|
||||||
"chipActionGoToExplorerPage": "Gezginde göster",
|
"chipActionGoToExplorerPage": "Gezginde göster",
|
||||||
"@chipActionGoToExplorerPage": {},
|
"@chipActionGoToExplorerPage": {},
|
||||||
"explorerPageTitle": "Gezgin",
|
"explorerPageTitle": "Gezgin",
|
||||||
"@explorerPageTitle": {}
|
"@explorerPageTitle": {},
|
||||||
|
"explorerActionSelectStorageVolume": "Depolama alanı seç",
|
||||||
|
"@explorerActionSelectStorageVolume": {},
|
||||||
|
"selectStorageVolumeDialogTitle": "Depolama Alanı Seç",
|
||||||
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"setHomeCustom": "Özel",
|
||||||
|
"@setHomeCustom": {},
|
||||||
|
"sortByDuration": "Süreye göre",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderShortestFirst": "Önce en kısa",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "Önce en uzun",
|
||||||
|
"@sortOrderLongestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1542,5 +1542,11 @@
|
||||||
"explorerActionSelectStorageVolume": "Обрати сховище",
|
"explorerActionSelectStorageVolume": "Обрати сховище",
|
||||||
"@explorerActionSelectStorageVolume": {},
|
"@explorerActionSelectStorageVolume": {},
|
||||||
"selectStorageVolumeDialogTitle": "Оберіть сховище",
|
"selectStorageVolumeDialogTitle": "Оберіть сховище",
|
||||||
"@selectStorageVolumeDialogTitle": {}
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"sortByDuration": "За тривалістю",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderShortestFirst": "Спершу найкоротше",
|
||||||
|
"@sortOrderShortestFirst": {},
|
||||||
|
"sortOrderLongestFirst": "Спершу найдовше",
|
||||||
|
"@sortOrderLongestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1378,5 +1378,17 @@
|
||||||
"explorerPageTitle": "资源管理器",
|
"explorerPageTitle": "资源管理器",
|
||||||
"@explorerPageTitle": {},
|
"@explorerPageTitle": {},
|
||||||
"chipActionGoToExplorerPage": "在资源管理器中显示",
|
"chipActionGoToExplorerPage": "在资源管理器中显示",
|
||||||
"@chipActionGoToExplorerPage": {}
|
"@chipActionGoToExplorerPage": {},
|
||||||
|
"setHomeCustom": "自定义",
|
||||||
|
"@setHomeCustom": {},
|
||||||
|
"explorerActionSelectStorageVolume": "选择存储器",
|
||||||
|
"@explorerActionSelectStorageVolume": {},
|
||||||
|
"selectStorageVolumeDialogTitle": "选择存储器",
|
||||||
|
"@selectStorageVolumeDialogTitle": {},
|
||||||
|
"sortByDuration": "按时长",
|
||||||
|
"@sortByDuration": {},
|
||||||
|
"sortOrderLongestFirst": "先长后短",
|
||||||
|
"@sortOrderLongestFirst": {},
|
||||||
|
"sortOrderShortestFirst": "先短后长",
|
||||||
|
"@sortOrderShortestFirst": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:aves/app_flavor.dart';
|
import 'package:aves/app_flavor.dart';
|
||||||
import 'package:aves/main_common.dart';
|
import 'package:aves/main_common.dart';
|
||||||
import 'package:aves/widgets/intent.dart';
|
import 'package:aves/model/app/intent.dart';
|
||||||
|
|
||||||
// https://developer.android.com/studio/command-line/adb.html#IntentSpec
|
// https://developer.android.com/studio/command-line/adb.html#IntentSpec
|
||||||
// adb shell am start -n deckers.thibault.aves.debug/deckers.thibault.aves.MainActivity -a android.intent.action.EDIT -d content://media/external/images/media/183128 -t image/*
|
// adb shell am start -n deckers.thibault.aves.debug/deckers.thibault.aves.MainActivity -a android.intent.action.EDIT -d content://media/external/images/media/183128 -t image/*
|
||||||
|
|
|
@ -95,6 +95,7 @@ class Contributors {
|
||||||
Contributor('elfriob', 'elfriob@ya.ru'),
|
Contributor('elfriob', 'elfriob@ya.ru'),
|
||||||
Contributor('Stephan Paternotte', 'stephan@paternottes.net'),
|
Contributor('Stephan Paternotte', 'stephan@paternottes.net'),
|
||||||
Contributor('Tung Anh', 'buihuutunganh2007@gmail.com'),
|
Contributor('Tung Anh', 'buihuutunganh2007@gmail.com'),
|
||||||
|
Contributor('Adrien N', 'adriennathaniel1999@gmail.com'),
|
||||||
// Contributor('Alvi Khan', 'aveenalvi@gmail.com'), // Bengali
|
// Contributor('Alvi Khan', 'aveenalvi@gmail.com'), // Bengali
|
||||||
// Contributor('Htet Oo Hlaing', 'htetoh2006@outlook.com'), // Burmese
|
// Contributor('Htet Oo Hlaing', 'htetoh2006@outlook.com'), // Burmese
|
||||||
// Contributor('Khant', 'khant@users.noreply.hosted.weblate.org'), // Burmese
|
// Contributor('Khant', 'khant@users.noreply.hosted.weblate.org'), // Burmese
|
||||||
|
@ -113,6 +114,7 @@ class Contributors {
|
||||||
// Contributor('Prasanta-Hembram', 'Prasantahembram720@gmail.com'), // Santali
|
// Contributor('Prasanta-Hembram', 'Prasantahembram720@gmail.com'), // Santali
|
||||||
// Contributor('mytja', 'mamnju21@gmail.com'), // Slovenian
|
// Contributor('mytja', 'mamnju21@gmail.com'), // Slovenian
|
||||||
// Contributor('Shift18', 'bribable.lawyer@posteo.net'), // Swedish
|
// Contributor('Shift18', 'bribable.lawyer@posteo.net'), // Swedish
|
||||||
|
// Contributor('Andreas Håll', 'ante_skalman@hotmail.com'), // Swedish
|
||||||
// Contributor('Nattapong K', 'mixer5056@gmail.com'), // Thai
|
// Contributor('Nattapong K', 'mixer5056@gmail.com'), // Thai
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,12 +338,6 @@ class Dependencies {
|
||||||
license: apache2,
|
license: apache2,
|
||||||
sourceUrl: 'https://github.com/jifalops/dart-latlong',
|
sourceUrl: 'https://github.com/jifalops/dart-latlong',
|
||||||
),
|
),
|
||||||
Dependency(
|
|
||||||
name: 'Material Color Utilities',
|
|
||||||
license: apache2,
|
|
||||||
licenseUrl: 'https://github.com/material-foundation/material-color-utilities/tree/main/dart/LICENSE',
|
|
||||||
sourceUrl: 'https://github.com/material-foundation/material-color-utilities/tree/main/dart',
|
|
||||||
),
|
|
||||||
Dependency(
|
Dependency(
|
||||||
name: 'Memory Leak Tracker',
|
name: 'Memory Leak Tracker',
|
||||||
license: bsd3,
|
license: bsd3,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/apps.dart';
|
import 'package:aves/model/app_inventory.dart';
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/filters/album.dart';
|
import 'package:aves/model/filters/album.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import 'package:aves/model/metadata/address.dart';
|
||||||
import 'package:aves/model/metadata/catalog.dart';
|
import 'package:aves/model/metadata/catalog.dart';
|
||||||
import 'package:aves/model/metadata/trash.dart';
|
import 'package:aves/model/metadata/trash.dart';
|
||||||
import 'package:aves/model/vaults/details.dart';
|
import 'package:aves/model/vaults/details.dart';
|
||||||
import 'package:aves/model/video_playback.dart';
|
import 'package:aves/model/viewer/video_playback.dart';
|
||||||
|
|
||||||
abstract class MetadataDb {
|
abstract class MetadataDb {
|
||||||
int get nextId;
|
int get nextId;
|
||||||
|
|
|
@ -10,7 +10,7 @@ import 'package:aves/model/metadata/address.dart';
|
||||||
import 'package:aves/model/metadata/catalog.dart';
|
import 'package:aves/model/metadata/catalog.dart';
|
||||||
import 'package:aves/model/metadata/trash.dart';
|
import 'package:aves/model/metadata/trash.dart';
|
||||||
import 'package:aves/model/vaults/details.dart';
|
import 'package:aves/model/vaults/details.dart';
|
||||||
import 'package:aves/model/video_playback.dart';
|
import 'package:aves/model/viewer/video_playback.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
|
@ -2,9 +2,9 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/entry/extensions/props.dart';
|
import 'package:aves/model/entry/extensions/props.dart';
|
||||||
import 'package:aves/model/geotiff.dart';
|
import 'package:aves/model/media/geotiff.dart';
|
||||||
import 'package:aves/model/metadata/catalog.dart';
|
import 'package:aves/model/metadata/catalog.dart';
|
||||||
import 'package:aves/model/video/metadata.dart';
|
import 'package:aves/model/media/video/metadata.dart';
|
||||||
import 'package:aves/ref/mime_types.dart';
|
import 'package:aves/ref/mime_types.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/services/metadata/svg_metadata_service.dart';
|
import 'package:aves/services/metadata/svg_metadata_service.dart';
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'dart:collection';
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/entry/extensions/multipage.dart';
|
import 'package:aves/model/entry/extensions/multipage.dart';
|
||||||
import 'package:aves/model/entry/extensions/props.dart';
|
import 'package:aves/model/entry/extensions/props.dart';
|
||||||
import 'package:aves/model/video/metadata.dart';
|
import 'package:aves/model/media/video/metadata.dart';
|
||||||
import 'package:aves/ref/mime_types.dart';
|
import 'package:aves/ref/mime_types.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/services/metadata/svg_metadata_service.dart';
|
import 'package:aves/services/metadata/svg_metadata_service.dart';
|
||||||
|
|
|
@ -35,4 +35,12 @@ class AvesEntrySort {
|
||||||
final c = (b.sizeBytes ?? 0).compareTo(a.sizeBytes ?? 0);
|
final c = (b.sizeBytes ?? 0).compareTo(a.sizeBytes ?? 0);
|
||||||
return c != 0 ? c : compareByDate(a, b);
|
return c != 0 ? c : compareByDate(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compare by:
|
||||||
|
// 1) duration descending
|
||||||
|
// 2) date descending
|
||||||
|
static int compareByDuration(AvesEntry a, AvesEntry b) {
|
||||||
|
final c = (b.durationMillis ?? 0).compareTo(a.durationMillis ?? 0);
|
||||||
|
return c != 0 ? c : compareByDate(a, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/metadata/catalog.dart';
|
import 'package:aves/model/metadata/catalog.dart';
|
||||||
import 'package:aves/model/video/channel_layouts.dart';
|
import 'package:aves/model/media/video/channel_layouts.dart';
|
||||||
import 'package:aves/model/video/codecs.dart';
|
import 'package:aves/model/media/video/codecs.dart';
|
||||||
import 'package:aves/model/video/profiles/aac.dart';
|
import 'package:aves/model/media/video/profiles/aac.dart';
|
||||||
import 'package:aves/model/video/profiles/h264.dart';
|
import 'package:aves/model/media/video/profiles/h264.dart';
|
||||||
import 'package:aves/model/video/profiles/hevc.dart';
|
import 'package:aves/model/media/video/profiles/hevc.dart';
|
||||||
import 'package:aves/ref/languages.dart';
|
import 'package:aves/ref/languages.dart';
|
||||||
import 'package:aves/ref/locales.dart';
|
import 'package:aves/ref/locales.dart';
|
||||||
import 'package:aves/ref/mime_types.dart';
|
import 'package:aves/ref/mime_types.dart';
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aves/convert/metadata/fields.dart';
|
import 'package:aves/convert/convert.dart';
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
mixin AppSettings on SettingsAccess {
|
mixin AppSettings on SettingsAccess {
|
||||||
static const int _recentFilterHistoryMax = 10;
|
static const int recentFilterHistoryMax = 20;
|
||||||
|
|
||||||
bool get hasAcceptedTerms => getBool(SettingKeys.hasAcceptedTermsKey) ?? SettingsDefaults.hasAcceptedTerms;
|
bool get hasAcceptedTerms => getBool(SettingKeys.hasAcceptedTermsKey) ?? SettingsDefaults.hasAcceptedTerms;
|
||||||
|
|
||||||
|
@ -105,9 +105,9 @@ mixin AppSettings on SettingsAccess {
|
||||||
|
|
||||||
List<String> get recentDestinationAlbums => getStringList(SettingKeys.recentDestinationAlbumsKey) ?? [];
|
List<String> get recentDestinationAlbums => getStringList(SettingKeys.recentDestinationAlbumsKey) ?? [];
|
||||||
|
|
||||||
set recentDestinationAlbums(List<String> newValue) => set(SettingKeys.recentDestinationAlbumsKey, newValue.take(_recentFilterHistoryMax).toList());
|
set recentDestinationAlbums(List<String> newValue) => set(SettingKeys.recentDestinationAlbumsKey, newValue.take(recentFilterHistoryMax).toList());
|
||||||
|
|
||||||
List<CollectionFilter> get recentTags => (getStringList(SettingKeys.recentTagsKey) ?? []).map(CollectionFilter.fromJson).whereNotNull().toList();
|
List<CollectionFilter> get recentTags => (getStringList(SettingKeys.recentTagsKey) ?? []).map(CollectionFilter.fromJson).whereNotNull().toList();
|
||||||
|
|
||||||
set recentTags(List<CollectionFilter> newValue) => set(SettingKeys.recentTagsKey, newValue.take(_recentFilterHistoryMax).map((filter) => filter.toJson()).toList());
|
set recentTags(List<CollectionFilter> newValue) => set(SettingKeys.recentTagsKey, newValue.take(recentFilterHistoryMax).map((filter) => filter.toJson()).toList());
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,18 @@ mixin PrivacySettings on SettingsAccess, SearchSettings {
|
||||||
set hiddenFilters(Set<CollectionFilter> newValue) => set(SettingKeys.hiddenFiltersKey, newValue.map((filter) => filter.toJson()).toList());
|
set hiddenFilters(Set<CollectionFilter> newValue) => set(SettingKeys.hiddenFiltersKey, newValue.map((filter) => filter.toJson()).toList());
|
||||||
|
|
||||||
void changeFilterVisibility(Set<CollectionFilter> filters, bool visible) {
|
void changeFilterVisibility(Set<CollectionFilter> filters, bool visible) {
|
||||||
|
final _deactivatedHiddenFilters = deactivatedHiddenFilters;
|
||||||
final _hiddenFilters = hiddenFilters;
|
final _hiddenFilters = hiddenFilters;
|
||||||
|
|
||||||
|
_deactivatedHiddenFilters.removeAll(filters);
|
||||||
if (visible) {
|
if (visible) {
|
||||||
_hiddenFilters.removeAll(filters);
|
_hiddenFilters.removeAll(filters);
|
||||||
} else {
|
} else {
|
||||||
_hiddenFilters.addAll(filters);
|
_hiddenFilters.addAll(filters);
|
||||||
searchHistory = searchHistory..removeWhere(filters.contains);
|
searchHistory = searchHistory..removeWhere(filters.contains);
|
||||||
|
|
||||||
final _deactivatedHiddenFilters = deactivatedHiddenFilters;
|
|
||||||
_deactivatedHiddenFilters.removeAll(filters);
|
|
||||||
deactivatedHiddenFilters = _deactivatedHiddenFilters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deactivatedHiddenFilters = _deactivatedHiddenFilters;
|
||||||
hiddenFilters = _hiddenFilters;
|
hiddenFilters = _hiddenFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,14 +30,18 @@ mixin PrivacySettings on SettingsAccess, SearchSettings {
|
||||||
|
|
||||||
void activateHiddenFilter(CollectionFilter filter, bool active) {
|
void activateHiddenFilter(CollectionFilter filter, bool active) {
|
||||||
final _deactivatedHiddenFilters = deactivatedHiddenFilters;
|
final _deactivatedHiddenFilters = deactivatedHiddenFilters;
|
||||||
|
final _hiddenFilters = hiddenFilters;
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
_deactivatedHiddenFilters.remove(filter);
|
_deactivatedHiddenFilters.remove(filter);
|
||||||
|
_hiddenFilters.add(filter);
|
||||||
|
searchHistory = searchHistory..remove(filter);
|
||||||
} else {
|
} else {
|
||||||
_deactivatedHiddenFilters.add(filter);
|
_deactivatedHiddenFilters.add(filter);
|
||||||
|
_hiddenFilters.remove(filter);
|
||||||
}
|
}
|
||||||
deactivatedHiddenFilters = _deactivatedHiddenFilters;
|
|
||||||
|
|
||||||
final visible = !active;
|
deactivatedHiddenFilters = _deactivatedHiddenFilters;
|
||||||
changeFilterVisibility({filter}, visible);
|
hiddenFilters = _hiddenFilters;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,7 @@ class CollectionLens with ChangeNotifier {
|
||||||
case EntrySortFactor.rating:
|
case EntrySortFactor.rating:
|
||||||
return !filters.any((f) => f is RatingFilter);
|
return !filters.any((f) => f is RatingFilter);
|
||||||
case EntrySortFactor.size:
|
case EntrySortFactor.size:
|
||||||
|
case EntrySortFactor.duration:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,6 +262,8 @@ class CollectionLens with ChangeNotifier {
|
||||||
_filteredSortedEntries.sort(AvesEntrySort.compareByRating);
|
_filteredSortedEntries.sort(AvesEntrySort.compareByRating);
|
||||||
case EntrySortFactor.size:
|
case EntrySortFactor.size:
|
||||||
_filteredSortedEntries.sort(AvesEntrySort.compareBySize);
|
_filteredSortedEntries.sort(AvesEntrySort.compareBySize);
|
||||||
|
case EntrySortFactor.duration:
|
||||||
|
_filteredSortedEntries.sort(AvesEntrySort.compareByDuration);
|
||||||
}
|
}
|
||||||
if (sortReverse) {
|
if (sortReverse) {
|
||||||
_filteredSortedEntries = _filteredSortedEntries.reversed.toList();
|
_filteredSortedEntries = _filteredSortedEntries.reversed.toList();
|
||||||
|
@ -294,6 +297,7 @@ class CollectionLens with ChangeNotifier {
|
||||||
case EntrySortFactor.rating:
|
case EntrySortFactor.rating:
|
||||||
sections = groupBy<AvesEntry, EntryRatingSectionKey>(_filteredSortedEntries, (entry) => EntryRatingSectionKey(entry.rating));
|
sections = groupBy<AvesEntry, EntryRatingSectionKey>(_filteredSortedEntries, (entry) => EntryRatingSectionKey(entry.rating));
|
||||||
case EntrySortFactor.size:
|
case EntrySortFactor.size:
|
||||||
|
case EntrySortFactor.duration:
|
||||||
sections = Map.fromEntries([
|
sections = Map.fromEntries([
|
||||||
MapEntry(const SectionKey(), _filteredSortedEntries),
|
MapEntry(const SectionKey(), _filteredSortedEntries),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/apps.dart';
|
import 'package:aves/model/app_inventory.dart';
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/entry/extensions/props.dart';
|
import 'package:aves/model/entry/extensions/props.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
|
|
@ -118,11 +118,6 @@ class PlatformMediaEditService implements MediaEditService {
|
||||||
required String destinationAlbum,
|
required String destinationAlbum,
|
||||||
required NameConflictStrategy nameConflictStrategy,
|
required NameConflictStrategy nameConflictStrategy,
|
||||||
}) {
|
}) {
|
||||||
// TODO TLAD remove log when OOMs are inspected
|
|
||||||
entries.where((v) => (v.sizeBytes ?? 0) > 20000000).forEach((entry) {
|
|
||||||
reportService.log('convert large entry=$entry size=${entry.sizeBytes}');
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return _opStream
|
return _opStream
|
||||||
.receiveBroadcastStream(<String, dynamic>{
|
.receiveBroadcastStream(<String, dynamic>{
|
||||||
|
|
|
@ -80,11 +80,6 @@ class PlatformMetadataEditService implements MetadataEditService {
|
||||||
Map<MetadataType, dynamic> metadata, {
|
Map<MetadataType, dynamic> metadata, {
|
||||||
bool autoCorrectTrailerOffset = true,
|
bool autoCorrectTrailerOffset = true,
|
||||||
}) async {
|
}) async {
|
||||||
// TODO TLAD remove log when OOMs are inspected
|
|
||||||
if ((entry.sizeBytes ?? 0) > 20000000) {
|
|
||||||
await reportService.log('edit metadata of large entry=$entry size=${entry.sizeBytes}');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final result = await _platform.invokeMethod('editMetadata', <String, dynamic>{
|
final result = await _platform.invokeMethod('editMetadata', <String, dynamic>{
|
||||||
'entry': entry.toPlatformEntryMap(),
|
'entry': entry.toPlatformEntryMap(),
|
||||||
|
|
|
@ -2,12 +2,11 @@ import 'package:aves/convert/convert.dart';
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/entry/extensions/multipage.dart';
|
import 'package:aves/model/entry/extensions/multipage.dart';
|
||||||
import 'package:aves/model/entry/extensions/props.dart';
|
import 'package:aves/model/entry/extensions/props.dart';
|
||||||
import 'package:aves/model/geotiff.dart';
|
import 'package:aves/model/media/geotiff.dart';
|
||||||
import 'package:aves/model/metadata/catalog.dart';
|
import 'package:aves/model/metadata/catalog.dart';
|
||||||
import 'package:aves/model/metadata/overlay.dart';
|
import 'package:aves/model/metadata/overlay.dart';
|
||||||
import 'package:aves/model/multipage.dart';
|
import 'package:aves/model/multipage.dart';
|
||||||
import 'package:aves/model/panorama.dart';
|
import 'package:aves/model/media/panorama.dart';
|
||||||
import 'package:aves/ref/mime_types.dart';
|
|
||||||
import 'package:aves/services/common/service_policy.dart';
|
import 'package:aves/services/common/service_policy.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/services/metadata/xmp.dart';
|
import 'package:aves/services/metadata/xmp.dart';
|
||||||
|
@ -69,11 +68,6 @@ class PlatformMetadataFetchService implements MetadataFetchService {
|
||||||
Future<CatalogMetadata?> getCatalogMetadata(AvesEntry entry, {bool background = false}) async {
|
Future<CatalogMetadata?> getCatalogMetadata(AvesEntry entry, {bool background = false}) async {
|
||||||
if (entry.isSvg) return null;
|
if (entry.isSvg) return null;
|
||||||
|
|
||||||
// TODO TLAD remove log when MP4/TIFF-related OOMs are fixed
|
|
||||||
if ({MimeTypes.mp4, MimeTypes.tiff}.contains(entry.mimeType) && (entry.sizeBytes ?? 0) > 20000000) {
|
|
||||||
await reportService.log('catalog large entry=$entry size=${entry.sizeBytes}');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<CatalogMetadata?> call() async {
|
Future<CatalogMetadata?> call() async {
|
||||||
try {
|
try {
|
||||||
// returns map with:
|
// returns map with:
|
||||||
|
|
|
@ -29,11 +29,10 @@ class ADurations {
|
||||||
// collection animations
|
// collection animations
|
||||||
static const filterBarRemovalAnimation = Duration(milliseconds: 400);
|
static const filterBarRemovalAnimation = Duration(milliseconds: 400);
|
||||||
static const collectionOpOverlayAnimation = Duration(milliseconds: 300);
|
static const collectionOpOverlayAnimation = Duration(milliseconds: 300);
|
||||||
static const sectionHeaderAnimation = Duration(milliseconds: 200);
|
|
||||||
static const thumbnailOverlayAnimation = Duration(milliseconds: 200);
|
|
||||||
|
|
||||||
// search animations
|
// search animations
|
||||||
static const filterRowExpandAnimation = Duration(milliseconds: 300);
|
static const filterRowExpandAnimation = Duration(milliseconds: 300);
|
||||||
|
static const searchBodyTransition = Duration(milliseconds: 300);
|
||||||
|
|
||||||
// viewer animations
|
// viewer animations
|
||||||
static const thumbnailScrollerScrollAnimation = Duration(milliseconds: 200);
|
static const thumbnailScrollerScrollAnimation = Duration(milliseconds: 200);
|
||||||
|
|
|
@ -28,6 +28,7 @@ class AIcons {
|
||||||
static const descriptionUntitled = Icons.comments_disabled_outlined;
|
static const descriptionUntitled = Icons.comments_disabled_outlined;
|
||||||
static const disc = Icons.fiber_manual_record;
|
static const disc = Icons.fiber_manual_record;
|
||||||
static const display = Icons.light_mode_outlined;
|
static const display = Icons.light_mode_outlined;
|
||||||
|
static const duration = Icons.timelapse_outlined;
|
||||||
static const error = Icons.error_outline;
|
static const error = Icons.error_outline;
|
||||||
static const explorer = Icons.account_tree_outlined;
|
static const explorer = Icons.account_tree_outlined;
|
||||||
static const folder = Icons.folder_outlined;
|
static const folder = Icons.folder_outlined;
|
||||||
|
@ -162,6 +163,8 @@ class AIcons {
|
||||||
static const zoomOut = Icons.remove_outlined;
|
static const zoomOut = Icons.remove_outlined;
|
||||||
static const collapse = Icons.expand_less_outlined;
|
static const collapse = Icons.expand_less_outlined;
|
||||||
static const expand = Icons.expand_more_outlined;
|
static const expand = Icons.expand_more_outlined;
|
||||||
|
static const up = Icons.keyboard_arrow_up_outlined;
|
||||||
|
static const down = Icons.keyboard_arrow_down_outlined;
|
||||||
static const previous = Icons.chevron_left_outlined;
|
static const previous = Icons.chevron_left_outlined;
|
||||||
static const next = Icons.chevron_right_outlined;
|
static const next = Icons.chevron_right_outlined;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aves/model/apps.dart';
|
import 'package:aves/model/app_inventory.dart';
|
||||||
import 'package:aves/model/vaults/vaults.dart';
|
import 'package:aves/model/vaults/vaults.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
|
@ -7,6 +7,8 @@ import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
final AndroidFileUtils androidFileUtils = AndroidFileUtils._private();
|
final AndroidFileUtils androidFileUtils = AndroidFileUtils._private();
|
||||||
|
|
||||||
|
enum _State { uninitialized, initializing, initialized }
|
||||||
|
|
||||||
class AndroidFileUtils {
|
class AndroidFileUtils {
|
||||||
// cf https://developer.android.com/reference/android/content/ContentResolver#SCHEME_CONTENT
|
// cf https://developer.android.com/reference/android/content/ContentResolver#SCHEME_CONTENT
|
||||||
static const contentScheme = 'content';
|
static const contentScheme = 'content';
|
||||||
|
@ -27,13 +29,19 @@ class AndroidFileUtils {
|
||||||
late final String dcimPath, downloadPath, moviesPath, picturesPath, avesVideoCapturesPath;
|
late final String dcimPath, downloadPath, moviesPath, picturesPath, avesVideoCapturesPath;
|
||||||
late final Set<String> videoCapturesPaths;
|
late final Set<String> videoCapturesPaths;
|
||||||
Set<StorageVolume> storageVolumes = {};
|
Set<StorageVolume> storageVolumes = {};
|
||||||
bool _initialized = false;
|
_State _initialized = _State.uninitialized;
|
||||||
|
|
||||||
AndroidFileUtils._private();
|
AndroidFileUtils._private();
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
if (_initialized) return;
|
if (_initialized == _State.uninitialized) {
|
||||||
|
_initialized = _State.initializing;
|
||||||
|
await _doInit();
|
||||||
|
_initialized = _State.initialized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _doInit() async {
|
||||||
separator = pContext.separator;
|
separator = pContext.separator;
|
||||||
await _initStorageVolumes();
|
await _initStorageVolumes();
|
||||||
vaultRoot = await storageService.getVaultRoot();
|
vaultRoot = await storageService.getVaultRoot();
|
||||||
|
@ -50,8 +58,6 @@ class AndroidFileUtils {
|
||||||
// from Aves
|
// from Aves
|
||||||
avesVideoCapturesPath,
|
avesVideoCapturesPath,
|
||||||
};
|
};
|
||||||
|
|
||||||
_initialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _initStorageVolumes() async {
|
Future<void> _initStorageVolumes() async {
|
||||||
|
|
|
@ -9,6 +9,7 @@ extension ExtraExplorerActionView on ExplorerAction {
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
ExplorerAction.addShortcut => l10n.collectionActionAddShortcut,
|
ExplorerAction.addShortcut => l10n.collectionActionAddShortcut,
|
||||||
ExplorerAction.setHome => l10n.collectionActionSetHome,
|
ExplorerAction.setHome => l10n.collectionActionSetHome,
|
||||||
|
ExplorerAction.stats => l10n.menuActionStats,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ extension ExtraExplorerActionView on ExplorerAction {
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
ExplorerAction.addShortcut => AIcons.addShortcut,
|
ExplorerAction.addShortcut => AIcons.addShortcut,
|
||||||
ExplorerAction.setHome => AIcons.home,
|
ExplorerAction.setHome => AIcons.home,
|
||||||
|
ExplorerAction.stats => AIcons.stats,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ extension ExtraMapActionView on MapAction {
|
||||||
final l10n = context.l10n;
|
final l10n = context.l10n;
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
MapAction.selectStyle => l10n.mapStyleTooltip,
|
MapAction.selectStyle => l10n.mapStyleTooltip,
|
||||||
|
MapAction.openMapApp => l10n.entryActionOpenMap,
|
||||||
MapAction.zoomIn => l10n.mapZoomInTooltip,
|
MapAction.zoomIn => l10n.mapZoomInTooltip,
|
||||||
MapAction.zoomOut => l10n.mapZoomOutTooltip,
|
MapAction.zoomOut => l10n.mapZoomOutTooltip,
|
||||||
};
|
};
|
||||||
|
@ -18,6 +19,7 @@ extension ExtraMapActionView on MapAction {
|
||||||
IconData _getIconData() {
|
IconData _getIconData() {
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
MapAction.selectStyle => AIcons.layers,
|
MapAction.selectStyle => AIcons.layers,
|
||||||
|
MapAction.openMapApp => AIcons.openOutside,
|
||||||
MapAction.zoomIn => AIcons.zoomIn,
|
MapAction.zoomIn => AIcons.zoomIn,
|
||||||
MapAction.zoomOut => AIcons.zoomOut,
|
MapAction.zoomOut => AIcons.zoomOut,
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@ extension ExtraEntrySortFactorView on EntrySortFactor {
|
||||||
EntrySortFactor.name => l10n.sortByAlbumFileName,
|
EntrySortFactor.name => l10n.sortByAlbumFileName,
|
||||||
EntrySortFactor.rating => l10n.sortByRating,
|
EntrySortFactor.rating => l10n.sortByRating,
|
||||||
EntrySortFactor.size => l10n.sortBySize,
|
EntrySortFactor.size => l10n.sortBySize,
|
||||||
|
EntrySortFactor.duration => l10n.sortByDuration,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ extension ExtraEntrySortFactorView on EntrySortFactor {
|
||||||
EntrySortFactor.name => AIcons.name,
|
EntrySortFactor.name => AIcons.name,
|
||||||
EntrySortFactor.rating => AIcons.rating,
|
EntrySortFactor.rating => AIcons.rating,
|
||||||
EntrySortFactor.size => AIcons.size,
|
EntrySortFactor.size => AIcons.size,
|
||||||
|
EntrySortFactor.duration => AIcons.duration,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +32,7 @@ extension ExtraEntrySortFactorView on EntrySortFactor {
|
||||||
EntrySortFactor.name => reverse ? l10n.sortOrderZtoA : l10n.sortOrderAtoZ,
|
EntrySortFactor.name => reverse ? l10n.sortOrderZtoA : l10n.sortOrderAtoZ,
|
||||||
EntrySortFactor.rating => reverse ? l10n.sortOrderLowestFirst : l10n.sortOrderHighestFirst,
|
EntrySortFactor.rating => reverse ? l10n.sortOrderLowestFirst : l10n.sortOrderHighestFirst,
|
||||||
EntrySortFactor.size => reverse ? l10n.sortOrderSmallestFirst : l10n.sortOrderLargestFirst,
|
EntrySortFactor.size => reverse ? l10n.sortOrderSmallestFirst : l10n.sortOrderLargestFirst,
|
||||||
|
EntrySortFactor.duration => reverse ? l10n.sortOrderShortestFirst : l10n.sortOrderLongestFirst,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ export 'src/actions/chip.dart';
|
||||||
export 'src/actions/chip_set.dart';
|
export 'src/actions/chip_set.dart';
|
||||||
export 'src/actions/entry.dart';
|
export 'src/actions/entry.dart';
|
||||||
export 'src/actions/entry_set.dart';
|
export 'src/actions/entry_set.dart';
|
||||||
|
export 'src/actions/explorer.dart';
|
||||||
export 'src/actions/map.dart';
|
export 'src/actions/map.dart';
|
||||||
export 'src/actions/map_cluster.dart';
|
export 'src/actions/map_cluster.dart';
|
||||||
export 'src/actions/share.dart';
|
export 'src/actions/share.dart';
|
||||||
|
|
|
@ -18,11 +18,13 @@ import 'package:flutter/services.dart';
|
||||||
const _widgetDrawChannel = MethodChannel('deckers.thibault/aves/widget_draw');
|
const _widgetDrawChannel = MethodChannel('deckers.thibault/aves/widget_draw');
|
||||||
|
|
||||||
void widgetMainCommon(AppFlavor flavor) async {
|
void widgetMainCommon(AppFlavor flavor) async {
|
||||||
|
debugPrint('Widget main start');
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
initPlatformServices();
|
initPlatformServices();
|
||||||
await settings.init(monitorPlatformSettings: false);
|
await settings.init(monitorPlatformSettings: false);
|
||||||
await reportService.init();
|
await reportService.init();
|
||||||
|
|
||||||
|
debugPrint('Widget channel method handling setup');
|
||||||
_widgetDrawChannel.setMethodCallHandler((call) async {
|
_widgetDrawChannel.setMethodCallHandler((call) async {
|
||||||
// widget settings may be modified in a different process after channel setup
|
// widget settings may be modified in a different process after channel setup
|
||||||
await settings.reload();
|
await settings.reload();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'dart:math';
|
||||||
import 'package:aves/app_flavor.dart';
|
import 'package:aves/app_flavor.dart';
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/l10n/l10n.dart';
|
import 'package:aves/l10n/l10n.dart';
|
||||||
import 'package:aves/model/apps.dart';
|
import 'package:aves/model/app_inventory.dart';
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/device.dart';
|
||||||
import 'package:aves/model/filters/recent.dart';
|
import 'package:aves/model/filters/recent.dart';
|
||||||
import 'package:aves/model/settings/defaults.dart';
|
import 'package:aves/model/settings/defaults.dart';
|
||||||
|
@ -345,12 +345,14 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
child: ValueListenableBuilder<PageTransitionsBuilder>(
|
child: ValueListenableBuilder<PageTransitionsBuilder>(
|
||||||
valueListenable: _pageTransitionsBuilderNotifier,
|
valueListenable: _pageTransitionsBuilderNotifier,
|
||||||
builder: (context, pageTransitionsBuilder, child) {
|
builder: (context, pageTransitionsBuilder, child) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
return Theme(
|
return Theme(
|
||||||
data: Theme.of(context).copyWith(
|
data: theme.copyWith(
|
||||||
pageTransitionsTheme: areAnimationsEnabled
|
pageTransitionsTheme: areAnimationsEnabled
|
||||||
? PageTransitionsTheme(builders: {TargetPlatform.android: pageTransitionsBuilder})
|
? PageTransitionsTheme(builders: {TargetPlatform.android: pageTransitionsBuilder})
|
||||||
// strip page transitions used by `MaterialPageRoute`
|
// strip page transitions used by `MaterialPageRoute`
|
||||||
: const DirectPageTransitionsTheme(),
|
: const DirectPageTransitionsTheme(),
|
||||||
|
splashFactory: areAnimationsEnabled ? theme.splashFactory : NoSplash.splashFactory,
|
||||||
),
|
),
|
||||||
child: MediaQueryDataProvider(child: child!),
|
child: MediaQueryDataProvider(child: child!),
|
||||||
);
|
);
|
||||||
|
@ -411,6 +413,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
void didHaveMemoryPressure() {
|
void didHaveMemoryPressure() {
|
||||||
super.didHaveMemoryPressure();
|
super.didHaveMemoryPressure();
|
||||||
reportService.log('App memory pressure');
|
reportService.log('App memory pressure');
|
||||||
|
imageCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -631,7 +634,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
final shouldReset = _exitedMainByPop;
|
final shouldReset = _exitedMainByPop;
|
||||||
_exitedMainByPop = false;
|
_exitedMainByPop = false;
|
||||||
|
|
||||||
if (!shouldReset && (intentData ?? {}).isEmpty) {
|
if (!shouldReset && (intentData ?? {}).values.whereNotNull().isEmpty) {
|
||||||
reportService.log('Relaunch');
|
reportService.log('Relaunch');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -665,6 +668,9 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flutter has various overscroll indicator implementations for Android:
|
||||||
|
// - `StretchingOverscrollIndicator`, default when using Material 3
|
||||||
|
// - `GlowingOverscrollIndicator`, default when not using Material 3
|
||||||
class AvesScrollBehavior extends MaterialScrollBehavior {
|
class AvesScrollBehavior extends MaterialScrollBehavior {
|
||||||
@override
|
@override
|
||||||
Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
|
Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
|
||||||
|
@ -674,11 +680,7 @@ class AvesScrollBehavior extends MaterialScrollBehavior {
|
||||||
axisDirection: details.direction,
|
axisDirection: details.direction,
|
||||||
child: child,
|
child: child,
|
||||||
)
|
)
|
||||||
: GlowingOverscrollIndicator(
|
: child;
|
||||||
axisDirection: details.direction,
|
|
||||||
color: Colors.white,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
EntrySortFactor.size,
|
EntrySortFactor.size,
|
||||||
EntrySortFactor.name,
|
EntrySortFactor.name,
|
||||||
EntrySortFactor.rating,
|
EntrySortFactor.rating,
|
||||||
|
EntrySortFactor.duration,
|
||||||
];
|
];
|
||||||
|
|
||||||
static const _groupOptions = [
|
static const _groupOptions = [
|
||||||
|
@ -94,6 +95,11 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
TileLayout.list,
|
TileLayout.list,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
static const _trashSelectionQuickActions = [
|
||||||
|
EntrySetAction.delete,
|
||||||
|
EntrySetAction.restore,
|
||||||
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -388,7 +394,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
final hasSelection = selectedItemCount > 0;
|
final hasSelection = selectedItemCount > 0;
|
||||||
|
|
||||||
final browsingQuickActions = settings.collectionBrowsingQuickActions;
|
final browsingQuickActions = settings.collectionBrowsingQuickActions;
|
||||||
final selectionQuickActions = isTrash ? [EntrySetAction.delete, EntrySetAction.restore] : settings.collectionSelectionQuickActions;
|
final selectionQuickActions = isTrash ? _trashSelectionQuickActions : settings.collectionSelectionQuickActions;
|
||||||
final quickActions = (isSelecting ? selectionQuickActions : browsingQuickActions).take(max(0, availableCount - 1)).toList();
|
final quickActions = (isSelecting ? selectionQuickActions : browsingQuickActions).take(max(0, availableCount - 1)).toList();
|
||||||
final quickActionButtons = quickActions.where(isVisible).map(
|
final quickActionButtons = quickActions.where(isVisible).map(
|
||||||
(action) => _buildButtonIcon(context, action, enabled: canApply(action), selection: selection),
|
(action) => _buildButtonIcon(context, action, enabled: canApply(action), selection: selection),
|
||||||
|
@ -430,7 +436,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
title: context.l10n.collectionActionEdit,
|
title: context.l10n.collectionActionEdit,
|
||||||
items: [
|
items: [
|
||||||
_buildRotateAndFlipMenuItems(context, canApply: canApply),
|
_buildRotateAndFlipMenuItems(context, canApply: canApply),
|
||||||
...EntrySetActions.edit.where((v) => isVisible(v) && !selectionQuickActions.contains(v)).map((action) => _toMenuItem(action, enabled: canApply(action), selection: selection)),
|
...EntrySetActions.edit.where((v) => isVisible(v) && !quickActions.contains(v)).map((action) => _toMenuItem(action, enabled: canApply(action), selection: selection)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
|
@ -697,6 +697,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge
|
||||||
addAlbums(collection, sectionLayouts, crumbs);
|
addAlbums(collection, sectionLayouts, crumbs);
|
||||||
case EntrySortFactor.rating:
|
case EntrySortFactor.rating:
|
||||||
case EntrySortFactor.size:
|
case EntrySortFactor.size:
|
||||||
|
case EntrySortFactor.duration:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return crumbs;
|
return crumbs;
|
||||||
|
|
|
@ -57,6 +57,10 @@ class CollectionDraggableThumbLabel extends StatelessWidget {
|
||||||
return [
|
return [
|
||||||
if (entry.sizeBytes != null) formatFileSize(context.locale, entry.sizeBytes!, round: 0),
|
if (entry.sizeBytes != null) formatFileSize(context.locale, entry.sizeBytes!, round: 0),
|
||||||
];
|
];
|
||||||
|
case EntrySortFactor.duration:
|
||||||
|
return [
|
||||||
|
if (entry.durationMillis != null) entry.durationText,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_app_bar.dart';
|
import 'package:aves/widgets/common/identity/aves_app_bar.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class FilterBar extends StatefulWidget {
|
class FilterBar extends StatefulWidget {
|
||||||
static const EdgeInsets chipPadding = EdgeInsets.symmetric(horizontal: 4);
|
static const EdgeInsets chipPadding = EdgeInsets.symmetric(horizontal: 4);
|
||||||
|
@ -12,7 +14,7 @@ class FilterBar extends StatefulWidget {
|
||||||
|
|
||||||
final List<CollectionFilter> filters;
|
final List<CollectionFilter> filters;
|
||||||
final bool interactive;
|
final bool interactive;
|
||||||
final FilterCallback? onTap, onRemove;
|
final AFilterCallback? onTap, onRemove;
|
||||||
|
|
||||||
FilterBar({
|
FilterBar({
|
||||||
super.key,
|
super.key,
|
||||||
|
@ -45,7 +47,7 @@ class _FilterBarState extends State<FilterBar> {
|
||||||
existing.removeAt(index);
|
existing.removeAt(index);
|
||||||
// only animate item removal when triggered by a user interaction with the chip,
|
// only animate item removal when triggered by a user interaction with the chip,
|
||||||
// not from automatic chip replacement following chip selection
|
// not from automatic chip replacement following chip selection
|
||||||
final animate = _userTappedFilter == filter;
|
final animate = context.read<Settings>().animate && _userTappedFilter == filter;
|
||||||
listState!.removeItem(
|
listState!.removeItem(
|
||||||
index,
|
index,
|
||||||
animate
|
animate
|
||||||
|
@ -123,7 +125,7 @@ class _FilterBarState extends State<FilterBar> {
|
||||||
class _Chip extends StatelessWidget {
|
class _Chip extends StatelessWidget {
|
||||||
final CollectionFilter filter;
|
final CollectionFilter filter;
|
||||||
final bool single, interactive;
|
final bool single, interactive;
|
||||||
final FilterCallback? onTap, onRemove;
|
final AFilterCallback? onTap, onRemove;
|
||||||
|
|
||||||
const _Chip({
|
const _Chip({
|
||||||
required this.filter,
|
required this.filter,
|
||||||
|
@ -142,7 +144,7 @@ class _Chip extends StatelessWidget {
|
||||||
key: ValueKey(filter),
|
key: ValueKey(filter),
|
||||||
filter: filter,
|
filter: filter,
|
||||||
maxWidth: single
|
maxWidth: single
|
||||||
? AvesFilterChip.computeMaxWidth(
|
? AvesFilterChip.computeMaxWidthForRow(
|
||||||
context,
|
context,
|
||||||
minChipPerRow: 1,
|
minChipPerRow: 1,
|
||||||
chipPadding: FilterBar.chipPadding.horizontal,
|
chipPadding: FilterBar.chipPadding.horizontal,
|
||||||
|
|
|
@ -66,6 +66,7 @@ class CollectionSectionHeader extends StatelessWidget {
|
||||||
selectable: selectable,
|
selectable: selectable,
|
||||||
);
|
);
|
||||||
case EntrySortFactor.size:
|
case EntrySortFactor.size:
|
||||||
|
case EntrySortFactor.duration:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/filters/album.dart';
|
import 'package:aves/model/filters/album.dart';
|
||||||
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/filter_quick_chooser_mixin.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class AlbumQuickChooser extends StatelessWidget {
|
class AlbumQuickChooser extends StatelessWidget with FilterQuickChooserMixin<String> {
|
||||||
final ValueNotifier<String?> valueNotifier;
|
final ValueNotifier<String?> valueNotifier;
|
||||||
|
@override
|
||||||
final List<String> options;
|
final List<String> options;
|
||||||
final bool blurred;
|
final bool blurred;
|
||||||
final PopupMenuPosition chooserPosition;
|
final PopupMenuPosition chooserPosition;
|
||||||
|
@ -25,7 +28,6 @@ class AlbumQuickChooser extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final source = context.read<CollectionSource>();
|
|
||||||
return MenuQuickChooser<String>(
|
return MenuQuickChooser<String>(
|
||||||
valueNotifier: valueNotifier,
|
valueNotifier: valueNotifier,
|
||||||
options: options,
|
options: options,
|
||||||
|
@ -33,10 +35,17 @@ class AlbumQuickChooser extends StatelessWidget {
|
||||||
blurred: blurred,
|
blurred: blurred,
|
||||||
chooserPosition: chooserPosition,
|
chooserPosition: chooserPosition,
|
||||||
pointerGlobalPosition: pointerGlobalPosition,
|
pointerGlobalPosition: pointerGlobalPosition,
|
||||||
itemBuilder: (context, album) => AvesFilterChip(
|
maxTotalOptionCount: FilterQuickChooserMixin.maxTotalOptionCount,
|
||||||
filter: AlbumFilter(album, source.getAlbumDisplayName(context, album)),
|
itemHeight: computeItemHeight(context),
|
||||||
allowGenericIcon: false,
|
contentWidth: computeLargestItemWidth,
|
||||||
),
|
itemBuilder: itemBuilder,
|
||||||
|
emptyBuilder: (context) => Text(context.l10n.albumEmpty),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
CollectionFilter buildFilter(BuildContext context, String option) {
|
||||||
|
final source = context.read<CollectionSource>();
|
||||||
|
return AlbumFilter(option, source.getAlbumDisplayName(context, option));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
|
import 'package:aves/theme/icons.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/common/quick_chooser.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/common/quick_chooser.dart';
|
||||||
import 'package:aves_ui/aves_ui.dart';
|
import 'package:aves_ui/aves_ui.dart';
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
|
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
|
||||||
|
@ -16,9 +17,13 @@ class MenuQuickChooser<T> extends StatefulWidget {
|
||||||
final bool blurred;
|
final bool blurred;
|
||||||
final PopupMenuPosition chooserPosition;
|
final PopupMenuPosition chooserPosition;
|
||||||
final Stream<Offset> pointerGlobalPosition;
|
final Stream<Offset> pointerGlobalPosition;
|
||||||
|
final int maxTotalOptionCount;
|
||||||
|
final double itemHeight;
|
||||||
|
final double? Function(BuildContext context)? contentWidth;
|
||||||
final Widget Function(BuildContext context, T menuItem) itemBuilder;
|
final Widget Function(BuildContext context, T menuItem) itemBuilder;
|
||||||
|
final WidgetBuilder? emptyBuilder;
|
||||||
|
|
||||||
static const int maxOptionCount = 5;
|
static const int maxVisibleOptionCount = 5;
|
||||||
|
|
||||||
MenuQuickChooser({
|
MenuQuickChooser({
|
||||||
super.key,
|
super.key,
|
||||||
|
@ -28,8 +33,12 @@ class MenuQuickChooser<T> extends StatefulWidget {
|
||||||
required this.blurred,
|
required this.blurred,
|
||||||
required this.chooserPosition,
|
required this.chooserPosition,
|
||||||
required this.pointerGlobalPosition,
|
required this.pointerGlobalPosition,
|
||||||
|
this.maxTotalOptionCount = maxVisibleOptionCount,
|
||||||
|
this.itemHeight = kMinInteractiveDimension,
|
||||||
|
this.contentWidth,
|
||||||
required this.itemBuilder,
|
required this.itemBuilder,
|
||||||
}) : options = options.take(maxOptionCount).toList();
|
this.emptyBuilder,
|
||||||
|
}) : options = options.take(maxTotalOptionCount).toList();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<MenuQuickChooser<T>> createState() => _MenuQuickChooserState<T>();
|
State<MenuQuickChooser<T>> createState() => _MenuQuickChooserState<T>();
|
||||||
|
@ -38,6 +47,10 @@ class MenuQuickChooser<T> extends StatefulWidget {
|
||||||
class _MenuQuickChooserState<T> extends State<MenuQuickChooser<T>> {
|
class _MenuQuickChooserState<T> extends State<MenuQuickChooser<T>> {
|
||||||
final List<StreamSubscription> _subscriptions = [];
|
final List<StreamSubscription> _subscriptions = [];
|
||||||
final ValueNotifier<Rect> _selectedRowRect = ValueNotifier(Rect.zero);
|
final ValueNotifier<Rect> _selectedRowRect = ValueNotifier(Rect.zero);
|
||||||
|
final ScrollController _scrollController = ScrollController();
|
||||||
|
int _scrollDirection = 0;
|
||||||
|
Timer? _scrollUpdateTimer;
|
||||||
|
Offset _globalPosition = Offset.zero;
|
||||||
|
|
||||||
ValueNotifier<T?> get valueNotifier => widget.valueNotifier;
|
ValueNotifier<T?> get valueNotifier => widget.valueNotifier;
|
||||||
|
|
||||||
|
@ -45,12 +58,26 @@ class _MenuQuickChooserState<T> extends State<MenuQuickChooser<T>> {
|
||||||
|
|
||||||
bool get reversed => widget.autoReverse && widget.chooserPosition == PopupMenuPosition.over;
|
bool get reversed => widget.autoReverse && widget.chooserPosition == PopupMenuPosition.over;
|
||||||
|
|
||||||
static const double intraPadding = 8;
|
bool get scrollable => options.length > MenuQuickChooser.maxVisibleOptionCount;
|
||||||
|
|
||||||
|
int get visibleOptionCount => min(MenuQuickChooser.maxVisibleOptionCount, options.length);
|
||||||
|
|
||||||
|
double get itemHeight => widget.itemHeight;
|
||||||
|
|
||||||
|
double get contentHeight => max(0, itemHeight * visibleOptionCount + _intraPadding * (visibleOptionCount - 1));
|
||||||
|
|
||||||
|
static const double _selectorMargin = 24;
|
||||||
|
static const double _intraPadding = 8;
|
||||||
|
static const double _nonScrollablePaddingHeight = _intraPadding;
|
||||||
|
static const double _scrollerAreaHeight = kMinInteractiveDimension;
|
||||||
|
static const double scrollMaxPixelPerSecond = 600.0;
|
||||||
|
static const Duration scrollUpdateInterval = Duration(milliseconds: 100);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_registerWidget(widget);
|
_registerWidget(widget);
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -69,6 +96,9 @@ class _MenuQuickChooserState<T> extends State<MenuQuickChooser<T>> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_unregisterWidget(widget);
|
_unregisterWidget(widget);
|
||||||
|
_selectedRowRect.dispose();
|
||||||
|
_scrollController.dispose();
|
||||||
|
_scrollUpdateTimer?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,28 +121,11 @@ class _MenuQuickChooserState<T> extends State<MenuQuickChooser<T>> {
|
||||||
builder: (context, selectedValue, child) {
|
builder: (context, selectedValue, child) {
|
||||||
final durations = context.watch<DurationsData>();
|
final durations = context.watch<DurationsData>();
|
||||||
|
|
||||||
List<Widget> optionChildren = options.mapIndexed((index, value) {
|
if (options.isEmpty) {
|
||||||
final isFirst = index == (reversed ? options.length - 1 : 0);
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(top: isFirst ? intraPadding : 0, bottom: intraPadding),
|
padding: const EdgeInsets.all(16),
|
||||||
child: widget.itemBuilder(context, value),
|
child: widget.emptyBuilder?.call(context) ?? const SizedBox(),
|
||||||
);
|
);
|
||||||
}).toList();
|
|
||||||
|
|
||||||
optionChildren = AnimationConfiguration.toStaggeredList(
|
|
||||||
duration: durations.staggeredAnimation * .5,
|
|
||||||
delay: durations.staggeredAnimationDelay * .5 * timeDilation,
|
|
||||||
childAnimationBuilder: (child) => SlideAnimation(
|
|
||||||
verticalOffset: 50.0 * (widget.chooserPosition == PopupMenuPosition.over ? 1 : -1),
|
|
||||||
child: FadeInAnimation(
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
children: optionChildren,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (reversed) {
|
|
||||||
optionChildren = optionChildren.reversed.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
|
@ -137,12 +150,67 @@ class _MenuQuickChooserState<T> extends State<MenuQuickChooser<T>> {
|
||||||
return child;
|
return child;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Padding(
|
Container(
|
||||||
padding: const EdgeInsetsDirectional.only(start: 24),
|
width: widget.contentWidth?.call(context),
|
||||||
|
margin: const EdgeInsetsDirectional.only(start: _selectorMargin),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: optionChildren,
|
scrollable
|
||||||
|
? ListenableBuilder(
|
||||||
|
listenable: _scrollController,
|
||||||
|
builder: (context, child) => Opacity(
|
||||||
|
opacity: canGoUp ? 1 : .5,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
child: _buildScrollerArea(AIcons.up),
|
||||||
|
)
|
||||||
|
: const SizedBox(height: _nonScrollablePaddingHeight),
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints.tightFor(height: contentHeight),
|
||||||
|
child: ListView.separated(
|
||||||
|
reverse: reversed,
|
||||||
|
controller: _scrollController,
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final child = Container(
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
constraints: BoxConstraints.tightFor(height: itemHeight),
|
||||||
|
child: widget.itemBuilder(context, options[index]),
|
||||||
|
);
|
||||||
|
if (index < MenuQuickChooser.maxVisibleOptionCount) {
|
||||||
|
// only animate items visible on first render
|
||||||
|
return AnimationConfiguration.staggeredList(
|
||||||
|
position: index,
|
||||||
|
duration: durations.staggeredAnimation * .5,
|
||||||
|
delay: durations.staggeredAnimationDelay * .5 * timeDilation,
|
||||||
|
child: SlideAnimation(
|
||||||
|
verticalOffset: 50.0 * (widget.chooserPosition == PopupMenuPosition.over ? 1 : -1),
|
||||||
|
child: FadeInAnimation(
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) => const SizedBox(height: _intraPadding),
|
||||||
|
itemCount: options.length,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
scrollable
|
||||||
|
? ListenableBuilder(
|
||||||
|
listenable: _scrollController,
|
||||||
|
builder: (context, child) => Opacity(
|
||||||
|
opacity: canGoDown ? 1 : .5,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
child: _buildScrollerArea(AIcons.down),
|
||||||
|
)
|
||||||
|
: const SizedBox(height: _nonScrollablePaddingHeight),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -152,30 +220,97 @@ class _MenuQuickChooserState<T> extends State<MenuQuickChooser<T>> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onPointerMove(Offset globalPosition) {
|
bool get canGoUp {
|
||||||
final padding = QuickChooser.margin.vertical + QuickChooser.padding.vertical;
|
if (!_scrollController.hasClients) return false;
|
||||||
|
final position = _scrollController.position;
|
||||||
|
return reversed ? position.pixels < position.maxScrollExtent : 0 < position.pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get canGoDown {
|
||||||
|
if (!_scrollController.hasClients) return false;
|
||||||
|
final position = _scrollController.position;
|
||||||
|
return reversed ? 0 < position.pixels : position.pixels < position.maxScrollExtent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildScrollerArea(IconData icon) {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
height: _scrollerAreaHeight,
|
||||||
|
margin: const EdgeInsetsDirectional.only(end: _selectorMargin),
|
||||||
|
child: Icon(icon),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onPointerMove(Offset globalPosition) {
|
||||||
|
_globalPosition = globalPosition;
|
||||||
|
final chooserBox = context.findRenderObject() as RenderBox?;
|
||||||
|
if (chooserBox == null) return;
|
||||||
|
|
||||||
final chooserBox = context.findRenderObject() as RenderBox;
|
|
||||||
final chooserSize = chooserBox.size;
|
final chooserSize = chooserBox.size;
|
||||||
final contentWidth = chooserSize.width;
|
final contentWidth = chooserSize.width;
|
||||||
final contentHeight = chooserSize.height - padding;
|
final chooserBoxEdgeHeight = (QuickChooser.margin.vertical + QuickChooser.padding.vertical) / 2;
|
||||||
|
|
||||||
final optionCount = options.length;
|
final localPosition = chooserBox.globalToLocal(globalPosition);
|
||||||
final itemHeight = (contentHeight - (optionCount + 1) * intraPadding) / optionCount;
|
final dx = localPosition.dx;
|
||||||
|
if (!(0 < dx && dx < contentWidth)) {
|
||||||
|
valueNotifier.value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final local = chooserBox.globalToLocal(globalPosition);
|
double dy = localPosition.dy - chooserBoxEdgeHeight;
|
||||||
final dx = local.dx;
|
int scrollDirection = 0;
|
||||||
final dy = local.dy - padding / 2;
|
if (scrollable) {
|
||||||
|
dy -= _scrollerAreaHeight;
|
||||||
|
if (-_scrollerAreaHeight < dy && dy < 0) {
|
||||||
|
scrollDirection = reversed ? 1 : -1;
|
||||||
|
} else if (contentHeight < dy && dy < contentHeight + _scrollerAreaHeight) {
|
||||||
|
scrollDirection = reversed ? -1 : 1;
|
||||||
|
}
|
||||||
|
_scroll(scrollDirection);
|
||||||
|
} else {
|
||||||
|
dy -= _nonScrollablePaddingHeight;
|
||||||
|
}
|
||||||
|
|
||||||
T? selectedValue;
|
T? selectedValue;
|
||||||
if (0 < dx && dx < contentWidth && 0 < dy && dy < contentHeight) {
|
if (scrollDirection == 0 && 0 < dy && dy < contentHeight) {
|
||||||
final index = (optionCount * dy / contentHeight).floor();
|
final visibleOffset = reversed ? contentHeight - dy : dy;
|
||||||
if (0 <= index && index < optionCount) {
|
final fullItemHeight = itemHeight + _intraPadding;
|
||||||
selectedValue = options[reversed ? optionCount - 1 - index : index];
|
final scrollOffset = _scrollController.offset;
|
||||||
final top = index * (itemHeight + intraPadding) + intraPadding;
|
final index = (visibleOffset + _intraPadding + scrollOffset) ~/ (fullItemHeight);
|
||||||
|
if (0 <= index && index < options.length) {
|
||||||
|
selectedValue = options[index];
|
||||||
|
double fromEdge = fullItemHeight * index;
|
||||||
|
fromEdge += (scrollable ? _scrollerAreaHeight - scrollOffset : _nonScrollablePaddingHeight);
|
||||||
|
final top = reversed ? chooserSize.height - chooserBoxEdgeHeight - fromEdge - fullItemHeight : fromEdge;
|
||||||
_selectedRowRect.value = Rect.fromLTWH(0, top, contentWidth, itemHeight);
|
_selectedRowRect.value = Rect.fromLTWH(0, top, contentWidth, itemHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
valueNotifier.value = selectedValue;
|
valueNotifier.value = selectedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _scroll(int scrollDirection) {
|
||||||
|
if (scrollDirection == _scrollDirection) return;
|
||||||
|
_scrollDirection = scrollDirection;
|
||||||
|
_scrollUpdateTimer?.cancel();
|
||||||
|
|
||||||
|
final current = _scrollController.offset;
|
||||||
|
if (scrollDirection == 0) {
|
||||||
|
_scrollController.jumpTo(current);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final target = scrollDirection > 0 ? _scrollController.position.maxScrollExtent : .0;
|
||||||
|
if (target != current) {
|
||||||
|
final distance = target - current;
|
||||||
|
final millis = distance * 1000 / scrollMaxPixelPerSecond / scrollDirection;
|
||||||
|
_scrollController.animateTo(
|
||||||
|
target,
|
||||||
|
duration: Duration(milliseconds: millis.round()),
|
||||||
|
curve: Curves.linear,
|
||||||
|
);
|
||||||
|
// use a timer to update the selection, because `_onPointerMove`
|
||||||
|
// is not called when the pointer stays still while the view is scrolling
|
||||||
|
_scrollUpdateTimer = Timer.periodic(scrollUpdateInterval, (_) => _onPointerMove(_globalPosition));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
import 'package:aves/model/settings/modules/app.dart';
|
||||||
|
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
|
mixin FilterQuickChooserMixin<T> {
|
||||||
|
List<T> get options;
|
||||||
|
|
||||||
|
static const int maxTotalOptionCount = AppSettings.recentFilterHistoryMax;
|
||||||
|
static const double _chipPadding = AvesFilterChip.defaultPadding;
|
||||||
|
static const bool _chipAllowGenericIcon = false;
|
||||||
|
|
||||||
|
CollectionFilter buildFilter(BuildContext context, T option);
|
||||||
|
|
||||||
|
Widget itemBuilder(BuildContext context, T option) {
|
||||||
|
return AvesFilterChip(
|
||||||
|
filter: buildFilter(context, option),
|
||||||
|
allowGenericIcon: _chipAllowGenericIcon,
|
||||||
|
padding: _chipPadding,
|
||||||
|
maxWidth: double.infinity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
double computeItemHeight(BuildContext context) => AvesFilterChip.minChipHeight;
|
||||||
|
|
||||||
|
double? computeLargestItemWidth(BuildContext context) {
|
||||||
|
if (options.isEmpty) return null;
|
||||||
|
|
||||||
|
final textStyle = DefaultTextStyle.of(context).style.copyWith(
|
||||||
|
fontSize: AvesFilterChip.fontSize,
|
||||||
|
);
|
||||||
|
final textDirection = Directionality.of(context);
|
||||||
|
final textScaler = MediaQuery.textScalerOf(context);
|
||||||
|
final iconSize = textScaler.scale(AvesFilterChip.iconSize);
|
||||||
|
|
||||||
|
return options.map((option) {
|
||||||
|
final filter = buildFilter(context, option);
|
||||||
|
final icon = filter.iconBuilder(context, iconSize, allowGenericIcon: _chipAllowGenericIcon);
|
||||||
|
final label = filter.getLabel(context);
|
||||||
|
final paragraph = RenderParagraph(
|
||||||
|
TextSpan(text: label, style: textStyle),
|
||||||
|
textDirection: textDirection,
|
||||||
|
textScaler: textScaler,
|
||||||
|
)..layout(const BoxConstraints(), parentUsesSize: true);
|
||||||
|
final labelWidth = paragraph.getMaxIntrinsicWidth(double.infinity);
|
||||||
|
double chipWidth = labelWidth + _chipPadding * 4;
|
||||||
|
if (icon != null) {
|
||||||
|
chipWidth += iconSize + _chipPadding;
|
||||||
|
}
|
||||||
|
return max(AvesFilterChip.minChipWidth, chipWidth);
|
||||||
|
}).reduce(max);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/view/view.dart';
|
import 'package:aves/view/view.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/album_chooser.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/album_chooser.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/common/button.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/common/button.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/filter_quick_chooser_mixin.dart';
|
||||||
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||||
import 'package:aves/widgets/filter_grids/common/filter_nav_page.dart';
|
import 'package:aves/widgets/filter_grids/common/filter_nav_page.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
|
@ -42,7 +42,7 @@ class _MoveButtonState extends ChooserQuickButtonState<MoveButton, String> {
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
final rawAlbums = source.rawAlbums;
|
final rawAlbums = source.rawAlbums;
|
||||||
final options = settings.recentDestinationAlbums.where(rawAlbums.contains).toList();
|
final options = settings.recentDestinationAlbums.where(rawAlbums.contains).toList();
|
||||||
final takeCount = MenuQuickChooser.maxOptionCount - options.length;
|
final takeCount = FilterQuickChooserMixin.maxTotalOptionCount - options.length;
|
||||||
if (takeCount > 0) {
|
if (takeCount > 0) {
|
||||||
final filters = rawAlbums.whereNot(options.contains).map((album) => AlbumFilter(album, null)).toSet();
|
final filters = rawAlbums.whereNot(options.contains).map((album) => AlbumFilter(album, null)).toSet();
|
||||||
final allMapEntries = filters.map((filter) => FilterGridItem(filter, source.recentEntry(filter))).toList();
|
final allMapEntries = filters.map((filter) => FilterGridItem(filter, source.recentEntry(filter))).toList();
|
||||||
|
|
|
@ -51,7 +51,6 @@ class _ShareButtonState extends ChooserQuickButtonState<ShareButton, ShareAction
|
||||||
child: ShareQuickChooser(
|
child: ShareQuickChooser(
|
||||||
valueNotifier: chooserValueNotifier,
|
valueNotifier: chooserValueNotifier,
|
||||||
options: options,
|
options: options,
|
||||||
autoReverse: false,
|
|
||||||
blurred: widget.blurred,
|
blurred: widget.blurred,
|
||||||
chooserPosition: chooserPosition,
|
chooserPosition: chooserPosition,
|
||||||
pointerGlobalPosition: pointerGlobalPosition,
|
pointerGlobalPosition: pointerGlobalPosition,
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/view/view.dart';
|
import 'package:aves/view/view.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
|
||||||
import 'package:aves/widgets/common/basic/popup/menu_row.dart';
|
import 'package:aves/widgets/common/basic/popup/menu_row.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
class ShareQuickChooser extends StatelessWidget {
|
class ShareQuickChooser extends StatelessWidget {
|
||||||
final ValueNotifier<ShareAction?> valueNotifier;
|
final ValueNotifier<ShareAction?> valueNotifier;
|
||||||
final List<ShareAction> options;
|
final List<ShareAction> options;
|
||||||
final bool autoReverse;
|
|
||||||
final bool blurred;
|
final bool blurred;
|
||||||
final PopupMenuPosition chooserPosition;
|
final PopupMenuPosition chooserPosition;
|
||||||
final Stream<Offset> pointerGlobalPosition;
|
final Stream<Offset> pointerGlobalPosition;
|
||||||
|
|
||||||
|
static const _itemPadding = EdgeInsetsDirectional.only(end: 8);
|
||||||
|
|
||||||
const ShareQuickChooser({
|
const ShareQuickChooser({
|
||||||
super.key,
|
super.key,
|
||||||
required this.valueNotifier,
|
required this.valueNotifier,
|
||||||
required this.options,
|
required this.options,
|
||||||
required this.autoReverse,
|
|
||||||
required this.blurred,
|
required this.blurred,
|
||||||
required this.chooserPosition,
|
required this.chooserPosition,
|
||||||
required this.pointerGlobalPosition,
|
required this.pointerGlobalPosition,
|
||||||
|
@ -29,20 +31,39 @@ class ShareQuickChooser extends StatelessWidget {
|
||||||
return MenuQuickChooser<ShareAction>(
|
return MenuQuickChooser<ShareAction>(
|
||||||
valueNotifier: valueNotifier,
|
valueNotifier: valueNotifier,
|
||||||
options: options,
|
options: options,
|
||||||
autoReverse: autoReverse,
|
autoReverse: false,
|
||||||
blurred: blurred,
|
blurred: blurred,
|
||||||
chooserPosition: chooserPosition,
|
chooserPosition: chooserPosition,
|
||||||
pointerGlobalPosition: pointerGlobalPosition,
|
pointerGlobalPosition: pointerGlobalPosition,
|
||||||
itemBuilder: (context, action) => ConstrainedBox(
|
itemHeight: kMinInteractiveDimension,
|
||||||
constraints: const BoxConstraints(minHeight: kMinInteractiveDimension),
|
contentWidth: _computeLargestItemWidth,
|
||||||
child: Padding(
|
itemBuilder: (context, action) => Padding(
|
||||||
padding: const EdgeInsetsDirectional.only(end: 8),
|
padding: _itemPadding,
|
||||||
child: MenuRow(
|
child: MenuRow(
|
||||||
text: action.getText(context),
|
text: action.getText(context),
|
||||||
icon: action.getIcon(),
|
icon: action.getIcon(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double? _computeLargestItemWidth(BuildContext context) {
|
||||||
|
if (options.isEmpty) return null;
|
||||||
|
|
||||||
|
final textStyle = DefaultTextStyle.of(context).style;
|
||||||
|
final textDirection = Directionality.of(context);
|
||||||
|
final textScaler = MediaQuery.textScalerOf(context);
|
||||||
|
final iconSize = IconTheme.of(context).size ?? 24;
|
||||||
|
|
||||||
|
return options.map((action) {
|
||||||
|
final text = action.getText(context);
|
||||||
|
final paragraph = RenderParagraph(
|
||||||
|
TextSpan(text: text, style: textStyle),
|
||||||
|
textDirection: textDirection,
|
||||||
|
textScaler: textScaler,
|
||||||
|
)..layout(const BoxConstraints(), parentUsesSize: true);
|
||||||
|
final labelWidth = paragraph.getMaxIntrinsicWidth(double.infinity);
|
||||||
|
return iconSize + MenuRow.leadingPadding.horizontal + labelWidth + _itemPadding.horizontal;
|
||||||
|
}).reduce(max);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/view/view.dart';
|
import 'package:aves/view/view.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/common/button.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/common/button.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/filter_quick_chooser_mixin.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/tag_chooser.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/tag_chooser.dart';
|
||||||
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||||
import 'package:aves/widgets/filter_grids/common/filter_nav_page.dart';
|
import 'package:aves/widgets/filter_grids/common/filter_nav_page.dart';
|
||||||
|
@ -38,7 +38,7 @@ class _TagButtonState extends ChooserQuickButtonState<TagButton, CollectionFilte
|
||||||
@override
|
@override
|
||||||
Widget buildChooser(Animation<double> animation, PopupMenuPosition chooserPosition) {
|
Widget buildChooser(Animation<double> animation, PopupMenuPosition chooserPosition) {
|
||||||
final options = settings.recentTags;
|
final options = settings.recentTags;
|
||||||
final takeCount = MenuQuickChooser.maxOptionCount - options.length;
|
final takeCount = FilterQuickChooserMixin.maxTotalOptionCount - options.length;
|
||||||
if (takeCount > 0) {
|
if (takeCount > 0) {
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
final filters = source.sortedTags.map(TagFilter.new).whereNot(options.contains).toSet();
|
final filters = source.sortedTags.map(TagFilter.new).whereNot(options.contains).toSet();
|
||||||
|
|
|
@ -2,11 +2,13 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/common/menu.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
import 'package:aves/widgets/common/action_controls/quick_choosers/filter_quick_chooser_mixin.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class TagQuickChooser extends StatelessWidget {
|
class TagQuickChooser extends StatelessWidget with FilterQuickChooserMixin<CollectionFilter> {
|
||||||
final ValueNotifier<CollectionFilter?> valueNotifier;
|
final ValueNotifier<CollectionFilter?> valueNotifier;
|
||||||
|
@override
|
||||||
final List<CollectionFilter> options;
|
final List<CollectionFilter> options;
|
||||||
final bool blurred;
|
final bool blurred;
|
||||||
final PopupMenuPosition chooserPosition;
|
final PopupMenuPosition chooserPosition;
|
||||||
|
@ -30,10 +32,14 @@ class TagQuickChooser extends StatelessWidget {
|
||||||
blurred: blurred,
|
blurred: blurred,
|
||||||
chooserPosition: chooserPosition,
|
chooserPosition: chooserPosition,
|
||||||
pointerGlobalPosition: pointerGlobalPosition,
|
pointerGlobalPosition: pointerGlobalPosition,
|
||||||
itemBuilder: (context, filter) => AvesFilterChip(
|
maxTotalOptionCount: FilterQuickChooserMixin.maxTotalOptionCount,
|
||||||
filter: filter,
|
itemHeight: computeItemHeight(context),
|
||||||
allowGenericIcon: false,
|
contentWidth: computeLargestItemWidth,
|
||||||
),
|
itemBuilder: itemBuilder,
|
||||||
|
emptyBuilder: (context) => Text(context.l10n.tagEmpty),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
CollectionFilter buildFilter(BuildContext context, CollectionFilter option) => option;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/entry/extensions/favourites.dart';
|
import 'package:aves/model/entry/extensions/favourites.dart';
|
||||||
import 'package:aves/model/favourites.dart';
|
import 'package:aves/model/favourites.dart';
|
||||||
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/theme/colors.dart';
|
import 'package:aves/theme/colors.dart';
|
||||||
import 'package:aves/theme/icons.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
import 'package:aves/widgets/common/basic/popup/menu_row.dart';
|
import 'package:aves/widgets/common/basic/popup/menu_row.dart';
|
||||||
|
@ -73,6 +74,7 @@ class _FavouriteTogglerState extends State<FavouriteToggler> {
|
||||||
icon: const Icon(isNotFavouriteIcon),
|
icon: const Icon(isNotFavouriteIcon),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
final animate = context.select<Settings, bool>((v) => v.animate);
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
@ -82,6 +84,7 @@ class _FavouriteTogglerState extends State<FavouriteToggler> {
|
||||||
focusNode: widget.focusNode,
|
focusNode: widget.focusNode,
|
||||||
tooltip: isFavourite ? context.l10n.entryActionRemoveFavourite : context.l10n.entryActionAddFavourite,
|
tooltip: isFavourite ? context.l10n.entryActionRemoveFavourite : context.l10n.entryActionAddFavourite,
|
||||||
),
|
),
|
||||||
|
if (animate)
|
||||||
Sweeper(
|
Sweeper(
|
||||||
key: ValueKey(entries.length == 1 ? entries.first : entries.length),
|
key: ValueKey(entries.length == 1 ? entries.first : entries.length),
|
||||||
builder: (context) => Icon(
|
builder: (context) => Icon(
|
||||||
|
|
|
@ -95,9 +95,9 @@ class _PlayTogglerState extends State<PlayToggler> with SingleTickerProviderStat
|
||||||
|
|
||||||
void _onStatusChanged(VideoStatus status) {
|
void _onStatusChanged(VideoStatus status) {
|
||||||
final status = _playPauseAnimation.status;
|
final status = _playPauseAnimation.status;
|
||||||
if (isPlaying && status != AnimationStatus.forward && status != AnimationStatus.completed) {
|
if (isPlaying && !status.isForwardOrCompleted) {
|
||||||
_playPauseAnimation.forward();
|
_playPauseAnimation.forward();
|
||||||
} else if (!isPlaying && status != AnimationStatus.reverse && status != AnimationStatus.dismissed) {
|
} else if (!isPlaying && status.isForwardOrCompleted) {
|
||||||
_playPauseAnimation.reverse();
|
_playPauseAnimation.reverse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ typedef MarginComputer = EdgeInsets Function(BuildContext context);
|
||||||
|
|
||||||
mixin FeedbackMixin {
|
mixin FeedbackMixin {
|
||||||
static final ValueNotifier<MarginComputer?> snackBarMarginOverrideNotifier = ValueNotifier(null);
|
static final ValueNotifier<MarginComputer?> snackBarMarginOverrideNotifier = ValueNotifier(null);
|
||||||
|
static OverlaySupportEntry? _overlayNotificationEntry;
|
||||||
|
|
||||||
static EdgeInsets snackBarMarginDefault(BuildContext context) {
|
static EdgeInsets snackBarMarginDefault(BuildContext context) {
|
||||||
return EdgeInsets.only(
|
return EdgeInsets.only(
|
||||||
|
@ -31,7 +32,11 @@ mixin FeedbackMixin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dismissFeedback(BuildContext context) => ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
void dismissFeedback(BuildContext context) {
|
||||||
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||||
|
_overlayNotificationEntry?.dismiss();
|
||||||
|
_overlayNotificationEntry = null;
|
||||||
|
}
|
||||||
|
|
||||||
void showFeedback(BuildContext context, FeedbackType type, String message, [SnackBarAction? action]) {
|
void showFeedback(BuildContext context, FeedbackType type, String message, [SnackBarAction? action]) {
|
||||||
ScaffoldMessengerState? scaffoldMessenger;
|
ScaffoldMessengerState? scaffoldMessenger;
|
||||||
|
@ -67,8 +72,7 @@ mixin FeedbackMixin {
|
||||||
// and space under the snack bar `margin` does not receive gestures
|
// and space under the snack bar `margin` does not receive gestures
|
||||||
// (because it is used by the `Dismissible` wrapping the snack bar)
|
// (because it is used by the `Dismissible` wrapping the snack bar)
|
||||||
// so we use `showOverlayNotification` instead
|
// so we use `showOverlayNotification` instead
|
||||||
OverlaySupportEntry? notificationOverlayEntry;
|
_overlayNotificationEntry = showOverlayNotification(
|
||||||
notificationOverlayEntry = showOverlayNotification(
|
|
||||||
(context) => SafeArea(
|
(context) => SafeArea(
|
||||||
bottom: false,
|
bottom: false,
|
||||||
child: ValueListenableBuilder<MarginComputer?>(
|
child: ValueListenableBuilder<MarginComputer?>(
|
||||||
|
@ -89,7 +93,7 @@ mixin FeedbackMixin {
|
||||||
foregroundColor: WidgetStateProperty.all(snackBarTheme.actionTextColor),
|
foregroundColor: WidgetStateProperty.all(snackBarTheme.actionTextColor),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
notificationOverlayEntry?.dismiss();
|
dismissFeedback(context);
|
||||||
action.onPressed();
|
action.onPressed();
|
||||||
},
|
},
|
||||||
child: Text(action.label),
|
child: Text(action.label),
|
||||||
|
@ -97,7 +101,7 @@ mixin FeedbackMixin {
|
||||||
: null,
|
: null,
|
||||||
animation: kAlwaysCompleteAnimation,
|
animation: kAlwaysCompleteAnimation,
|
||||||
dismissDirection: DismissDirection.horizontal,
|
dismissDirection: DismissDirection.horizontal,
|
||||||
onDismiss: () => notificationOverlayEntry?.dismiss(),
|
onDismiss: () => dismissFeedback(context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -135,8 +135,8 @@ class _OverlaySnackBarState extends State<OverlaySnackBar> {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAnimationStatusChanged(AnimationStatus animationStatus) {
|
void _onAnimationStatusChanged(AnimationStatus status) {
|
||||||
if (animationStatus == AnimationStatus.completed) {
|
if (status.isCompleted) {
|
||||||
if (widget.onVisible != null && !_wasVisible) {
|
if (widget.onVisible != null && !_wasVisible) {
|
||||||
widget.onVisible!();
|
widget.onVisible!();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class AvesPopupMenuButton<T> extends PopupMenuButton<T> {
|
|
||||||
final VoidCallback? onMenuOpened;
|
|
||||||
|
|
||||||
const AvesPopupMenuButton({
|
|
||||||
super.key,
|
|
||||||
required super.itemBuilder,
|
|
||||||
super.initialValue,
|
|
||||||
super.onSelected,
|
|
||||||
super.onCanceled,
|
|
||||||
super.tooltip,
|
|
||||||
super.elevation,
|
|
||||||
super.padding = const EdgeInsets.all(8),
|
|
||||||
super.child,
|
|
||||||
super.icon,
|
|
||||||
super.offset = Offset.zero,
|
|
||||||
super.enabled = true,
|
|
||||||
super.shape,
|
|
||||||
super.color,
|
|
||||||
super.enableFeedback,
|
|
||||||
super.iconSize,
|
|
||||||
this.onMenuOpened,
|
|
||||||
super.popUpAnimationStyle,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
PopupMenuButtonState<T> createState() => _AvesPopupMenuButtonState<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AvesPopupMenuButtonState<T> extends PopupMenuButtonState<T> {
|
|
||||||
@override
|
|
||||||
void showButtonMenu() {
|
|
||||||
(widget as AvesPopupMenuButton).onMenuOpened?.call();
|
|
||||||
super.showButtonMenu();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,6 +10,8 @@ class MenuRow extends StatelessWidget {
|
||||||
this.icon,
|
this.icon,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static const leadingPadding = EdgeInsetsDirectional.only(end: 12);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
|
@ -17,7 +19,7 @@ class MenuRow extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
if (icon != null)
|
if (icon != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsetsDirectional.only(end: 12),
|
padding: leadingPadding,
|
||||||
child: IconTheme.merge(
|
child: IconTheme.merge(
|
||||||
data: IconThemeData(
|
data: IconThemeData(
|
||||||
color: ListTileTheme.of(context).iconColor,
|
color: ListTileTheme.of(context).iconColor,
|
||||||
|
|
|
@ -17,7 +17,7 @@ class AvesPopScope extends StatelessWidget {
|
||||||
final blocker = handlers.firstWhereOrNull((v) => !v.canPop(context));
|
final blocker = handlers.firstWhereOrNull((v) => !v.canPop(context));
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: blocker == null,
|
canPop: blocker == null,
|
||||||
onPopInvoked: (didPop) {
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
if (!didPop) {
|
if (!didPop) {
|
||||||
blocker?.onPopBlocked(context);
|
blocker?.onPopBlocked(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ class TitledExpandableFilterRow extends StatelessWidget {
|
||||||
final ValueNotifier<String?> expandedNotifier;
|
final ValueNotifier<String?> expandedNotifier;
|
||||||
final bool showGenericIcon;
|
final bool showGenericIcon;
|
||||||
final HeroType Function(CollectionFilter filter)? heroTypeBuilder;
|
final HeroType Function(CollectionFilter filter)? heroTypeBuilder;
|
||||||
final FilterCallback onTap;
|
final AFilterCallback onTap;
|
||||||
final OffsetFilterCallback? onLongPress;
|
final OffsetFilterCallback? onLongPress;
|
||||||
|
|
||||||
const TitledExpandableFilterRow({
|
const TitledExpandableFilterRow({
|
||||||
|
@ -96,8 +96,8 @@ class ExpandableFilterRow extends StatelessWidget {
|
||||||
final bool showGenericIcon;
|
final bool showGenericIcon;
|
||||||
final Widget? Function(CollectionFilter)? leadingBuilder;
|
final Widget? Function(CollectionFilter)? leadingBuilder;
|
||||||
final HeroType Function(CollectionFilter filter)? heroTypeBuilder;
|
final HeroType Function(CollectionFilter filter)? heroTypeBuilder;
|
||||||
final FilterCallback onTap;
|
final AFilterCallback onTap;
|
||||||
final FilterCallback? onRemove;
|
final AFilterCallback? onRemove;
|
||||||
final OffsetFilterCallback? onLongPress;
|
final OffsetFilterCallback? onLongPress;
|
||||||
|
|
||||||
static const double horizontalPadding = 8;
|
static const double horizontalPadding = 8;
|
||||||
|
|
|
@ -105,7 +105,7 @@ class _SweeperState extends State<Sweeper> with SingleTickerProviderStateMixin {
|
||||||
|
|
||||||
void _onAnimationStatusChanged(AnimationStatus status) {
|
void _onAnimationStatusChanged(AnimationStatus status) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
if (status == AnimationStatus.completed) {
|
if (status.isCompleted) {
|
||||||
widget.onSweepEnd?.call();
|
widget.onSweepEnd?.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,6 +189,7 @@ class _SectionSelectableLeading<T> extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (!selectable) return _buildBrowsing(context);
|
if (!selectable) return _buildBrowsing(context);
|
||||||
|
|
||||||
|
final duration = context.select<DurationsData, Duration>((v) => v.formTransition);
|
||||||
final isSelecting = context.select<Selection<T>, bool>((selection) => selection.isSelecting);
|
final isSelecting = context.select<Selection<T>, bool>((selection) => selection.isSelecting);
|
||||||
final Widget child = isSelecting
|
final Widget child = isSelecting
|
||||||
? _SectionSelectingLeading<T>(
|
? _SectionSelectingLeading<T>(
|
||||||
|
@ -201,7 +202,7 @@ class _SectionSelectableLeading<T> extends StatelessWidget {
|
||||||
descendantsAreFocusable: false,
|
descendantsAreFocusable: false,
|
||||||
descendantsAreTraversable: false,
|
descendantsAreTraversable: false,
|
||||||
child: AnimatedSwitcher(
|
child: AnimatedSwitcher(
|
||||||
duration: ADurations.sectionHeaderAnimation,
|
duration: duration,
|
||||||
switchInCurve: Curves.easeInOut,
|
switchInCurve: Curves.easeInOut,
|
||||||
switchOutCurve: Curves.easeInOut,
|
switchOutCurve: Curves.easeInOut,
|
||||||
transitionBuilder: (child, animation) {
|
transitionBuilder: (child, animation) {
|
||||||
|
@ -240,11 +241,12 @@ class _SectionSelectingLeading<T> extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final duration = context.select<DurationsData, Duration>((v) => v.formTransition);
|
||||||
final sectionEntries = context.watch<SectionedListLayout<T>>().sections[sectionKey] ?? [];
|
final sectionEntries = context.watch<SectionedListLayout<T>>().sections[sectionKey] ?? [];
|
||||||
final selection = context.watch<Selection<T>>();
|
final selection = context.watch<Selection<T>>();
|
||||||
final isSelected = selection.isSelected(sectionEntries);
|
final isSelected = selection.isSelected(sectionEntries);
|
||||||
return AnimatedSwitcher(
|
return AnimatedSwitcher(
|
||||||
duration: ADurations.sectionHeaderAnimation,
|
duration: duration,
|
||||||
switchInCurve: Curves.easeOutBack,
|
switchInCurve: Curves.easeOutBack,
|
||||||
switchOutCurve: Curves.easeOutBack,
|
switchOutCurve: Curves.easeOutBack,
|
||||||
transitionBuilder: (child, animation) => ScaleTransition(
|
transitionBuilder: (child, animation) => ScaleTransition(
|
||||||
|
|
|
@ -10,8 +10,6 @@ class GridItemSelectionOverlay<T> extends StatelessWidget {
|
||||||
final BorderRadius? borderRadius;
|
final BorderRadius? borderRadius;
|
||||||
final EdgeInsets? padding;
|
final EdgeInsets? padding;
|
||||||
|
|
||||||
static const duration = ADurations.thumbnailOverlayAnimation;
|
|
||||||
|
|
||||||
const GridItemSelectionOverlay({
|
const GridItemSelectionOverlay({
|
||||||
super.key,
|
super.key,
|
||||||
required this.item,
|
required this.item,
|
||||||
|
@ -21,6 +19,7 @@ class GridItemSelectionOverlay<T> extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final duration = context.select<DurationsData, Duration>((v) => v.formTransition);
|
||||||
final isSelecting = context.select<Selection<T>, bool>((selection) => selection.isSelecting);
|
final isSelecting = context.select<Selection<T>, bool>((selection) => selection.isSelecting);
|
||||||
return AnimatedSwitcher(
|
return AnimatedSwitcher(
|
||||||
duration: duration,
|
duration: duration,
|
||||||
|
|
|
@ -55,9 +55,9 @@ class _GridSelectionGestureDetectorState<T> extends State<GridSelectionGestureDe
|
||||||
return scrollableBox.size.width;
|
return scrollableBox.size.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const double scrollEdgeRatio = .15;
|
static const double _scrollEdgeRatio = .15;
|
||||||
static const double scrollMaxPixelPerSecond = 600.0;
|
static const double _scrollMaxPixelPerSecond = 600.0;
|
||||||
static const Duration scrollUpdateInterval = Duration(milliseconds: 100);
|
static const Duration _scrollUpdateInterval = Duration(milliseconds: 100);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -158,7 +158,7 @@ class _GridSelectionGestureDetectorState<T> extends State<GridSelectionGestureDe
|
||||||
final top = dy < height / 2;
|
final top = dy < height / 2;
|
||||||
|
|
||||||
final distanceToEdge = max(0, top ? dy - _scrollableInsets.top : height - dy - _scrollableInsets.bottom);
|
final distanceToEdge = max(0, top ? dy - _scrollableInsets.top : height - dy - _scrollableInsets.bottom);
|
||||||
final threshold = height * scrollEdgeRatio;
|
final threshold = height * _scrollEdgeRatio;
|
||||||
if (distanceToEdge < threshold) {
|
if (distanceToEdge < threshold) {
|
||||||
_setScrollSpeed((top ? -1 : 1) * roundToPrecision((threshold - distanceToEdge) / threshold, decimals: 1));
|
_setScrollSpeed((top ? -1 : 1) * roundToPrecision((threshold - distanceToEdge) / threshold, decimals: 1));
|
||||||
} else {
|
} else {
|
||||||
|
@ -185,7 +185,7 @@ class _GridSelectionGestureDetectorState<T> extends State<GridSelectionGestureDe
|
||||||
final target = speedFactor > 0 ? scrollController.position.maxScrollExtent : .0;
|
final target = speedFactor > 0 ? scrollController.position.maxScrollExtent : .0;
|
||||||
if (target != current) {
|
if (target != current) {
|
||||||
final distance = target - current;
|
final distance = target - current;
|
||||||
final millis = distance * 1000 / scrollMaxPixelPerSecond / speedFactor;
|
final millis = distance * 1000 / _scrollMaxPixelPerSecond / speedFactor;
|
||||||
scrollController.animateTo(
|
scrollController.animateTo(
|
||||||
target,
|
target,
|
||||||
duration: Duration(milliseconds: millis.round()),
|
duration: Duration(milliseconds: millis.round()),
|
||||||
|
@ -193,7 +193,7 @@ class _GridSelectionGestureDetectorState<T> extends State<GridSelectionGestureDe
|
||||||
);
|
);
|
||||||
// use a timer to update the selection, because `onLongPressMoveUpdate`
|
// use a timer to update the selection, because `onLongPressMoveUpdate`
|
||||||
// is not called when the pointer stays still while the view is scrolling
|
// is not called when the pointer stays still while the view is scrolling
|
||||||
_selectionUpdateTimer = Timer.periodic(scrollUpdateInterval, (_) => _onLongPressUpdate());
|
_selectionUpdateTimer = Timer.periodic(_scrollUpdateInterval, (_) => _onLongPressUpdate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,50 @@ class AvesAppBar extends StatelessWidget {
|
||||||
final colorScheme = theme.colorScheme;
|
final colorScheme = theme.colorScheme;
|
||||||
final textScaler = MediaQuery.textScalerOf(context);
|
final textScaler = MediaQuery.textScalerOf(context);
|
||||||
final useTvLayout = settings.useTvLayout;
|
final useTvLayout = settings.useTvLayout;
|
||||||
|
|
||||||
|
Widget? _leading = leading;
|
||||||
|
if (_leading != null) {
|
||||||
|
_leading = FontSizeIconTheme(
|
||||||
|
child: _leading,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _title = FontSizeIconTheme(
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
return Row(
|
||||||
|
key: ValueKey(transitionKey),
|
||||||
|
children: [
|
||||||
|
Expanded(child: title),
|
||||||
|
...(actions(context, max(0, constraints.maxWidth - _titleMinWidth))),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final animate = context.select<Settings, bool>((v) => v.animate);
|
||||||
|
if (animate) {
|
||||||
|
_title = Hero(
|
||||||
|
tag: titleHeroTag,
|
||||||
|
flightShuttleBuilder: _flightShuttleBuilder,
|
||||||
|
transitionOnUserGestures: true,
|
||||||
|
child: AnimatedSwitcher(
|
||||||
|
duration: context.read<DurationsData>().iconAnimation,
|
||||||
|
child: _title,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (_leading != null) {
|
||||||
|
_leading = Hero(
|
||||||
|
tag: leadingHeroTag,
|
||||||
|
flightShuttleBuilder: _flightShuttleBuilder,
|
||||||
|
transitionOnUserGestures: true,
|
||||||
|
child: _leading,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SliverPersistentHeader(
|
return SliverPersistentHeader(
|
||||||
floating: !useTvLayout,
|
floating: !useTvLayout,
|
||||||
pinned: pinned,
|
pinned: pinned,
|
||||||
|
@ -70,43 +114,16 @@ class AvesAppBar extends StatelessWidget {
|
||||||
height: textScaler.scale(kToolbarHeight),
|
height: textScaler.scale(kToolbarHeight),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
leading != null
|
_leading != null
|
||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
child: Hero(
|
child: _leading,
|
||||||
tag: leadingHeroTag,
|
|
||||||
flightShuttleBuilder: _flightShuttleBuilder,
|
|
||||||
transitionOnUserGestures: true,
|
|
||||||
child: FontSizeIconTheme(
|
|
||||||
child: leading!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const SizedBox(width: 16),
|
: const SizedBox(width: 16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultTextStyle(
|
child: DefaultTextStyle(
|
||||||
style: theme.appBarTheme.titleTextStyle!,
|
style: theme.appBarTheme.titleTextStyle!,
|
||||||
child: Hero(
|
child: _title,
|
||||||
tag: titleHeroTag,
|
|
||||||
flightShuttleBuilder: _flightShuttleBuilder,
|
|
||||||
transitionOnUserGestures: true,
|
|
||||||
child: AnimatedSwitcher(
|
|
||||||
duration: context.read<DurationsData>().iconAnimation,
|
|
||||||
child: FontSizeIconTheme(
|
|
||||||
child: LayoutBuilder(
|
|
||||||
builder: (context, constraints) {
|
|
||||||
return Row(
|
|
||||||
key: ValueKey(transitionKey),
|
|
||||||
children: [
|
|
||||||
Expanded(child: title),
|
|
||||||
...(actions(context, max(0, constraints.maxWidth - _titleMinWidth))),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -26,7 +26,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
typedef FilterCallback = void Function(CollectionFilter filter);
|
typedef AFilterCallback = void Function(CollectionFilter filter);
|
||||||
typedef OffsetFilterCallback = void Function(BuildContext context, CollectionFilter filter, Offset tapPosition);
|
typedef OffsetFilterCallback = void Function(BuildContext context, CollectionFilter filter, Offset tapPosition);
|
||||||
|
|
||||||
enum HeroType { always, onTap, never }
|
enum HeroType { always, onTap, never }
|
||||||
|
@ -56,9 +56,10 @@ class AvesFilterChip extends StatefulWidget {
|
||||||
final double padding;
|
final double padding;
|
||||||
final double? maxWidth;
|
final double? maxWidth;
|
||||||
final HeroType heroType;
|
final HeroType heroType;
|
||||||
final FilterCallback? onTap, onRemove;
|
final AFilterCallback? onTap, onRemove;
|
||||||
final OffsetFilterCallback? onLongPress;
|
final OffsetFilterCallback? onLongPress;
|
||||||
|
|
||||||
|
static const double defaultPadding = 6.0;
|
||||||
static const double defaultRadius = 32;
|
static const double defaultRadius = 32;
|
||||||
static const double outlineWidth = 2;
|
static const double outlineWidth = 2;
|
||||||
static const double minChipHeight = kMinInteractiveDimension;
|
static const double minChipHeight = kMinInteractiveDimension;
|
||||||
|
@ -79,7 +80,7 @@ class AvesFilterChip extends StatefulWidget {
|
||||||
this.banner,
|
this.banner,
|
||||||
this.leadingOverride,
|
this.leadingOverride,
|
||||||
this.details,
|
this.details,
|
||||||
this.padding = 6.0,
|
this.padding = defaultPadding,
|
||||||
this.maxWidth,
|
this.maxWidth,
|
||||||
this.heroType = HeroType.onTap,
|
this.heroType = HeroType.onTap,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
|
@ -87,7 +88,7 @@ class AvesFilterChip extends StatefulWidget {
|
||||||
this.onLongPress = showDefaultLongPressMenu,
|
this.onLongPress = showDefaultLongPressMenu,
|
||||||
});
|
});
|
||||||
|
|
||||||
static double computeMaxWidth(
|
static double computeMaxWidthForRow(
|
||||||
BuildContext context, {
|
BuildContext context, {
|
||||||
required int minChipPerRow,
|
required int minChipPerRow,
|
||||||
required double chipPadding,
|
required double chipPadding,
|
||||||
|
@ -347,7 +348,7 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
|
||||||
maxWidth: max(
|
maxWidth: max(
|
||||||
AvesFilterChip.minChipWidth,
|
AvesFilterChip.minChipWidth,
|
||||||
widget.maxWidth ??
|
widget.maxWidth ??
|
||||||
AvesFilterChip.computeMaxWidth(
|
AvesFilterChip.computeMaxWidthForRow(
|
||||||
context,
|
context,
|
||||||
minChipPerRow: 2,
|
minChipPerRow: 2,
|
||||||
chipPadding: FilterBar.chipPadding.horizontal,
|
chipPadding: FilterBar.chipPadding.horizontal,
|
||||||
|
|
|
@ -124,7 +124,13 @@ class MapButtonPanel extends StatelessWidget {
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: padding),
|
padding: EdgeInsets.only(top: padding),
|
||||||
// key is expected by test driver
|
// key is expected by test driver
|
||||||
child: _buildButton(context, MapAction.selectStyle, buttonKey: const Key('map-menu-layers')),
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildButton(context, MapAction.selectStyle, buttonKey: const Key('map-menu-layers')),
|
||||||
|
SizedBox(height: padding),
|
||||||
|
_buildButton(context, MapAction.openMapApp),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue