Merge branch 'develop'

This commit is contained in:
Thibault Deckers 2024-10-09 00:10:04 +02:00
commit 35aeefe34b
201 changed files with 1949 additions and 1286 deletions

View file

@ -22,6 +22,6 @@ jobs:
egress-policy: audit
- name: 'Checkout Repository'
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- name: 'Dependency Review'
uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4

View file

@ -23,7 +23,7 @@ jobs:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- name: Get Flutter packages
run: scripts/pub_get_all.sh
@ -59,17 +59,17 @@ jobs:
# Building relies on the Android Gradle plugin,
# which requires a modern Java version (not the default one).
- name: Set up JDK for Android Gradle plugin
uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4.3.0
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
with:
distribution: 'temurin'
java-version: '21'
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7
uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@ -83,6 +83,6 @@ jobs:
./flutterw build apk --profile -t lib/main_play.dart --flavor play
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7
uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
with:
category: "/language:${{matrix.language}}"

View file

@ -23,13 +23,13 @@ jobs:
# Building relies on the Android Gradle plugin,
# which requires a modern Java version (not the default one).
- name: Set up JDK for Android Gradle plugin
uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4.3.0
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
with:
distribution: 'temurin'
java-version: '21'
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- name: Get Flutter packages
run: scripts/pub_get_all.sh
@ -80,7 +80,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload app bundle
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1
with:
name: appbundle
path: outputs/app-play-release.aab
@ -96,7 +96,7 @@ jobs:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- name: Get appbundle from artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8

View file

@ -36,7 +36,7 @@ jobs:
egress-policy: audit
- name: "Checkout code"
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
with:
persist-credentials: false
@ -63,7 +63,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1
with:
name: SARIF file
path: results.sarif
@ -71,6 +71,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7
uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
with:
sarif_file: results.sarif

View file

@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
## <a id="unreleased"></a>[Unreleased]
## <a id="v1.11.14"></a>[v1.11.14] - 2024-10-09
### Added
- Map: OpenTopoMap raster layer
- Map: OSM Liberty vector layer (hosted by OSM Americana)
- Interoperability: receiving `geo:` URI generally opens map page at location
- Interoperability: receiving `geo:` URI when editing item location fills in coordinates
- Map basic app shortcut
- Enterprise: support for work profile switching from the drawer
- Settings: hidden path filters are merged with others and can be toggled
### Removed
- `Safe mode` basic app shortcut
### Fixed
- hanging when cataloguing some JPEG MPF images
- Apple HDR image detection
## <a id="v1.11.13"></a>[v1.11.13] - 2024-09-17
### Added
@ -1126,6 +1147,7 @@ All notable changes to this project will be documented in this file.
- app launching on some devices
- corrupting motion photo exif editing (e.g. rotation)
- accessing files in `Download` directory when not using reference case
## [v1.4.9] - 2021-08-20

View file

@ -36,3 +36,8 @@ linter:
prefer_single_quotes: true
sort_child_properties_last: true
unawaited_futures: true
# `const` related, included
prefer_const_constructors: true
prefer_const_literals_to_create_immutables: true
prefer_const_declarations: true

View file

@ -10,18 +10,6 @@ plugins {
def packageName = "deckers.thibault.aves"
// Flutter properties
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
def flutterVersionName = localProperties.getProperty('flutter.versionName')
// Keys
def keystoreProperties = new Properties()
@ -53,22 +41,12 @@ android {
targetCompatibility JavaVersion.VERSION_21
}
lint {
checkAllWarnings true
warningsAsErrors true
disable 'InvalidPackage'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
applicationId packageName
minSdk flutter.minSdkVersion
targetSdk 35
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
versionCode flutter.versionCode
versionName flutter.versionName
manifestPlaceholders = [googleApiKey: keystoreProperties["googleApiKey"] ?: "<NONE>"]
multiDexEnabled true
}
@ -189,7 +167,7 @@ dependencies {
implementation "androidx.appcompat:appcompat:1.7.0"
implementation 'androidx.core:core-ktx:1.13.1'
implementation 'androidx.lifecycle:lifecycle-process:2.8.5'
implementation 'androidx.lifecycle:lifecycle-process:2.8.6'
implementation 'androidx.media:media:1.7.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.security:security-crypto:1.1.0-alpha06'

View file

@ -39,6 +39,10 @@
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROCESSING"
tools:ignore="SystemPermissionTypo" />
<!-- to switch between regular and work profiles -->
<uses-permission
android:name="android.permission.INTERACT_ACROSS_PROFILES"
tools:ignore="ProtectedPermissions" />
<!-- TODO TLAD still needed to fetch map tiles / reverse geocoding / else ? check in release mode -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- from Android 12 (API 31), users can optionally grant access to the media management special permission -->
@ -179,6 +183,13 @@
<data android:scheme="content" />
<data android:scheme="file" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="geo" />
</intent-filter>
<!--
<intent-filter>
<action android:name="android.intent.action.EDIT" />

View file

@ -1,6 +1,7 @@
package deckers.thibault.aves
import android.annotation.SuppressLint
import android.app.KeyguardManager
import android.app.SearchManager
import android.appwidget.AppWidgetManager
import android.content.ClipData
@ -23,6 +24,7 @@ import deckers.thibault.aves.channel.AvesByteSendingMethodCodec
import deckers.thibault.aves.channel.calls.AccessibilityHandler
import deckers.thibault.aves.channel.calls.AnalysisHandler
import deckers.thibault.aves.channel.calls.AppAdapterHandler
import deckers.thibault.aves.channel.calls.AppProfileHandler
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.channel.calls.DebugHandler
import deckers.thibault.aves.channel.calls.DeviceHandler
@ -142,6 +144,7 @@ open class MainActivity : FlutterFragmentActivity() {
MethodChannel(messenger, MetadataEditHandler.CHANNEL).setMethodCallHandler(MetadataEditHandler(this))
MethodChannel(messenger, WallpaperHandler.CHANNEL).setMethodCallHandler(WallpaperHandler(this))
// - need Activity
MethodChannel(messenger, AppProfileHandler.CHANNEL).setMethodCallHandler(AppProfileHandler(this))
MethodChannel(messenger, WindowHandler.CHANNEL).setMethodCallHandler(ActivityWindowHandler(this))
// result streaming: dart -> platform ->->-> dart
@ -293,14 +296,11 @@ open class MainActivity : FlutterFragmentActivity() {
open fun extractIntentData(intent: Intent?): FieldMap {
when (val action = intent?.action) {
Intent.ACTION_MAIN -> {
val fields = HashMap<String, Any?>()
if (intent.getBooleanExtra(EXTRA_KEY_SAFE_MODE, false)) {
fields[INTENT_DATA_KEY_SAFE_MODE] = true
}
fields[INTENT_DATA_KEY_PAGE] = intent.getStringExtra(EXTRA_KEY_PAGE)
fields[INTENT_DATA_KEY_FILTERS] = extractFiltersFromIntent(intent)
fields[INTENT_DATA_KEY_EXPLORER_PATH] = intent.getStringExtra(EXTRA_KEY_EXPLORER_PATH)
return fields
return hashMapOf(
INTENT_DATA_KEY_PAGE to intent.getStringExtra(EXTRA_KEY_PAGE),
INTENT_DATA_KEY_FILTERS to extractFiltersFromIntent(intent),
INTENT_DATA_KEY_EXPLORER_PATH to intent.getStringExtra(EXTRA_KEY_EXPLORER_PATH),
)
}
Intent.ACTION_VIEW,
@ -310,6 +310,13 @@ open class MainActivity : FlutterFragmentActivity() {
"com.android.camera.action.REVIEW",
"com.android.camera.action.SPLIT_SCREEN_REVIEW" -> {
(intent.data ?: intent.getParcelableExtraCompat<Uri>(Intent.EXTRA_STREAM))?.let { uri ->
if (uri.scheme == "geo") {
return hashMapOf(
INTENT_DATA_KEY_ACTION to INTENT_ACTION_VIEW_GEO,
INTENT_DATA_KEY_URI to uri.toString(),
)
}
// MIME type is optional
val type = intent.type ?: intent.resolveType(this)
val fields = hashMapOf<String, Any?>(
@ -318,7 +325,7 @@ open class MainActivity : FlutterFragmentActivity() {
INTENT_DATA_KEY_URI to uri.toString(),
)
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as android.app.KeyguardManager
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val isLocked = keyguardManager.isKeyguardLocked
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(isLocked)
@ -427,7 +434,7 @@ open class MainActivity : FlutterFragmentActivity() {
val pickedUris = call.argument<List<String>>("uris")
try {
if (!pickedUris.isNullOrEmpty()) {
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this, Uri.parse(uriString)) }
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this@MainActivity, Uri.parse(uriString)) }
val intent = Intent().apply {
val firstUri = toUri(pickedUris.first())
if (pickedUris.size == 1) {
@ -445,7 +452,8 @@ open class MainActivity : FlutterFragmentActivity() {
} else {
setResult(RESULT_CANCELED)
}
finish()
// move code triggering `Binder` call off the main thread
defaultScope.launch { finish() }
} catch (e: Exception) {
if (e is TransactionTooLargeException || e.cause is TransactionTooLargeException) {
result.error("submitPickedItems-large", "transaction too large with ${pickedUris?.size} URIs", e)
@ -481,7 +489,16 @@ open class MainActivity : FlutterFragmentActivity() {
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_search else R.drawable.ic_shortcut_search))
.setIntent(
Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java)
.putExtra(EXTRA_KEY_PAGE, "/search")
.putExtra(EXTRA_KEY_PAGE, SEARCH_PAGE_ROUTE_NAME)
)
.build()
val map = ShortcutInfoCompat.Builder(this, "map")
.setShortLabel(getString(R.string.map_shortcut_short_label))
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_map else R.drawable.ic_shortcut_map))
.setIntent(
Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java)
.putExtra(EXTRA_KEY_PAGE, MAP_PAGE_ROUTE_NAME)
)
.build()
@ -490,21 +507,12 @@ open class MainActivity : FlutterFragmentActivity() {
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_movie else R.drawable.ic_shortcut_movie))
.setIntent(
Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java)
.putExtra(EXTRA_KEY_PAGE, "/collection")
.putExtra(EXTRA_KEY_PAGE, COLLECTION_PAGE_ROUTE_NAME)
.putExtra("filters", arrayOf("{\"type\":\"mime\",\"mime\":\"video/*\"}"))
)
.build()
val safeMode = ShortcutInfoCompat.Builder(this, "safeMode")
.setShortLabel(getString(R.string.safe_mode_shortcut_short_label))
.setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_safe_mode else R.drawable.ic_shortcut_safe_mode))
.setIntent(
Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java)
.putExtra(EXTRA_KEY_SAFE_MODE, true)
)
.build()
val shortcutInfoList = listOf(videos, search, safeMode)
val shortcutInfoList = listOf(videos, search, map)
ShortcutManagerCompat.setDynamicShortcuts(this, shortcutInfoList)
Log.i(LOG_TAG, "set shortcuts: ${shortcutInfoList.joinToString(", ") { v -> v.id }}")
}
@ -534,6 +542,7 @@ open class MainActivity : FlutterFragmentActivity() {
const val INTENT_ACTION_SEARCH = "search"
const val INTENT_ACTION_SET_WALLPAPER = "set_wallpaper"
const val INTENT_ACTION_VIEW = "view"
const val INTENT_ACTION_VIEW_GEO = "view_geo"
const val INTENT_ACTION_WIDGET_OPEN = "widget_open"
const val INTENT_ACTION_WIDGET_SETTINGS = "widget_settings"
@ -545,7 +554,6 @@ open class MainActivity : FlutterFragmentActivity() {
const val INTENT_DATA_KEY_MIME_TYPE = "mimeType"
const val INTENT_DATA_KEY_PAGE = "page"
const val INTENT_DATA_KEY_QUERY = "query"
const val INTENT_DATA_KEY_SAFE_MODE = "safeMode"
const val INTENT_DATA_KEY_SECURE_URIS = "secureUris"
const val INTENT_DATA_KEY_URI = "uri"
const val INTENT_DATA_KEY_WIDGET_ID = "widgetId"
@ -554,9 +562,13 @@ open class MainActivity : FlutterFragmentActivity() {
const val EXTRA_KEY_EXPLORER_PATH = "explorerPath"
const val EXTRA_KEY_FILTERS_ARRAY = "filters"
const val EXTRA_KEY_FILTERS_STRING = "filtersString"
const val EXTRA_KEY_SAFE_MODE = "safeMode"
const val EXTRA_KEY_WIDGET_ID = "widgetId"
// dart page routes
const val COLLECTION_PAGE_ROUTE_NAME = "/collection"
const val MAP_PAGE_ROUTE_NAME = "/map"
const val SEARCH_PAGE_ROUTE_NAME = "/search"
// request code to pending runnable
val pendingStorageAccessResultHandlers = ConcurrentHashMap<Int, PendingStorageAccessResultHandler>()

View file

@ -1,6 +1,10 @@
package deckers.thibault.aves.channel.calls
import android.content.*
import android.content.ClipData
import android.content.ClipboardManager
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.res.Configuration
import android.content.res.Resources
@ -42,7 +46,8 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.util.*
import java.util.Locale
import java.util.UUID
import kotlin.math.roundToInt
class AppAdapterHandler(private val context: Context) : MethodCallHandler {

View file

@ -0,0 +1,97 @@
package deckers.thibault.aves.channel.calls
import android.app.Activity
import android.content.Context
import android.content.pm.CrossProfileApps
import android.os.Build
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
class AppProfileHandler(private val activity: Activity) : MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"canInteractAcrossProfiles" -> safe(call, result, ::canInteractAcrossProfiles)
"canRequestInteractAcrossProfiles" -> safe(call, result, ::canRequestInteractAcrossProfiles)
"requestInteractAcrossProfiles" -> safe(call, result, ::requestInteractAcrossProfiles)
"switchProfile" -> safe(call, result, ::switchProfile)
"getProfileSwitchingLabel" -> safe(call, result, ::getProfileSwitchingLabel)
"getTargetUserProfiles" -> safe(call, result, ::getTargetUserProfiles)
else -> result.notImplemented()
}
}
private fun canInteractAcrossProfiles(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
result.success(false)
return
}
val crossProfileApps = activity.getSystemService(Context.CROSS_PROFILE_APPS_SERVICE) as CrossProfileApps
result.success(crossProfileApps.canInteractAcrossProfiles())
}
private fun canRequestInteractAcrossProfiles(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
result.success(false)
return
}
val crossProfileApps = activity.getSystemService(Context.CROSS_PROFILE_APPS_SERVICE) as CrossProfileApps
result.success(crossProfileApps.canRequestInteractAcrossProfiles())
}
private fun requestInteractAcrossProfiles(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
result.success(false)
return
}
val crossProfileApps = activity.getSystemService(Context.CROSS_PROFILE_APPS_SERVICE) as CrossProfileApps
val intent = crossProfileApps.createRequestInteractAcrossProfilesIntent()
val started = activity.startActivity(intent)
result.success(started)
}
private fun switchProfile(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
result.success(false)
return
}
val crossProfileApps = activity.getSystemService(Context.CROSS_PROFILE_APPS_SERVICE) as CrossProfileApps
val userHandles = crossProfileApps.targetUserProfiles
crossProfileApps.startMainActivity(activity.componentName, userHandles.first())
result.success(null)
}
private fun getProfileSwitchingLabel(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
result.success(null)
return
}
val crossProfileApps = activity.getSystemService(Context.CROSS_PROFILE_APPS_SERVICE) as CrossProfileApps
val userHandles = crossProfileApps.targetUserProfiles
val label = if (userHandles.isEmpty()) "" else crossProfileApps.getProfileSwitchingLabel(userHandles.first())
result.success(label)
}
private fun getTargetUserProfiles(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
result.success(false)
return
}
val crossProfileApps = activity.getSystemService(Context.CROSS_PROFILE_APPS_SERVICE) as CrossProfileApps
val userProfiles = crossProfileApps.targetUserProfiles.map { it.toString() }.toList()
result.success(userProfiles)
}
companion object {
const val CHANNEL = "deckers.thibault/aves/app_profile"
}
}

View file

@ -6,7 +6,6 @@ import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.Build
import android.util.Log
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
import com.adobe.internal.xmp.XMPException
import com.adobe.internal.xmp.XMPMeta
import com.adobe.internal.xmp.XMPMetaFactory
@ -20,7 +19,6 @@ import com.drew.metadata.exif.ExifDirectoryBase
import com.drew.metadata.exif.ExifIFD0Directory
import com.drew.metadata.exif.ExifSubIFDDirectory
import com.drew.metadata.exif.GpsDirectory
import com.drew.metadata.exif.makernotes.AppleMakernoteDirectory
import com.drew.metadata.file.FileTypeDirectory
import com.drew.metadata.gif.GifAnimationDirectory
import com.drew.metadata.iptc.IptcDirectory
@ -108,6 +106,7 @@ import java.text.ParseException
import java.util.Locale
import kotlin.math.roundToInt
import kotlin.math.roundToLong
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
@ -164,9 +163,11 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
}
// remove this stat as it is not actual XMP data
dirMap.remove(XmpDirectory().getTagName(XmpDirectory.TAG_XMP_VALUE_COUNT))
// add schema prefixes for namespace resolution
val prefixes = XMPMetaFactory.getSchemaRegistry().prefixes
dirMap["schemaRegistryPrefixes"] = JSONObject(prefixes).toString()
if (dirMap.isNotEmpty()) {
// add schema prefixes for namespace resolution
val prefixes = XMPMetaFactory.getSchemaRegistry().prefixes
dirMap["schemaRegistryPrefixes"] = JSONObject(prefixes).toString()
}
}
val mp4UuidDirCount = HashMap<String, Int>()
@ -660,7 +661,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
if (metadata.getDirectoriesOfType(MpEntryDirectory::class.java).count { !it.entry.isThumbnail } > 1) {
flags = flags or MASK_IS_MULTIPAGE
if (hasAppleHdrGainMap(uri, sizeBytes, metadata)) {
if (hasAppleHdrGainMap(uri, sizeBytes)) {
flags = flags or MASK_IS_HDR
}
}
@ -789,9 +790,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
metadataMap[KEY_FLAGS] = flags
}
private fun hasAppleHdrGainMap(uri: Uri, sizeBytes: Long?, primaryMetadata: com.drew.metadata.Metadata): Boolean {
if (!primaryMetadata.containsDirectoryOfType(AppleMakernoteDirectory::class.java)) return false
private fun hasAppleHdrGainMap(uri: Uri, sizeBytes: Long?): Boolean {
val mpEntries = MultiPage.getJpegMpfEntries(context, uri, sizeBytes) ?: return false
mpEntries.filter { it.type == MpEntry.TYPE_UNDEFINED }.forEach { mpEntry ->
var dataOffset = mpEntry.dataOffset

View file

@ -21,15 +21,11 @@ class MediaStoreStreamHandler(private val context: Context, arguments: Any?) : E
private var knownEntries: Map<Long?, Int?>? = null
private var directory: String? = null
private var safe: Boolean = false
init {
if (arguments is Map<*, *>) {
knownEntries = (arguments["knownEntries"] as? Map<*, *>?)?.map { (it.key as Number?)?.toLong() to it.value as Int? }?.toMap()
directory = arguments["directory"] as String?
// do not use kotlin.collections `getOrDefault` as it crashes on API <24
// and there is no warning from Android Studio
safe = arguments["safe"] as Boolean? ?: false
}
}
@ -63,7 +59,7 @@ class MediaStoreStreamHandler(private val context: Context, arguments: Any?) : E
}
private fun fetchAll() {
MediaStoreImageProvider().fetchAll(context, knownEntries ?: emptyMap(), directory, safe) { success(it) }
MediaStoreImageProvider().fetchAll(context, knownEntries ?: emptyMap(), directory) { success(it) }
endOfStream()
}

View file

@ -2,8 +2,9 @@ package deckers.thibault.aves.metadata
import android.content.Context
import android.net.Uri
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
import android.util.Log
import deckers.thibault.aves.utils.FileUtils.transferFrom
import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.MimeTypes
import deckers.thibault.aves.utils.StorageUtils
import java.io.File
@ -14,8 +15,11 @@ import java.util.Date
import java.util.Locale
import java.util.TimeZone
import java.util.regex.Pattern
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
object Metadata {
private val LOG_TAG = LogUtils.createTag<Metadata>()
const val IPTC_MARKER_BYTE: Byte = 0x1c
// Pattern to extract latitude & longitude from a video location tag (cf ISO 6709)
@ -135,29 +139,42 @@ object Metadata {
private fun getSafeUri(context: Context, uri: Uri, mimeType: String, sizeBytes: Long?): Uri {
// formats known to yield OOM for large files
return if ((MimeTypes.isImage(mimeType) || mimeType == MimeTypes.MP4)) {
if (isDangerouslyLarge(sizeBytes)) {
// make a preview from the beginning of the file,
// hoping the metadata is accessible in the copied chunk
var previewFile = previewFiles[uri]
if (previewFile == null) {
previewFile = createPreviewFile(context, uri)
previewFiles[uri] = previewFile
return when (mimeType) {
// formats known to yield OOM for large files
MimeTypes.DNG,
MimeTypes.DNG_ADOBE,
MimeTypes.HEIC,
MimeTypes.HEIF,
MimeTypes.MP4,
MimeTypes.PSD_VND,
MimeTypes.PSD_X,
MimeTypes.TIFF ->
if (isDangerouslyLarge(sizeBytes)) {
Log.d(LOG_TAG, "Dangerously large file with uri=$uri, mimeType=$mimeType, size=$sizeBytes")
// make a preview from the beginning of the file,
// hoping the metadata is accessible in the copied chunk
var previewFile = previewFiles[uri]
if (previewFile == null) {
previewFile = createPreviewFile(context, uri)
previewFiles[uri] = previewFile
}
Uri.fromFile(previewFile)
} else {
// small enough to be safe as it is
uri
}
Uri.fromFile(previewFile)
} else {
// small enough to be safe as it is
else ->
// *probably* safe
uri
}
} else {
// *probably* safe
uri
}
}
fun createPreviewFile(context: Context, uri: Uri): File {
val size = PREVIEW_SIZE
Log.d(LOG_TAG, "create preview of size=$size for uri=$uri")
return StorageUtils.createTempFile(context).apply {
transferFrom(StorageUtils.openInputStream(context, uri), PREVIEW_SIZE)
transferFrom(StorageUtils.openInputStream(context, uri), size)
}
}

View file

@ -9,7 +9,6 @@ import android.net.Uri
import android.os.Build
import android.os.ParcelFileDescriptor
import android.util.Log
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
import com.adobe.internal.xmp.XMPMeta
import com.drew.imaging.jpeg.JpegSegmentType
import com.drew.metadata.exif.ExifDirectoryBase
@ -30,6 +29,8 @@ import deckers.thibault.aves.utils.StorageUtils
import deckers.thibault.aves.utils.indexOfBytes
import org.beyka.tiffbitmapfactory.TiffBitmapFactory
import java.io.DataInputStream
import java.io.EOFException
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
object MultiPage {
private val LOG_TAG = LogUtils.createTag<MultiPage>()
@ -136,21 +137,31 @@ object MultiPage {
// starts after `[APP2 marker (1 byte)] [segment size (2 bytes)] [MPF marker (4 bytes)]`
fun getJpegMpfBaseOffset(context: Context, uri: Uri, sizeBytes: Long?): Int? {
val mimeType = MimeTypes.JPEG
val endMarker = 0xFF
val app2Marker = JpegSegmentType.APP2.byteValue
val mpfMarker = "MPF".toByteArray() + 0x00
try {
Metadata.openSafeInputStream(context, uri, mimeType, sizeBytes)?.use { input ->
var offset = 0
val marker = ByteArray(4)
while (true) {
do {
val b = input.read().toByte()
// look for APP2 marker (0xFFE2)
var found = false
while (!found) {
var i = input.read()
if (i == -1) throw EOFException()
offset++
} while (b != app2Marker)
if (i == endMarker) {
i = input.read()
if (i == -1) throw EOFException()
offset++
found = i.toByte() == app2Marker
}
}
// skip 2 bytes for segment size
input.skip(2)
offset += 2
val marker = ByteArray(4)
input.read(marker, 0, marker.size)
offset += 4
if (marker.contentEquals(mpfMarker)) {

View file

@ -5,7 +5,6 @@ import android.content.Context
import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever
import android.net.Uri
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
import com.drew.metadata.avi.AviDirectory
import com.drew.metadata.exif.ExifIFD0Directory
import com.drew.metadata.jpeg.JpegDirectory
@ -29,6 +28,7 @@ import deckers.thibault.aves.utils.StorageUtils
import deckers.thibault.aves.utils.UriUtils.tryParseId
import org.beyka.tiffbitmapfactory.TiffBitmapFactory
import java.io.IOException
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
class SourceEntry {
private val origin: Int
@ -116,8 +116,8 @@ class SourceEntry {
// metadata retrieval
// expects entry with: uri, mimeType
// finds: width, height, orientation/rotation, date, title, duration
fun fillPreCatalogMetadata(context: Context, safe: Boolean): SourceEntry {
if (isSvg || safe) return this
fun fillPreCatalogMetadata(context: Context): SourceEntry {
if (isSvg) return this
if (isVideo) {
fillVideoByMediaMetadataRetriever(context)
if (isSized && hasDuration) return this

View file

@ -53,7 +53,7 @@ internal class FileImageProvider : ImageProvider() {
return
}
}
entry.fillPreCatalogMetadata(context, safe = false)
entry.fillPreCatalogMetadata(context)
if (allowUnsized || entry.isSized || entry.isSvg || entry.isVideo) {
callback.onSuccess(entry.toMap())

View file

@ -12,6 +12,7 @@ import android.graphics.BitmapFactory
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import androidx.annotation.RequiresApi
@ -51,10 +52,9 @@ class MediaStoreImageProvider : ImageProvider() {
context: Context,
knownEntries: Map<Long?, Int?>,
directory: String?,
safe: Boolean,
handleNewEntry: NewEntryHandler,
) {
Log.d(LOG_TAG, "fetching all media store items for ${knownEntries.size} known entries, directory=$directory safe=$safe")
Log.d(LOG_TAG, "fetching all media store items for ${knownEntries.size} known entries, directory=$directory")
val isModified = fun(contentId: Long, dateModifiedSecs: Int): Boolean {
val knownDate = knownEntries[contentId]
return knownDate == null || knownDate < dateModifiedSecs
@ -84,8 +84,8 @@ class MediaStoreImageProvider : ImageProvider() {
} else {
handleNew = handleNewEntry
}
fetchFrom(context, isModified, handleNew, IMAGE_CONTENT_URI, IMAGE_PROJECTION, selection, selectionArgs, safe = safe)
fetchFrom(context, isModified, handleNew, VIDEO_CONTENT_URI, VIDEO_PROJECTION, selection, selectionArgs, safe = safe)
fetchFrom(context, isModified, handleNew, IMAGE_CONTENT_URI, IMAGE_PROJECTION, selection, selectionArgs)
fetchFrom(context, isModified, handleNew, VIDEO_CONTENT_URI, VIDEO_PROJECTION, selection, selectionArgs)
}
// the provided URI can point to the wrong media collection,
@ -208,7 +208,6 @@ class MediaStoreImageProvider : ImageProvider() {
selection: String? = null,
selectionArgs: Array<String>? = null,
fileMimeType: String? = null,
safe: Boolean = false,
): Boolean {
var found = false
val orderBy = "${MediaStore.MediaColumns.DATE_MODIFIED} DESC"
@ -302,7 +301,7 @@ class MediaStoreImageProvider : ImageProvider() {
// missing some attributes such as width, height, orientation.
// Also, the reported size of raw images is inconsistent across devices
// and Android versions (sometimes the raw size, sometimes the decoded size).
val entry = SourceEntry(entryMap).fillPreCatalogMetadata(context, safe)
val entry = SourceEntry(entryMap).fillPreCatalogMetadata(context)
entryMap = entry.toMap()
}
@ -454,10 +453,8 @@ class MediaStoreImageProvider : ImageProvider() {
effectiveTargetDir = targetDir
targetDirDocFile = StorageUtils.createDirectoryDocIfAbsent(activity, targetDir)
if (!File(targetDir).exists()) {
val downloadDirPath = StorageUtils.getDownloadDirPath(activity, targetDir)
val isDownloadSubdir = downloadDirPath != null && targetDir.startsWith(downloadDirPath)
// download subdirectories can be created later by Media Store insertion
if (!isDownloadSubdir) {
if (!isDownloadSubdir(activity, targetDir)) {
callback.onFailure(Exception("failed to create directory at path=$targetDir"))
return
}
@ -627,9 +624,7 @@ class MediaStoreImageProvider : ImageProvider() {
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val downloadDirPath = StorageUtils.getDownloadDirPath(activity, targetDir)
val isDownloadSubdir = downloadDirPath != null && targetDir.startsWith(downloadDirPath)
if (isDownloadSubdir) {
if (isDownloadSubdir(activity, targetDir)) {
return insertByMediaStore(
activity = activity,
targetDir = targetDir,
@ -649,6 +644,13 @@ class MediaStoreImageProvider : ImageProvider() {
)
}
private fun isDownloadSubdir(context: Context, dir: String): Boolean {
val volumePath = StorageUtils.getVolumePath(context, dir) ?: return false
val downloadDirPath = ensureTrailingSeparator(File(volumePath, Environment.DIRECTORY_DOWNLOADS).path)
// effective download path may have a different case
return dir.lowercase().startsWith(downloadDirPath.lowercase())
}
private fun insertByFile(
targetDir: String,
targetFileName: String,

View file

@ -70,7 +70,7 @@ open class UnknownContentProvider : ImageProvider() {
return
}
val entry = SourceEntry(fields).fillPreCatalogMetadata(context, safe = false)
val entry = SourceEntry(fields).fillPreCatalogMetadata(context)
if (allowUnsized || entry.isSized || entry.isSvg || entry.isVideo) {
callback.onSuccess(entry.toMap())
} else {

View file

@ -17,8 +17,8 @@ object MimeTypes {
private const val ICO = "image/x-icon"
const val JPEG = "image/jpeg"
const val PNG = "image/png"
private const val PSD_VND = "image/vnd.adobe.photoshop"
private const val PSD_X = "image/x-photoshop"
const val PSD_VND = "image/vnd.adobe.photoshop"
const val PSD_X = "image/x-photoshop"
const val TIFF = "image/tiff"
private const val WBMP = "image/vnd.wap.wbmp"
const val WEBP = "image/webp"

View file

@ -17,6 +17,7 @@ import deckers.thibault.aves.PendingStorageAccessResultHandler
import deckers.thibault.aves.model.FieldMap
import deckers.thibault.aves.utils.StorageUtils.PathSegments
import java.io.File
import java.util.Locale
import java.util.concurrent.CompletableFuture
object PermissionManager {
@ -86,6 +87,7 @@ object PermissionManager {
fun getInaccessibleDirectories(context: Context, dirPaths: List<String>): List<Map<String, String>> {
val concreteDirPaths = dirPaths.filter { it != StorageUtils.TRASH_PATH_PLACEHOLDER }
val accessibleDirs = getAccessibleDirs(context)
val restrictedPrimaryDirectoriesLower = getRestrictedPrimaryDirectories().map { it.lowercase(Locale.ROOT) }
// find set of inaccessible directories for each volume
val dirsPerVolume = HashMap<String, MutableSet<String>>()
@ -101,7 +103,7 @@ object PermissionManager {
if (relativeDir != null) {
val dirSegments = relativeDir.split(File.separator).takeWhile { it.isNotEmpty() }
val primaryDir = dirSegments.firstOrNull()
if (getRestrictedPrimaryDirectories().contains(primaryDir) && dirSegments.size > 1) {
if (dirSegments.size > 1 && restrictedPrimaryDirectoriesLower.contains(primaryDir?.lowercase(Locale.ROOT))) {
// request secondary directory (if any) for restricted primary directory
val dir = dirSegments.take(2).joinToString(File.separator)
// only register directories that exist on storage, so they can be selected for access grant
@ -140,10 +142,11 @@ object PermissionManager {
fun canInsertByMediaStore(directories: List<FieldMap>): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val insertionDirsLower = MEDIA_STORE_INSERTION_PRIMARY_DIRS.map { it.lowercase(Locale.ROOT) }
directories.all {
val relativeDir = it["relativeDir"] as String
val segments = relativeDir.split(File.separator)
segments.isNotEmpty() && MEDIA_STORE_INSERTION_PRIMARY_DIRS.contains(segments.first())
segments.isNotEmpty() && insertionDirsLower.contains(segments.first().lowercase(Locale.ROOT))
}
} else {
true

View file

@ -120,10 +120,6 @@ object StorageUtils {
return getVolumePaths(context).firstOrNull { anyPath.startsWith(it) }
}
fun getDownloadDirPath(context: Context, anyPath: String): String? {
return getVolumePath(context, anyPath)?.let { volumePath -> ensureTrailingSeparator(File(volumePath, Environment.DIRECTORY_DOWNLOADS).path) }
}
private fun getPathStepIterator(context: Context, anyPath: String, root: String?): Iterator<String?>? {
val rootLength = (root ?: getVolumePath(context, anyPath))?.length ?: return null

View file

@ -1,16 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:tint="@color/ic_shortcut_foreground"
android:viewportWidth="108"
android:viewportHeight="108">
<group
android:scaleX="1.7226"
android:scaleY="1.7226"
android:translateX="33.3288"
android:translateY="33.3288">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM19.46,9.12l-2.78,1.15c-0.51,-1.36 -1.58,-2.44 -2.95,-2.94l1.15,-2.78C16.98,5.35 18.65,7.02 19.46,9.12zM12,15c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3s3,1.34 3,3S13.66,15 12,15zM9.13,4.54l1.17,2.78c-1.38,0.5 -2.47,1.59 -2.98,2.97L4.54,9.13C5.35,7.02 7.02,5.35 9.13,4.54zM4.54,14.87l2.78,-1.15c0.51,1.38 1.59,2.46 2.97,2.96l-1.17,2.78C7.02,18.65 5.35,16.98 4.54,14.87zM14.88,19.46l-1.15,-2.78c1.37,-0.51 2.45,-1.59 2.95,-2.97l2.78,1.17C18.65,16.98 16.98,18.65 14.88,19.46z" />
</group>
</vector>

View file

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:fillColor="@color/ic_shortcut_background"
android:pathData="M0,24 A1,1 0 1,1 48,24 A1,1 0 1,1 0,24" />
<group
android:translateX="12"
android:translateY="12">
<path
android:fillColor="@color/ic_shortcut_foreground"
android:pathData="M20.5,3l-0.16,0.03L15,5.1 9,3 3.36,4.9c-0.21,0.07 -0.36,0.25 -0.36,0.48L3,20.5c0,0.28 0.22,0.5 0.5,0.5l0.16,-0.03L9,18.9l6,2.1 5.64,-1.9c0.21,-0.07 0.36,-0.25 0.36,-0.48L21,3.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM10,5.47l4,1.4v11.66l-4,-1.4L10,5.47zM5,6.46l3,-1.01v11.7l-3,1.16L5,6.46zM19,17.54l-3,1.01L16,6.86l3,-1.16v11.84z" />
</group>
</vector>

View file

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:tint="@color/ic_shortcut_foreground"
android:viewportWidth="108"
android:viewportHeight="108">
<group
android:scaleX="1.7226"
android:scaleY="1.7226"
android:translateX="33.3288"
android:translateY="33.3288">
<path
android:fillColor="@android:color/white"
android:pathData="M20.5,3l-0.16,0.03L15,5.1 9,3 3.36,4.9c-0.21,0.07 -0.36,0.25 -0.36,0.48L3,20.5c0,0.28 0.22,0.5 0.5,0.5l0.16,-0.03L9,18.9l6,2.1 5.64,-1.9c0.21,-0.07 0.36,-0.25 0.36,-0.48L21,3.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM10,5.47l4,1.4v11.66l-4,-1.4L10,5.47zM5,6.46l3,-1.01v11.7l-3,1.16L5,6.46zM19,17.54l-3,1.01L16,6.86l3,-1.16v11.84z" />
</group>
</vector>

View file

@ -1,16 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:fillColor="@color/ic_shortcut_background"
android:pathData="M0,24 A1,1 0 1,1 48,24 A1,1 0 1,1 0,24" />
<group
android:translateX="12"
android:translateY="12">
<path
android:fillColor="@color/ic_shortcut_foreground"
android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM19.46,9.12l-2.78,1.15c-0.51,-1.36 -1.58,-2.44 -2.95,-2.94l1.15,-2.78C16.98,5.35 18.65,7.02 19.46,9.12zM12,15c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3s3,1.34 3,3S13.66,15 12,15zM9.13,4.54l1.17,2.78c-1.38,0.5 -2.47,1.59 -2.98,2.97L4.54,9.13C5.35,7.02 7.02,5.35 9.13,4.54zM4.54,14.87l2.78,-1.15c0.51,1.38 1.59,2.46 2.97,2.96l-1.17,2.78C7.02,18.65 5.35,16.98 4.54,14.87zM14.88,19.46l-1.15,-2.78c1.37,-0.51 2.45,-1.59 2.95,-2.97l2.78,1.17C18.65,16.98 16.98,18.65 14.88,19.46z" />
</group>
</vector>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_shortcut_background" />
<foreground android:drawable="@drawable/ic_shortcut_safe_mode_foreground" />
<foreground android:drawable="@drawable/ic_shortcut_map_foreground" />
</adaptive-icon>

View file

@ -7,6 +7,5 @@
<string name="analysis_channel_name">فحص الوسائط</string>
<string name="analysis_notification_default_title">يتم فحص الوسائط</string>
<string name="analysis_notification_action_stop">إيقاف</string>
<string name="safe_mode_shortcut_short_label">الوضع الآمن</string>
<string name="app_name">Aves</string>
</resources>

View file

@ -6,7 +6,6 @@
<string name="analysis_notification_default_title">Сканаванне носьбітаў</string>
<string name="app_name">Aves</string>
<string name="app_widget_label">Фотарамка</string>
<string name="safe_mode_shortcut_short_label">Бяспечны рэжым</string>
<string name="search_shortcut_short_label">Пошук</string>
<string name="analysis_notification_action_stop">Стоп</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_notification_action_stop">থামান</string>
<string name="app_name">আভেস</string>
<string name="app_widget_label">ছবির ফ্রেম</string>
<string name="safe_mode_shortcut_short_label">নিরাপদ মোড</string>
</resources>

View file

@ -3,7 +3,6 @@
<string name="app_name">Aves</string>
<string name="app_widget_label">Marc de foto</string>
<string name="wallpaper">Fons de pantalla</string>
<string name="safe_mode_shortcut_short_label">Mode segur</string>
<string name="search_shortcut_short_label">Buscar</string>
<string name="videos_shortcut_short_label">Vídeos</string>
<string name="analysis_channel_name">Exploració de mitjans</string>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">گەڕان لە پەڕگە</string>
<string name="analysis_notification_default_title">لە پەڕگەکان دەگەڕێت</string>
<string name="analysis_notification_action_stop">وەستاندن</string>
<string name="safe_mode_shortcut_short_label">دۆخی پارێزراو</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_notification_default_title">Prohledávání médií</string>
<string name="analysis_notification_action_stop">Zastavit</string>
<string name="app_widget_label">Fotorámeček</string>
<string name="safe_mode_shortcut_short_label">Bezpečný režim</string>
</resources>

View file

@ -7,6 +7,5 @@
<string name="analysis_notification_default_title">Scanner medier</string>
<string name="analysis_notification_action_stop">Stop</string>
<string name="app_name">Aves</string>
<string name="safe_mode_shortcut_short_label">Sikker tilstand</string>
<string name="search_shortcut_short_label">Søg</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">Analyse von Medien</string>
<string name="analysis_notification_default_title">Medien scannen</string>
<string name="analysis_notification_action_stop">Abbrechen</string>
<string name="safe_mode_shortcut_short_label">Sicherer Modus</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">Σάρωση πολυμέσων</string>
<string name="analysis_notification_default_title">Σάρωση στοιχείων</string>
<string name="analysis_notification_action_stop">Διακοπή</string>
<string name="safe_mode_shortcut_short_label">Ασφαλής κατάσταση λειτουργίας</string>
</resources>

View file

@ -8,5 +8,5 @@
<string name="analysis_channel_name">Explorar medios</string>
<string name="analysis_notification_default_title">Explorando medios</string>
<string name="analysis_notification_action_stop">Anular</string>
<string name="safe_mode_shortcut_short_label">Modo seguro</string>
<string name="map_shortcut_short_label">Mapa</string>
</resources>

View file

@ -8,5 +8,5 @@
<string name="analysis_notification_action_stop">Gelditu</string>
<string name="analysis_notification_default_title">Media eskaneatzen</string>
<string name="app_name">Aves</string>
<string name="safe_mode_shortcut_short_label">Modu segurua</string>
<string name="map_shortcut_short_label">Mapa</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_notification_action_stop">توقف کردن</string>
<string name="app_widget_label">قاب عکس</string>
<string name="app_name">Aves</string>
<string name="safe_mode_shortcut_short_label">حالت امن</string>
</resources>

View file

@ -4,7 +4,6 @@
<string name="app_widget_label">Valokuvakehys</string>
<string name="analysis_notification_default_title">Mediaan skannataan</string>
<string name="videos_shortcut_short_label">Videot</string>
<string name="safe_mode_shortcut_short_label">Turva tila</string>
<string name="wallpaper">Taustakuva</string>
<string name="app_name">Aves</string>
<string name="analysis_channel_name">Median skannaus</string>

View file

@ -8,5 +8,5 @@
<string name="analysis_channel_name">Analyse des images</string>
<string name="analysis_notification_default_title">Analyse des images</string>
<string name="analysis_notification_action_stop">Annuler</string>
<string name="safe_mode_shortcut_short_label">Mode sans échec</string>
<string name="map_shortcut_short_label">Carte</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">मीडिया जाँचे</string>
<string name="app_name">ऐवीज</string>
<string name="videos_shortcut_short_label">वीडियो</string>
<string name="safe_mode_shortcut_short_label">सेफ मोड</string>
</resources>

View file

@ -6,7 +6,7 @@
<string name="videos_shortcut_short_label">Videók</string>
<string name="analysis_notification_action_stop">Állj</string>
<string name="app_widget_label">Fotó keret</string>
<string name="safe_mode_shortcut_short_label">Biztonsági üzemmód</string>
<string name="analysis_channel_name">Tartalom keresése</string>
<string name="analysis_notification_default_title">Média beolvasása</string>
<string name="map_shortcut_short_label">Térkép</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">Pindai media</string>
<string name="analysis_notification_default_title">Memindai media</string>
<string name="analysis_notification_action_stop">Berhenti</string>
<string name="safe_mode_shortcut_short_label">Mode aman</string>
</resources>

View file

@ -4,7 +4,6 @@
<string name="app_widget_label">Myndarammi</string>
<string name="analysis_notification_default_title">Skanna myndefni</string>
<string name="videos_shortcut_short_label">Myndskeið</string>
<string name="safe_mode_shortcut_short_label">Öruggur hamur</string>
<string name="wallpaper">Bakgrunnur</string>
<string name="app_name">Aves</string>
<string name="analysis_channel_name">Skönnun myndefnis</string>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">Scansione media</string>
<string name="analysis_notification_default_title">Scansione in corso</string>
<string name="analysis_notification_action_stop">Annulla</string>
<string name="safe_mode_shortcut_short_label">Modalità provvisoria</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">メディアスキャン</string>
<string name="analysis_notification_default_title">メディアをスキャン中</string>
<string name="analysis_notification_action_stop">停止</string>
<string name="safe_mode_shortcut_short_label">セーフモード</string>
</resources>

View file

@ -3,7 +3,6 @@
<string name="app_name">Aves</string>
<string name="app_widget_label">ಫೋಟೋ ಫ್ರೇಮ್</string>
<string name="wallpaper">ವಾಲ್ಪೇಪರ್</string>
<string name="safe_mode_shortcut_short_label">ಸುರಕ್ಷಿತ ಮೋಡ್</string>
<string name="videos_shortcut_short_label">ವೀಡಿಯೊಗಳು</string>
<string name="analysis_channel_name">ಮೀಡಿಯಾ ಸ್ಕ್ಯಾನ್</string>
<string name="analysis_notification_default_title">ಮೀಡಿಯಾ ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ</string>

View file

@ -8,5 +8,5 @@
<string name="analysis_channel_name">미디어 분석</string>
<string name="analysis_notification_default_title">미디어 분석</string>
<string name="analysis_notification_action_stop">취소</string>
<string name="safe_mode_shortcut_short_label">안전 모드</string>
<string name="map_shortcut_short_label">지도</string>
</resources>

View file

@ -3,7 +3,6 @@
<string name="app_name">Aves</string>
<string name="app_widget_label">ရုပ်ပုံဘောင်</string>
<string name="wallpaper">နောက်ခံ ရုပ်ပုံ</string>
<string name="safe_mode_shortcut_short_label">လုံခြုံရေးလုပ်ဆောင်ချက်</string>
<string name="analysis_channel_name">မီဒီယာ စကင်</string>
<string name="search_shortcut_short_label">ရှာရန်</string>
<string name="videos_shortcut_short_label">ဗီဒီယိုများ</string>

View file

@ -8,5 +8,4 @@
<string name="wallpaper">Bakgrunnsbilde</string>
<string name="search_shortcut_short_label">Søk</string>
<string name="analysis_notification_action_stop">Stopp</string>
<string name="safe_mode_shortcut_short_label">Trygt modus</string>
</resources>

View file

@ -8,5 +8,5 @@
<string name="analysis_channel_name">Media indexeren</string>
<string name="analysis_notification_default_title">Media indexeren</string>
<string name="analysis_notification_action_stop">Stoppen</string>
<string name="safe_mode_shortcut_short_label">Veilige modus</string>
<string name="map_shortcut_short_label">Kaart</string>
</resources>

View file

@ -8,5 +8,5 @@
<string name="analysis_notification_action_stop">Zatrzymaj</string>
<string name="app_name">Aves</string>
<string name="wallpaper">Tapeta</string>
<string name="safe_mode_shortcut_short_label">Tryb bezpieczny</string>
<string name="map_shortcut_short_label">Mapa</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">Digitalização de mídia</string>
<string name="analysis_notification_default_title">Digitalizando mídia</string>
<string name="analysis_notification_action_stop">Pare</string>
<string name="safe_mode_shortcut_short_label">Modo seguro</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_notification_default_title">Scanarea suporturilor</string>
<string name="analysis_notification_action_stop">Stop</string>
<string name="search_shortcut_short_label">Căutare</string>
<string name="safe_mode_shortcut_short_label">Modul de siguranță</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">Сканировать медия</string>
<string name="analysis_notification_default_title">Сканирование медиа</string>
<string name="analysis_notification_action_stop">Стоп</string>
<string name="safe_mode_shortcut_short_label">Безопасный режим</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_notification_action_stop">Zastaviť</string>
<string name="analysis_channel_name">Skenovanie médií</string>
<string name="analysis_notification_default_title">Skenovanie média</string>
<string name="safe_mode_shortcut_short_label">Bezpečný režim</string>
</resources>

View file

@ -2,7 +2,6 @@
<resources>
<string name="app_widget_label">Okvir za sliko</string>
<string name="app_name">Aves</string>
<string name="safe_mode_shortcut_short_label">Varni način</string>
<string name="videos_shortcut_short_label">Videoposnetki</string>
<string name="wallpaper">Ozadje</string>
<string name="search_shortcut_short_label">Iskanje</string>

View file

@ -2,7 +2,6 @@
<resources>
<string name="app_widget_label">Okvir Slike</string>
<string name="wallpaper">Pozadina</string>
<string name="safe_mode_shortcut_short_label">Siguran režim</string>
<string name="videos_shortcut_short_label">Snimci</string>
<string name="analysis_channel_name">Pretraga medija</string>
<string name="analysis_notification_default_title">Skeniranje medija</string>

View file

@ -3,10 +3,10 @@
<string name="app_name">Aves</string>
<string name="app_widget_label">Fotoram</string>
<string name="wallpaper">Bakgrund</string>
<string name="safe_mode_shortcut_short_label">Felsäkert läge</string>
<string name="videos_shortcut_short_label">Videor</string>
<string name="analysis_channel_name">Media scanning</string>
<string name="analysis_notification_default_title">Scannar media</string>
<string name="analysis_notification_action_stop">Stopp</string>
<string name="search_shortcut_short_label">Sök</string>
<string name="map_shortcut_short_label">Karta</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">Medya tarama</string>
<string name="analysis_notification_default_title">Medya taranıyor</string>
<string name="analysis_notification_action_stop">Durdur</string>
<string name="safe_mode_shortcut_short_label">Güvenli mod</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_notification_action_stop">Стоп</string>
<string name="app_widget_label">Фоторамка</string>
<string name="analysis_notification_default_title">Сканування медіа</string>
<string name="safe_mode_shortcut_short_label">Безпечний режим</string>
</resources>

View file

@ -4,7 +4,6 @@
<string name="app_widget_label">Khung Ảnh</string>
<string name="analysis_notification_default_title">Đang quét phương tiện</string>
<string name="videos_shortcut_short_label">Video</string>
<string name="safe_mode_shortcut_short_label">Chế độ an toàn</string>
<string name="wallpaper">Hình nền</string>
<string name="app_name">Aves</string>
<string name="analysis_channel_name">Quét phương tiện</string>

View file

@ -8,5 +8,4 @@
<string name="search_shortcut_short_label">搜尋</string>
<string name="analysis_channel_name">媒體掃描</string>
<string name="analysis_notification_action_stop">停止</string>
<string name="safe_mode_shortcut_short_label">安全模式</string>
</resources>

View file

@ -8,5 +8,4 @@
<string name="analysis_channel_name">媒体扫描</string>
<string name="analysis_notification_default_title">正在扫描媒体</string>
<string name="analysis_notification_action_stop">停止</string>
<string name="safe_mode_shortcut_short_label">安全模式</string>
</resources>

View file

@ -3,7 +3,7 @@
<string name="app_name">Aves</string>
<string name="app_widget_label">Photo Frame</string>
<string name="wallpaper">Wallpaper</string>
<string name="safe_mode_shortcut_short_label">Safe mode</string>
<string name="map_shortcut_short_label">Map</string>
<string name="search_shortcut_short_label">Search</string>
<string name="videos_shortcut_short_label">Videos</string>
<string name="analysis_channel_name">Media scan</string>

View file

@ -10,7 +10,7 @@ pluginManagement {
settings.ext.kotlin_version = '1.9.24'
settings.ext.ksp_version = "$kotlin_version-1.0.20"
settings.ext.agp_version = '8.6.0'
settings.ext.agp_version = '8.6.1'
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")

View file

@ -1,4 +0,0 @@
In v1.11.5:
- explore your collection with the... explorer
- convert your motion photos to stills in bulk
Full changelog available on GitHub

View file

@ -1,4 +0,0 @@
In v1.11.5:
- explore your collection with the... explorer
- convert your motion photos to stills in bulk
Full changelog available on GitHub

View file

@ -1,4 +0,0 @@
In v1.11.6:
- explore your collection with the... explorer
- convert your motion photos to stills in bulk
Full changelog available on GitHub

View file

@ -1,4 +0,0 @@
In v1.11.6:
- explore your collection with the... explorer
- convert your motion photos to stills in bulk
Full changelog available on GitHub

View file

@ -1,4 +0,0 @@
In v1.11.7:
- explore your collection with the... explorer
- convert your motion photos to stills in bulk
Full changelog available on GitHub

View file

@ -1,4 +0,0 @@
In v1.11.7:
- explore your collection with the... explorer
- convert your motion photos to stills in bulk
Full changelog available on GitHub

View file

@ -1,4 +0,0 @@
In v1.11.8:
- explore your collection with the... explorer
- convert your motion photos to stills in bulk
Full changelog available on GitHub

View file

@ -1,4 +0,0 @@
In v1.11.8:
- explore your collection with the... explorer
- convert your motion photos to stills in bulk
Full changelog available on GitHub

View file

@ -1,5 +0,0 @@
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

View file

@ -1,5 +0,0 @@
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

View file

@ -1,3 +0,0 @@
In v1.11.10:
- enjoy the app in Swedish
Full changelog available on GitHub

View file

@ -1,3 +0,0 @@
In v1.11.10:
- enjoy the app in Swedish
Full changelog available on GitHub

View file

@ -0,0 +1,4 @@
In v1.11.14:
- enjoy new map layers
- share "geo" addresses to Aves and see your collection in that area
Full changelog available on GitHub

View file

@ -0,0 +1,4 @@
In v1.11.14:
- enjoy new map layers
- share "geo" addresses to Aves and see your collection in that area
Full changelog available on GitHub

26
lib/geo/uri.dart Normal file
View file

@ -0,0 +1,26 @@
import 'package:latlong2/latlong.dart';
// e.g. `geo:44.4361283,26.1027248?z=4.0(Bucharest)`
// cf https://en.wikipedia.org/wiki/Geo_URI_scheme
// cf https://developer.android.com/guide/components/intents-common#ViewMap
(LatLng, double?)? parseGeoUri(String? uri) {
if (uri != null) {
final geoUri = Uri.tryParse(uri);
if (geoUri != null) {
final coordinates = geoUri.path.split(',');
if (coordinates.length == 2) {
final lat = double.tryParse(coordinates[0]);
final lon = double.tryParse(coordinates[1]);
if (lat != null && lon != null) {
double? zoom;
final zoomString = geoUri.queryParameters['z'];
if (zoomString != null) {
zoom = double.tryParse(zoomString);
}
return (LatLng(lat, lon), zoom);
}
}
}
}
return null;
}

View file

@ -127,7 +127,7 @@
"@settingsEnableBinSubtitle": {},
"viewerInfoPageTitle": "معلومات",
"@viewerInfoPageTitle": {},
"mapAttributionStamen": "بيانات الخريطة © [OpenStreetMap](https://www.openstreetmap.org/copyright) المساهمين • البلاط بواسطة [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "البلاط بواسطة [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"widgetOpenPageViewer": "افتح العارض",
"@widgetOpenPageViewer": {},
@ -533,8 +533,6 @@
"@albumGroupTier": {},
"aboutBugReportInstruction": "تقرير على GitHub مع السجلات ومعلومات النظام",
"@aboutBugReportInstruction": {},
"addPathTooltip": "أضف المسار",
"@addPathTooltip": {},
"videoActionCaptureFrame": "التقاط الإطار",
"@videoActionCaptureFrame": {},
"patternDialogEnter": "أدخل النمط",
@ -873,8 +871,6 @@
"@drawerCollectionMotionPhotos": {},
"settingsDefault": "افتراضي",
"@settingsDefault": {},
"settingsHiddenItemsTabFilters": "المرشحات المخفية",
"@settingsHiddenItemsTabFilters": {},
"settingsSlideshowAnimatedZoomEffect": "تأثير التكبير المتحرك",
"@settingsSlideshowAnimatedZoomEffect": {},
"viewerActionSettings": "الإعدادات",
@ -1059,7 +1055,7 @@
"@entryInfoActionEditTags": {},
"collectionActionHideTitleSearch": "إخفاء مرشح العنوان",
"@collectionActionHideTitleSearch": {},
"mapAttributionOsmHot": "بيانات الخريطة © [OpenStreetMap](https://www.openstreetmap.org/copyright) المساهمين • البلاط بواسطة [HOT](https://www.hotosm.org/) • استضافة بواسطة [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "البلاط بواسطة [HOT](https://www.hotosm.org/) • استضافة بواسطة [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"settingsNavigationDrawerTile": "قائمة تنقل",
"@settingsNavigationDrawerTile": {},
@ -1073,8 +1069,6 @@
"@keepScreenOnViewerOnly": {},
"durationDialogHours": "ساعات",
"@durationDialogHours": {},
"settingsHiddenPathsBanner": "لن تظهر الصور ومقاطع الفيديو الموجودة في هذه المجلدات، أو أي من مجلداتها الفرعية في مجموعتك.",
"@settingsHiddenPathsBanner": {},
"settingsKeepScreenOnDialogTitle": "ابقاء الشَاشة قيد التشغيل",
"@settingsKeepScreenOnDialogTitle": {},
"wallpaperTargetHome": "الشاشة الرئيسية",
@ -1475,8 +1469,6 @@
"@settingsThemeColorHighlights": {},
"appPickDialogTitle": "اختر التطبيق",
"@appPickDialogTitle": {},
"settingsHiddenItemsTabPaths": "المسارات المخفية",
"@settingsHiddenItemsTabPaths": {},
"viewerInfoSearchSuggestionRights": "الحقوق",
"@viewerInfoSearchSuggestionRights": {},
"mapPointNorthUpTooltip": "نقطة الشمال لأعلى",
@ -1548,5 +1540,9 @@
"sortOrderLongestFirst": "الأطول أولاً",
"@sortOrderLongestFirst": {},
"sortByDuration": "حسب المدة",
"@sortByDuration": {}
"@sortByDuration": {},
"mapStyleOpenTopoMap": "الخريطة الطبوغرافية المفتوحة",
"@mapStyleOpenTopoMap": {},
"mapAttributionOsmData": "بيانات الخريطة © [OpenStreetMap](https://www.openstreetmap.org/copyright) المساهمين",
"@mapAttributionOsmData": {}
}

View file

@ -541,7 +541,7 @@
"@viewerInfoViewXmlLinkText": {},
"viewerInfoOpenLinkText": "Адкрыць",
"@viewerInfoOpenLinkText": {},
"mapAttributionStamen": "Даныя карты © [OpenStreetMap](https://www.openstreetmap.org/copyright) удзельнікі • Пліткі ад [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Пліткі ад [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"mapPointNorthUpTooltip": "Пакажыце поўнач уверх",
"@mapPointNorthUpTooltip": {},
@ -637,7 +637,7 @@
"@filePickerDoNotShowHiddenFiles": {},
"viewerInfoOpenEmbeddedFailureFeedback": "Не ўдалося атрымаць убудаваныя даныя",
"@viewerInfoOpenEmbeddedFailureFeedback": {},
"mapAttributionOsmHot": "Даныя карты © [OpenStreetMap](https://www.openstreetmap.org/copyright) удзельнікі • Пліткі ад [HOT](https://www.hotosm.org/) • Арганізаваны [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Пліткі ад [HOT](https://www.hotosm.org/) • Арганізаваны [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"viewerInfoLabelSize": "Памер",
"@viewerInfoLabelSize": {},
@ -1283,8 +1283,6 @@
},
"settingsVideoGestureDoubleTapTogglePlay": "Двойчы націсніце, каб прайграць/прыпыніць",
"@settingsVideoGestureDoubleTapTogglePlay": {},
"addPathTooltip": "Дадаць шлях",
"@addPathTooltip": {},
"settingsEnableBin": "Выкарыстоўваць сметніцу",
"@settingsEnableBin": {},
"collectionMoveSuccessFeedback": "{count, plural, =1{Перамяшчаны 1 элемент} few{Перамяшчаны {count} элементы} other{Перамяшчаны {count} элементаў}}",
@ -1353,8 +1351,6 @@
"@settingsVideoBackgroundMode": {},
"settingsAllowInstalledAppAccess": "Дазволіць доступ да інвентара праграм",
"@settingsAllowInstalledAppAccess": {},
"settingsHiddenItemsTabFilters": "Схаваныя фільтры",
"@settingsHiddenItemsTabFilters": {},
"settingsSlideshowAnimatedZoomEffect": "Аніміраваны эфект маштабавання",
"@settingsSlideshowAnimatedZoomEffect": {},
"settingsViewerOverlayPageTitle": "Навязванне",
@ -1383,8 +1379,6 @@
"@settingsNavigationDrawerTile": {},
"settingsHiddenItemsPageTitle": "Схаваныя элементы",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenPathsBanner": "Фатаграфіі і відэа ў гэтых тэчках або ў любой з іх укладзеных тэчках не будуць адлюстроўвацца ў вашай калекцыі.",
"@settingsHiddenPathsBanner": {},
"settingsViewerShowOverlayOnOpening": "Паказаць на адкрыцці",
"@settingsViewerShowOverlayOnOpening": {},
"settingsViewerShowShootingDetails": "Паказаць дэталі здымкі",
@ -1473,8 +1467,6 @@
"@settingsSubtitleThemeTextSize": {},
"settingsCollectionQuickActionTabBrowsing": "Прагляд",
"@settingsCollectionQuickActionTabBrowsing": {},
"settingsHiddenItemsTabPaths": "Схаваныя шляхі",
"@settingsHiddenItemsTabPaths": {},
"collectionDeleteFailureFeedback": "{count, plural, =1{Не атрымалася выдаліць 1 элемент} few{Не атрымалася выдаліць {count} элементы} other{Не атрымалася выдаліць {count} элементаў}}",
"@collectionDeleteFailureFeedback": {
"placeholders": {
@ -1548,5 +1540,11 @@
"selectStorageVolumeDialogTitle": "Выбраць сховішча",
"@selectStorageVolumeDialogTitle": {},
"setHomeCustom": "Па-свойму",
"@setHomeCustom": {}
"@setHomeCustom": {},
"mapStyleOpenTopoMap": "OpenTopoMap",
"@mapStyleOpenTopoMap": {},
"mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Пліткі ад [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)",
"@mapAttributionOpenTopoMap": {},
"mapAttributionOsmData": "Даныя карты © [OpenStreetMap](https://www.openstreetmap.org/copyright) удзельнікі",
"@mapAttributionOsmData": {}
}

View file

@ -1167,12 +1167,8 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "Elements Amagats",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "Filtres Amagats",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "Les fotos i els vídeos que coincideixin amb filtres amagats no apareixeran a la teva coŀlecció.",
"@settingsHiddenFiltersBanner": {},
"addPathTooltip": "Afegeix ruta",
"@addPathTooltip": {},
"settingsStorageAccessBanner": "Alguns directoris requereixen permís explícit per modificar-hi fitxers. Podeu revisar aquí els directoris als quals heu donat accés anteriorment.",
"@settingsStorageAccessBanner": {},
"settingsStorageAccessEmpty": "Cap permís daccés",
@ -1289,7 +1285,7 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "Apuntar el nord cap amunt",
"@mapPointNorthUpTooltip": {},
"mapAttributionStamen": "Dades de mapa © [OpenStreetMap](https://www.openstreetmap.org/copyright) contribuïdors • Rajoles per [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Rajoles per [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "Veure a la pàgina de mapa",
"@openMapPageTooltip": {},
@ -1351,10 +1347,6 @@
"@settingsAllowInstalledAppAccessSubtitle": {},
"settingsHiddenFiltersEmpty": "Cap filtre amagat",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Rutes Amagades",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Les fotos i vídeos daquestes carpetes, o a les seves subcarpetes, no apareixeran a la teva coŀlecció.",
"@settingsHiddenPathsBanner": {},
"settingsStorageAccessTile": "Accés demmagatzematge",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Accés dEmmagatzematge",
@ -1451,7 +1443,7 @@
"@appExportCovers": {},
"appExportFavourites": "Preferits",
"@appExportFavourites": {},
"mapAttributionOsmHot": "Dades de mapa © [OpenStreetMap](https://www.openstreetmap.org/copyright) contribuïdors • Rajoles de [HOT](https://www.hotosm.org/) • Allotjat a [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Rajoles de [HOT](https://www.hotosm.org/) • Allotjat a [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"viewerInfoSearchSuggestionDescription": "Descripció",
"@viewerInfoSearchSuggestionDescription": {},
@ -1520,5 +1512,7 @@
}
},
"chipActionShowCollection": "Mostrar a Coŀlecció",
"@chipActionShowCollection": {}
"@chipActionShowCollection": {},
"mapAttributionOsmData": "Dades de mapa © [OpenStreetMap](https://www.openstreetmap.org/copyright) contribuïdors",
"@mapAttributionOsmData": {}
}

View file

@ -771,16 +771,8 @@
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenFiltersBanner": "Fotografie a videa odpovídající filtrům skrytých položek nebudou zobrazeny ve vaši sbírce.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenItemsTabFilters": "Filtry položek",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersEmpty": "Žádné filtry skrytých položek",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Filtry umístění",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Fotografie a videa v těchto adresářích a jejich podsložkách nebudou zobrazeny ve vaši sbírce.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Přidat umístění",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Přístup k úložišti",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Přístup k úložišti",
@ -911,7 +903,7 @@
"@wallpaperUseScrollEffect": {},
"tagEditorPageTitle": "Upravit štítky",
"@tagEditorPageTitle": {},
"mapAttributionOsmHot": "Mapová data © [OpenStreetMap](https://www.openstreetmap.org/copyright) přispěvatelé • Dlaždice z [HOT](https://www.hotosm.org/) • Hostováno na [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Dlaždice z [HOT](https://www.hotosm.org/) • Hostováno na [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"viewerInfoSearchSuggestionRights": "Práva",
"@viewerInfoSearchSuggestionRights": {},
@ -1343,7 +1335,7 @@
"@tagEditorPageNewTagFieldLabel": {},
"tagEditorSectionRecent": "Nedávné",
"@tagEditorSectionRecent": {},
"mapAttributionStamen": "Mapová data © [OpenStreetMap](https://www.openstreetmap.org/copyright) přispěvatelé • Dlaždice z [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Dlaždice z [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"panoramaDisableSensorControl": "Zakázat ovládání senzorem",
"@panoramaDisableSensorControl": {},
@ -1528,5 +1520,7 @@
"videoActionABRepeat": "Opakování A-B",
"@videoActionABRepeat": {},
"chipActionShowCollection": "Zobrazit ve sbírce",
"@chipActionShowCollection": {}
"@chipActionShowCollection": {},
"mapAttributionOsmData": "Mapová data © [OpenStreetMap](https://www.openstreetmap.org/copyright) přispěvatelé",
"@mapAttributionOsmData": {}
}

View file

@ -955,18 +955,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "Versteckte Elemente",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "Versteckte Filter",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "Fotos und Videos, die versteckten Filtern entsprechen, werden nicht in Ihrer Sammlung angezeigt.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "Keine versteckten Filter",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Verborgene Pfade",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Fotos und Videos, die sich in diesen Ordnern oder in einem ihrer Unterordner befinden, werden nicht in Ihrer Sammlung angezeigt.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Pfad hinzufügen",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Speicherzugriff",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Speicherzugriff",
@ -1081,9 +1073,9 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "Richtung Norden aufwärts",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "Kartendaten © [OpenStreetMap](https://www.openstreetmap.org/copyright) Mitwirkende • Kacheln von [HOT](https://www.hotosm.org/) • Gehostet von [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Kacheln von [HOT](https://www.hotosm.org/) • Gehostet von [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "Kartendaten © [OpenStreetMap](https://www.openstreetmap.org/copyright) Mitwirkende • Kacheln von [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Kacheln von [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "Auf der Karte anzeigen",
"@openMapPageTooltip": {},
@ -1390,5 +1382,7 @@
"chipActionGoToExplorerPage": "Im Explorer anzeigen",
"@chipActionGoToExplorerPage": {},
"explorerPageTitle": "Explorer",
"@explorerPageTitle": {}
"@explorerPageTitle": {},
"mapAttributionOsmData": "Kartendaten © [OpenStreetMap](https://www.openstreetmap.org/copyright) Mitwirkende",
"@mapAttributionOsmData": {}
}

View file

@ -955,18 +955,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "Κρυφα Στοιχεια",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "Κρυφά φίλτρα",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "Οι φωτογραφίες και τα βίντεο που είναι κρυφά δεν θα εμφανίζονται στη συλλογή σας.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "Χωρίς κρυφά φίλτρα",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Κρυφές διαδρομές",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Οι φωτογραφίες και τα βίντεο σε αυτούς τους φακέλους ή σε οποιονδήποτε από τους υποφακέλους τους, δεν θα εμφανίζονται στη συλλογή σας.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Προσθήκη διαδρομής",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Πρόσβαση στον χώρο αποθήκευσης",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Προσβαση στον Χωρο Αποθηκευσης",
@ -1081,10 +1073,6 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "Εμφάνιση του βορρά στην κορυφή",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [HOT](https://www.hotosm.org/) • Hosted by [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "Προβολή στη σελίδα του χάρτη",
"@openMapPageTooltip": {},
"mapEmptyRegion": "Δεν υπάρχουν εικόνες σε αυτήν την περιοχή",

View file

@ -238,6 +238,8 @@
"mapStyleGoogleNormal": "Google Maps",
"mapStyleGoogleHybrid": "Google Maps (Hybrid)",
"mapStyleGoogleTerrain": "Google Maps (Terrain)",
"mapStyleOsmLiberty": "OSM Liberty",
"mapStyleOpenTopoMap": "OpenTopoMap",
"mapStyleOsmHot": "Humanitarian OSM",
"mapStyleStamenWatercolor": "Stamen Watercolor",
@ -944,14 +946,9 @@
"settingsHiddenItemsTile": "Hidden items",
"settingsHiddenItemsPageTitle": "Hidden Items",
"settingsHiddenItemsTabFilters": "Hidden Filters",
"settingsHiddenFiltersBanner": "Photos and videos matching hidden filters will not appear in your collection.",
"settingsHiddenFiltersEmpty": "No hidden filters",
"settingsHiddenItemsTabPaths": "Hidden Paths",
"settingsHiddenPathsBanner": "Photos and videos in these folders, or any of their subfolders, will not appear in your collection.",
"addPathTooltip": "Add path",
"settingsStorageAccessTile": "Storage access",
"settingsStorageAccessPageTitle": "Storage Access",
"settingsStorageAccessBanner": "Some directories require an explicit access grant to modify files in them. You can review here directories to which you previously gave access.",
@ -1032,8 +1029,11 @@
"mapZoomInTooltip": "Zoom in",
"mapZoomOutTooltip": "Zoom out",
"mapPointNorthUpTooltip": "Point north up",
"mapAttributionOsmHot": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [HOT](https://www.hotosm.org/) • Hosted by [OSM France](https://openstreetmap.fr/)",
"mapAttributionStamen": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionOsmData": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors",
"mapAttributionOsmLiberty": "Tiles by [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Hosted by [OSM Americana](https://tile.ourmap.us)",
"mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Tiles by [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)",
"mapAttributionOsmHot": "Tiles by [HOT](https://www.hotosm.org/) • Hosted by [OSM France](https://openstreetmap.fr/)",
"mapAttributionStamen": "Tiles by [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"openMapPageTooltip": "View on Map page",
"mapEmptyRegion": "No images in this region",

View file

@ -905,18 +905,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "Elementos ocultos",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "Filtros",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "Fotos y videos que concuerden con los filtros no aparecerán en su colección.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "Sin filtros",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Ubicaciones ocultas",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Fotos y videos que se encuentren en estos directorios y cualquiera de sus subdirectorios no aparecerán en su colección.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Añadir ubicación",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Acceso al almacenamiento",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Acceso al almacenamiento",
@ -1025,9 +1017,9 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "Apuntar el Norte hacia arriba",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "Datos de mapas © [OpenStreetMap](https://www.openstreetmap.org/copyright) contribuidores • Teselas por [HOT](https://www.hotosm.org/) • Alojado por [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Mosaicos por [HOT](https://www.hotosm.org/) • Alojado por [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "Datos de mapas © [OpenStreetMap](https://www.openstreetmap.org/copyright) contribuidores • Teselas por [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Mosaicos por [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "Ver en página del mapa",
"@openMapPageTooltip": {},
@ -1390,5 +1382,15 @@
"sortOrderShortestFirst": "El más corto primero",
"@sortOrderShortestFirst": {},
"sortOrderLongestFirst": "El más largo primero",
"@sortOrderLongestFirst": {}
"@sortOrderLongestFirst": {},
"mapStyleOpenTopoMap": "OpenTopoMap",
"@mapStyleOpenTopoMap": {},
"mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Mosaicos por [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)",
"@mapAttributionOpenTopoMap": {},
"mapAttributionOsmData": "Datos de mapas © [OpenStreetMap](https://www.openstreetmap.org/copyright) contribuidores",
"@mapAttributionOsmData": {},
"mapAttributionOsmLiberty": "Mosaicos por [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Alojado por [OSM Americana](https://tile.ourmap.us)",
"@mapAttributionOsmLiberty": {},
"mapStyleOsmLiberty": "OSM Liberty",
"@mapStyleOsmLiberty": {}
}

View file

@ -273,20 +273,10 @@
"@videoLoopModeShortOnly": {},
"videoControlsPlaySeek": "Erreproduzitu eta aurrera edo atzera egin",
"@videoControlsPlaySeek": {},
"mapStyleGoogleNormal": "Google Maps",
"@mapStyleGoogleNormal": {},
"nameConflictStrategySkip": "Jauzi",
"@nameConflictStrategySkip": {},
"videoControlsNone": "Bat ere ez",
"@videoControlsNone": {},
"mapStyleGoogleHybrid": "Google Maps (higikorra)",
"@mapStyleGoogleHybrid": {},
"mapStyleGoogleTerrain": "Google Maps (lurra)",
"@mapStyleGoogleTerrain": {},
"mapStyleOsmHot": "OSM humanitarioa",
"@mapStyleOsmHot": {},
"mapStyleStamenWatercolor": "Stamen Watercolor (akuarela)",
"@mapStyleStamenWatercolor": {},
"keepScreenOnNever": "Inoiz",
"@keepScreenOnNever": {},
"nameConflictStrategyReplace": "Ordezkatu",
@ -1109,8 +1099,6 @@
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenFiltersBanner": "Iragazkiekin bat datozen argazki eta bideoak ez dira zure bilduman agertuko.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenItemsTabPaths": "Ezkutuko bideak",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenFiltersEmpty": "Ezkutuko iragazkirik ez",
"@settingsHiddenFiltersEmpty": {},
"settingsStorageAccessTile": "Biltegiratzerako sarrera",
@ -1185,12 +1173,6 @@
"@settingsAllowInstalledAppAccessSubtitle": {},
"settingsEnableBinSubtitle": "Mantendu ezabatutako elementuak 30 egunez",
"@settingsEnableBinSubtitle": {},
"settingsHiddenItemsTabFilters": "Ezkutuko iragazkiak",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenPathsBanner": "Karpeta hauetako argazki eta bideoak, hauen azpikarpetak barne, ez dira zure bilduman agertuko.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Gehitu bidea",
"@addPathTooltip": {},
"settingsStorageAccessPageTitle": "Biltegiratzerako sarrera",
"@settingsStorageAccessPageTitle": {},
"settingsStorageAccessEmpty": "Baimenik ez",
@ -1339,10 +1321,6 @@
"@settingsWidgetDisplayedItem": {},
"tagEditorPageNewTagFieldLabel": "Etiketa berria",
"@tagEditorPageNewTagFieldLabel": {},
"mapAttributionStamen": "Maparen datuak © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Teselak: [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"mapAttributionOsmHot": "Maparen datuak © [OpenStreetMap](https://www.openstreetmap.org/copyright) laguntzaileak • Teselak: [HOT](https://www.hotosm.org/) • Ostalaria: [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"filePickerNoItems": "Elementurik ez",
"@filePickerNoItems": {},
"viewerInfoSearchFieldLabel": "Bilatu metadatuak",
@ -1532,5 +1510,45 @@
"videoRepeatActionSetEnd": "Ezarri amaiera",
"@videoRepeatActionSetEnd": {},
"chipActionShowCollection": "Erakutsi bilduman",
"@chipActionShowCollection": {}
"@chipActionShowCollection": {},
"sortByDuration": "Iraupenaren arabera",
"@sortByDuration": {},
"sortOrderShortestFirst": "Laburrena lehenik",
"@sortOrderShortestFirst": {},
"sortOrderLongestFirst": "Luzeena lehenik",
"@sortOrderLongestFirst": {},
"mapStyleGoogleNormal": "Google Maps",
"@mapStyleGoogleNormal": {},
"mapStyleGoogleHybrid": "Google Maps (higikorra)",
"@mapStyleGoogleHybrid": {},
"mapStyleGoogleTerrain": "Google Maps (lurra)",
"@mapStyleGoogleTerrain": {},
"mapStyleOsmHot": "OSM humanitarioa",
"@mapStyleOsmHot": {},
"mapStyleStamenWatercolor": "Stamen Watercolor (akuarela)",
"@mapStyleStamenWatercolor": {},
"mapStyleOpenTopoMap": "OpenTopoMap",
"@mapStyleOpenTopoMap": {},
"mapStyleOsmLiberty": "OSM Liberty",
"@mapStyleOsmLiberty": {},
"mapAttributionOsmData": "Maparen datuak © [OpenStreetMap](https://www.openstreetmap.org/copyright)-en laguntzaileak",
"@mapAttributionOsmData": {},
"mapAttributionStamen": "Lauzak: [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"mapAttributionOsmHot": "Lauzak: [HOT](https://www.hotosm.org/) • Ostalaria: [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Lauzak: [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)",
"@mapAttributionOpenTopoMap": {},
"mapAttributionOsmLiberty": "Lauzak: [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Ostalaria: [OSM Americana](https://tile.ourmap.us)",
"@mapAttributionOsmLiberty": {},
"explorerActionSelectStorageVolume": "Hautatu biltegia",
"@explorerActionSelectStorageVolume": {},
"selectStorageVolumeDialogTitle": "Hautatu biltegia",
"@selectStorageVolumeDialogTitle": {},
"explorerPageTitle": "Arakatzailea",
"@explorerPageTitle": {},
"setHomeCustom": "Pertsonalizatua",
"@setHomeCustom": {},
"chipActionGoToExplorerPage": "Erakutsi arakatzailean",
"@chipActionGoToExplorerPage": {}
}

View file

@ -1265,8 +1265,6 @@
"@settingsVideoControlsTile": {},
"settingsVideoButtonsTile": "دکمه ها",
"@settingsVideoButtonsTile": {},
"addPathTooltip": "افزودن مسیر",
"@addPathTooltip": {},
"passwordDialogConfirm": "تایید گذرواژه",
"@passwordDialogConfirm": {},
"renameProcessorCounter": "شمارنده",
@ -1317,8 +1315,6 @@
"@settingsViewerQuickActionEditorBanner": {},
"settingsSlideshowRepeat": "تکرار",
"@settingsSlideshowRepeat": {},
"settingsHiddenItemsTabPaths": "مسیر های پنهان",
"@settingsHiddenItemsTabPaths": {},
"settingsTimeToTakeActionTile": "زمان اقدام",
"@settingsTimeToTakeActionTile": {},
"settingsLanguagePageTitle": "زبان",
@ -1405,8 +1401,6 @@
"@settingsCoordinateFormatTile": {},
"collectionActionShowTitleSearch": "نمایش پالایش عنوان",
"@collectionActionShowTitleSearch": {},
"settingsHiddenItemsTabFilters": "پالایش های پنهان",
"@settingsHiddenItemsTabFilters": {},
"openMapPageTooltip": "نمایش در صفحه نقشه",
"@openMapPageTooltip": {},
"viewerInfoLabelPath": "مسیر",
@ -1459,8 +1453,6 @@
"@settingsDisablingBinWarningDialogMessage": {},
"settingsAllowInstalledAppAccessSubtitle": "برای بهبود نمایش آلبوم بهره‌وری میشود",
"@settingsAllowInstalledAppAccessSubtitle": {},
"settingsHiddenPathsBanner": "تصاویر و ویدیوهای موجود در این پوشه‌ها یا هر یک از زیرپوشه‌های آن‌ها در مجموعه شما دیده نمی‌شوند.",
"@settingsHiddenPathsBanner": {},
"settingsStorageAccessBanner": "برخی پوشه ها برای اصلاح پرونپه های موجود در آنها به یک مجوز دسترسی نیاز دارند. در اینجا می توانید پوشه هایی را که قبلاً به آنها دسترسی داشته اید، مرور کنید.",
"@settingsStorageAccessBanner": {},
"collectionMoveFailureFeedback": "{count, plural, =1{هدایت ۱ مورد ناموفق بود} other{هدایت {count} مورد ناموفق بود}}",
@ -1509,9 +1501,9 @@
"@settingsVideoGestureVerticalDragBrightnessVolume": {},
"mapEmptyRegion": "تصویری در این ناحیه وجود ندارد",
"@mapEmptyRegion": {},
"mapAttributionOsmHot": "داده‌های نقشه © [OpenStreetMap](https:www.openstreetmap.orgcopyright) مشارکت‌کنندگان • کاشی ها توسط [HOT](https:www.hotosm.org) • میزبانی شده به دست [OSM France](https:openstreetmap.fr)",
"mapAttributionOsmHot": "کاشی ها توسط [HOT](https:www.hotosm.org) • میزبانی شده به دست [OSM France](https:openstreetmap.fr)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "داده‌های نقشه © [OpenStreetMap](https:www.openstreetmap.org/copyright) مشارکت‌کنندگان • کاشی ها بدست [Stamen Design](https:stamen.com)، [CC BY 3.0](https:creativecommons.orglicensesby3.0)",
"mapAttributionStamen": "کاشی ها بدست [Stamen Design](https:stamen.com)، [CC BY 3.0](https:creativecommons.orglicensesby3.0)",
"@mapAttributionStamen": {},
"addShortcutButtonLabel": "افزودن",
"@addShortcutButtonLabel": {},
@ -1532,5 +1524,7 @@
}
},
"chipActionShowCollection": "نمایش در مجموعه",
"@chipActionShowCollection": {}
"@chipActionShowCollection": {},
"mapAttributionOsmData": "داده‌های نقشه © [OpenStreetMap](https:www.openstreetmap.org/copyright) مشارکت‌کنندگان",
"@mapAttributionOsmData": {}
}

View file

@ -959,18 +959,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "Éléments masqués",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "Filtres masqués",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "Les images et vidéos correspondantes aux filtres masqués napparaîtront pas dans votre collection.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "Aucun filtre masqué",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Chemins masqués",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Les images et vidéos dans ces dossiers, ou leurs sous-dossiers, napparaîtront pas dans votre collection.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Ajouter un chemin",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Accès au stockage",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Accès au stockage",
@ -1085,9 +1077,9 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "Placer le nord en haut",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "Données © les contributeurs d[OpenStreetMap](https://www.openstreetmap.org/copyright) • Fond de carte par [HOT](https://www.hotosm.org/) • Hébergé par [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Fond de carte par [HOT](https://www.hotosm.org/) • Hébergé par [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "Données © les contributeurs d[OpenStreetMap](https://www.openstreetmap.org/copyright) • Fond de carte par [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Fond de carte par [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "Ouvrir la page Carte",
"@openMapPageTooltip": {},
@ -1390,5 +1382,15 @@
"sortOrderShortestFirst": "Plus courts dabord",
"@sortOrderShortestFirst": {},
"sortOrderLongestFirst": "Plus longs dabord",
"@sortOrderLongestFirst": {}
"@sortOrderLongestFirst": {},
"mapStyleOpenTopoMap": "OpenTopoMap",
"@mapStyleOpenTopoMap": {},
"mapStyleOsmLiberty": "OSM Liberty",
"@mapStyleOsmLiberty": {},
"mapAttributionOsmLiberty": "Fond de carte par [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Hébergé par [OSM Americana](https://tile.ourmap.us)",
"@mapAttributionOsmLiberty": {},
"mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Fond de carte par [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)",
"@mapAttributionOpenTopoMap": {},
"mapAttributionOsmData": "Données © les contributeurs d[OpenStreetMap](https://www.openstreetmap.org/copyright)",
"@mapAttributionOsmData": {}
}

View file

@ -491,8 +491,6 @@
"@settingsVideoAutoPlay": {},
"settingsVideoPageTitle": "Videó beállítások",
"@settingsVideoPageTitle": {},
"settingsHiddenItemsTabPaths": "Rejtett helyek",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenItemsPageTitle": "Rejtett elemek",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTile": "Rejtett elemek",
@ -715,13 +713,13 @@
"@sortByAlbumFileName": {},
"sortByRating": "Értékelés",
"@sortByRating": {},
"sortOrderNewestFirst": "Legújabb legelől",
"sortOrderNewestFirst": "Legújabb legelöl",
"@sortOrderNewestFirst": {},
"sortOrderOldestFirst": "Legrégebbi legelől",
"sortOrderOldestFirst": "Legrégebbi legelöl",
"@sortOrderOldestFirst": {},
"sortOrderLargestFirst": "Legnagyobb legelől",
"sortOrderLargestFirst": "Legnagyobb legelöl",
"@sortOrderLargestFirst": {},
"sortOrderSmallestFirst": "Legkisebb legelől",
"sortOrderSmallestFirst": "Legkisebb legelöl",
"@sortOrderSmallestFirst": {},
"albumGroupType": "Típus szerint",
"@albumGroupType": {},
@ -1114,9 +1112,9 @@
"count": {}
}
},
"sortOrderHighestFirst": "Legmagasabb legelől",
"sortOrderHighestFirst": "Legmagasabb legelöl",
"@sortOrderHighestFirst": {},
"sortOrderLowestFirst": "Legalacsonyabb legelől",
"sortOrderLowestFirst": "Legalacsonyabb legelöl",
"@sortOrderLowestFirst": {},
"albumGroupNone": "Nincs csoportositás",
"@albumGroupNone": {},
@ -1278,12 +1276,8 @@
"@settingsEnableBinSubtitle": {},
"settingsAllowMediaManagement": "Média kezelés engedélyezése",
"@settingsAllowMediaManagement": {},
"settingsHiddenItemsTabFilters": "Rejtett szűrők",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersEmpty": "Nincsenek rejtett szűrők",
"@settingsHiddenFiltersEmpty": {},
"addPathTooltip": "Hely hozzáadása",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Tárhely hozzáférés",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Tárhely hozzáférés",
@ -1419,8 +1413,6 @@
"@settingsAllowInstalledAppAccessSubtitle": {},
"settingsAllowInstalledAppAccess": "Hozzáférés engedélyezése az app leltárhoz",
"@settingsAllowInstalledAppAccess": {},
"settingsHiddenPathsBanner": "Képek és videók ezekből a mappákból és ezek almappáikból nem jelennek meg a gyűjteményedben.",
"@settingsHiddenPathsBanner": {},
"settingsHiddenFiltersBanner": "A rejtett szűrőknek megfelelő képek és videók nem jelennek meg a gyűjteményében.",
"@settingsHiddenFiltersBanner": {},
"settingsTimeToTakeActionTile": "Ideje cselekedni",
@ -1429,10 +1421,6 @@
"@settingsAccessibilityShowPinchGestureAlternatives": {},
"settingsStorageAccessBanner": "Egyes könyvtárak kifejezett hozzáférési engedélyt igényelnek a benne lévő fájlok módosításához. Itt áttekintheted a könyvtárakat, amelyekhez korábban hozzáférést adtál.",
"@settingsStorageAccessBanner": {},
"mapAttributionOsmHot": "Térképadatok © [OpenStreetMap](https://www.openstreetmap.org/copyright) közreműködők • [HOT](https://www.hotosm.org/) csempék • [OSM France](https://openstreetmap.fr/) kiszolgáló",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "Térképadatok © [OpenStreetMap](https://www.openstreetmap.org/copyright) közreműködők • [Stamen Design](https://stamen.com) csempék, [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"viewerInfoSearchEmpty": "Nincs egyező kulcs",
"@viewerInfoSearchEmpty": {},
"viewerInfoSearchSuggestionRights": "Jogok",
@ -1528,5 +1516,39 @@
"videoRepeatActionSetEnd": "Végpont beállítása",
"@videoRepeatActionSetEnd": {},
"chipActionShowCollection": "Megjelenítés a gyűjteményekben",
"@chipActionShowCollection": {}
"@chipActionShowCollection": {},
"sortByDuration": "Hossz szerint",
"@sortByDuration": {},
"explorerActionSelectStorageVolume": "Tároló kiválasztása",
"@explorerActionSelectStorageVolume": {},
"setHomeCustom": "Egyéni",
"@setHomeCustom": {},
"sortOrderShortestFirst": "Legrövidebb legelöl",
"@sortOrderShortestFirst": {},
"explorerPageTitle": "Böngésző",
"@explorerPageTitle": {},
"sortOrderLongestFirst": "Leghosszabb legelöl",
"@sortOrderLongestFirst": {},
"selectStorageVolumeDialogTitle": "Tároló Kiválasztása",
"@selectStorageVolumeDialogTitle": {},
"mapStyleOpenTopoMap": "OpenTopoMap",
"@mapStyleOpenTopoMap": {},
"mapStyleOsmLiberty": "OSM Liberty",
"@mapStyleOsmLiberty": {},
"mapAttributionOsmData": "Térképadatok © [OpenStreetMap](https://www.openstreetmap.org/copyright) közreműködők",
"@mapAttributionOsmData": {},
"mapAttributionOsmHot": "Csempék: [HOT](https://www.hotosm.org/) • Kiszolgálja: [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "Csempék: [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | Csempék: [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)",
"@mapAttributionOpenTopoMap": {},
"mapAttributionOsmLiberty": "Csempék: [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • Kiszolgálja: [OSM Americana](https://tile.ourmap.us)",
"@mapAttributionOsmLiberty": {},
"renameProcessorHash": "Hash-kulcs",
"@renameProcessorHash": {},
"settingsForceWesternArabicNumeralsTile": "Arab számok használata",
"@settingsForceWesternArabicNumeralsTile": {},
"chipActionGoToExplorerPage": "Mutatás a böngészőben",
"@chipActionGoToExplorerPage": {}
}

View file

@ -935,18 +935,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "Benda Tersembunyi",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "Filter Tersembunyi",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "Foto dan video filter tersembunyi yang cocok tidak akan muncul di koleksi Anda.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "Tidak ada filter tersembunyi",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Jalan Tersembunyi",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Foto dan video di folder ini, atau subfoldernya, tidak akan muncul di koleksi Anda.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Tambahkan jalan",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Akses penyimpanan",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Akses Penyimpanan",
@ -1057,9 +1049,9 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "Arahkan ke utara ke atas",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "Data peta © [OpenStreetMap](https://www.openstreetmap.org/copyright) kontributor • Tile oleh [HOT](https://www.hotosm.org/) • Diselenggarakan oleh [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Tile oleh [HOT](https://www.hotosm.org/) • Diselenggarakan oleh [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "Data peta © [OpenStreetMap](https://www.openstreetmap.org/copyright) kontributor • Tile oleh [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Tile oleh [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "Lihat di halaman Peta",
"@openMapPageTooltip": {},
@ -1390,5 +1382,7 @@
"sortOrderShortestFirst": "Yang terpendek dulu",
"@sortOrderShortestFirst": {},
"chipActionGoToExplorerPage": "Tampilkan di Explorer",
"@chipActionGoToExplorerPage": {}
"@chipActionGoToExplorerPage": {},
"mapAttributionOsmData": "Data peta © [OpenStreetMap](https://www.openstreetmap.org/copyright) kontributor",
"@mapAttributionOsmData": {}
}

View file

@ -17,7 +17,7 @@
"@settingsEnableBinSubtitle": {},
"viewerInfoPageTitle": "Upplýsingar",
"@viewerInfoPageTitle": {},
"mapAttributionStamen": "Kortagögn frá © [OpenStreetMap](https://www.openstreetmap.org/copyright) þátttakendum • Kortatíglar frá [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Kortatíglar frá [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"widgetOpenPageViewer": "Opna skoðara",
"@widgetOpenPageViewer": {},
@ -453,8 +453,6 @@
"@albumGroupTier": {},
"aboutBugReportInstruction": "Tilkynna á GitHub með atvikaskrám og kerfisupplýsingum",
"@aboutBugReportInstruction": {},
"addPathTooltip": "Bæta við slóð",
"@addPathTooltip": {},
"filePickerUseThisFolder": "Nota þessa möppu",
"@filePickerUseThisFolder": {},
"videoActionCaptureFrame": "Taka ramma",
@ -768,8 +766,6 @@
"@drawerCollectionMotionPhotos": {},
"settingsDefault": "Sjálfgefið",
"@settingsDefault": {},
"settingsHiddenItemsTabFilters": "Felusíur",
"@settingsHiddenItemsTabFilters": {},
"settingsSlideshowAnimatedZoomEffect": "Aðdráttur með hreyfingu",
"@settingsSlideshowAnimatedZoomEffect": {},
"viewerActionSettings": "Stillingar",
@ -948,7 +944,7 @@
"@entryInfoActionEditTags": {},
"collectionActionHideTitleSearch": "Fela titilsíu",
"@collectionActionHideTitleSearch": {},
"mapAttributionOsmHot": "Kortagögn frá © [OpenStreetMap](https://www.openstreetmap.org/copyright) þátttakendum • Kortatíglar frá [HOT](https://www.hotosm.org/) • Hýst af [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Kortatíglar frá [HOT](https://www.hotosm.org/) • Hýst af [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"settingsNavigationDrawerTile": "Leiðsagnarval",
"@settingsNavigationDrawerTile": {},
@ -960,8 +956,6 @@
"@settingsHiddenItemsPageTitle": {},
"durationDialogHours": "Klukkustundir",
"@durationDialogHours": {},
"settingsHiddenPathsBanner": "Myndir og myndskeið í þessum möppum, eða undirmöppum þeirra, munu ekki birtast í safninu þínu.",
"@settingsHiddenPathsBanner": {},
"settingsKeepScreenOnDialogTitle": "Halda skjá í gangi",
"@settingsKeepScreenOnDialogTitle": {},
"wallpaperTargetHome": "Upphafsskjár",
@ -1376,8 +1370,6 @@
"@appPickDialogTitle": {},
"cancelTooltip": "Hætta við",
"@cancelTooltip": {},
"settingsHiddenItemsTabPaths": "Faldar slóðir",
"@settingsHiddenItemsTabPaths": {},
"viewerInfoSearchSuggestionRights": "Réttindi",
"@viewerInfoSearchSuggestionRights": {},
"mapPointNorthUpTooltip": "Norður beint upp",
@ -1532,5 +1524,7 @@
"videoRepeatActionSetEnd": "Stilla endi",
"@videoRepeatActionSetEnd": {},
"chipActionShowCollection": "Sýna í safni",
"@chipActionShowCollection": {}
"@chipActionShowCollection": {},
"mapAttributionOsmData": "Kortagögn frá © [OpenStreetMap](https://www.openstreetmap.org/copyright) þátttakendum",
"@mapAttributionOsmData": {}
}

View file

@ -955,18 +955,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "Elementi nascosti",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "Filtri nascosti",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "Le foto e i video che corrispondono ai filtri nascosti non appariranno nella tua collezione.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "Nessun filtro nascosto",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Percorsi nascosti",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Le foto e i video in queste cartelle, o in qualsiasi loro sottocartella, non appariranno nella tua collezione.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Aggiungi percorso",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Accesso a tutti i file",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Accesso a tutti i file",
@ -1081,9 +1073,9 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "Punta a nord verso lalto",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "Dati della mappa © collaboratori di [OpenStreetMap](https://www.openstreetmap.org/copyright) • Titoli di [HOT](https://www.hotosm.org/) • Ospitato da [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Titoli di [HOT](https://www.hotosm.org/) • Ospitato da [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "Dati della mappa © collaboratori di [OpenStreetMap](https://www.openstreetmap.org/copyright) • Titoli di [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Titoli di [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "Visualizza sulla pagina della mappa",
"@openMapPageTooltip": {},
@ -1390,5 +1382,7 @@
"setHomeCustom": "Personalizzato",
"@setHomeCustom": {},
"chipActionGoToExplorerPage": "Mostra nell'Esploratore",
"@chipActionGoToExplorerPage": {}
"@chipActionGoToExplorerPage": {},
"mapAttributionOsmData": "Dati della mappa © collaboratori di [OpenStreetMap](https://www.openstreetmap.org/copyright)",
"@mapAttributionOsmData": {}
}

View file

@ -903,18 +903,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "非表示アイテム",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "非表示フィルター",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "非表示のフィルターに一致する写真と動画は、コレクションに表示されません。",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "非表示フィルターがありません",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "非表示パス",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "これらのフォルダまたはそのサブフォルダにある写真と動画は、コレクションに表示されません。",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "パスを追加",
"@addPathTooltip": {},
"settingsStorageAccessTile": "ストレージへのアクセス",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "ストレージへのアクセス",
@ -1023,10 +1015,6 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "北が上になるように表示",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "地図データ © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [HOT](https://www.hotosm.org/) • Hosted by [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "地図データ © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "地図ページで表示",
"@openMapPageTooltip": {},
"mapEmptyRegion": "この地域の画像はありません",
@ -1376,5 +1364,7 @@
"chipActionGoToExplorerPage": "エクスプローラーで表示",
"@chipActionGoToExplorerPage": {},
"filterLocatedLabel": "位置情報あり",
"@filterLocatedLabel": {}
"@filterLocatedLabel": {},
"mapAttributionOsmData": "地図データ © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors",
"@mapAttributionOsmData": {}
}

View file

@ -959,18 +959,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "숨겨진 항목",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "숨겨진 필터",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "이 필터에 맞는 사진과 동영상이 숨겨지고 있으며 이 앱에서 보여지지 않을 것입니다.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "숨겨진 필터가 없습니다",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "숨겨진 경로",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "이 경로에 있는 사진과 동영상이 숨겨지고 있으며 이 앱에서 보여지지 않을 것입니다.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "경로 추가",
"@addPathTooltip": {},
"settingsStorageAccessTile": "저장공간 접근",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "저장공간 접근",
@ -1085,9 +1077,9 @@
"@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "북쪽을 위로 가리키기",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [HOT](https://www.hotosm.org/) • 호스팅 [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "타일 [HOT](https://www.hotosm.org/) • 호스팅 [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapAttributionStamen": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "타일 [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"openMapPageTooltip": "지도 페이지에서 보기",
"@openMapPageTooltip": {},
@ -1390,5 +1382,15 @@
"sortOrderShortestFirst": "짧은 순",
"@sortOrderShortestFirst": {},
"sortOrderLongestFirst": "긴 순",
"@sortOrderLongestFirst": {}
"@sortOrderLongestFirst": {},
"mapStyleOpenTopoMap": "OpenTopoMap",
"@mapStyleOpenTopoMap": {},
"mapAttributionOpenTopoMap": "[SRTM](https://www.earthdata.nasa.gov/sensors/srtm) | 타일 [OpenTopoMap](https://opentopomap.org/), [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/)",
"@mapAttributionOpenTopoMap": {},
"mapAttributionOsmData": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자",
"@mapAttributionOsmData": {},
"mapAttributionOsmLiberty": "타일 [OpenMapTiles](https://www.openmaptiles.org/), [CC BY](http://creativecommons.org/licenses/by/4.0) • 호스팅 [OSM Americana](https://tile.ourmap.us)",
"@mapAttributionOsmLiberty": {},
"mapStyleOsmLiberty": "OSM Liberty",
"@mapStyleOsmLiberty": {}
}

View file

@ -731,18 +731,10 @@
"@settingsHiddenItemsTile": {},
"settingsHiddenItemsPageTitle": "Paslėpti elementai",
"@settingsHiddenItemsPageTitle": {},
"settingsHiddenItemsTabFilters": "Paslėpti filtrai",
"@settingsHiddenItemsTabFilters": {},
"settingsHiddenFiltersBanner": "Nuotraukos ir vaizdo įrašai, atitinkantys paslėptus filtrus, nebus rodomi jūsų kolekcijoje.",
"@settingsHiddenFiltersBanner": {},
"settingsHiddenFiltersEmpty": "Nėra paslėptų filtrų",
"@settingsHiddenFiltersEmpty": {},
"settingsHiddenItemsTabPaths": "Paslėpti keliai",
"@settingsHiddenItemsTabPaths": {},
"settingsHiddenPathsBanner": "Nuotraukos ir vaizdo įrašai šiuose aplankuose ar jų pakatalogiuose nebus rodomi jūsų kolekcijoje.",
"@settingsHiddenPathsBanner": {},
"addPathTooltip": "Pridėti kelią",
"@addPathTooltip": {},
"settingsStorageAccessTile": "Prieiga prie saugyklos",
"@settingsStorageAccessTile": {},
"settingsStorageAccessPageTitle": "Prieiga prie saugyklos",
@ -1255,7 +1247,7 @@
"@viewerInfoLabelDescription": {},
"mapPointNorthUpTooltip": "Centruoti pagal šiaurę",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "Žemėlapio duomenys © [OpenStreetMap](https://www.openstreetmap.org/copyright) bendraautoriai • Sluoksniai [HOT](https://www.hotosm.org/) • Priegloba [OSM France](https://openstreetmap.fr/)",
"mapAttributionOsmHot": "Sluoksniai [HOT](https://www.hotosm.org/) • Priegloba [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {},
"mapEmptyRegion": "Šiame regione paveikslėlių nėra",
"@mapEmptyRegion": {},
@ -1317,7 +1309,7 @@
"@settingsThumbnailShowLocationIcon": {},
"tagPlaceholderCountry": "Šalis",
"@tagPlaceholderCountry": {},
"mapAttributionStamen": "Žemėlapio duomenys © [OpenStreetMap](https://www.openstreetmap.org/copyright) bendradarbiai • Sluoksniai [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"mapAttributionStamen": "Sluoksniai [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {},
"tagPlaceholderPlace": "Vieta",
"@tagPlaceholderPlace": {},
@ -1338,5 +1330,7 @@
"entryInfoActionRemoveLocation": "Pašalinti vietą",
"@entryInfoActionRemoveLocation": {},
"chipActionShowCollection": "Rodyti kolekcijoje",
"@chipActionShowCollection": {}
"@chipActionShowCollection": {},
"mapAttributionOsmData": "Žemėlapio duomenys © [OpenStreetMap](https://www.openstreetmap.org/copyright) bendradarbiai",
"@mapAttributionOsmData": {}
}

Some files were not shown because too many files have changed in this diff Show more