Merge branch 'main' into mobile-preview-video

This commit is contained in:
Prateek Sunal 2025-02-04 13:43:55 +05:30
commit 5203b764c5
106 changed files with 3927 additions and 3148 deletions

View File

@ -492,6 +492,12 @@
{
"title": "Kagi"
},
{
"title": "Keygen",
"altNames": [
"keygen.sh"
]
},
{
"title": "Kick"
},

View File

@ -0,0 +1,19 @@
<svg width="100%" height="100%" viewBox="0 0 113 113" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-1298.97,-1016.72)">
<g transform="matrix(0.5,0,0,0.5,736.463,641.721)">
<g transform="matrix(0.834925,0,0,0.834925,161.667,288.323)">
<circle cx="1198.72" cy="777.527" r="44.914" style="fill:#000811;"/>
</g>
</g>
<g transform="matrix(0.5,0,0,0.5,736.463,641.721)">
<g transform="matrix(0.834925,0,0,0.834925,311.66,138.323)">
<circle cx="1198.72" cy="777.527" r="44.914" style="fill:#000811;"/>
</g>
</g>
<g transform="matrix(0.5,0,0,0.5,736.463,641.721)">
<g transform="matrix(1,0,0,1,281.792,137.715)">
<path d="M955.708,762.285C935.011,762.285 918.208,745.482 918.208,724.785C918.208,704.088 935.011,687.285 955.708,687.285C976.405,687.285 993.208,704.088 993.208,724.785C993.208,745.482 1010.01,762.285 1030.71,762.285C1051.4,762.285 1068.21,779.088 1068.21,799.785C1068.21,820.482 1051.4,837.285 1030.71,837.285C1010.01,837.285 993.208,820.482 993.208,799.785C993.208,779.088 976.405,762.285 955.708,762.285Z" style="fill:#000811;"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -3,6 +3,7 @@
## v1.7.9 (Unreleased)
- Faster and more stable thumbnail generation.
- Support `.supplemental-metadata` JSON files in Google Takeout.
- .
## v1.7.8

View File

@ -108,7 +108,7 @@ For video conversions and metadata extraction, we use ffmpeg. To bundle a
[ffmpeg-static](https://github.com/eugeneware/ffmpeg-static).
> There is a significant (~20x) speed difference between using the compiled
> ffmpeg binary and using the wasm one (that our renderer process already has).
> FFmpeg binary and using the Wasm one (that our renderer process already has).
> Which is why we bundle it to speed up operations on the desktop app.
On Linux and Windows, we use `vips` for thumbnail generation and JPEG conversion

View File

@ -9,7 +9,7 @@ import {
makeTempFilePath,
} from "../utils/temp";
/* Ditto in the web app's code (used by the WASM FFmpeg invocation). */
/* Ditto in the web app's code (used by the Wasm FFmpeg invocation). */
const ffmpegPathPlaceholder = "FFMPEG";
const inputPathPlaceholder = "INPUT";
const outputPathPlaceholder = "OUTPUT";
@ -19,7 +19,7 @@ const outputPathPlaceholder = "OUTPUT";
*
* [Note: FFmpeg in Electron]
*
* There is a wasm build of FFmpeg, but that is currently 10-20 times slower
* There is a Wasm build of FFmpeg, but that is currently 10-20 times slower
* that the native build. That is slow enough to be unusable for our purposes.
* https://ffmpegwasm.netlify.app/docs/performance
*

View File

@ -20,7 +20,7 @@ let _child: UtilityProcess | undefined;
* [Note: ML IPC]
*
* The primary reason for doing ML tasks in the Node.js layer is so that we can
* use the binary ONNX runtime, which is 10-20x faster than the WASM one that
* use the binary ONNX runtime, which is 10-20x faster than the Wasm one that
* can be used directly on the web layer.
*
* For this to work, the main and renderer process need to communicate with each

View File

@ -108,6 +108,9 @@ abstract class IMLDataDB<T> {
Future<List<EmbeddingVector>> getAllClipVectors();
Future<Map<int, int>> clipIndexedFileWithVersion();
Future<Map<int, EmbeddingVector>> getClipVectorsForFileIDs(
Iterable<int> fileIDs,
);
Future<int> getClipIndexedFileCount({int minimumMlVersion});
Future<void> putClip(List<ClipEmbedding> embeddings);
Future<void> deleteClipEmbeddings(List<T> fileIDs);

View File

@ -342,11 +342,6 @@ class MLDataDB extends IMLDataDB<int> {
);
final clusterIDs =
clusterRows.map((e) => e[clusterIDColumn] as String).toList();
// final List<Map<String, dynamic>> faceMaps = await db.getAll(
// 'SELECT * FROM $facesTable where '
// '$faceIDColumn in (SELECT $faceIDColumn from $faceClustersTable where $clusterIDColumn IN (${clusterIDs.join(",")}))'
// 'AND $fileIDColumn in (${fileId.join(",")}) AND $faceScore > $kMinimumQualityFaceScore ORDER BY $faceScore DESC',
// );
final List<Map<String, dynamic>> faceMaps = await db.getAll(
'''
@ -357,10 +352,9 @@ class MLDataDB extends IMLDataDB<int> {
WHERE $clusterIDColumn IN (${List.filled(clusterIDs.length, '?').join(',')})
)
AND $fileIDColumn IN (${List.filled(fileId.length, '?').join(',')})
AND $faceScore > ?
ORDER BY $faceScore DESC
''',
[...clusterIDs, ...fileId, kMinimumQualityFaceScore],
[...clusterIDs, ...fileId],
);
if (faceMaps.isNotEmpty) {
if (avatarFileId != null) {
@ -418,6 +412,28 @@ class MLDataDB extends IMLDataDB<int> {
return maps.map((e) => mapRowToFace(e)).toList();
}
Future<Map<int, List<Face>>> getFacesForFileIDs(
Iterable<int> fileUploadIDs,
) async {
final db = await instance.asyncDB;
final List<Map<String, dynamic>> maps = await db.getAll(
'''
SELECT * FROM $facesTable
WHERE $fileIDColumn IN (${fileUploadIDs.map((id) => "'$id'").join(",")})
''',
);
if (maps.isEmpty) {
return {};
}
final result = <int, List<Face>>{};
for (final map in maps) {
final face = mapRowToFace(map);
final fileID = map[fileIDColumn] as int;
result.putIfAbsent(fileID, () => <Face>[]).add(face);
}
return result;
}
@override
Future<Map<String, Iterable<String>>> getClusterToFaceIDs(
Set<String> clusterIDs,
@ -503,6 +519,22 @@ class MLDataDB extends IMLDataDB<int> {
return result;
}
Future<Map<String, String>> getFaceIdToPersonIdForFaces(
Iterable<String> faceIDs,
) async {
final db = await instance.asyncDB;
final List<Map<String, dynamic>> maps = await db.getAll(
'SELECT $faceIDColumn, $personIdColumn FROM $clusterPersonTable '
'INNER JOIN $faceClustersTable ON $clusterPersonTable.$clusterIDColumn = $faceClustersTable.$clusterIDColumn '
'WHERE $faceIDColumn IN (${faceIDs.map((id) => "'$id'").join(",")})',
);
final Map<String, String> result = {};
for (final map in maps) {
result[map[faceIDColumn] as String] = map[personIdColumn] as String;
}
return result;
}
@override
Future<Map<String, Set<String>>> getClusterIdToFaceIdsForPerson(
String personID,
@ -1164,6 +1196,22 @@ class MLDataDB extends IMLDataDB<int> {
return _convertToVectors(results);
}
@override
Future<Map<int, EmbeddingVector>> getClipVectorsForFileIDs(
Iterable<int> fileIDs,
) async {
final db = await MLDataDB.instance.asyncDB;
final results = await db.getAll(
'SELECT * FROM $clipTable WHERE $fileIDColumn IN (${fileIDs.join(", ")})',
);
final Map<int, EmbeddingVector> embeddings = {};
for (final result in results) {
final embedding = _getVectorFromRow(result);
embeddings[embedding.fileID] = embedding;
}
return embeddings;
}
// Get indexed FileIDs
@override
Future<Map<int, int>> clipIndexedFileWithVersion() async {

View File

@ -4,10 +4,11 @@ import "package:photos/services/machine_learning/face_ml/person/person_service.d
extension UserExtension on User {
//Some initial users have name in name field.
String? get displayName =>
PersonService.instance.emailToPartialPersonDataMapCache[email]?["name"] ??
PersonService.instance.emailToPartialPersonDataMapCache[email]
?[PersonService.kNameKey] ??
((name?.isEmpty ?? true) ? null : name);
String? get linkedPersonID =>
PersonService.instance.emailToPartialPersonDataMapCache[email]
?["person_id"];
?[PersonService.kPersonIDKey];
}

View File

@ -33,7 +33,7 @@ class GenericSearchResult extends SearchResult {
@override
EnteFile? previewThumbnail() {
return _files.first;
return _files.isEmpty ? null : _files.first;
}
@override

View File

@ -1,4 +1,5 @@
import "dart:async";
import "dart:io";
import "package:flutter/material.dart";
import "package:logging/logging.dart";
@ -241,7 +242,7 @@ extension SectionTypeExtensions on SectionType {
return SearchService.instance.getMagicSectionResults(context);
case SectionType.moment:
if (flagService.internalUser) {
if (flagService.internalUser && Platform.isIOS) {
return SearchService.instance.onThisDayOrWeekResults(context, limit);
}
return SearchService.instance.getRandomMomentsSearchResults(context);

View File

@ -80,11 +80,16 @@ class FileDataEntity {
)
: null;
RemoteClipEmbedding? get clipEmbedding => remoteRawData[_clipKey] != null
? RemoteClipEmbedding.fromJson(
remoteRawData[_clipKey] as Map<String, dynamic>,
)
: null;
RemoteClipEmbedding? getClipEmbeddingIfCompatible(
int minClipMlVersion,
) {
final clipData = remoteRawData[_clipKey];
if (clipData == null) return null;
final clipEmbedding =
RemoteClipEmbedding.fromJson(clipData as Map<String, dynamic>);
return clipEmbedding.version >= minClipMlVersion ? clipEmbedding : null;
}
}
class RemoteFaceEmbedding {

View File

@ -27,6 +27,8 @@ class PersonService {
// instance
static PersonService? _instance;
static const kPersonIDKey = "person_id";
static const kNameKey = "name";
static PersonService get instance {
if (_instance == null) {
@ -59,8 +61,8 @@ class PersonService {
for (var person in value) {
if (person.data.email != null && person.data.email!.isNotEmpty) {
_instance!._emailToPartialPersonDataMapCache[person.data.email!] = {
"person_id": person.remoteID,
"name": person.data.name,
kPersonIDKey: person.remoteID,
kNameKey: person.data.name,
};
}
}

View File

@ -4,6 +4,7 @@ import "package:flutter/cupertino.dart";
import "package:flutter/material.dart";
import "package:intl/intl.dart";
import 'package:logging/logging.dart';
import "package:ml_linalg/linalg.dart";
import "package:photos/core/constants.dart";
import 'package:photos/core/event_bus.dart';
import 'package:photos/data/holidays.dart';
@ -40,8 +41,10 @@ import "package:photos/services/filter/db_filters.dart";
import "package:photos/services/location_service.dart";
import "package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart";
import "package:photos/services/machine_learning/face_ml/person/person_service.dart";
import "package:photos/services/machine_learning/ml_computer.dart";
import 'package:photos/services/machine_learning/semantic_search/semantic_search_service.dart';
import "package:photos/services/user_remote_flag_service.dart";
import "package:photos/services/user_service.dart";
import "package:photos/states/location_screen_state.dart";
import "package:photos/ui/viewer/location/add_location_sheet.dart";
import "package:photos/ui/viewer/location/location_screen.dart";
@ -1196,9 +1199,12 @@ class SearchService {
final currentTime = DateTime.now().toLocal();
final currentDayMonth = currentTime.month * 100 + currentTime.day;
final currentWeek = _getWeekNumber(currentTime);
final currentMonth = currentTime.month;
final cutOffTime = currentTime.subtract(const Duration(days: 365));
final averageDailyPhotos = allFiles.length / 365;
final significanceThreshold = averageDailyPhotos * 0.25;
final significantDayThreshold = averageDailyPhotos * 0.25;
final significantWeekThreshold = averageDailyPhotos * 0.40;
// Group files by day-month and year
final dayMonthYearGroups = <int, Map<int, List<EnteFile>>>{};
@ -1217,59 +1223,62 @@ class SearchService {
.add(file);
}
// Process each day-month
// Process each nearby day-month to find significant days
for (final dayMonth in dayMonthYearGroups.keys) {
final dayDiff = dayMonth - currentDayMonth;
if (dayDiff < 0 || dayDiff > 2) continue;
// TODO: lau: this doesn't cover month changes properly
final yearGroups = dayMonthYearGroups[dayMonth]!;
final significantYears = yearGroups.entries
.where((e) => e.value.length > significanceThreshold)
final significantDays = yearGroups.entries
.where((e) => e.value.length > significantDayThreshold)
.map((e) => e.key)
.toList();
if (significantYears.length >= 3) {
if (significantDays.length >= 3) {
// Combine all years for this day-month
final date =
DateTime(currentTime.year, dayMonth ~/ 100, dayMonth % 100);
final allPhotos = yearGroups.values.expand((x) => x).toList();
final photoSelection = await _bestSelection(allPhotos);
searchResults.add(
GenericSearchResult(
ResultType.event,
'Memories of ${DateFormat('MMMM d').format(date)}',
allPhotos,
"${DateFormat('MMMM d').format(date)} through the years",
photoSelection,
hierarchicalSearchFilter: TopLevelGenericFilter(
filterName: DateFormat('MMMM d').format(date),
occurrence: kMostRelevantFilter,
filterResultType: ResultType.event,
matchedUploadedIDs: filesToUploadedFileIDs(allPhotos),
matchedUploadedIDs: filesToUploadedFileIDs(photoSelection),
filterIcon: Icons.event_outlined,
),
),
);
} else {
// Individual entries for significant years
for (final year in significantYears) {
for (final year in significantDays) {
final date = DateTime(year, dayMonth ~/ 100, dayMonth % 100);
final files = yearGroups[year]!;
final photoSelection = await _bestSelection(files);
String name =
DateFormat.yMMMd(Localizations.localeOf(context).languageCode)
.format(date);
if (date.day == currentTime.day && date.month == currentTime.month) {
name = 'This day, ${currentTime.year - date.year} years back';
name = "This day, ${currentTime.year - date.year} years back";
}
searchResults.add(
GenericSearchResult(
ResultType.event,
name,
files,
photoSelection,
hierarchicalSearchFilter: TopLevelGenericFilter(
filterName: name,
occurrence: kMostRelevantFilter,
filterResultType: ResultType.event,
matchedUploadedIDs: filesToUploadedFileIDs(files),
matchedUploadedIDs: filesToUploadedFileIDs(photoSelection),
filterIcon: Icons.event_outlined,
),
),
@ -1277,12 +1286,342 @@ class SearchService {
}
}
if (limit != null && searchResults.length >= limit) break;
if (limit != null && searchResults.length >= limit) return searchResults;
}
// process to find significant weeks (only if there are no significant days)
if (searchResults.isEmpty) {
// Group files by week and year
final currentWeekYearGroups = <int, List<EnteFile>>{};
for (final file in allFiles) {
if (file.creationTime! > cutOffTime.microsecondsSinceEpoch) continue;
final creationTime =
DateTime.fromMicrosecondsSinceEpoch(file.creationTime!);
final week = _getWeekNumber(creationTime);
if (week != currentWeek) continue;
final year = creationTime.year;
currentWeekYearGroups.putIfAbsent(year, () => []).add(file);
}
// Process the week and see if it's significant
if (currentWeekYearGroups.isNotEmpty) {
final significantWeeks = currentWeekYearGroups.entries
.where((e) => e.value.length > significantWeekThreshold)
.map((e) => e.key)
.toList();
if (significantWeeks.length >= 3) {
// Combine all years for this week
final allPhotos =
currentWeekYearGroups.values.expand((x) => x).toList();
final photoSelection = await _bestSelection(allPhotos);
searchResults.add(
GenericSearchResult(
ResultType.event,
"This week through the years",
photoSelection,
hierarchicalSearchFilter: TopLevelGenericFilter(
filterName: "Week $currentWeek",
occurrence: kMostRelevantFilter,
filterResultType: ResultType.event,
matchedUploadedIDs: filesToUploadedFileIDs(photoSelection),
filterIcon: Icons.event_outlined,
),
),
);
} else {
// Individual entries for significant years
for (final year in significantWeeks) {
final date = DateTime(year, 1, 1).add(
Duration(days: (currentWeek - 1) * 7),
);
final files = currentWeekYearGroups[year]!;
final photoSelection = await _bestSelection(files);
final name =
"This week, ${currentTime.year - date.year} years back";
searchResults.add(
GenericSearchResult(
ResultType.event,
name,
photoSelection,
hierarchicalSearchFilter: TopLevelGenericFilter(
filterName: name,
occurrence: kMostRelevantFilter,
filterResultType: ResultType.event,
matchedUploadedIDs: filesToUploadedFileIDs(photoSelection),
filterIcon: Icons.event_outlined,
),
),
);
}
}
}
}
if (limit != null && searchResults.length >= limit) return searchResults;
// process to find fillers (months)
const wantedMemories = 3;
final neededMemories = wantedMemories - searchResults.length;
if (neededMemories <= 0) return searchResults;
const monthSelectionSize = 20;
// Group files by month and year
final currentMonthYearGroups = <int, List<EnteFile>>{};
for (final file in allFiles) {
if (file.creationTime! > cutOffTime.microsecondsSinceEpoch) continue;
final creationTime =
DateTime.fromMicrosecondsSinceEpoch(file.creationTime!);
final month = creationTime.month;
if (month != currentMonth) continue;
final year = creationTime.year;
currentMonthYearGroups.putIfAbsent(year, () => []).add(file);
}
// Add the largest two months plus the month through the years
final sortedYearsForCurrentMonth = currentMonthYearGroups.keys.toList()
..sort(
(a, b) => currentMonthYearGroups[b]!.length.compareTo(
currentMonthYearGroups[a]!.length,
),
);
if (neededMemories > 1) {
for (int i = neededMemories; i > 1; i--) {
if (sortedYearsForCurrentMonth.isEmpty) break;
final year = sortedYearsForCurrentMonth.removeAt(0);
final monthYearFiles = currentMonthYearGroups[year]!;
final photoSelection = await _bestSelection(
monthYearFiles,
prefferedSize: monthSelectionSize,
);
final monthName =
DateFormat.MMMM(Localizations.localeOf(context).languageCode)
.format(DateTime(year, currentMonth));
final name = monthName + ", ${currentTime.year - year} years back";
searchResults.add(
GenericSearchResult(
ResultType.event,
name,
photoSelection,
hierarchicalSearchFilter: TopLevelGenericFilter(
filterName: name,
occurrence: kMostRelevantFilter,
filterResultType: ResultType.event,
matchedUploadedIDs: filesToUploadedFileIDs(photoSelection),
filterIcon: Icons.event_outlined,
),
),
);
}
}
// Show the month through the remaining years
if (sortedYearsForCurrentMonth.isEmpty) return searchResults;
final allPhotos = sortedYearsForCurrentMonth
.expand((year) => currentMonthYearGroups[year]!)
.toList();
final photoSelection =
await _bestSelection(allPhotos, prefferedSize: monthSelectionSize);
final monthName =
DateFormat.MMMM(Localizations.localeOf(context).languageCode)
.format(DateTime(currentTime.year, currentMonth));
final name = monthName + " through the years";
searchResults.add(
GenericSearchResult(
ResultType.event,
name,
photoSelection,
hierarchicalSearchFilter: TopLevelGenericFilter(
filterName: name,
occurrence: kMostRelevantFilter,
filterResultType: ResultType.event,
matchedUploadedIDs: filesToUploadedFileIDs(photoSelection),
filterIcon: Icons.event_outlined,
),
),
);
return searchResults;
}
int _getWeekNumber(DateTime date) {
// Get day of year (1-366)
final int dayOfYear = int.parse(DateFormat('D').format(date));
// Integer division by 7 and add 1 to start from week 1
return ((dayOfYear - 1) ~/ 7) + 1;
}
/// Returns the best selection of files from the given list.
/// Makes sure that the selection is not more than [prefferedSize] or 10 files,
/// and that each year of the original list is represented.
Future<List<EnteFile>> _bestSelection(
List<EnteFile> files, {
int? prefferedSize,
}) async {
final fileCount = files.length;
int targetSize = prefferedSize ?? 10;
if (fileCount <= targetSize) return files;
final safeFiles =
files.where((file) => file.uploadedFileID != null).toList();
final fileIDs = safeFiles.map((e) => e.uploadedFileID!).toSet();
final fileIdToFace = await MLDataDB.instance.getFacesForFileIDs(fileIDs);
final faceIDs =
fileIdToFace.values.expand((x) => x.map((face) => face.faceID)).toSet();
final faceIDsToPersonID =
await MLDataDB.instance.getFaceIdToPersonIdForFaces(faceIDs);
final fileIdToClip =
await MLDataDB.instance.getClipVectorsForFileIDs(fileIDs);
final allYears = safeFiles.map((e) {
final creationTime = DateTime.fromMicrosecondsSinceEpoch(e.creationTime!);
return creationTime.year;
}).toSet();
// Get clip scores for each file
const query =
'Photo of a precious memory radiating warmth, vibrant energy, or quiet beauty — alive with color, light, or emotion';
// TODO: lau: optimize this later so we don't keep computing embedding
final textEmbedding = await MLComputer.instance.runClipText(query);
final textVector = Vector.fromList(textEmbedding);
const clipThreshold = 0.75;
final fileToScore = <int, double>{};
for (final file in safeFiles) {
final clip = fileIdToClip[file.uploadedFileID!];
if (clip == null) {
fileToScore[file.uploadedFileID!] = 0;
continue;
}
final score = clip.vector.dot(textVector);
fileToScore[file.uploadedFileID!] = score;
}
// Get face scores for each file
final fileToFaceCount = <int, int>{};
for (final file in safeFiles) {
final fileID = file.uploadedFileID!;
fileToFaceCount[fileID] = 0;
final faces = fileIdToFace[fileID];
if (faces == null || faces.isEmpty) {
continue;
}
for (final face in faces) {
if (faceIDsToPersonID.containsKey(face.faceID)) {
fileToFaceCount[fileID] = fileToFaceCount[fileID]! + 10;
} else {
fileToFaceCount[fileID] = fileToFaceCount[fileID]! + 1;
}
}
}
final filteredFiles = <EnteFile>[];
if (allYears.length <= 1) {
// TODO: lau: eventually this sorting might have to be replaced with some scoring system
// sort first on clip embeddings score (descending)
safeFiles.sort(
(a, b) => fileToScore[b.uploadedFileID!]!
.compareTo(fileToScore[a.uploadedFileID!]!),
);
// then sort on faces (descending), heavily prioritizing named faces
safeFiles.sort(
(a, b) => fileToFaceCount[b.uploadedFileID!]!
.compareTo(fileToFaceCount[a.uploadedFileID!]!),
);
// then filter out similar images as much as possible
filteredFiles.add(safeFiles.first);
int skipped = 0;
filesLoop:
for (final file in safeFiles.sublist(1)) {
if (filteredFiles.length >= targetSize) break;
final clip = fileIdToClip[file.uploadedFileID!];
if (clip != null && (fileCount - skipped) > targetSize) {
for (final filteredFile in filteredFiles) {
final fClip = fileIdToClip[filteredFile.uploadedFileID!];
if (fClip == null) continue;
final similarity = clip.vector.dot(fClip.vector);
if (similarity > clipThreshold) {
skipped++;
continue filesLoop;
}
}
}
filteredFiles.add(file);
}
} else {
// Multiple years, each represented and roughly equally distributed
if (prefferedSize == null && (allYears.length * 2) > 10) {
targetSize = allYears.length * 3;
if (fileCount < targetSize) return safeFiles;
}
// Group files by year and sort each year's list by CLIP then face count
final yearToFiles = <int, List<EnteFile>>{};
for (final file in safeFiles) {
final creationTime =
DateTime.fromMicrosecondsSinceEpoch(file.creationTime!);
final year = creationTime.year;
yearToFiles.putIfAbsent(year, () => []).add(file);
}
for (final year in yearToFiles.keys) {
final yearFiles = yearToFiles[year]!;
// sort first on clip embeddings score (descending)
yearFiles.sort(
(a, b) => fileToScore[b.uploadedFileID!]!
.compareTo(fileToScore[a.uploadedFileID!]!),
);
// then sort on faces (descending), heavily prioritizing named faces
yearFiles.sort(
(a, b) => fileToFaceCount[b.uploadedFileID!]!
.compareTo(fileToFaceCount[a.uploadedFileID!]!),
);
}
// Then join the years together one by one and filter similar images
final years = yearToFiles.keys.toList()
..sort((a, b) => b.compareTo(a)); // Recent years first
int round = 0;
int skipped = 0;
whileLoop:
while (filteredFiles.length + skipped < fileCount) {
yearLoop:
for (final year in years) {
final yearFiles = yearToFiles[year]!;
if (yearFiles.isEmpty) continue;
final newFile = yearFiles.removeAt(0);
if (round != 0 && (fileCount - skipped) > targetSize) {
// check for filtering
final clip = fileIdToClip[newFile.uploadedFileID!];
if (clip != null) {
for (final filteredFile in filteredFiles) {
final fClip = fileIdToClip[filteredFile.uploadedFileID!];
if (fClip == null) continue;
final similarity = clip.vector.dot(fClip.vector);
if (similarity > clipThreshold) {
skipped++;
continue yearLoop;
}
}
}
}
filteredFiles.add(newFile);
if (filteredFiles.length >= targetSize ||
filteredFiles.length + skipped >= fileCount) {
break whileLoop;
}
}
round++;
}
}
// Order the final selection chronologically
filteredFiles.sort((a, b) => b.creationTime!.compareTo(a.creationTime!));
return filteredFiles;
}
Future<GenericSearchResult?> getRandomDateResults(
BuildContext context,
) async {
@ -1340,6 +1679,7 @@ class SearchService {
final searchResults = <GenericSearchResult>[];
final allFiles = await getAllFilesForSearch();
final peopleToSharedFiles = <User, List<EnteFile>>{};
final existingEmails = <String>{};
for (EnteFile file in allFiles) {
if (file.isOwner) continue;
@ -1353,10 +1693,23 @@ class SearchService {
peopleToSharedFiles[fileOwner]!.add(file);
} else {
peopleToSharedFiles[fileOwner] = [file];
existingEmails.add(fileOwner.email);
}
}
}
final relevantContactEmails =
UserService.instance.getEmailIDsOfRelevantContacts();
for (final email in relevantContactEmails.difference(existingEmails)) {
final user = User(email: email);
if (user.email.toLowerCase().contains(lowerCaseQuery) ||
((user.displayName?.toLowerCase().contains(lowerCaseQuery)) ??
false)) {
peopleToSharedFiles[user] = [];
}
}
peopleToSharedFiles.forEach((key, value) {
searchResults.add(
GenericSearchResult(
@ -1387,6 +1740,8 @@ class SearchService {
final searchResults = <GenericSearchResult>[];
final allFiles = await getAllFilesForSearch();
final peopleToSharedFiles = <User, List<EnteFile>>{};
final existingEmails = <String>{};
int peopleCount = 0;
for (EnteFile file in allFiles) {
if (file.isOwner) continue;
@ -1398,10 +1753,37 @@ class SearchService {
} else {
if (limit != null && limit <= peopleCount) continue;
peopleToSharedFiles[fileOwner] = [file];
existingEmails.add(fileOwner.email);
peopleCount++;
}
}
final allRelevantEmails =
UserService.instance.getEmailIDsOfRelevantContacts();
int? remainingLimit = limit != null ? limit - peopleCount : null;
if (remainingLimit != null) {
// limit - peopleCount will never be negative as of writing this.
// Just in case if something changes in future, we are handling it here.
remainingLimit = max(remainingLimit, 0);
}
final emailsWithNoSharedFiles =
allRelevantEmails.difference(existingEmails);
if (remainingLimit == null) {
for (final email in emailsWithNoSharedFiles) {
final user = User(email: email);
peopleToSharedFiles[user] = [];
}
} else {
for (final email in emailsWithNoSharedFiles) {
if (remainingLimit == 0) break;
final user = User(email: email);
peopleToSharedFiles[user] = [];
remainingLimit = remainingLimit! - 1;
}
}
peopleToSharedFiles.forEach((key, value) {
final name = key.displayName != null && key.displayName!.isNotEmpty
? key.displayName!

View File

@ -1307,6 +1307,7 @@ class UserService {
final existingEmails = <String>{};
final int ownerID = Configuration.instance.getUserID()!;
final String ownerEmail = Configuration.instance.getEmail()!;
existingEmails.add(ownerEmail);
for (final c in CollectionsService.instance.getActiveCollections()) {
// Add collaborators and viewers of collections owned by user
@ -1373,4 +1374,82 @@ class UserService {
return relevantUsers;
}
/// Returns emails of Users that are relevant to the account owner.
/// Note: "User" refers to the account owner in the points below.
/// This includes:
/// - Collaborators and viewers of collections owned by user
/// - Owners of collections shared to user.
/// - All collaborators of collections in which user is a collaborator or
/// a viewer.
/// - All family members of user.
/// - All contacts linked to a person.
Set<String> getEmailIDsOfRelevantContacts() {
final emailIDs = <String>{};
final int ownerID = Configuration.instance.getUserID()!;
final String ownerEmail = Configuration.instance.getEmail()!;
for (final c in CollectionsService.instance.getActiveCollections()) {
// Add collaborators and viewers of collections owned by user
if (c.owner?.id == ownerID) {
for (final User? u in c.sharees ?? []) {
if (u != null && u.id != null && u.email.isNotEmpty) {
if (!emailIDs.contains(u.email)) {
emailIDs.add(u.email);
}
}
}
} else if (c.owner?.id != null && c.owner!.email.isNotEmpty) {
// Add owners of collections shared with user
if (!emailIDs.contains(c.owner!.email)) {
emailIDs.add(c.owner!.email);
}
// Add collaborators of collections shared with user where user is a
// viewer or a collaborator
for (final User? u in c.sharees ?? []) {
if (u != null &&
u.id != null &&
u.email.isNotEmpty &&
u.email == ownerEmail &&
(u.isCollaborator || u.isViewer)) {
for (final User? u in c.sharees ?? []) {
if (u != null &&
u.id != null &&
u.email.isNotEmpty &&
u.isCollaborator) {
if (!emailIDs.contains(u.email)) {
emailIDs.add(u.email);
}
}
}
break;
}
}
}
}
// Add user's family members
final cachedUserDetails = getCachedUserDetails();
if (cachedUserDetails?.familyData?.members?.isNotEmpty ?? false) {
for (final member in cachedUserDetails!.familyData!.members!) {
if (!emailIDs.contains(member.email)) {
emailIDs.add(member.email);
}
}
}
// Add contacts linked to people
final cachedEmailToPartialPersonData =
PersonService.instance.emailToPartialPersonDataMapCache;
for (final email in cachedEmailToPartialPersonData.keys) {
if (!emailIDs.contains(email)) {
emailIDs.add(email);
}
}
emailIDs.remove(ownerEmail);
return emailIDs;
}
}

View File

@ -1,6 +1,5 @@
import 'package:email_validator/email_validator.dart';
import 'package:flutter/material.dart';
import 'package:photos/core/configuration.dart';
import "package:photos/extensions/user_extension.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/api/collection/user.dart";
@ -364,7 +363,6 @@ class _AddParticipantPage extends State<AddParticipantPage> {
List<User> _getSuggestedUser() {
final Set<String> existingEmails = {};
existingEmails.add(Configuration.instance.getEmail()!);
for (final User? u in widget.collection.sharees ?? []) {
if (u != null && u.id != null && u.email.isNotEmpty) {
existingEmails.add(u.email);

View File

@ -118,6 +118,14 @@ class _UserAvatarWidgetState extends State<UserAvatarWidget> {
child: PersonFaceWidget(
_faceThumbnail!,
personId: personID,
onErrorCallback: () {
if (mounted) {
setState(() {
_personID = null;
_faceThumbnail = null;
});
}
},
),
);
} else if (snapshot.hasError) {

View File

@ -3,7 +3,7 @@ import 'package:photos/theme/ente_theme.dart';
class NoThumbnailWidget extends StatelessWidget {
final bool addBorder;
const NoThumbnailWidget({this.addBorder = true, Key? key}) : super(key: key);
const NoThumbnailWidget({this.addBorder = true, super.key});
@override
Widget build(BuildContext context) {

View File

@ -100,7 +100,9 @@ class _ContactResultPageState extends State<ContactResultPage> {
tagPrefix: widget.tagPrefix + widget.searchResult.heroTag(),
selectedFiles: _selectedFiles,
enableFileGrouping: widget.enableGrouping,
initialFiles: [widget.searchResult.resultFiles().first],
initialFiles: widget.searchResult.resultFiles().isNotEmpty
? [widget.searchResult.resultFiles().first]
: null,
header: EmailValidator.validate(_searchResultName)
? Padding(
padding: const EdgeInsets.only(top: 12, bottom: 8),

View File

@ -25,6 +25,7 @@ class PersonFaceWidget extends StatefulWidget {
final bool thumbnailFallback;
final bool cannotTrustFile;
final Uint8List? faceCrop;
final VoidCallback? onErrorCallback;
// PersonFaceWidget constructor checks that both personId and clusterID are not null
// and that the file is not null
@ -36,6 +37,7 @@ class PersonFaceWidget extends StatefulWidget {
this.thumbnailFallback = false,
this.cannotTrustFile = false,
this.faceCrop,
this.onErrorCallback,
super.key,
}) : assert(
personId != null || clusterID != null,
@ -169,6 +171,7 @@ class _PersonFaceWidgetState extends State<PersonFaceWidget> {
e,
s,
);
widget.onErrorCallback?.call();
return null;
}
}

View File

@ -93,7 +93,9 @@ class _SearchResultPageState extends State<SearchResultPage> {
tagPrefix: widget.tagPrefix + widget.searchResult.heroTag(),
selectedFiles: _selectedFiles,
enableFileGrouping: widget.enableGrouping,
initialFiles: [widget.searchResult.resultFiles().first],
initialFiles: widget.searchResult.resultFiles().isNotEmpty
? [widget.searchResult.resultFiles().first]
: null,
);
return GalleryFilesState(

View File

@ -28,108 +28,111 @@ class SearchResultWidget extends StatelessWidget {
final heroTagPrefix = searchResult.heroTag();
final textTheme = getEnteTextTheme(context);
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(4)),
border: Border.all(
color: getEnteColorScheme(context).strokeFainter,
return SizedBox(
key: ValueKey(searchResult.hashCode),
child: GestureDetector(
behavior: HitTestBehavior.opaque,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(4)),
border: Border.all(
color: getEnteColorScheme(context).strokeFainter,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
searchResult.type() == ResultType.shared
? ContactSearchThumbnailWidget(
heroTagPrefix,
searchResult: searchResult as GenericSearchResult,
)
: SearchThumbnailWidget(
searchResult.previewThumbnail(),
heroTagPrefix,
searchResult: searchResult,
),
const SizedBox(width: 12),
Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 220,
child: Text(
searchResult.name(),
style: textTheme.body,
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(height: 4),
Row(
children: [
Text(
_resultTypeName(searchResult.type()),
style: textTheme.smallMuted,
),
FutureBuilder<int>(
future: resultCount ??
Future.value(searchResult.resultFiles().length),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data! > 0) {
final noOfMemories = snapshot.data;
return Text(
" \u2022 " +
(noOfMemories! > 9999
? NumberFormat().format(noOfMemories)
: noOfMemories.toString()),
style: textTheme.smallMuted,
);
} else {
return const SizedBox.shrink();
}
},
),
],
),
],
),
),
const Spacer(),
Padding(
padding: const EdgeInsets.all(16.0),
child: Icon(
Icons.chevron_right,
color: Theme.of(context).colorScheme.subTextColor,
),
),
],
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
searchResult.type() == ResultType.shared
? ContactSearchThumbnailWidget(
heroTagPrefix,
searchResult: searchResult as GenericSearchResult,
)
: SearchThumbnailWidget(
searchResult.previewThumbnail(),
heroTagPrefix,
searchResult: searchResult,
),
const SizedBox(width: 12),
Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 220,
child: Text(
searchResult.name(),
style: textTheme.body,
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(height: 4),
Row(
children: [
Text(
_resultTypeName(searchResult.type()),
style: textTheme.smallMuted,
),
FutureBuilder<int>(
future: resultCount ??
Future.value(searchResult.resultFiles().length),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data! > 0) {
final noOfMemories = snapshot.data;
onTap: () {
RecentSearches().add(searchResult.name());
return Text(
" \u2022 " +
(noOfMemories! > 9999
? NumberFormat().format(noOfMemories)
: noOfMemories.toString()),
style: textTheme.smallMuted,
);
} else {
return const SizedBox.shrink();
}
},
),
],
),
],
),
),
const Spacer(),
Padding(
padding: const EdgeInsets.all(16.0),
child: Icon(
Icons.chevron_right,
color: Theme.of(context).colorScheme.subTextColor,
),
),
],
),
),
onTap: () {
RecentSearches().add(searchResult.name());
if (onResultTap != null) {
onResultTap!();
} else {
if (searchResult.type() == ResultType.shared) {
routeToPage(
context,
ContactResultPage(
searchResult,
),
);
if (onResultTap != null) {
onResultTap!();
} else {
routeToPage(
context,
SearchResultPage(
searchResult,
),
);
if (searchResult.type() == ResultType.shared) {
routeToPage(
context,
ContactResultPage(
searchResult,
),
);
} else {
routeToPage(
context,
SearchResultPage(
searchResult,
),
);
}
}
}
},
},
),
);
}

View File

@ -112,12 +112,21 @@ class _SearchSectionAllPageState extends State<SearchSectionAllPage> {
builder: (context, snapshot) {
if (snapshot.hasData) {
List<SearchResult> sectionResults = snapshot.data!;
if (widget.sectionType.sortByName) {
sectionResults.sort(
(a, b) =>
compareAsciiLowerCaseNatural(b.name(), a.name()),
compareAsciiLowerCaseNatural(a.name(), b.name()),
);
}
if (widget.sectionType == SectionType.contacts) {
final split = sectionResults.splitMatch(
(e) => e.resultFiles().isNotEmpty,
);
sectionResults = split.matched + split.unmatched;
}
if (widget.sectionType == SectionType.location) {
final result = sectionResults.splitMatch(
(e) => e.type() == ResultType.location,

View File

@ -1,4 +1,4 @@
import 'package:flutter/widgets.dart';
import "package:flutter/material.dart";
import "package:logging/logging.dart";
import 'package:photos/models/file/file.dart';
import "package:photos/models/search/generic_search_result.dart";
@ -6,6 +6,7 @@ import "package:photos/models/search/search_constants.dart";
import "package:photos/models/search/search_result.dart";
import "package:photos/models/search/search_types.dart";
import "package:photos/services/machine_learning/face_ml/person/person_service.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/common/loading_widget.dart";
import 'package:photos/ui/viewer/file/no_thumbnail_widget.dart';
import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
@ -107,6 +108,13 @@ class _ContactSearchThumbnailWidgetState
return PersonFaceWidget(
snapshot.data!,
personId: _personID,
onErrorCallback: () {
if (mounted) {
setState(() {
_mostRecentFileOfPerson = null;
});
}
},
);
} else if (snapshot.connectionState == ConnectionState.done &&
snapshot.data == null) {
@ -114,13 +122,13 @@ class _ContactSearchThumbnailWidgetState
? ThumbnailWidget(
_previewThumbnail!,
)
: const NoThumbnailWidget();
: const NoFaceOrFileContactWidget();
} else if (snapshot.hasError) {
_logger.severe(
"Error loading personID",
snapshot.error,
);
return const NoThumbnailWidget();
return const NoFaceOrFileContactWidget();
} else {
return const EnteLoadingWidget();
}
@ -130,7 +138,38 @@ class _ContactSearchThumbnailWidgetState
? ThumbnailWidget(
_previewThumbnail!,
)
: const NoThumbnailWidget(),
: const NoFaceOrFileContactWidget(),
),
);
}
}
class NoFaceOrFileContactWidget extends StatelessWidget {
final bool addBorder;
const NoFaceOrFileContactWidget({this.addBorder = true, super.key});
@override
Widget build(BuildContext context) {
final enteColorScheme = getEnteColorScheme(context);
return Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.horizontal(
left: Radius.circular(4),
),
border: addBorder
? Border.all(
color: enteColorScheme.strokeFaint,
width: 1,
)
: null,
color: enteColorScheme.fillFaint,
),
child: Center(
child: Icon(
Icons.person_2_outlined,
color: enteColorScheme.strokeMuted,
size: 24,
),
),
);
}

View File

@ -213,6 +213,13 @@ class _ContactRecommendationState extends State<ContactRecommendation> {
return PersonFaceWidget(
snapshot.data!,
personId: _personID,
onErrorCallback: () {
if (mounted) {
setState(() {
_mostRecentFileOfPerson = null;
});
}
},
);
} else if (snapshot.connectionState ==
ConnectionState.done &&

View File

@ -217,13 +217,14 @@ Stream<List<FileMLInstruction>> fetchEmbeddingsAndInstructions(
faces.addAll(facesFromRemoteEmbedding);
existingInstruction.shouldRunFaces = false;
}
if (fileMl.clipEmbedding != null &&
fileMl.clipEmbedding!.version >= clipMlVersion) {
final remoteClipEmbedding =
fileMl.getClipEmbeddingIfCompatible(clipMlVersion);
if (remoteClipEmbedding != null) {
clipEmbeddings.add(
ClipEmbedding(
fileID: fileMl.fileID,
embedding: fileMl.clipEmbedding!.embedding,
version: fileMl.clipEmbedding!.version,
embedding: remoteClipEmbedding.embedding,
version: remoteClipEmbedding.version,
),
);
existingInstruction.shouldRunClip = false;
@ -235,6 +236,9 @@ Stream<List<FileMLInstruction>> fetchEmbeddingsAndInstructions(
pendingIndex[fileMl.fileID] = existingInstruction;
}
}
await mlDataDB.bulkInsertFaces(faces);
await mlDataDB.putClip(clipEmbeddings);
for (final fileID in pendingIndex.keys) {
final instruction = pendingIndex[fileID]!;
if (instruction.pendingML) {
@ -246,8 +250,6 @@ Stream<List<FileMLInstruction>> fetchEmbeddingsAndInstructions(
}
}
}
await mlDataDB.bulkInsertFaces(faces);
await mlDataDB.putClip(clipEmbeddings);
}
// Yield any remaining instructions
if (batchToYield.isNotEmpty) {

View File

@ -12,7 +12,7 @@ description: ente photos application
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.9.91+991
version: 0.9.92+992
publish_to: none
environment:

View File

@ -168,7 +168,7 @@ function SharingDetails({ collection, type }) {
<>
<Stack>
<RowButtonGroupTitle icon={<AdminPanelSettingsIcon />}>
{t("OWNER")}
{t("owner")}
</RowButtonGroupTitle>
<RowButtonGroup>
<RowLabel
@ -181,7 +181,7 @@ function SharingDetails({ collection, type }) {
collaborators?.length > 0 && (
<Stack>
<RowButtonGroupTitle icon={<ModeEditIcon />}>
{t("COLLABORATORS")}
{t("collaborators")}
</RowButtonGroupTitle>
<RowButtonGroup>
{collaborators.map((item, index) => (
@ -202,7 +202,7 @@ function SharingDetails({ collection, type }) {
{viewers?.length > 0 && (
<Stack>
<RowButtonGroupTitle icon={<Photo />}>
{t("VIEWERS")}
{t("viewers")}
</RowButtonGroupTitle>
<RowButtonGroup>
{viewers.map((item, index) => (
@ -279,17 +279,17 @@ const EnablePublicShareOptions: React.FC<EnablePublicShareOptionsProps> = ({
return (
<Stack>
<RowButtonGroupTitle icon={<PublicIcon />}>
{t("LINK_SHARE_TITLE")}
{t("share_link_section_title")}
</RowButtonGroupTitle>
<RowButtonGroup>
<RowButton
label={t("CREATE_PUBLIC_SHARING")}
label={t("create_public_link")}
startIcon={<LinkIcon />}
onClick={createSharableURLHelper}
/>
<RowButtonDivider hasIcon />
<RowButton
label={t("COLLECT_PHOTOS")}
label={t("collect_photos")}
startIcon={<DownloadSharpIcon />}
onClick={createCollectPhotoShareableURLHelper}
/>
@ -315,13 +315,13 @@ const handleSharingErrors = (error) => {
let errorMessage = "";
switch (parsedError.message) {
case CustomError.BAD_REQUEST:
errorMessage = t("SHARING_BAD_REQUEST_ERROR");
errorMessage = t("sharing_album_not_allowed");
break;
case CustomError.SUBSCRIPTION_NEEDED:
errorMessage = t("SHARING_DISABLED_FOR_FREE_ACCOUNTS");
errorMessage = t("sharing_disabled_for_free_accounts");
break;
case CustomError.NOT_FOUND:
errorMessage = t("USER_DOES_NOT_EXIST");
errorMessage = t("sharing_user_does_not_exist");
break;
default:
errorMessage = `${t("generic_error_retry")} ${parsedError.message}`;
@ -388,13 +388,13 @@ const EmailShare: React.FC<EmailShareProps> = ({ collection, onRootClose }) => {
<RowButton
startIcon={<AddIcon />}
onClick={openAddViewer}
label={t("ADD_VIEWERS")}
label={t("add_viewers")}
/>
<RowButtonDivider hasIcon />
<RowButton
startIcon={<AddIcon />}
onClick={openAddCollab}
label={t("ADD_COLLABORATORS")}
label={t("add_collaborators")}
/>
</RowButtonGroup>
</Stack>
@ -502,11 +502,11 @@ const AddParticipant: React.FC<AddParticipantProps> = ({
// and already shared
if (email) {
if (email === user.email) {
throw new Error(t("SHARE_WITH_SELF"));
throw new Error(t("sharing_with_self"));
} else if (
collection?.sharees?.find((value) => value.email === email)
) {
throw new Error(t("ALREADY_SHARED", { email: email }));
throw new Error(t("sharing_already_shared", { email: email }));
}
// set emails to array of one email
emails = [email];
@ -541,8 +541,8 @@ const AddParticipant: React.FC<AddParticipantProps> = ({
onRootClose={handleRootClose}
title={
type === COLLECTION_ROLE.VIEWER
? t("ADD_VIEWERS")
: t("ADD_COLLABORATORS")
? t("add_viewers")
: t("add_collaborators")
}
caption={collection.name}
/>
@ -554,8 +554,8 @@ const AddParticipant: React.FC<AddParticipantProps> = ({
fieldType="email"
buttonText={
type === COLLECTION_ROLE.VIEWER
? t("ADD_VIEWERS")
: t("ADD_COLLABORATORS")
? t("add_viewers")
: t("add_collaborators")
}
submitButtonProps={{
size: "large",
@ -658,7 +658,7 @@ const AddParticipantForm: React.FC<AddParticipantFormProps> = (props) => {
{props.hiddenPreInput}
<Stack>
<RowButtonGroupTitle>
{t("ADD_NEW_EMAIL")}
{t("add_new_email")}
</RowButtonGroupTitle>
<TextField
sx={{ marginTop: 0 }}
@ -686,14 +686,13 @@ const AddParticipantForm: React.FC<AddParticipantFormProps> = (props) => {
{props.optionsList.length > 0 && (
<Stack>
<RowButtonGroupTitle>
{t("OR_ADD_EXISTING")}
{t("or_add_existing")}
</RowButtonGroupTitle>
<RowButtonGroup>
{props.optionsList.map((item, index) => (
<>
<React.Fragment key={item}>
<RowButton
fontWeight="regular"
key={item}
onClick={() => {
if (
values.selectedOptions.includes(
@ -735,7 +734,7 @@ const AddParticipantForm: React.FC<AddParticipantFormProps> = (props) => {
{index !==
props.optionsList.length -
1 && <RowButtonDivider />}
</>
</React.Fragment>
))}
</RowButtonGroup>
</Stack>
@ -899,7 +898,7 @@ const ManageEmailShare: React.FC<ManageEmailShareProps> = ({
<RowButtonGroupTitle
icon={<AdminPanelSettingsIcon />}
>
{t("OWNER")}
{t("owner")}
</RowButtonGroupTitle>
<RowButtonGroup>
<RowLabel
@ -910,14 +909,13 @@ const ManageEmailShare: React.FC<ManageEmailShareProps> = ({
</Stack>
<Stack>
<RowButtonGroupTitle icon={<ModeEditIcon />}>
{t("COLLABORATORS")}
{t("collaborators")}
</RowButtonGroupTitle>
<RowButtonGroup>
{collaborators.map((item) => (
<>
<React.Fragment key={item}>
<RowButton
fontWeight="regular"
key={item}
onClick={() =>
openManageParticipant(item)
}
@ -926,7 +924,7 @@ const ManageEmailShare: React.FC<ManageEmailShareProps> = ({
endIcon={<ChevronRightIcon />}
/>
<RowButtonDivider hasIcon />
</>
</React.Fragment>
))}
<RowButton
@ -934,22 +932,21 @@ const ManageEmailShare: React.FC<ManageEmailShareProps> = ({
onClick={openAddCollab}
label={
collaborators?.length
? t("ADD_MORE")
: t("ADD_COLLABORATORS")
? t("add_more")
: t("add_collaborators")
}
/>
</RowButtonGroup>
</Stack>
<Stack>
<RowButtonGroupTitle icon={<Photo />}>
{t("VIEWERS")}
{t("viewers")}
</RowButtonGroupTitle>
<RowButtonGroup>
{viewers.map((item) => (
<>
<React.Fragment key={item}>
<RowButton
fontWeight="regular"
key={item}
onClick={() =>
openManageParticipant(item)
}
@ -957,17 +954,16 @@ const ManageEmailShare: React.FC<ManageEmailShareProps> = ({
startIcon={<Avatar email={item} />}
endIcon={<ChevronRightIcon />}
/>
<RowButtonDivider hasIcon />
</>
</React.Fragment>
))}
<RowButton
startIcon={<AddIcon />}
onClick={openAddViewer}
label={
viewers?.length
? t("ADD_MORE")
: t("ADD_VIEWERS")
? t("add_more")
: t("add_viewers")
}
/>
</RowButtonGroup>
@ -1047,23 +1043,21 @@ const ManageParticipant: React.FC<ManageParticipantProps> = ({
if (newRole === "VIEWER") {
contentText = (
<Trans
i18nKey="CHANGE_PERMISSIONS_TO_VIEWER"
values={{
selectedEmail: `${selectedEmail}`,
}}
i18nKey="change_permission_to_viewer"
values={{ selectedEmail }}
/>
);
buttonText = t("CONVERT_TO_VIEWER");
buttonText = t("confirm_convert_to_viewer");
} else if (newRole === "COLLABORATOR") {
contentText = t("CHANGE_PERMISSIONS_TO_COLLABORATOR", {
selectedEmail: selectedEmail,
contentText = t("change_permission_to_collaborator", {
selectedEmail,
});
buttonText = t("CONVERT_TO_COLLABORATOR");
buttonText = t("confirm_convert_to_collaborator");
}
showMiniDialog({
title: t("CHANGE_PERMISSION"),
title: t("change_permission_title"),
message: contentText,
continue: {
text: buttonText,
@ -1075,17 +1069,17 @@ const ManageParticipant: React.FC<ManageParticipantProps> = ({
const removeParticipant = () => {
showMiniDialog({
title: t("REMOVE_PARTICIPANT"),
title: t("remove_participant_title"),
message: (
<Trans
i18nKey="REMOVE_PARTICIPANT_MESSAGE"
i18nKey="remove_participant_message"
values={{
selectedEmail: selectedParticipant.email,
}}
/>
),
continue: {
text: t("CONFIRM_REMOVE"),
text: t("confirm_remove"),
color: "critical",
action: handleRemove,
},
@ -1105,7 +1099,7 @@ const ManageParticipant: React.FC<ManageParticipantProps> = ({
<Stack sx={{ gap: "4px", py: "12px" }}>
<Titlebar
onClose={onClose}
title={t("MANAGE")}
title={t("manage")}
onRootClose={handleRootClose}
caption={selectedParticipant.email}
/>
@ -1116,7 +1110,7 @@ const ManageParticipant: React.FC<ManageParticipantProps> = ({
variant="small"
sx={{ color: "text.muted", padding: 1 }}
>
{t("ADDED_AS")}
{t("added_as")}
</Typography>
<RowButtonGroup>
@ -1149,7 +1143,7 @@ const ManageParticipant: React.FC<ManageParticipantProps> = ({
variant="small"
sx={{ color: "text.muted", padding: 1 }}
>
{t("COLLABORATOR_RIGHTS")}
{t("collaborator_hint")}
</Typography>
<Stack sx={{ py: "30px" }}>
@ -1157,7 +1151,7 @@ const ManageParticipant: React.FC<ManageParticipantProps> = ({
variant="small"
sx={{ color: "text.muted", padding: 1 }}
>
{t("REMOVE_PARTICIPANT_HEAD")}
{t("remove_participant")}
</Typography>
<RowButtonGroup>
@ -1268,7 +1262,7 @@ const ManagePublicShare: React.FC<ManagePublicShareProps> = ({
sx={{ color: "text.muted", padding: 1 }}
>
<PublicIcon style={{ fontSize: 17, marginRight: 8 }} />
{t("PUBLIC_LINK_ENABLED")}
{t("public_link_enabled")}
</Typography>
<RowButtonGroup>
{isLinkExpired(publicShareProp.validTill) ? (
@ -1293,7 +1287,7 @@ const ManagePublicShare: React.FC<ManagePublicShareProps> = ({
startIcon={<LinkIcon />}
endIcon={<ChevronRightIcon />}
onClick={openManageShare}
label={t("MANAGE_LINK")}
label={t("manage_link")}
/>
</RowButtonGroup>
</Stack>
@ -1436,7 +1430,7 @@ const ManagePublicShareOptions: React.FC<ManagePublicShareOptionsProps> = ({
color="critical"
startIcon={<RemoveCircleOutlineIcon />}
onClick={disablePublicSharing}
label={t("REMOVE_LINK")}
label={t("remove_link")}
/>
</RowButtonGroup>
{sharableLinkError && (
@ -1475,13 +1469,13 @@ const ManagePublicCollect: React.FC<ManagePublicCollectProps> = ({
<Stack>
<RowButtonGroup>
<RowSwitch
label={t("PUBLIC_COLLECT")}
label={t("allow_adding_photos")}
checked={publicShareProp?.enableCollect}
onClick={handleFileDownloadSetting}
/>
</RowButtonGroup>
<RowButtonGroupHint>
{t("PUBLIC_COLLECT_SUBTEXT")}
{t("allow_adding_photos_hint")}
</RowButtonGroupHint>
</Stack>
);
@ -1535,7 +1529,7 @@ const ManageLinkExpiry: React.FC<ManageLinkExpiryProps> = ({
<RowButton
onClick={openShareExpiryOptionsModalView}
endIcon={<ChevronRightIcon />}
label={t("LINK_EXPIRY")}
label={t("link_expiry")}
color={
isLinkExpired(publicShareProp?.validTill)
? "critical"
@ -1562,15 +1556,14 @@ const ManageLinkExpiry: React.FC<ManageLinkExpiryProps> = ({
<Titlebar
onClose={closeShareExpiryOptionsModalView}
onRootClose={handleRootClose}
title={t("LINK_EXPIRY")}
title={t("link_expiry")}
/>
<Stack sx={{ gap: "32px", py: "20px", px: "8px" }}>
<RowButtonGroup>
{shareExpireOption.map((item, index) => (
<>
<React.Fragment key={item.value()}>
<RowButton
fontWeight="regular"
key={item.value()}
onClick={changeShareExpiryValue(
item.value(),
)}
@ -1579,7 +1572,7 @@ const ManageLinkExpiry: React.FC<ManageLinkExpiryProps> = ({
{index !== shareExpireOption.length - 1 && (
<RowButtonDivider />
)}
</>
</React.Fragment>
))}
</RowButtonGroup>
</Stack>
@ -1661,10 +1654,10 @@ const ManageDeviceLimit: React.FC<ManageDeviceLimitProps> = ({
return (
<>
<RowButton
label={t("LINK_DEVICE_LIMIT")}
label={t("device_limit")}
caption={
publicShareProp.deviceLimit === 0
? t("NO_DEVICE_LIMIT")
? t("none")
: publicShareProp.deviceLimit.toString()
}
onClick={openDeviceLimitChangeModalView}
@ -1680,15 +1673,14 @@ const ManageDeviceLimit: React.FC<ManageDeviceLimitProps> = ({
<Titlebar
onClose={closeDeviceLimitChangeModal}
onRootClose={handleRootClose}
title={t("LINK_DEVICE_LIMIT")}
title={t("device_limit")}
/>
<Stack sx={{ gap: "32px", py: "20px", px: "8px" }}>
<RowButtonGroup>
{deviceLimitOptions.map((item, index) => (
<>
<React.Fragment key={item.label}>
<RowButton
fontWeight="regular"
key={item.label}
onClick={changeDeviceLimitValue(
item.value,
)}
@ -1698,7 +1690,7 @@ const ManageDeviceLimit: React.FC<ManageDeviceLimitProps> = ({
deviceLimitOptions.length - 1 && (
<RowButtonDivider />
)}
</>
</React.Fragment>
))}
</RowButtonGroup>
</Stack>
@ -1749,7 +1741,7 @@ const ManageDownloadAccess: React.FC<ManageDownloadAccessProps> = ({
};
return (
<RowSwitch
label={t("FILE_DOWNLOAD")}
label={t("allow_downloads")}
checked={publicShareProp?.enableDownload ?? true}
onClick={handleFileDownloadSetting}
/>

View File

@ -999,7 +999,7 @@ const FreehandCropRegion = forwardRef(
key={index}
sx={{
border: "1px solid",
borderColor: "fixed.white",
borderColor: "white",
boxSizing: "border-box",
pointerEvents: "none",
}}
@ -1011,9 +1011,9 @@ const FreehandCropRegion = forwardRef(
position: "absolute",
height: "10px",
width: "10px",
backgroundColor: "fixed.white",
backgroundColor: "white",
border: "1px solid",
borderColor: "fixed.black",
borderColor: "black",
right: "-5px",
bottom: "-5px",
cursor: "se-resize",
@ -1029,13 +1029,13 @@ const FreehandCropRegion = forwardRef(
},
);
const CropOverlayRegionTemplate = styled("div")(({ theme }) => ({
const CropOverlayRegionTemplate = styled("div")({
position: "absolute",
backgroundColor: theme.vars.palette.fixed.croppedAreaOverlay,
backgroundColor: "rgba(0 0 0 / 0.5)",
pointerEvents: "none",
}));
});
const PRESET_ASPECT_RATIOS = [
const presetAspectRatios = [
{
width: 16,
height: 9,
@ -1241,7 +1241,7 @@ const TransformMenu: React.FC<CommonMenuProps> = ({
/>
</RowButtonGroup>
<RowButtonGroup sx={{ mb: "1rem" }}>
{PRESET_ASPECT_RATIOS.map((ratio, index) => (
{presetAspectRatios.map((ratio, index) => (
<Fragment key={index}>
<RowButton
disabled={canvasLoading}
@ -1252,14 +1252,14 @@ const TransformMenu: React.FC<CommonMenuProps> = ({
ratio.height,
)}
/>
{index !== PRESET_ASPECT_RATIOS.length - 1 && (
{index !== presetAspectRatios.length - 1 && (
<RowButtonDivider />
)}
</Fragment>
))}
</RowButtonGroup>
<RowButtonGroup sx={{ mb: "1rem" }}>
{PRESET_ASPECT_RATIOS.map((ratio, index) => (
{presetAspectRatios.map((ratio, index) => (
<Fragment key={index}>
<RowButton
key={index}
@ -1271,7 +1271,7 @@ const TransformMenu: React.FC<CommonMenuProps> = ({
ratio.width,
)}
/>
{index !== PRESET_ASPECT_RATIOS.length - 1 && (
{index !== presetAspectRatios.length - 1 && (
<RowButtonDivider />
)}
</Fragment>

View File

@ -114,8 +114,14 @@ const LanguageSelector = () => {
const updateCurrentLocale = (newLocale: SupportedLocale) => {
setLocaleInUse(newLocale);
// [Note: Changing locale causes a full reload]
//
// A full reload is needed because we use the global `t` instance
// instead of the useTranslation hook.
//
// We also rely on this behaviour by caching various formatters in
// module static variables that not get updated if the i18n.language
// changes unless there is a full reload.
window.location.reload();
};

View File

@ -48,7 +48,7 @@ export const SubscriptionCard: React.FC<SubscriptionCardProps> = ({
sx={{ borderRadius: "8px" }}
/>
) : (
<Box sx={{ position: "relative", color: "fixed.white" }}>
<Box sx={{ position: "relative", color: "white" }}>
<BackgroundOverlay />
<SubscriptionCardContentOverlay userDetails={userDetails} />
<ClickOverlay onClick={onClick} />
@ -244,15 +244,15 @@ const UsageBarSegment: React.FC<UsageBarSegmentProps> = ({
position: "absolute",
left: 0,
top: 0,
width: "max(var(--width), 2px)",
width: "max(var(--et-width), 2px)",
height: "4px",
borderRadius: "4px",
backgroundColor: "var(--background-color)",
backgroundColor: "var(--et-background-color)",
}}
style={
{
"--width": `${Math.min(usage / storage, 1) * 100}%`,
"--background-color": fillColor,
"--et-width": `${Math.min(usage / storage, 1) * 100}%`,
"--et-background-color": fillColor,
} as React.CSSProperties
}
/>

View File

@ -1,23 +1,22 @@
import { Overlay } from "@/base/components/containers";
import { formattedDateRelative } from "@/base/i18n-date";
import log from "@/base/log";
import { downloadManager } from "@/gallery/services/download";
import { enteFileDeletionDate } from "@/media/file";
import { FileType } from "@/media/file-type";
import {
GAP_BTW_TILES,
IMAGE_CONTAINER_MAX_WIDTH,
} from "@/new/photos/components/PhotoList";
import { GAP_BTW_TILES } from "@/new/photos/components/PhotoList";
import {
LoadingThumbnail,
StaticThumbnail,
} from "@/new/photos/components/PlaceholderThumbnails";
import { TileBottomTextOverlay } from "@/new/photos/components/Tiles";
import { TRASH_SECTION } from "@/new/photos/services/collection";
import useLongPress from "@ente/shared/hooks/useLongPress";
import AlbumOutlinedIcon from "@mui/icons-material/AlbumOutlined";
import FavoriteRoundedIcon from "@mui/icons-material/FavoriteRounded";
import PlayCircleOutlineOutlinedIcon from "@mui/icons-material/PlayCircleOutlineOutlined";
import { styled } from "@mui/material";
import { styled, Typography } from "@mui/material";
import type { DisplayFile } from "components/PhotoFrame";
import i18n from "i18next";
import { GalleryContext } from "pages/gallery";
import React, { useContext, useEffect, useRef, useState } from "react";
import { shouldShowAvatar } from "utils/file";
@ -82,7 +81,7 @@ const Check = styled("input")<{ $active: boolean }>(
content: "";
background-color: ${theme.vars.palette.accent.main};
border-color: ${theme.vars.palette.accent.main};
color: ${theme.vars.palette.fixed.white};
color: white;
}
/* checkmark foreground (tick) */
&:checked::after {
@ -112,21 +111,45 @@ const HoverOverlay = styled("div")<{ checked: boolean }>`
"background:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0))"};
`;
/**
* An overlay showing the avatars of the person who shared the item, at the top
* right.
*/
const AvatarOverlay = styled(Overlay)`
display: flex;
justify-content: flex-end;
align-items: flex-start;
padding-right: 5px;
padding-top: 5px;
padding: 5px;
`;
const FavOverlay = styled(Overlay)`
/**
* An overlay showing the favorite icon at bottom left.
*/
const FavoriteOverlay = styled(Overlay)`
display: flex;
justify-content: flex-start;
align-items: flex-end;
padding-left: 5px;
padding-bottom: 5px;
opacity: 0.9;
padding: 5px;
color: white;
opacity: 0.6;
`;
/**
* An overlay with a gradient, showing the file type indicator (e.g. live photo,
* video) at the bottom right.
*/
const FileTypeIndicatorOverlay = styled(Overlay)`
display: flex;
justify-content: flex-end;
align-items: flex-end;
padding: 5px;
color: white;
background: linear-gradient(
315deg,
rgba(0 0 0 / 0.14) 0%,
rgba(0 0 0 / 0.05) 30%,
transparent 50%
);
`;
const InSelectRangeOverlay = styled(Overlay)(
@ -137,32 +160,6 @@ const InSelectRangeOverlay = styled(Overlay)(
`,
);
const FileAndCollectionNameOverlay = styled("div")(
({ theme }) => `
width: 100%;
bottom: 0;
left: 0;
max-height: 40%;
width: 100%;
background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 2));
& > p {
max-width: calc(${IMAGE_CONTAINER_MAX_WIDTH}px - 10px);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin: 2px;
text-align: center;
}
padding: 7px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: ${theme.vars.palette.fixed.white};
position: absolute;
`,
);
const SelectedOverlay = styled(Overlay)(
({ theme }) => `
z-index: 5;
@ -171,23 +168,6 @@ const SelectedOverlay = styled(Overlay)(
`,
);
const FileTypeIndicatorOverlay = styled(Overlay)(({ theme }) => ({
display: "flex",
justifyContent: "flex-end",
alignItems: "flex-end",
padding: "8px",
// TODO(LM): Ditto the dark one until lm is ready.
// background:
// "linear-gradient(315deg, rgba(255, 255, 255, 0.14) 0%, rgba(255, 255,
// 255, 0.05) 29.61%, rgba(255, 255, 255, 0) 49.86%)",
background:
"linear-gradient(315deg, rgba(0, 0, 0, 0.14) 0%, rgba(0, 0, 0, 0.05) 29.61%, rgba(0, 0, 0, 0) 49.86%)",
...theme.applyStyles("dark", {
background:
"linear-gradient(315deg, rgba(0, 0, 0, 0.14) 0%, rgba(0, 0, 0, 0.05) 29.61%, rgba(0, 0, 0, 0) 49.86%)",
}),
}));
const Cont = styled("div")<{ disabled: boolean }>`
display: flex;
width: fit-content;
@ -241,6 +221,7 @@ export default function PreviewCard(props: IProps) {
onRangeSelect,
isRangeSelectActive,
isInsSelectRange,
isFav,
} = props;
const [imgSrc, setImgSrc] = useState<string>(file.msrc);
@ -345,10 +326,10 @@ export default function PreviewCard(props: IProps) {
<Avatar file={file} />
</AvatarOverlay>
)}
{props.isFav && (
<FavOverlay>
{isFav && (
<FavoriteOverlay>
<FavoriteRoundedIcon />
</FavOverlay>
</FavoriteOverlay>
)}
<HoverOverlay
@ -360,34 +341,12 @@ export default function PreviewCard(props: IProps) {
)}
{props?.activeCollectionID === TRASH_SECTION && file.isTrashed && (
<FileAndCollectionNameOverlay>
<p>{formatDateRelative(file.deleteBy / 1000)}</p>
</FileAndCollectionNameOverlay>
<TileBottomTextOverlay>
<Typography variant="small">
{formattedDateRelative(enteFileDeletionDate(file))}
</Typography>
</TileBottomTextOverlay>
)}
</Cont>
);
}
function formatDateRelative(date: number) {
const units = {
year: 24 * 60 * 60 * 1000 * 365,
month: (24 * 60 * 60 * 1000 * 365) / 12,
day: 24 * 60 * 60 * 1000,
hour: 60 * 60 * 1000,
minute: 60 * 1000,
second: 1000,
};
const relativeDateFormat = new Intl.RelativeTimeFormat(i18n.language, {
localeMatcher: "best fit",
numeric: "always",
style: "long",
});
const elapsed = date - Date.now(); // "Math.abs" accounts for both "past" & "future" scenarios
for (const u in units)
if (Math.abs(elapsed) > units[u] || u === "second")
return relativeDateFormat.format(
Math.round(elapsed / units[u]),
u as Intl.RelativeTimeFormatUnit,
);
}

View File

@ -908,7 +908,7 @@ const Page: React.FC = () => {
variant="small"
sx={{ color: "text.muted" }}
>
{t("INITIAL_LOAD_DELAY_WARNING")}
{t("initial_load_delay_warning")}
</Typography>
</CenteredFlex>
)}

View File

@ -384,7 +384,7 @@ export default function PublicCollectionGallery() {
) {
setErrorMessage(
parsedError.message === CustomError.TOO_MANY_REQUESTS
? t("LINK_TOO_MANY_REQUESTS")
? t("link_request_limit_exceeded")
: t("link_expired_message"),
);
// share has been disabled

View File

@ -23,67 +23,112 @@ export interface ParsedMetadataJSON {
description?: string;
}
export const MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT = 46;
export const getMetadataJSONMapKeyForJSON = (
/**
* Derive a key for the given {@link jsonFileName} that should be used to index
* into the {@link ParsedMetadataJSON} JSON map.
*
* @param collectionID The collection to which we're uploading.
*
* @param jsonFileName The file name for the JSON file.
*
* @returns A key suitable for indexing into the metadata JSON map.
*/
export const metadataJSONMapKeyForJSON = (
collectionID: number,
jsonFileName: string,
) => {
let title = jsonFileName.slice(0, -1 * ".json".length);
const endsWithNumberedSuffixWithBrackets = /\(\d+\)$/.exec(title);
if (endsWithNumberedSuffixWithBrackets) {
title = title.slice(
0,
-1 * endsWithNumberedSuffixWithBrackets[0].length,
);
const [name, extension] = nameAndExtension(title);
return `${collectionID}-${name}${endsWithNumberedSuffixWithBrackets[0]}.${extension}`;
}
return `${collectionID}-${title}`;
};
) => `${collectionID}-${jsonFileName.slice(0, -1 * ".json".length)}`;
// if the file name is greater than MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT(46) , then google photos clips the file name
// so we need to use the clipped file name to get the metadataJSON file
export const getClippedMetadataJSONMapKeyForFile = (
collectionID: number,
/**
* Return the matching entry, if any, from {@link parsedMetadataJSONMap} for the
* {@link fileName} and {@link collectionID} combination.
*
* This is the sibling of {@link metadataJSONMapKeyForJSON}, except for deriving
* the filename key we might have to try a bunch of different variations, so
* this does not return a single key but instead tries the combinations until it
* finds an entry in the map, and returns the found entry instead of the key.
*/
export const matchTakeoutMetadata = (
fileName: string,
) => {
return `${collectionID}-${fileName.slice(
0,
MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT,
)}`;
};
export const getMetadataJSONMapKeyForFile = (
collectionID: number,
fileName: string,
parsedMetadataJSONMap: Map<string, ParsedMetadataJSON>,
) => {
return `${collectionID}-${getFileOriginalName(fileName)}`;
};
const EDITED_FILE_SUFFIX = "-edited";
/*
Get the original file name for edited file to associate it to original file's metadataJSON file
as edited file doesn't have their own metadata file
*/
function getFileOriginalName(fileName: string) {
let originalName: string = null;
const [name, extension] = nameAndExtension(fileName);
const isEditedFile = name.endsWith(EDITED_FILE_SUFFIX);
if (isEditedFile) {
originalName = name.slice(0, -1 * EDITED_FILE_SUFFIX.length);
} else {
originalName = name;
}
// Break the fileName down into its components.
let [name, extension] = nameAndExtension(fileName);
if (extension) {
originalName += "." + extension;
extension = "." + extension;
}
return originalName;
}
/** Try to parse the contents of a metadata JSON file from a Google Takeout. */
// Trim off a suffix like "(1)" from the name, remembering what we trimmed
// since we need to add it back later.
//
// It needs to be handled separately because of the clipping (see below).
// The numbered suffix (if present) is not clipped. It is added at the end
// of the clipped ".supplemental-metadata" portion, instead of after the
// original filename.
//
// For example, "IMG_1234(1).jpg" would have a metadata filename of either
// "IMG_1234.jpg(1).json" or "IMG_1234.jpg.supplemental-metadata(1).json".
// And if the filename is too long, it gets turned into something like
// "IMG_1234.jpg.suppl(1).json".
let numberedSuffix = "";
const endsWithNumberedSuffixWithBrackets = /\(\d+\)$/.exec(name);
if (endsWithNumberedSuffixWithBrackets) {
name = name.slice(0, -1 * endsWithNumberedSuffixWithBrackets[0].length);
numberedSuffix = endsWithNumberedSuffixWithBrackets[0];
}
// Removes the "-edited" suffix, if present, so that the edited file can be
// associated to the original file's metadataJSON file as edited files don't
// have their own metadata files.
const editedFileSuffix = "-edited";
if (name.endsWith(editedFileSuffix)) {
name = name.slice(0, -1 * editedFileSuffix.length);
}
// Derive a key from the collection name, file name and the suffix if any.
let baseFileName = `${name}${extension}`;
let key = `${collectionID}-${baseFileName}${numberedSuffix}`;
let takeoutMetadata = parsedMetadataJSONMap.get(key);
if (takeoutMetadata) return takeoutMetadata;
// If the file name is greater than 46 characters, then Google Photos, with
// its infinite storage, clips the file name. In such cases we need to use
// the clipped file name to get the key.
const maxGoogleFileNameLength = 46;
key = `${collectionID}-${baseFileName.slice(0, maxGoogleFileNameLength)}${numberedSuffix}`;
takeoutMetadata = parsedMetadataJSONMap.get(key);
if (takeoutMetadata) return takeoutMetadata;
// Newer Takeout exports are attaching a ".supplemental-metadata" suffix to
// the file name of the metadataJSON file, you know, just to cause havoc,
// and then clipping the file name if it's too long (ending up with
// filenames "very_long_file_name.jpg.supple.json").
//
// Note that If the original filename is longer than 46 characters, then the
// ".supplemental-metadata" suffix gets completely removed during the
// clipping, along with a portion of the original filename (as before).
//
// For example, if the original filename is 45 characters long, then
// everything except for the "." from ".supplemental-metadata" will get
// clipped. So the metadata file ends up with a filename like
// "filename_that_is_45_chars_long.jpg..json".
const supplSuffix = ".supplemental-metadata";
baseFileName = `${name}${extension}${supplSuffix}`;
key = `${collectionID}-${baseFileName.slice(0, maxGoogleFileNameLength)}${numberedSuffix}`;
takeoutMetadata = parsedMetadataJSONMap.get(key);
return takeoutMetadata;
};
/**
* Try to parse the contents of a metadata JSON file from a Google Takeout.
*/
export const tryParseTakeoutMetadataJSON = async (
uploadItem: UploadItem,
): Promise<ParsedMetadataJSON | undefined> => {
@ -184,23 +229,3 @@ const parseGTLocation = (o: unknown): Location | undefined => {
*/
const parseGTNonEmptyString = (o: unknown): string | undefined =>
o && typeof o == "string" ? o : undefined;
/**
* Return the matching entry (if any) from {@link parsedMetadataJSONMap} for the
* {@link fileName} and {@link collectionID} combination.
*/
export const matchTakeoutMetadata = (
fileName: string,
collectionID: number,
parsedMetadataJSONMap: Map<string, ParsedMetadataJSON>,
) => {
let key = getMetadataJSONMapKeyForFile(collectionID, fileName);
let takeoutMetadata = parsedMetadataJSONMap.get(key);
if (!takeoutMetadata && key.length > MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT) {
key = getClippedMetadataJSONMapKeyForFile(collectionID, fileName);
takeoutMetadata = parsedMetadataJSONMap.get(key);
}
return takeoutMetadata;
};

View File

@ -131,7 +131,7 @@ const generateVideoThumbnailWeb = async (blob: Blob) => {
return await ffmpeg.generateVideoThumbnailWeb(blob);
} catch (e) {
log.error(
`Failed to generate video thumbnail using the wasm FFmpeg web worker, will fallback to canvas`,
`Failed to generate video thumbnail using the Wasm FFmpeg web worker, will fallback to canvas`,
e,
);
return generateVideoThumbnailUsingCanvas(blob);

View File

@ -34,7 +34,7 @@ import {
import watcher from "services/watch";
import { getUserOwnedFiles } from "utils/file";
import {
getMetadataJSONMapKeyForJSON,
metadataJSONMapKeyForJSON,
tryParseTakeoutMetadataJSON,
type ParsedMetadataJSON,
} from "./takeout";
@ -522,7 +522,7 @@ class UploadManager {
const metadataJSON = await tryParseTakeoutMetadataJSON(uploadItem!);
if (metadataJSON) {
this.parsedMetadataJSONMap.set(
getMetadataJSONMapKeyForJSON(collectionID, fileName),
metadataJSONMapKeyForJSON(collectionID, fileName),
metadataJSON,
);
this.uiService.increaseFileUploaded();

View File

@ -190,7 +190,7 @@ async function createCollectionDownloadFolder(
}
const _intSelectOption = (i: number) => {
const label = i === 0 ? t("NO_DEVICE_LIMIT") : i.toString();
const label = i === 0 ? t("none") : i.toString();
return { label, value: i };
};

View File

@ -7,10 +7,8 @@ import {
} from "@/new/photos/services/files";
import { parseDateFromDigitGroups } from "services/upload/date";
import {
MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT,
getClippedMetadataJSONMapKeyForFile,
getMetadataJSONMapKeyForFile,
getMetadataJSONMapKeyForJSON,
matchTakeoutMetadata,
metadataJSONMapKeyForJSON,
} from "services/upload/takeout";
import { getUserDetailsV2 } from "services/userService";
@ -71,7 +69,7 @@ const DATE_TIME_PARSING_TEST_FILE_NAMES_MUST_FAIL = [
"Snapchat-100-10-20-19-15-12",
];
const FILE_NAME_TO_JSON_NAME = [
const fileNameToJSONMappingCases = [
{
filename: "IMG20210211125718-edited.jpg",
jsonFilename: "IMG20210211125718.jpg.json",
@ -100,19 +98,50 @@ const FILE_NAME_TO_JSON_NAME = [
filename: "IMG2021021(1)74722(1).jpg",
jsonFilename: "IMG2021021(1)74722.jpg(1).json",
},
{
filename: "IMG_1159.HEIC",
jsonFilename: "IMG_1159.HEIC.supplemental-metadata.json",
},
{
filename: "PXL_20241231_151646544.MP.jpg",
jsonFilename: "PXL_20241231_151646544.MP.jpg.supplemental-met.json",
},
{
filename: "PXL_20240827_094331806.PORTRAIT(1).jpg",
jsonFilename: "PXL_20240827_094331806.PORTRAIT.jpg.supplement(1).json",
},
{
filename: "PXL_20240506_142610305.LONG_EXPOSURE-01.COVER.jpg",
jsonFilename: "PXL_20240506_142610305.LONG_EXPOSURE-01.COVER..json",
},
{
filename: "PXL_20211120_223243932.MOTION-02.ORIGINAL.jpg",
jsonFilename: "PXL_20211120_223243932.MOTION-02.ORIGINAL.jpg..json",
},
{
filename: "20220322_205147-edited(1).jpg",
jsonFilename: "20220322_205147.jpg.supplemental-metadata(1).json",
},
];
export async function testUpload() {
try {
parseDateTimeFromFileNameTest();
fileNameToJSONMappingTests();
} catch (e) {
console.log(e);
}
const jsonString = process.env.NEXT_PUBLIC_ENTE_TEST_EXPECTED_JSON;
if (!jsonString) {
throw Error(
"Please specify the NEXT_PUBLIC_ENTE_TEST_EXPECTED_JSON to run the upload tests",
console.warn(
"Not running upload tests. Please specify the NEXT_PUBLIC_ENTE_TEST_EXPECTED_JSON to run the upload tests",
);
return;
}
const expectedState = JSON.parse(jsonString);
if (!expectedState) {
throw Error("upload test failed expectedState missing");
}
if (!expectedState) throw Error("Invalid JSON");
try {
await totalCollectionCountCheck(expectedState);
@ -123,8 +152,6 @@ export async function testUpload() {
await fileDimensionExtractionCheck(expectedState);
await googleMetadataReadingCheck(expectedState);
await totalFileCountCheck(expectedState);
parseDateTimeFromFileNameTest();
mappingFileAndJSONFileCheck();
} catch (e) {
console.log(e);
}
@ -395,33 +422,23 @@ function parseDateTimeFromFileNameTest() {
console.log("parseDateTimeFromFileNameTest passed ✅");
}
function mappingFileAndJSONFileCheck() {
FILE_NAME_TO_JSON_NAME.forEach(({ filename, jsonFilename }) => {
const jsonFileNameGeneratedKey = getMetadataJSONMapKeyForJSON(
0,
jsonFilename,
);
let fileNameGeneratedKey = getMetadataJSONMapKeyForFile(0, filename);
if (
fileNameGeneratedKey !== jsonFileNameGeneratedKey &&
filename.length > MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT
) {
fileNameGeneratedKey = getClippedMetadataJSONMapKeyForFile(
0,
filename,
);
}
const fileNameToJSONMappingTests = () => {
for (const { filename, jsonFilename } of fileNameToJSONMappingCases) {
const jsonKey = metadataJSONMapKeyForJSON(0, jsonFilename);
if (fileNameGeneratedKey !== jsonFileNameGeneratedKey) {
// See the docs for the file name matcher as to why it doesn't return
// the key but instead indexes into the map for us. To test it, we
// construct a placeholder map with a dummy entry for the expected key.
const map = new Map([[jsonKey, {}]]);
if (!matchTakeoutMetadata(filename, 0, map)) {
throw Error(
`mappingFileAndJSONFileCheck failed ❌ ,
for ${filename}
expected: ${jsonFileNameGeneratedKey} got: ${fileNameGeneratedKey}`,
`fileNameToJSONMappingTests failed ❌ for ${filename} and ${jsonFilename}`,
);
}
});
console.log("mappingFileAndJSONFileCheck passed ✅");
}
}
console.log("fileNameToJSONMappingTests passed ✅");
};
// format: YYYY-MM-DD HH:MM:SS
function getFormattedDateTime(date: Date) {

View File

@ -198,9 +198,9 @@ via [@fontsource-variable/inter](https://fontsource.org/fonts/inter/install).
## Media
- [ffmpeg.wasm](https://github.com/ffmpegwasm/ffmpeg.wasm) is used to run FFmpeg
in the browser using WASM. Note that this is substantially slower than native
ffmpeg (the desktop app can, and does, bundle the faster native ffmpeg
implementation too).
in the browser using WebAssembly (Wasm). Note that this is substantially
slower than native ffmpeg (the desktop app can, and does, bundle the faster
native ffmpeg implementation too).
- [ExifReader](https://github.com/mattiasw/ExifReader) is used for Exif parsing.

View File

@ -70,7 +70,7 @@ FFmpeg, as of 2024, partially supports converting HEIC files
border on the right and bottom (and the orientation is also not respected).
FFmpeg support would be nice since we already bundle it both in the desktop app
and also as a web WASM build.
and also as a web Wasm build.
---
@ -83,6 +83,6 @@ option to swap libde265 with libx265 or kvazaar.
Currently our web app uses
[heic-convert](https://github.com/catdad-experiments/heic-convert), which
provides packaged wasm builds of libheif + libde265, and the desktop app uses a
provides packaged Wasm builds of libheif + libde265, and the desktop app uses a
[custom build](https://github.com/ente-io/libvips-packaging) of `vips` on Linux
and Windows, and Apple's `sips` on macOS.

View File

@ -30,9 +30,9 @@ export const PasswordStrengthHint: React.FC<PasswordStrengthHintProps> = ({
mt: "8px",
alignSelf: "flex-start",
whiteSpace: "pre",
color: "var(--color)",
color: "var(--et-color)",
}}
style={{ "--color": color } as React.CSSProperties}
style={{ "--et-color": color } as React.CSSProperties}
>
{password
? t("passphrase_strength", { context: passwordStrength })

View File

@ -99,10 +99,7 @@ const Page: React.FC<PageProps> = ({ appContext }) => {
) : openRecoveryKey ? (
<RecoveryKey
open={openRecoveryKey}
onClose={() => {
setOpenRecoveryKey(false);
void router.push(appHomeRoute);
}}
onClose={() => void router.push(appHomeRoute)}
showMiniDialog={showMiniDialog}
/>
) : (

View File

@ -16,7 +16,7 @@ export const EnteSwitch: React.FC<SwitchProps> = styled((props) => (
transitionDuration: "300ms",
"&.Mui-checked": {
transform: "translateX(16px)",
color: theme.vars.palette.fixed.white,
color: "white",
"& + .MuiSwitch-track": {
opacity: 1,
border: 0,

View File

@ -46,8 +46,16 @@ export const CenteredFill = styled("div")`
`;
/**
* An absolute positioned div that fills the entire nearest relatively
* positioned ancestor.
* An empty overlay on top of the nearest relative positioned ancestor.
*
* {@link Overlay} is an an absolute positioned div that fills the entire
* nearest relatively positioned ancestor. It is usually used in tandem with a
* derivate of {@link BaseTile} or {@link BaseTileButton} to show various
* indicators on top of thumbnails; but it can be used in any context where we
* want to overlay (usually) transparent content on top of a component.
*
* For filling much larger areas (e.g. showing a translucent overlay on top of
* the entire screen), use the MUI {@link Backdrop} instead.
*/
export const Overlay = styled("div")`
position: absolute;

View File

@ -1,5 +1,6 @@
import { Overlay, Stack100vhCenter } from "@/base/components/containers";
import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator";
import { Backdrop } from "@mui/material";
import React from "react";
/**
@ -38,18 +39,23 @@ export const LoadingOverlay: React.FC = () => (
* An translucent overlay that covers the entire viewport and shows an activity
* indicator in its center.
*
* Used as a overscreen during blocking actions.
* Used as a overscreen during blocking actions. The use of this component is
* not recommended for new code.
*/
export const TranslucentLoadingOverlay: React.FC = () => (
<Overlay
<Backdrop
// Specifying open here causes us to lose animations. This is not
// optimal, but fine for now since this the use of this is limited to a
// few interstitial overlays, and if refactoring consider replacing this
// entirely with a more localized activity indicator.
open={true}
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "var(--mui-palette-backdrop-muted)",
backdropFilter: "blur(30px) opacity(95%)",
// TODO: Why is this zIndex override required? + use a constant.
zIndex: 9000,
backgroundColor: "backdrop.muted",
}}
>
<ActivityIndicator />
</Overlay>
</Backdrop>
);

View File

@ -120,8 +120,6 @@ declare module "@mui/material/styles" {
* These do not change with the color scheme.
*/
fixed: {
white: string;
black: string;
/**
* Various fixed shades of gray.
* TODO(LM) - audit and rename.
@ -145,20 +143,6 @@ declare module "@mui/material/styles" {
* The color of a switch when it is enabled.
*/
switchOn: string;
/**
* The transparent overlay on top of the region that will be cropped
* during image editing.
*/
croppedAreaOverlay: string;
/**
* Color of overlaid icons on top of thumbnails. e.g. color of the
* "archived" indicator shown on top of albums.
*/
overlayIndicatorMuted: string;
/**
* Color of the total space in the usage bar on the storage card.
*/
storageCardUsageFill: string;
};
/**
* MUI as of v6 does not allow customizing shadows easily. This is due

View File

@ -159,9 +159,6 @@ const _colors = {
E: "#ddd",
},
switchOn: "#2eca45",
croppedAreaOverlay: "rgba(0 0 0 / 0.5)",
overlayIndicatorMuted: "rgba(255 255 255 / 0.48)",
storageCardUsageFill: "rgba(255 255 255 / 0.2)",
},
light: {
// Keep these solid.
@ -336,8 +333,10 @@ const getColorSchemes = (colors: ReturnType<typeof getColors>) => ({
FilledInput: {
bg: colors.light.fill.faint,
hoverBg: colors.light.fill.faintHover,
// We don't use this currently.
// disabledBg: colors.light.fill.fainter,
// While we don't specifically have disabled inputs, TextInputs
// do get disabled when the form is submitting, and this value
// comes into play then.
disabledBg: colors.light.fill.fainter,
},
},
},
@ -399,7 +398,7 @@ const getColorSchemes = (colors: ReturnType<typeof getColors>) => ({
FilledInput: {
bg: colors.dark.fill.faint,
hoverBg: colors.dark.fill.faintHover,
// disabledBg: colors.dark.fill.faint,
disabledBg: colors.dark.fill.fainter,
},
},
},
@ -498,6 +497,14 @@ const typography: TypographyOptions = {
},
};
/**
* > [!NOTE]
* >
* > The theme isn't tree-shakeable, prefer creating new components for heavy
* > customization.
* >
* > https://mui.com/material-ui/customization/theme-components/
*/
const components: Components = {
MuiCssBaseline: {
styleOverrides: {

14
web/packages/base/date.ts Normal file
View File

@ -0,0 +1,14 @@
/**
* Convert an epoch microsecond value to a JavaScript date.
*
* This is a convenience API for dealing with optional epoch microseconds in
* various data structures. Remote talks in terms of epoch microseconds, but
* JavaScript dates are underlain by epoch milliseconds, and this does a
* conversion, with a convenience of short circuiting undefined values.
*/
export const dateFromEpochMicroseconds = (
epochMicroseconds: number | undefined,
) =>
epochMicroseconds === undefined
? undefined
: new Date(epochMicroseconds / 1000);

View File

@ -0,0 +1,38 @@
/**
* @file Various date formatters.
*
* Note that we rely on the current behaviour of a full reload on changing the
* language. See: [Note: Changing locale causes a full reload].
*/
import i18n from "i18next";
let _relativeTimeFormat: Intl.RelativeTimeFormat | undefined;
export const formattedDateRelative = (date: Date) => {
const units: [Intl.RelativeTimeFormatUnit, number][] = [
["year", 24 * 60 * 60 * 1000 * 365],
["month", (24 * 60 * 60 * 1000 * 365) / 12],
["day", 24 * 60 * 60 * 1000],
["hour", 60 * 60 * 1000],
["minute", 60 * 1000],
["second", 1000],
];
// Math.abs accounts for both past and future scenarios.
const elapsed = Math.abs(date.getTime() - Date.now());
// Lazily created, then cached, instance of RelativeTimeFormat.
const relativeTimeFormat = (_relativeTimeFormat ??=
new Intl.RelativeTimeFormat(i18n.language, {
localeMatcher: "best fit",
numeric: "always",
style: "short",
}));
for (const [u, d] of units) {
if (elapsed > d)
return relativeTimeFormat.format(Math.round(elapsed / d), u);
}
return relativeTimeFormat.format(Math.round(elapsed / 1000), "second");
};

View File

@ -228,7 +228,15 @@ export const setLocaleInUse = async (locale: SupportedLocale) => {
return i18n.changeLanguage(locale);
};
const numberFormatter = new Intl.NumberFormat(i18n.language);
let _numberFormat: Intl.NumberFormat | undefined;
/**
* Lazily created, cached, instance of NumberFormat used by
* {@link formattedNumber}.
*
* See: [Note: Changing locale causes a full reload].
*/
const numberFormat = () =>
(_numberFormat ??= new Intl.NumberFormat(i18n.language));
/**
* Return the given {@link value} formatted for the current language and locale.
@ -238,7 +246,7 @@ const numberFormatter = new Intl.NumberFormat(i18n.language);
* However, in some rare cases, we need to format a standalone number. For such
* scenarios, this function can be used.
*/
export const formattedNumber = (value: number) => numberFormatter.format(value);
export const formattedNumber = (value: number) => numberFormat().format(value);
/**
* A no-op marker for strings that, for various reasons, pending addition to the

View File

@ -66,8 +66,7 @@
"5": "اكتمل النسخ الاحتياطي"
},
"FILE_NOT_UPLOADED_LIST": "لم يتم تحميل الملفات التالية",
"INITIAL_LOAD_DELAY_WARNING": "التحميل الأول قد يستغرق بعض الوقت",
"USER_DOES_NOT_EXIST": "عذرا، لم يتم العثور على مستخدم بهذا البريد الإلكتروني",
"initial_load_delay_warning": "التحميل الأول قد يستغرق بعض الوقت",
"no_account": "ليس لديك حساب",
"existing_account": "لديك حساب بالفعل",
"create": "إنشاء",
@ -202,10 +201,11 @@
"delete_photos": "حذف الصور",
"keep_photos": "الاحتفاظ بالصور",
"share_album": "مشاركة الألبوم",
"SHARE_WITH_SELF": "عفوا، لا يمكنك المشاركة مع نفسك",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "لا يسمح بمشاركة الألبوم",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "المشاركة معطلة للحسابات المجانية",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "لا يسمح بمشاركة الألبوم",
"sharing_disabled_for_free_accounts": "المشاركة معطلة للحسابات المجانية",
"sharing_user_does_not_exist": "",
"search": "بحث",
"search_results": "نتائج البحث",
"no_results": "لا توجد نتائج",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "Sicherung abgeschlossen"
},
"FILE_NOT_UPLOADED_LIST": "Die folgenden Dateien wurden nicht hochgeladen",
"INITIAL_LOAD_DELAY_WARNING": "Das erste Laden kann einige Zeit in Anspruch nehmen",
"USER_DOES_NOT_EXIST": "Leider konnte kein Benutzer mit dieser E-Mail gefunden werden",
"initial_load_delay_warning": "Das erste Laden kann einige Zeit in Anspruch nehmen",
"no_account": "Kein Konto vorhanden",
"existing_account": "Es ist bereits ein Account vorhanden",
"create": "Erstellen",
@ -202,10 +201,11 @@
"delete_photos": "Fotos löschen",
"keep_photos": "Fotos behalten",
"share_album": "Album teilen",
"SHARE_WITH_SELF": "Du kannst nicht mit dir selbst teilen",
"ALREADY_SHARED": "Hoppla, Sie teilen dies bereits mit {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Albumfreigabe nicht erlaubt",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Freigabe ist für kostenlose Konten deaktiviert",
"sharing_with_self": "Du kannst nicht mit dir selbst teilen",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Albumfreigabe nicht erlaubt",
"sharing_disabled_for_free_accounts": "Freigabe ist für kostenlose Konten deaktiviert",
"sharing_user_does_not_exist": "",
"search": "Suchen",
"search_results": "Ergebnisse durchsuchen",
"no_results": "Keine Ergebnisse gefunden",
@ -362,43 +362,59 @@
"caption_character_limit": "Maximal 5000 Zeichen",
"sharing_details": "Details teilen",
"modify_sharing": "Freigabe ändern",
"ADD_COLLABORATORS": "Bearbeiter hinzufügen",
"ADD_NEW_EMAIL": "Neue E-Mail-Adresse hinzufügen",
"add_collaborators": "Bearbeiter hinzufügen",
"add_new_email": "Neue E-Mail-Adresse hinzufügen",
"shared_with_people_count_zero": "Mit bestimmten Personen teilen",
"shared_with_people_count_one": "Geteilt mit einer Person",
"shared_with_people_count": "Geteilt mit {{count, number}} Personen",
"participants_count_zero": "Keine Teilnehmer",
"participants_count_one": "1 Teilnehmer",
"participants_count": "{{count, number}} Teilnehmer",
"ADD_VIEWERS": "Betrachter hinzufügen",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} wird nicht in der Lage sein, weitere Fotos zum Album</p><p>hinzuzufügen. {{selectedEmail}} wird weiterhin die eigenen Fotos aus dem Album entfernen können</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} wird Fotos zum Album hinzufügen können",
"CONVERT_TO_VIEWER": "Ja, zu \"Beobachter\" ändern",
"CONVERT_TO_COLLABORATOR": "Ja, in Kollaborateur umwandeln",
"CHANGE_PERMISSION": "Berechtigung ändern?",
"REMOVE_PARTICIPANT": "Entfernen?",
"CONFIRM_REMOVE": "Ja, entfernen",
"MANAGE": "Verwalten",
"ADDED_AS": "Hinzugefügt als",
"COLLABORATOR_RIGHTS": "Bearbeiter können Fotos & Videos zu dem geteilten Album hinzufügen",
"REMOVE_PARTICIPANT_HEAD": "Teilnehmer entfernen",
"OWNER": "Besitzer",
"COLLABORATORS": "Bearbeiter",
"ADD_MORE": "Mehr hinzufügen",
"VIEWERS": "Zuschauer",
"OR_ADD_EXISTING": "Oder eine Vorherige auswählen",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} wird vom Album entfernt</p><p>Alle Bilder von {{selectedEmail}} werden ebenfalls aus dem Album entfernt</p>",
"add_viewers": "Betrachter hinzufügen",
"change_permission_to_viewer": "<p>{{selectedEmail}} wird nicht in der Lage sein, weitere Fotos zum Album</p><p>hinzuzufügen. {{selectedEmail}} wird weiterhin die eigenen Fotos aus dem Album entfernen können</p>",
"change_permission_to_collaborator": "{{selectedEmail}} wird Fotos zum Album hinzufügen können",
"change_permission_title": "Berechtigung ändern?",
"confirm_convert_to_viewer": "Ja, zu \"Beobachter\" ändern",
"confirm_convert_to_collaborator": "Ja, in Kollaborateur umwandeln",
"manage": "Verwalten",
"added_as": "Hinzugefügt als",
"collaborator_hint": "Bearbeiter können Fotos & Videos zu dem geteilten Album hinzufügen",
"remove_participant": "Teilnehmer entfernen",
"remove_participant_title": "Entfernen?",
"remove_participant_message": "<p>{{selectedEmail}} wird vom Album entfernt</p><p>Alle Bilder von {{selectedEmail}} werden ebenfalls aus dem Album entfernt</p>",
"confirm_remove": "Ja, entfernen",
"owner": "Besitzer",
"collaborators": "Bearbeiter",
"viewers": "Zuschauer",
"add_more": "Mehr hinzufügen",
"or_add_existing": "Oder eine Vorherige auswählen",
"NOT_FOUND": "404 - Nicht gefunden",
"link_expired": "Link ist abgelaufen",
"link_expired_message": "",
"MANAGE_LINK": "Link verwalten",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "Downloads erlauben",
"PUBLIC_COLLECT": "Hinzufügen von Fotos erlauben",
"LINK_DEVICE_LIMIT": "Geräte Limit",
"NO_DEVICE_LIMIT": "Keins",
"LINK_EXPIRY": "Ablaufdatum des Links",
"manage_link": "Link verwalten",
"link_request_limit_exceeded": "",
"allow_downloads": "Downloads erlauben",
"allow_adding_photos": "Hinzufügen von Fotos erlauben",
"allow_adding_photos_hint": "Erlaube Personen mit diesem Link, Fotos zum gemeinsamen Album hinzuzufügen.",
"device_limit": "Geräte Limit",
"none": "Keins",
"link_expiry": "Ablaufdatum des Links",
"never": "Niemals",
"after_time": {
"hour": "Nach einer Stunde",
"day": "Nach einem Tag",
"week": "Nach 1 Woche",
"month": "Nach einem Monat",
"year": "Nach einem Jahr"
},
"copy_link": "Link kopieren",
"done": "Fertig",
"share_link_section_title": "Oder einen Link teilen",
"remove_link": "Link entfernen",
"create_public_link": "Öffentlichen Link erstellen",
"public_link_created": "Öffentlicher Link erstellt",
"public_link_enabled": "Öffentlicher Link aktiviert",
"collect_photos": "Bilder sammeln",
"disable_file_download": "Download deaktivieren",
"disable_file_download_message": "<p>Bist du sicher, dass du den Downloadbutton für Dateien deaktivieren möchtest?</p><p>Betrachter können weiterhin Screenshots machen oder die Bilder mithilfe externer Werkzeuge speichern</p>",
"shared_using": "Freigegeben über <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Nach einer Stunde",
"day": "Nach einem Tag",
"week": "Nach 1 Woche",
"month": "Nach einem Monat",
"year": "Nach einem Jahr"
},
"copy_link": "Link kopieren",
"done": "Fertig",
"LINK_SHARE_TITLE": "Oder einen Link teilen",
"REMOVE_LINK": "Link entfernen",
"CREATE_PUBLIC_SHARING": "Öffentlichen Link erstellen",
"public_link_created": "Öffentlicher Link erstellt",
"PUBLIC_LINK_ENABLED": "Öffentlicher Link aktiviert",
"COLLECT_PHOTOS": "Bilder sammeln",
"PUBLIC_COLLECT_SUBTEXT": "Erlaube Personen mit diesem Link, Fotos zum gemeinsamen Album hinzuzufügen.",
"STOP_EXPORT": "Stop",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> Dateien synchronisiert",
"MIGRATING_EXPORT": "Vorbereiten...",

View File

@ -66,8 +66,7 @@
"5": "Το αντίγραφο ασφαλείας ολοκληρώθηκε"
},
"FILE_NOT_UPLOADED_LIST": "Τα ακόλουθα αρχεία δεν μεταφορτώθηκαν",
"INITIAL_LOAD_DELAY_WARNING": "Η πρώτη φόρτωση μπορεί να πάρει κάποιο χρόνο",
"USER_DOES_NOT_EXIST": "Συγγνώμη, δε βρέθηκε χρήστης με αυτή τη διεύθυνση ηλ. ταχυδρομείου",
"initial_load_delay_warning": "Η πρώτη φόρτωση μπορεί να πάρει κάποιο χρόνο",
"no_account": "Δεν έχετε λογαριασμό",
"existing_account": "Έχετε ήδη λογαριασμό",
"create": "Δημιουργία",
@ -202,10 +201,11 @@
"delete_photos": "Διαγραφή φωτογραφιών",
"keep_photos": "Διατήρηση φωτογραφιών",
"share_album": "Κοινοποίηση άλμπουμ",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "Δεν επιτρέπεται η κοινοποίηση άλμπουμ",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Η κοινοποίηση είναι απενεργοποιημένη στους δωρεάν λογαριασμούς",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Δεν επιτρέπεται η κοινοποίηση άλμπουμ",
"sharing_disabled_for_free_accounts": "Η κοινοποίηση είναι απενεργοποιημένη στους δωρεάν λογαριασμούς",
"sharing_user_does_not_exist": "",
"search": "Αναζήτηση",
"search_results": "Αποτελέσματα αναζήτησης",
"no_results": "Δε βρέθηκαν αποτελέσματα",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "Ο σύνδεσμος έληξε",
"link_expired_message": "",
"MANAGE_LINK": "Διαχείριση συνδέσμου",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "Επιτρέπονται λήψεις",
"PUBLIC_COLLECT": "Επιτρέπεται η προσθήκη φωτογραφιών",
"LINK_DEVICE_LIMIT": "Όριο συσκευών",
"NO_DEVICE_LIMIT": "Κανένα",
"LINK_EXPIRY": "",
"manage_link": "Διαχείριση συνδέσμου",
"link_request_limit_exceeded": "",
"allow_downloads": "Επιτρέπονται λήψεις",
"allow_adding_photos": "Επιτρέπεται η προσθήκη φωτογραφιών",
"allow_adding_photos_hint": "",
"device_limit": "Όριο συσκευών",
"none": "Κανένα",
"link_expiry": "",
"never": "Ποτέ",
"after_time": {
"hour": "Μετά από μία ώρα",
"day": "Μετά από μια μέρα",
"week": "Μετά από μία εβδομάδα",
"month": "Μετά από ένα μήνα",
"year": "Μετά από ένα έτος"
},
"copy_link": "Αντιγραφή συνδέσμου",
"done": "Ολοκληρώθηκε",
"share_link_section_title": "Ή μοιραστείτε έναν σύνδεσμο",
"remove_link": "Αφαίρεση συνδέσμου",
"create_public_link": "Δημιουργία δημόσιου συνδέσμου",
"public_link_created": "Ο δημόσιος σύνδεσμος δημιουργήθηκε",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "Απενεργοποίηση λήψεων",
"disable_file_download_message": "",
"shared_using": "Κοινοποίηση μέσω <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Μετά από μία ώρα",
"day": "Μετά από μια μέρα",
"week": "Μετά από μία εβδομάδα",
"month": "Μετά από ένα μήνα",
"year": "Μετά από ένα έτος"
},
"copy_link": "Αντιγραφή συνδέσμου",
"done": "Ολοκληρώθηκε",
"LINK_SHARE_TITLE": "Ή μοιραστείτε έναν σύνδεσμο",
"REMOVE_LINK": "Αφαίρεση συνδέσμου",
"CREATE_PUBLIC_SHARING": "Δημιουργία δημόσιου συνδέσμου",
"public_link_created": "Ο δημόσιος σύνδεσμος δημιουργήθηκε",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "Διακοπή",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "Προετοιμασία...",

View File

@ -66,8 +66,7 @@
"5": "Backup complete"
},
"FILE_NOT_UPLOADED_LIST": "The following files were not uploaded",
"INITIAL_LOAD_DELAY_WARNING": "First load may take some time",
"USER_DOES_NOT_EXIST": "Sorry, could not find a user with that email",
"initial_load_delay_warning": "First load may take some time",
"no_account": "Don't have an account",
"existing_account": "Already have an account",
"create": "Create",
@ -202,10 +201,11 @@
"delete_photos": "Delete photos",
"keep_photos": "Keep photos",
"share_album": "Share album",
"SHARE_WITH_SELF": "Oops, you cannot share with yourself",
"ALREADY_SHARED": "Oops, you're already sharing this with {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Sharing album not allowed",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Sharing is disabled for free accounts",
"sharing_with_self": "You cannot share with yourself",
"sharing_already_shared": "You're already sharing this with {{email}}",
"sharing_album_not_allowed": "Sharing album not allowed",
"sharing_disabled_for_free_accounts": "Sharing is disabled for free accounts",
"sharing_user_does_not_exist": "Could not find a user with that email",
"search": "Search",
"search_results": "Search results",
"no_results": "No results found",
@ -362,43 +362,59 @@
"caption_character_limit": "5000 characters max",
"sharing_details": "Sharing details",
"modify_sharing": "Modify sharing",
"ADD_COLLABORATORS": "Add collaborators",
"ADD_NEW_EMAIL": "Add a new email",
"add_collaborators": "Add collaborators",
"add_new_email": "Add a new email",
"shared_with_people_count_zero": "Share with specific people",
"shared_with_people_count_one": "Shared with 1 person",
"shared_with_people_count": "Shared with {{count, number}} people",
"participants_count_zero": "No participants",
"participants_count_one": "1 participant",
"participants_count": "{{count, number}} participants",
"ADD_VIEWERS": "Add viewers",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} will not be able to add more photos to the album</p><p>They will still be able to remove photos added by them</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} will be able to add photos to the album",
"CONVERT_TO_VIEWER": "Yes, convert to viewer",
"CONVERT_TO_COLLABORATOR": "Yes, convert to collaborator",
"CHANGE_PERMISSION": "Change permission?",
"REMOVE_PARTICIPANT": "Remove?",
"CONFIRM_REMOVE": "Yes, remove",
"MANAGE": "Manage",
"ADDED_AS": "Added as",
"COLLABORATOR_RIGHTS": "Collaborators can add photos and videos to the shared album",
"REMOVE_PARTICIPANT_HEAD": "Remove participant",
"OWNER": "Owner",
"COLLABORATORS": "Collaborators",
"ADD_MORE": "Add more",
"VIEWERS": "Viewers",
"OR_ADD_EXISTING": "Or pick an existing one",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} will be removed from the album</p><p>Any photos added by them will also be removed from the album</p>",
"add_viewers": "Add viewers",
"change_permission_to_viewer": "<p>{{selectedEmail}} will not be able to add more photos to the album</p><p>They will still be able to remove photos added by them</p>",
"change_permission_to_collaborator": "{{selectedEmail}} will be able to add photos to the album",
"change_permission_title": "Change permission?",
"confirm_convert_to_viewer": "Yes, convert to viewer",
"confirm_convert_to_collaborator": "Yes, convert to collaborator",
"manage": "Manage",
"added_as": "Added as",
"collaborator_hint": "Collaborators can add photos and videos to the shared album",
"remove_participant": "Remove participant",
"remove_participant_title": "Remove?",
"remove_participant_message": "<p>{{selectedEmail}} will be removed from the album</p><p>Any photos added by them will also be removed from the album</p>",
"confirm_remove": "Yes, remove",
"owner": "Owner",
"collaborators": "Collaborators",
"viewers": "Viewers",
"add_more": "Add more",
"or_add_existing": "Or pick an existing one",
"NOT_FOUND": "404 - not found",
"link_expired": "Link expired",
"link_expired_message": "This link has either expired or has been disabled",
"MANAGE_LINK": "Manage link",
"LINK_TOO_MANY_REQUESTS": "This album has been viewed on too many devices",
"FILE_DOWNLOAD": "Allow downloads",
"PUBLIC_COLLECT": "Allow adding photos",
"LINK_DEVICE_LIMIT": "Device limit",
"NO_DEVICE_LIMIT": "None",
"LINK_EXPIRY": "Link expiry",
"manage_link": "Manage link",
"link_request_limit_exceeded": "This album has been viewed on too many devices",
"allow_downloads": "Allow downloads",
"allow_adding_photos": "Allow adding photos",
"allow_adding_photos_hint": "Allow people with the link to also add photos to the shared album.",
"device_limit": "Device limit",
"none": "None",
"link_expiry": "Link expiry",
"never": "Never",
"after_time": {
"hour": "After an hour",
"day": "After a day",
"week": "After a week",
"month": "After a month",
"year": "After a year"
},
"copy_link": "Copy link",
"done": "Done",
"share_link_section_title": "Or share a link",
"remove_link": "Remove link",
"create_public_link": "Create public link",
"public_link_created": "Public link created",
"public_link_enabled": "Public link enabled",
"collect_photos": "Collect photos",
"disable_file_download": "Disable download",
"disable_file_download_message": "<p>Are you sure that you want to disable the download button for files?</p><p>Viewers can still take screenshots or save a copy of your photos using external tools.</p>",
"shared_using": "Shared using <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "After an hour",
"day": "After a day",
"week": "After a week",
"month": "After a month",
"year": "After a year"
},
"copy_link": "Copy link",
"done": "Done",
"LINK_SHARE_TITLE": "Or share a link",
"REMOVE_LINK": "Remove link",
"CREATE_PUBLIC_SHARING": "Create public link",
"public_link_created": "Public link created",
"PUBLIC_LINK_ENABLED": "Public link enabled",
"COLLECT_PHOTOS": "Collect photos",
"PUBLIC_COLLECT_SUBTEXT": "Allow people with the link to also add photos to the shared album.",
"STOP_EXPORT": "Stop",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> items synced",
"MIGRATING_EXPORT": "Preparing...",

View File

@ -66,8 +66,7 @@
"5": "Copia de seguridad completa"
},
"FILE_NOT_UPLOADED_LIST": "Los siguientes archivos no se han subido",
"INITIAL_LOAD_DELAY_WARNING": "La primera carga puede tomar algún tiempo",
"USER_DOES_NOT_EXIST": "Lo sentimos, no se pudo encontrar un usuario con ese correo electrónico",
"initial_load_delay_warning": "La primera carga puede tomar algún tiempo",
"no_account": "No tienes una cuenta",
"existing_account": "Ya tienes una cuenta",
"create": "Crear",
@ -202,10 +201,11 @@
"delete_photos": "Eliminar fotos",
"keep_photos": "Conservar fotos",
"share_album": "Compartir álbum",
"SHARE_WITH_SELF": "Uy, no puedes compartir contigo mismo",
"ALREADY_SHARED": "Uy, ya estás compartiendo esto con {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Compartir álbum no permitido",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Compartir está desactivado para cuentas gratis",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Compartir álbum no permitido",
"sharing_disabled_for_free_accounts": "Compartir está desactivado para cuentas gratis",
"sharing_user_does_not_exist": "",
"search": "Buscar",
"search_results": "Buscar resultados",
"no_results": "No se han encontrado resultados",
@ -362,43 +362,59 @@
"caption_character_limit": "Máximo 5000 caracteres",
"sharing_details": "Compartir detalles",
"modify_sharing": "Modificar compartir",
"ADD_COLLABORATORS": "Añadir colaboradores",
"ADD_NEW_EMAIL": "Añadir un nuevo correo electrónico",
"add_collaborators": "Añadir colaboradores",
"add_new_email": "Añadir un nuevo correo electrónico",
"shared_with_people_count_zero": "Compartir con personas específicas",
"shared_with_people_count_one": "Compartido con 1 persona",
"shared_with_people_count": "Compartido con {{count, number}} personas",
"participants_count_zero": "No hay participantes",
"participants_count_one": "1 participante",
"participants_count": "{{count, number}} participantes",
"ADD_VIEWERS": "Añadir espectadores",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} no podrá añadir más fotos al álbum</p><p>Todavía podrán eliminar fotos añadidas por ellos</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} podrá añadir fotos al álbum",
"CONVERT_TO_VIEWER": "Sí, convertir a espectador",
"CONVERT_TO_COLLABORATOR": "Sí, convertir a colaborador",
"CHANGE_PERMISSION": "¿Cambiar Permiso?",
"REMOVE_PARTICIPANT": "¿Eliminar?",
"CONFIRM_REMOVE": "Sí, eliminar",
"MANAGE": "Administrar",
"ADDED_AS": "Añadido como",
"COLLABORATOR_RIGHTS": "Los colaboradores pueden añadir fotos y videos al álbum compartido",
"REMOVE_PARTICIPANT_HEAD": "Quitar participante",
"OWNER": "Propietario",
"COLLABORATORS": "Colaboradores",
"ADD_MORE": "Añadir más",
"VIEWERS": "Espectadores",
"OR_ADD_EXISTING": "O elige uno existente",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} será eliminado del álbum</p><p>Cualquier foto añadida por él también será eliminada del álbum</p>",
"add_viewers": "Añadir espectadores",
"change_permission_to_viewer": "<p>{{selectedEmail}} no podrá añadir más fotos al álbum</p><p>Todavía podrán eliminar fotos añadidas por ellos</p>",
"change_permission_to_collaborator": "{{selectedEmail}} podrá añadir fotos al álbum",
"change_permission_title": "¿Cambiar Permiso?",
"confirm_convert_to_viewer": "Sí, convertir a espectador",
"confirm_convert_to_collaborator": "Sí, convertir a colaborador",
"manage": "Administrar",
"added_as": "Añadido como",
"collaborator_hint": "Los colaboradores pueden añadir fotos y videos al álbum compartido",
"remove_participant": "Quitar participante",
"remove_participant_title": "¿Eliminar?",
"remove_participant_message": "<p>{{selectedEmail}} será eliminado del álbum</p><p>Cualquier foto añadida por él también será eliminada del álbum</p>",
"confirm_remove": "Sí, eliminar",
"owner": "Propietario",
"collaborators": "Colaboradores",
"viewers": "Espectadores",
"add_more": "Añadir más",
"or_add_existing": "O elige uno existente",
"NOT_FOUND": "404 - No Encontrado",
"link_expired": "Enlace expirado",
"link_expired_message": "Este enlace ha caducado o ha sido desactivado",
"MANAGE_LINK": "Administrar enlace",
"LINK_TOO_MANY_REQUESTS": "Este álbum ha sido visto en demasiados dispositivos",
"FILE_DOWNLOAD": "Permitir descargas",
"PUBLIC_COLLECT": "Permitir añadir fotos",
"LINK_DEVICE_LIMIT": "Límites del dispositivo",
"NO_DEVICE_LIMIT": "Ninguno",
"LINK_EXPIRY": "Enlace caducado",
"manage_link": "Administrar enlace",
"link_request_limit_exceeded": "Este álbum ha sido visto en demasiados dispositivos",
"allow_downloads": "Permitir descargas",
"allow_adding_photos": "Permitir añadir fotos",
"allow_adding_photos_hint": "Permitir a las personas con el enlace añadir fotos al álbum compartido.",
"device_limit": "Límites del dispositivo",
"none": "Ninguno",
"link_expiry": "Enlace caducado",
"never": "Nunca",
"after_time": {
"hour": "Después de una hora",
"day": "Después de un día",
"week": "Después de una semana",
"month": "Después de un mes",
"year": "Después de un año"
},
"copy_link": "Copiar enlace",
"done": "Hecho",
"share_link_section_title": "O comparte un enlace",
"remove_link": "Eliminar enlace",
"create_public_link": "Crear un enlace público",
"public_link_created": "Enlace público creado",
"public_link_enabled": "Enlace público activado",
"collect_photos": "Obtener fotos",
"disable_file_download": "Deshabilitar descarga",
"disable_file_download_message": "<p>¿Está seguro que desea desactivar el botón de descarga de archivos?</p><p>Los visualizadores todavía pueden tomar capturas de pantalla o guardar una copia de sus fotos usando herramientas externas.</p>",
"shared_using": "Compartido usando <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Después de una hora",
"day": "Después de un día",
"week": "Después de una semana",
"month": "Después de un mes",
"year": "Después de un año"
},
"copy_link": "Copiar enlace",
"done": "Hecho",
"LINK_SHARE_TITLE": "O comparte un enlace",
"REMOVE_LINK": "Eliminar enlace",
"CREATE_PUBLIC_SHARING": "Crear un enlace público",
"public_link_created": "Enlace público creado",
"PUBLIC_LINK_ENABLED": "Enlace público activado",
"COLLECT_PHOTOS": "Obtener fotos",
"PUBLIC_COLLECT_SUBTEXT": "Permitir a las personas con el enlace añadir fotos al álbum compartido.",
"STOP_EXPORT": "Stop",
"EXPORT_PROGRESS": "<a>{{progress.success}} / {{progress.total}}</a> archivos exportados",
"MIGRATING_EXPORT": "Preparando...",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "نتایج جستجو",
"no_results": "هیچ نتیجه‌ای پیدا نشد",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -2,7 +2,7 @@
"intro_slide_1_title": "Yksityiset varmuuskopiot<br/>muistoillesi",
"intro_slide_1": "Päästä päähän -salaus käytössä oletuksena",
"intro_slide_2_title": "Turvallisesti varastoitu<br/>väestönsuojan tiloissa",
"intro_slide_2": "",
"intro_slide_2": "Suunniteltu selviytymään",
"intro_slide_3_title": "Saatavilla<br/>kaikkialla",
"intro_slide_3": "Android, iOS, Web, Tietokone",
"login": "Kirjaudu sisään",
@ -12,15 +12,15 @@
"enter_email": "Syötä sähköpostiosoite",
"invalid_email_error": "Syötä voimassa oleva sähköpostiosoite",
"required": "Pakollinen",
"email_not_registered": "",
"email_already_registered": "",
"email_not_registered": "Sähköpostiosoitetta ei ole rekisteröity",
"email_already_registered": "Sähköpostiosoite on jo rekisteröity",
"email_sent": "Vahvistuskoodi lähetetty osoitteeseen <a>{{email}}</a>",
"check_inbox_hint": "Tarkista saapuneet-kansiosi (ja roskaposti) suorittaaksesi vahvistuksen",
"verification_code": "Vahvistuskoodi",
"resend_code": "Lähetä koodi uudelleen",
"verify": "Vahvista",
"send_otp": "",
"generic_error": "",
"send_otp": "Lähetä OTP",
"generic_error": "Jotakin meni pieleen",
"generic_error_retry": "Jokin meni vikaan. Yritä uudelleen",
"invalid_code_error": "Virheellinen vahvistuskoodi",
"expired_code_error": "Vahvistuskoodisi on vanhentunut",
@ -34,22 +34,22 @@
"incorrect_password": "Väärä salasana",
"pick_password_hint": "Anna salasana, jota voimme käyttää salaamaan tietosi",
"pick_password_caution": "Emme säilytä salasanaasi, joten jos unohdat sen, <strong>emme voi auttaa sinua </strong>palauttamaan tietojasi ilman palautusavainta.",
"key_generation_in_progress": "",
"confirm_password": "",
"key_generation_in_progress": "Luodaan salausavaimia...",
"confirm_password": "Vahvista salasana",
"referral_source_hint": "Miten kuulit Entestä? (valinnainen)",
"referral_source_info": "Emme seuraa sovelluksen asennuksia. Se auttaisi meitä, jos kertoisit mistä löysit meidät!",
"password_mismatch_error": "Salasanat eivät täsmää",
"welcome_to_ente_title": "",
"welcome_to_ente_subtitle": "",
"welcome_to_ente_subtitle": "Päästä päähän salattu valokuvien tallennustila ja jakaminen",
"new_album": "Uusi albumi",
"create_albums": "",
"create_albums": "Luo albumit",
"enter_album_name": "Albumin nimi",
"close_key": "Sulje (Esc)",
"enter_file_name": "Tiedoston nimi",
"close": "Sulje",
"yes": "",
"yes": "Kyllä",
"no": "Ei",
"nothing_here": "",
"nothing_here": "Täällä ei ole vielä mitään",
"upload": "Lataa",
"import": "Tuo",
"add_photos": "Lisää kuvia",
@ -61,151 +61,151 @@
"UPLOAD_STAGE_MESSAGE": {
"0": "Valmistellaan latausta",
"1": "Luetaan googlen metatietotiedostoja",
"3": "",
"4": "",
"5": ""
"3": "{{uploadCounter.finished, number}} / {{uploadCounter.total, number}} tiedostoa käsitelty",
"4": "Peruutetaan jäljellä olevat lataukset",
"5": "Varmuuskopiointi on valmis"
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"no_account": "",
"existing_account": "",
"create": "",
"files_count": "",
"download": "",
"download_album": "",
"download_favorites": "",
"download_uncategorized": "",
"download_hidden_items": "",
"download_key": "",
"copy_key": "",
"toggle_fullscreen_key": "",
"zoom_in_out_key": "",
"previous_key": "",
"next_key": "",
"title_photos": "",
"title_auth": "",
"title_accounts": "",
"upload_first_photo": "",
"import_your_folders": "",
"upload_dropzone_hint": "",
"watch_folder_dropzone_hint": "",
"trash_files_title": "",
"trash_file_title": "",
"delete_files_title": "",
"delete_files_message": "",
"selected_count": "",
"selected_and_yours_count": "",
"delete": "",
"delete_key": "",
"favorite": "",
"favorite_key": "",
"unfavorite_key": "",
"convert": "",
"multi_folder_upload": "",
"upload_to_choice": "",
"upload_to_single_album": "",
"upload_to_album_per_folder": "",
"session_expired": "",
"session_expired_message": "",
"password_generation_failed": "",
"change_password": "",
"password_changed_elsewhere": "",
"password_changed_elsewhere_message": "",
"go_back": "",
"recovery_key": "",
"do_this_later": "",
"save_key": "",
"recovery_key_description": "",
"key_not_stored_note": "",
"recovery_key_generation_failed": "",
"forgot_password": "",
"recover_account": "",
"FILE_NOT_UPLOADED_LIST": "Seuraavia tiedostoja ei ladattu",
"initial_load_delay_warning": "Ensimmäinen lataus voi kestää jonkin aikaa",
"no_account": "Ei tiliä",
"existing_account": "Sinulla on jo tili",
"create": "Luo",
"files_count": "{{count, number}} tiedostoa",
"download": "Lataa",
"download_album": "Lataa albumi",
"download_favorites": "Lataa suosikit",
"download_uncategorized": "Lataa luokittelemattomat",
"download_hidden_items": "Lataa piilotetut kohteet",
"download_key": "Lataa (D)",
"copy_key": "Kopioi PNG-muodossa (Ctrl/Cmd - C)",
"toggle_fullscreen_key": "Vaihda koko näytön tilaan (F)",
"zoom_in_out_key": "Lähennä/Loitonna",
"previous_key": "Edellinen (←)",
"next_key": "Seuraava (→)",
"title_photos": "Ente Kuvat",
"title_auth": "Ente Auth",
"title_accounts": "Ente Tilit",
"upload_first_photo": "Lataa ensimmäinen valokuvasi",
"import_your_folders": "Tuo kansiosi",
"upload_dropzone_hint": "Pudota varmuuskopioidaksesi tiedostosi",
"watch_folder_dropzone_hint": "Pudota lisätäksesi katsottu kansio",
"trash_files_title": "Poistetaanko tiedostot?",
"trash_file_title": "Poistetaanko tiedosto?",
"delete_files_title": "Poista välittömästi?",
"delete_files_message": "Valitut tiedostot poistetaan pysyvästi Ente tililtäsi.",
"selected_count": "{{selected, number}} valittu",
"selected_and_yours_count": "{{selected, number}} valittu {{yours, number}} omaasi",
"delete": "Poista",
"delete_key": "Poista (DEL)",
"favorite": "Lisää suosikkeihin",
"favorite_key": "Lisää suosikkeihin (L)",
"unfavorite_key": "Poista suosikeista (L)",
"convert": "Muunna",
"multi_folder_upload": "Useita kansioita havaittu",
"upload_to_choice": "Haluaisitko ladata ne kohteeseen",
"upload_to_single_album": "Yksittäinen albumi",
"upload_to_album_per_folder": "Erilliset albumit",
"session_expired": "Istunto on vanhentunut",
"session_expired_message": "Istuntosi on vanhentunut. Kirjaudu sisään uudelleen jatkaaksesi",
"password_generation_failed": "Selaimesi ei pystynyt luomaan vahvaa avainta, joka vastaa Enten salausstandardeja, kokeile mobiilisovellusta tai toista selainta",
"change_password": "Vaihda salasana",
"password_changed_elsewhere": "Salasana vaihdettu muualla",
"password_changed_elsewhere_message": "Ole hyvä ja kirjaudu uudelleen tähän laitteeseen käyttääksesi uutta salasanaasi tunnistautumiseen.",
"go_back": "Palaa",
"recovery_key": "Palautusavain",
"do_this_later": "Tee tämä myöhemmin",
"save_key": "Tallenna avain",
"recovery_key_description": "Jos unohdat salasanasi, tämä avain on ainoa tapa palauttaa tietosi.",
"key_not_stored_note": "Emme tallenna tätä avainta, joten tallenna se turvalliseen paikkaan",
"recovery_key_generation_failed": "Palautuskoodia ei voitu luoda, yritä uudelleen",
"forgot_password": "Unohdin salasanani",
"recover_account": "Palauta tilisi",
"recover": "",
"no_recovery_key_title": "",
"incorrect_recovery_key": "",
"sorry": "",
"no_recovery_key_message": "",
"no_two_factor_recovery_key_message": "",
"contact_support": "",
"request_feature": "",
"support": "",
"cancel": "",
"logout": "",
"logout_message": "",
"delete_account": "",
"delete_account_manually_message": "",
"change_email": "",
"ok": "",
"success": "",
"error": "",
"offline_message": "",
"install": "",
"install_mobile_app": "",
"download_app": "",
"download_app_message": "",
"subscription": "",
"manage_payment_method": "",
"manage_family": "",
"family_plan": "",
"leave_family_plan": "",
"leave": "",
"leave_family_plan_confirm": "",
"choose_plan": "",
"manage_plan": "",
"current_usage": "",
"two_months_free": "",
"free_plan_option": "",
"free_plan_description": "",
"active": "",
"subscription_info_free": "",
"subscription_info_family": "",
"subscription_info_expired": "",
"subscription_info_renewal_cancelled": "",
"subscription_info_storage_quota_exceeded": "",
"subscription_status_renewal_active": "",
"subscription_status_renewal_cancelled": "",
"add_on_valid_till": "",
"subscription_expired": "",
"storage_quota_exceeded": "",
"subscription_purchase_success": "",
"subscription_purchase_cancelled": "",
"subscription_purchase_failed": "",
"subscription_verification_error": "",
"update_payment_method_message": "",
"payment_method_authentication_failed": "",
"update_payment_method": "",
"monthly": "",
"yearly": "",
"month_short": "",
"year": "",
"update_subscription": "",
"update_subscription_title": "",
"update_subscription_message": "",
"cancel_subscription": "",
"cancel_subscription_message": "",
"cancel_subscription_with_addon_message": "",
"subscription_cancel_success": "",
"reactivate_subscription": "",
"reactivate_subscription_message": "",
"subscription_activate_success": "",
"thank_you": "",
"cancel_subscription_on_mobile": "",
"cancel_subscription_on_mobile_message": "",
"mail_to_manage_subscription": "",
"rename": "",
"rename_file": "",
"rename_album": "",
"delete_album": "",
"delete_album_title": "",
"delete_album_message": "",
"no_recovery_key_title": "Ei palautusavainta?",
"incorrect_recovery_key": "Virheellinen palautusavain",
"sorry": "Pahoittelut",
"no_recovery_key_message": "Päästä päähän -salausprotokollamme vuoksi tietojasi ei voida purkaa ilman salasanaa tai palautusavainta",
"no_two_factor_recovery_key_message": "Ole hyvä ja lähetä sähköpostia osoitteeseen <a>{{emailID}}</a> omasta rekisteröidystä sähköpostiosoitteestasi",
"contact_support": "Ota yhteyttä tukeen",
"request_feature": "Pyydä ominaisuutta",
"support": "Tuki",
"cancel": "Peruuta",
"logout": "Kirjaudu ulos",
"logout_message": "Oletko varma, että haluat kirjautua ulos?",
"delete_account": "Poista tili",
"delete_account_manually_message": "<p>Ole hyvä ja lähetä sähköpostia osoitteeseen <a>{{emailID}}</a> omasta rekisteröidystä sähköpostiosoitteestasi.</p><p>Pyyntösi käsitellään 72 tunnin kuluessa.</p>",
"change_email": "Vaihda sähköpostiosoite",
"ok": "OK",
"success": "Onnistui",
"error": "Virhe",
"offline_message": "Olet offline-tilassa, välimuistissa olevat muistot näytetään",
"install": "Asenna",
"install_mobile_app": "Asenna <a>Android</a> tai <b>iOS</b> -sovellus varmuuskopioidaksesi automaattisesti kaikki valokuvasi",
"download_app": "Lataa työpöytäsovellus",
"download_app_message": "Valitettavasti tämä toiminto on tällä hetkellä tuettu vain työpöytäsovelluksessamme",
"subscription": "Tilaus",
"manage_payment_method": "Hallinnoi maksutapoja",
"manage_family": "Hallinnoi perhettä",
"family_plan": "Perhetilaus",
"leave_family_plan": "Poistu perhetilauksesta",
"leave": "Poistu",
"leave_family_plan_confirm": "Oletko varma että haluat poistua perhetilauksesta?",
"choose_plan": "Valitse tilauksesi",
"manage_plan": "Hallinnoi tilaustasi",
"current_usage": "Nykyinen käyttö <strong>{{usage}}</strong>",
"two_months_free": "Saat 2 kuukautta ilmaiseksi vuositilauksista",
"free_plan_option": "Jatka ilmaisella tilauksella",
"free_plan_description": "{{storage}} ilmaiseksi ikuisesti",
"active": "Aktiivinen",
"subscription_info_free": "Sinulla on ilmainen tilaus",
"subscription_info_family": "Olet perhetilauksessa, jota hallinnoi",
"subscription_info_expired": "Tilauksesi on vanhentunut, ole hyvä ja <a>uusi</a>",
"subscription_info_renewal_cancelled": "Tilauksesi peruutetaan {{date, date}}",
"subscription_info_storage_quota_exceeded": "Olet ylittänyt tallennuskiintiösi, ole hyvä ja <a>päivitä</a>",
"subscription_status_renewal_active": "Uusiutuu {{date, date}}",
"subscription_status_renewal_cancelled": "Päättyy {{date, date}}",
"add_on_valid_till": "Sinun {{storage}} lisäsi on voimassa {{date, date}} asti",
"subscription_expired": "Tilaus on päättynyt",
"storage_quota_exceeded": "Tallennuskiintiö ylitetty",
"subscription_purchase_success": "<p>Olemme vastaanottaneet maksusi</p><p>Tilauksesi on voimassa <strong>{{date, date}}</strong></p> asti",
"subscription_purchase_cancelled": "Ostosi peruttiin, yritä uudelleen jos haluat tilata",
"subscription_purchase_failed": "Tilauksen osto epäonnistui, yritä uudelleen",
"subscription_verification_error": "Tilauksen vahvistus epäonnistui",
"update_payment_method_message": "Olemme pahoillamme, maksu epäonnistui, kun yritimme veloittaa korttiasi, päivitä maksutapasi ja yritä uudelleen",
"payment_method_authentication_failed": "Emme voi todentaa maksutapaasi. Valitse toinen maksutapa ja yritä uudelleen",
"update_payment_method": "Päivitä maksutapa",
"monthly": "Kuukausittainen",
"yearly": "Vuosittainen",
"month_short": "kk",
"year": "vuosi",
"update_subscription": "Muuta tilausta",
"update_subscription_title": "Vahvista tilauksen muutos",
"update_subscription_message": "Haluatko varmasti muuttaa tilaustasi?",
"cancel_subscription": "Peruuta tilaus",
"cancel_subscription_message": "<p>Kaikki tietosi poistetaan palvelimiltamme tämän laskutusajan päättyessä.</p><p>Oletko varma, että haluat peruuttaa tilauksesi?</p>",
"cancel_subscription_with_addon_message": "<p>Oletko varma, että haluat peruuttaa tilauksesi?</p>",
"subscription_cancel_success": "Tilaus peruutettu onnistuneesti",
"reactivate_subscription": "Tilauksen uudelleenaktivointi",
"reactivate_subscription_message": "Uudelleenaktivoinnin jälkeen sinua laskutetaan {{date, date}}",
"subscription_activate_success": "Tilaus aktivoitu onnistuneesti ",
"thank_you": "Kiitos",
"cancel_subscription_on_mobile": "Peruuta mobiilitilaus",
"cancel_subscription_on_mobile_message": "Peruuta tilauksesi mobiilisovelluksessa aktivoidaksesi tilauksen täällä",
"mail_to_manage_subscription": "Ota yhteyttä osoitteeseen <a>{{emailID}}</a> hallitaksesi tilaustasi",
"rename": "Nimeä uudelleen",
"rename_file": "Nimeä tiedosto uudelleen",
"rename_album": "Nimeä albumi uudelleen",
"delete_album": "Poista albumi",
"delete_album_title": "Poistetaanko albumi?",
"delete_album_message": "Poistetaanko tämän albumin kuvat (ja videot) myös <a>kaikilta</a> muilta albumeilta, joilla ne ovat?",
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "Valitettavasti käyttäjää ei löytynyt tällä sähköpostiosoitteella",
"search": "",
"search_results": "",
"no_results": "",
@ -249,56 +249,56 @@
"file_name": "",
"caption_placeholder": "",
"location": "",
"view_on_map": "",
"map": "",
"enable_map": "",
"enable_maps_confirm": "",
"enable_maps_confirm_message": "",
"disable_map": "",
"disable_maps_confirm": "",
"disable_maps_confirm_message": "",
"details": "",
"view_exif": "",
"no_exif": "",
"exif": "",
"two_factor": "",
"two_factor_authentication": "",
"two_factor_qr_help": "",
"two_factor_manual_entry_title": "",
"two_factor_manual_entry_message": "",
"scan_qr_title": "",
"enable_two_factor": "",
"enable": "",
"enabled": "",
"lost_2fa_device": "",
"incorrect_code": "",
"two_factor_info": "",
"disable": "",
"reconfigure": "",
"reconfigure_two_factor_hint": "",
"update_two_factor": "",
"update_two_factor_message": "",
"update": "",
"disable_two_factor": "",
"disable_two_factor_message": "",
"export_data": "",
"select_folder": "",
"select_zips": "",
"faq": "",
"view_on_map": "Näytä OpenStreetMapissa",
"map": "Kartta",
"enable_map": "Ota kartta käyttöön",
"enable_maps_confirm": "Otetaanko kartat käyttöön?",
"enable_maps_confirm_message": "<p>Tämä näyttää kuvasi maailmankartalla.</p><p>Karttaa isännöi <a>OpenStreetMap</a>ja valokuvien tarkkoja sijainteja ei koskaan jaeta.</p><p>Voit poistaa tämän ominaisuuden käytöstä milloin tahansa Asetuksista.</p>",
"disable_map": "Poista kartta käytöstä",
"disable_maps_confirm": "Poista kartat käytöstä?",
"disable_maps_confirm_message": "<p>Tämä poistaa valokuvien näytön käytöstä maailmankartalla.</p><p>Voit ottaa tämän ominaisuuden käyttöön milloin tahansa Asetuksista.</p>",
"details": "Tiedot",
"view_exif": "Näytä kaikki Exif -tiedot",
"no_exif": "Ei Exif -tietoja",
"exif": "Exif",
"two_factor": "Kaksivaiheinen",
"two_factor_authentication": "Kaksivaiheinen vahvistus",
"two_factor_qr_help": "Skannaa alla oleva QR-koodi suosikki todennussovelluksellasi",
"two_factor_manual_entry_title": "Syötä koodi käsin",
"two_factor_manual_entry_message": "Syötä tämä koodi suosikki todennussovellukseesi",
"scan_qr_title": "Lue QR-koodi sen sijaan",
"enable_two_factor": "Ota kaksivaiheinen vahvistus käyttöön",
"enable": "Ota käyttöön",
"enabled": "Käytössä",
"lost_2fa_device": "Kadonnut kaksivaiheisen vahvistuksen laite",
"incorrect_code": "Virheellinen koodi",
"two_factor_info": "Lisää turvallisuutta vaatimalla tilillesi kirjautumiseen muutakin kuin sähköpostiosoitteen ja salasanan",
"disable": "Poista käytöstä",
"reconfigure": "Määritä uudelleen",
"reconfigure_two_factor_hint": "Päivitä vahvistuslaitteesi",
"update_two_factor": "Päivitä kaksivaiheinen vahvistus",
"update_two_factor_message": "Eteenpäin jatkaminen mitätöi kaikki aiemmin määritetyt vahvistustavat",
"update": "Päivitä",
"disable_two_factor": "Poista kaksivaiheinen vahvistus käytöstä",
"disable_two_factor_message": "Oletko varma, että haluat poistaa kaksivaiheisen vahvistuksen käytöstä",
"export_data": "Vie tiedot",
"select_folder": "Valitse kansio",
"select_zips": "Valitse zip-tiedostot",
"faq": "UKK",
"takeout_hint": "",
"destination": "",
"start": "",
"last_export_time": "",
"export_again": "",
"LOCAL_STORAGE_NOT_ACCESSIBLE_MESSAGE": "",
"email_already_taken": "",
"ETAGS_BLOCKED": "",
"LIVE_PHOTOS_DETECTED": "",
"RETRY_FAILED": "",
"FAILED_UPLOADS": "",
"failed_uploads_hint": "",
"SKIPPED_FILES": "",
"THUMBNAIL_GENERATION_FAILED_UPLOADS": "",
"destination": "Kohde",
"start": "Aloita",
"last_export_time": "Viimeisimmän viennin ajankohta",
"export_again": "Synkronoi uudelleen",
"LOCAL_STORAGE_NOT_ACCESSIBLE_MESSAGE": "Selaimesi tai lisäosa estää Enteä tallentamasta tietoja paikalliseen tallennustilaan",
"email_already_taken": "Sähköpostiosoite on jo käytössä",
"ETAGS_BLOCKED": "Selaimesi tai lisäosa estää Enteä käyttämästä <code>eTags</code> ladatakseen suuria tiedostoja.",
"LIVE_PHOTOS_DETECTED": "Valokuva- ja videotiedostot Live Photo -kuvistasi on yhdistetty yhteen tiedostoon",
"RETRY_FAILED": "Yritä uudelleen epäonnistuneita latauksia",
"FAILED_UPLOADS": "Epäonnistuneet lataukset ",
"failed_uploads_hint": "Kun lataus valmistuu, voit yrittää näitä uudelleen",
"SKIPPED_FILES": "Ohitetut lataukset",
"THUMBNAIL_GENERATION_FAILED_UPLOADS": "Pienoiskuvan luonti epäonnistui",
"UNSUPPORTED_FILES": "",
"SUCCESSFUL_UPLOADS": "",
"SKIPPED_INFO": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -12,8 +12,8 @@
"enter_email": "Saisir l'adresse e-mail",
"invalid_email_error": "Saisir un e-mail valide",
"required": "Nécessaire",
"email_not_registered": "",
"email_already_registered": "",
"email_not_registered": "Adresse e-mail non enregistrée",
"email_already_registered": "Adresse e-mail déjà enregistrée",
"email_sent": "Code de vérification envoyé à <a>{{email}}</a>",
"check_inbox_hint": "Veuillez consulter votre boite de réception (et indésirables) pour poursuivre la vérification",
"verification_code": "Code de vérification",
@ -66,8 +66,7 @@
"5": "Sauvegarde terminée"
},
"FILE_NOT_UPLOADED_LIST": "Les fichiers suivants n'ont pas été chargés",
"INITIAL_LOAD_DELAY_WARNING": "La première consultation peut prendre du temps",
"USER_DOES_NOT_EXIST": "Désolé, impossible de trouver un utilisateur avec cet e-mail",
"initial_load_delay_warning": "Le premier affichage peut prendre du temps",
"no_account": "Je n'ai pas de compte",
"existing_account": "J'ai déjà un compte",
"create": "Créer",
@ -202,10 +201,11 @@
"delete_photos": "Supprimer des photos",
"keep_photos": "Conserver des photos",
"share_album": "Partager l'album",
"SHARE_WITH_SELF": "Oups, vous ne pouvez pas partager avec vous-même",
"ALREADY_SHARED": "Oups, vous partager déjà cela avec {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Partage d'album non autorisé",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Le partage est désactivé pour les comptes gratuits",
"sharing_with_self": "Vous ne pouvez pas partager avec vous-même",
"sharing_already_shared": "Vous partagez déjà ceci avec {{email}}",
"sharing_album_not_allowed": "Partage d'album non autorisé",
"sharing_disabled_for_free_accounts": "Le partage est désactivé pour les comptes gratuits",
"sharing_user_does_not_exist": "Impossible de trouver un utilisateur avec cet email",
"search": "Recherche",
"search_results": "Résultats de la recherche",
"no_results": "Aucun résultat trouvé",
@ -362,43 +362,59 @@
"caption_character_limit": "5000 caractères max",
"sharing_details": "Détails du partage",
"modify_sharing": "Modifier le partage",
"ADD_COLLABORATORS": "Ajouter des collaborateurs",
"ADD_NEW_EMAIL": "Ajouter un nouvel email",
"add_collaborators": "Ajouter des collaborateurs",
"add_new_email": "Ajouter un nouvel email",
"shared_with_people_count_zero": "Partager avec des personnes spécifiques",
"shared_with_people_count_one": "Partagé avec 1 personne",
"shared_with_people_count": "Partagé avec {{count, number}} personnes",
"participants_count_zero": "Aucun participant",
"participants_count_one": "1 participant",
"participants_count": "{{count, number}} participants",
"ADD_VIEWERS": "Ajouter un observateur",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} ne pourra plus ajouter de photos à l'album</p><p>Il pourra toujours supprimer les photos qu'il a ajoutées</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} pourra ajouter des photos à l'album",
"CONVERT_TO_VIEWER": "Oui, convertir en observateur",
"CONVERT_TO_COLLABORATOR": "Oui, convertir en collaborateur",
"CHANGE_PERMISSION": "Modifier la permission?",
"REMOVE_PARTICIPANT": "Retirer?",
"CONFIRM_REMOVE": "Oui, supprimer",
"MANAGE": "Gérer",
"ADDED_AS": "Ajouté comme",
"COLLABORATOR_RIGHTS": "Les collaborateurs peuvent ajouter des photos et des vidéos à l'album partagé",
"REMOVE_PARTICIPANT_HEAD": "Supprimer le participant",
"OWNER": "Propriétaire",
"COLLABORATORS": "Collaborateurs",
"ADD_MORE": "Ajouter plus",
"VIEWERS": "Observateurs",
"OR_ADD_EXISTING": "ou sélectionner un fichier existant",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} sera supprimé de l'album</p><p>Toutes les photos ajoutées par cette personne seront également supprimées de l'album</p>",
"add_viewers": "Ajouter des spectateurs",
"change_permission_to_viewer": "<p>{{selectedEmail}} ne pourra plus ajouter de photos à l'album</p><p>Il pourra toujours supprimer les photos qu'il a ajouté</p>",
"change_permission_to_collaborator": "{{selectedEmail}} pourra ajouter des photos à l'album",
"change_permission_title": "Modifier les permissions ?",
"confirm_convert_to_viewer": "Oui, convertir en spectateur",
"confirm_convert_to_collaborator": "Oui, convertir en collaborateur",
"manage": "Gérer",
"added_as": "Ajouté comme",
"collaborator_hint": "Les collaborateurs peuvent ajouter des photos et vidéos à l'album partagé",
"remove_participant": "Supprimer le participant",
"remove_participant_title": "Retirer ?",
"remove_participant_message": "<p>{{selectedEmail}} sera supprimé de l'album</p><p>Toutes les photos ajoutées par cette personne seront également supprimées de l'album</p>",
"confirm_remove": "Oui, supprimer",
"owner": "Propriétaire",
"collaborators": "Collaborateurs",
"viewers": "Spectateurs",
"add_more": "Ajouter plus",
"or_add_existing": "ou sélectionner un fichier existant",
"NOT_FOUND": "404 - non trouvé",
"link_expired": "Lien expiré",
"link_expired_message": "Ce lien a soit expiré, soit été supprimé",
"MANAGE_LINK": "Gérer le lien",
"LINK_TOO_MANY_REQUESTS": "Cet album a été consulté sur trop d'appareils",
"FILE_DOWNLOAD": "Autoriser les téléchargements",
"PUBLIC_COLLECT": "Autoriser l'ajout de photos",
"LINK_DEVICE_LIMIT": "Limite d'appareil",
"NO_DEVICE_LIMIT": "Aucune",
"LINK_EXPIRY": "Expiration du lien",
"manage_link": "Gérer le lien",
"link_request_limit_exceeded": "Cet album a été consulté sur trop d'appareils",
"allow_downloads": "Autoriser les téléchargements",
"allow_adding_photos": "Autoriser l'ajout de photos",
"allow_adding_photos_hint": "Autoriser les personnes ayant le lien d'ajouter des photos à l'album partagé.",
"device_limit": "Limite d'appareil",
"none": "Aucune",
"link_expiry": "Expiration du lien",
"never": "Jamais",
"after_time": {
"hour": "Dans une heure",
"day": "Dans un jour",
"week": "Dans une semaine",
"month": "Dans un mois",
"year": "Dans un an"
},
"copy_link": "Copier le lien",
"done": "Terminé",
"share_link_section_title": "Ou partager un lien",
"remove_link": "Supprimer le lien",
"create_public_link": "Créer un lien public",
"public_link_created": "Lien public créé",
"public_link_enabled": "Lien public activé",
"collect_photos": "Récupérer les photos",
"disable_file_download": "Désactiver le téléchargement",
"disable_file_download_message": "<p>Êtes-vous certains de vouloir désactiver le bouton de téléchargement pour les fichiers?</p><p>Ceux qui les visualisent pourront tout de même faire des captures d'écrans ou sauvegarder une copie de vos photos en utilisant des outils externes.</p>",
"shared_using": "Partagé en utilisant <a>{{url}}</a>",
@ -412,13 +428,13 @@
"folder": "Dossier",
"google_takeout": "Google Takeout",
"deduplicate_files": "Déduplication de fichiers",
"remove_duplicates": "",
"total_size": "",
"remove_duplicates": "Supprimer les doublons",
"total_size": "Poids total",
"count": "",
"deselect_all": "",
"no_duplicates": "",
"duplicate_group_description": "",
"remove_duplicates_button_count": "",
"deselect_all": "Tout déselectionner",
"no_duplicates": "Aucun doublon",
"duplicate_group_description": "{{count}} éléments, {{itemSize}} chacun",
"remove_duplicates_button_count": "Supprimer {{count, number}} éléments",
"stop_uploads_title": "Arrêter les chargements ?",
"stop_uploads_message": "Êtes-vous certains de vouloir arrêter tous les chargements en cours?",
"yes_stop_uploads": "Oui, arrêter tout",
@ -511,22 +527,6 @@
"gb": "Go",
"tb": "To"
},
"after_time": {
"hour": "Dans une heure",
"day": "Dans un jour",
"week": "Dans une semaine",
"month": "Dans un mois",
"year": "Dans un an"
},
"copy_link": "Copier le lien",
"done": "Terminé",
"LINK_SHARE_TITLE": "Ou partager un lien",
"REMOVE_LINK": "Supprimer le lien",
"CREATE_PUBLIC_SHARING": "Créer un lien public",
"public_link_created": "Lien public créé",
"PUBLIC_LINK_ENABLED": "Lien public activé",
"COLLECT_PHOTOS": "Récupérer les photos",
"PUBLIC_COLLECT_SUBTEXT": "Autoriser les personnes ayant le lien d'ajouter des photos à l'album partagé.",
"STOP_EXPORT": "Stop",
"EXPORT_PROGRESS": "<a>{{progress.success}} / {{progress.total}}</a> fichiers exportés",
"MIGRATING_EXPORT": "Préparations...",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "Cadangan selesai"
},
"FILE_NOT_UPLOADED_LIST": "File berikut tidak terunggah",
"INITIAL_LOAD_DELAY_WARNING": "Pemuatan pertama mungkin memakan waktu",
"USER_DOES_NOT_EXIST": "Maaf, tidak dapat menemukan pengguna dengan email tersebut",
"initial_load_delay_warning": "Pemuatan pertama mungkin memakan waktu",
"no_account": "Belum memiliki akun",
"existing_account": "Sudah memiliki akun",
"create": "Buat",
@ -202,10 +201,11 @@
"delete_photos": "Hapus foto",
"keep_photos": "",
"share_album": "Bagikan album",
"SHARE_WITH_SELF": "Aduh, kamu tidak bisa berbagi dengan dirimu sendiri",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "Berbagi album tidak diizinkan",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Berbagi album tidak diizinkan",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "Hasil penelusuran",
"no_results": "Tidak ditemukan hasil",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "Tambah kolaborator",
"ADD_NEW_EMAIL": "",
"add_collaborators": "Tambah kolaborator",
"add_new_email": "",
"shared_with_people_count_zero": "Bagikan dengan orang tertentu",
"shared_with_people_count_one": "Berbagi dengan 1 orang",
"shared_with_people_count": "Berbagi dengan {{count, number}} orang",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "Hapus?",
"CONFIRM_REMOVE": "Ya, hapus",
"MANAGE": "Atur",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "Kolaborator bisa menambahkan foto dan video ke album bersama ini",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "Pemilik",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} akan dikeluarkan dari album ini</p><p>Semua foto yang ia tambahkan juga akan dihapus dari album ini</p>",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "Atur",
"added_as": "",
"collaborator_hint": "Kolaborator bisa menambahkan foto dan video ke album bersama ini",
"remove_participant": "",
"remove_participant_title": "Hapus?",
"remove_participant_message": "<p>{{selectedEmail}} akan dikeluarkan dari album ini</p><p>Semua foto yang ia tambahkan juga akan dihapus dari album ini</p>",
"confirm_remove": "Ya, hapus",
"owner": "Pemilik",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "404 - tidak ditemukan",
"link_expired": "Link telah kedaluwarsa",
"link_expired_message": "",
"MANAGE_LINK": "Atur link",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "Izinkan pengunduhan",
"PUBLIC_COLLECT": "Izinkan menambah foto",
"LINK_DEVICE_LIMIT": "Batas perangkat",
"NO_DEVICE_LIMIT": "Tidak ada",
"LINK_EXPIRY": "Waktu kedaluwarsa link",
"manage_link": "Atur link",
"link_request_limit_exceeded": "",
"allow_downloads": "Izinkan pengunduhan",
"allow_adding_photos": "Izinkan menambah foto",
"allow_adding_photos_hint": "Izinkan orang yang memiliki link untuk menambahkan foto ke album berbagi ini.",
"device_limit": "Batas perangkat",
"none": "Tidak ada",
"link_expiry": "Waktu kedaluwarsa link",
"never": "Tidak pernah",
"after_time": {
"hour": "Setelah satu jam",
"day": "Setelah satu hari",
"week": "Setelah satu minggu",
"month": "Setelah satu bulan",
"year": "Setelah satu tahun"
},
"copy_link": "Salin link",
"done": "Selesai",
"share_link_section_title": "Atau bagikan link",
"remove_link": "Hapus link",
"create_public_link": "Buat link publik",
"public_link_created": "Link publik dibuat",
"public_link_enabled": "Link publik aktif",
"collect_photos": "Kumpulkan foto",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Setelah satu jam",
"day": "Setelah satu hari",
"week": "Setelah satu minggu",
"month": "Setelah satu bulan",
"year": "Setelah satu tahun"
},
"copy_link": "Salin link",
"done": "Selesai",
"LINK_SHARE_TITLE": "Atau bagikan link",
"REMOVE_LINK": "Hapus link",
"CREATE_PUBLIC_SHARING": "Buat link publik",
"public_link_created": "Link publik dibuat",
"PUBLIC_LINK_ENABLED": "Link publik aktif",
"COLLECT_PHOTOS": "Kumpulkan foto",
"PUBLIC_COLLECT_SUBTEXT": "Izinkan orang yang memiliki link untuk menambahkan foto ke album berbagi ini.",
"STOP_EXPORT": "Hentikan",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> item tersinkron",
"MIGRATING_EXPORT": "Menyiapkan...",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "hámark 5000 stafir",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "Eigandi",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "Eigandi",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "404 - fannst ekki",
"link_expired": "Hlekkur rann út",
"link_expired_message": "",
"MANAGE_LINK": "Stjórna hlekk",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "Stjórna hlekk",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "Backup completato"
},
"FILE_NOT_UPLOADED_LIST": "I seguenti file non sono stati caricati",
"INITIAL_LOAD_DELAY_WARNING": "Il primo caricamento potrebbe richiedere del tempo",
"USER_DOES_NOT_EXIST": "Purtroppo non abbiamo trovato nessun account con quell'indirizzo e-mail",
"initial_load_delay_warning": "Il primo caricamento potrebbe richiedere del tempo",
"no_account": "Non ho un account",
"existing_account": "Ho già un account",
"create": "Crea",
@ -202,10 +201,11 @@
"delete_photos": "Elimina foto",
"keep_photos": "Mantieni foto",
"share_album": "Condividi album",
"SHARE_WITH_SELF": "Ops, non puoi condividere a te stesso",
"ALREADY_SHARED": "Ops, lo stai già condividendo con {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Condividere gli album non è consentito",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "La condivisione è disabilitata per gli account free",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Condividere gli album non è consentito",
"sharing_disabled_for_free_accounts": "La condivisione è disabilitata per gli account free",
"sharing_user_does_not_exist": "",
"search": "Ricerca",
"search_results": "Risultati della ricerca",
"no_results": "Nessun risultato trovato",
@ -362,43 +362,59 @@
"caption_character_limit": "Massimo 5000 caratteri",
"sharing_details": "Dettagli di condivisione",
"modify_sharing": "Modifica i dettagli di ccondivisione",
"ADD_COLLABORATORS": "Aggiungi collaboratori",
"ADD_NEW_EMAIL": "Aggiungi una nuova email",
"add_collaborators": "Aggiungi collaboratori",
"add_new_email": "Aggiungi una nuova email",
"shared_with_people_count_zero": "Condividi con persone specifiche",
"shared_with_people_count_one": "Condiviso con 1 persona",
"shared_with_people_count": "Condiviso con {{count, number}} persone",
"participants_count_zero": "Nessun partecipante",
"participants_count_one": "1 partecipante",
"participants_count": "{{count, number}} partecipanti",
"ADD_VIEWERS": "Aggiungi visualizzatori",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} non sarà in grado di aggiungere altre foto all'album</p><p>Essi saranno comunque in grado di rimuovere le foto aggiunte da loro</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} potrà aggiungere foto all'album",
"CONVERT_TO_VIEWER": "Sì, converti in visualizzatore",
"CONVERT_TO_COLLABORATOR": "Sì, converti in collaboratore",
"CHANGE_PERMISSION": "Cambiare i permessi?",
"REMOVE_PARTICIPANT": "Rimuovere?",
"CONFIRM_REMOVE": "Sì, rimuovi",
"MANAGE": "Gestisci",
"ADDED_AS": "Aggiunto come",
"COLLABORATOR_RIGHTS": "I collaboratori possono aggiungere foto e video all'album condiviso",
"REMOVE_PARTICIPANT_HEAD": "Rimuovi partecipante",
"OWNER": "Proprietario",
"COLLABORATORS": "Collaboratori",
"ADD_MORE": "Aggiungi altri",
"VIEWERS": "Visualizzatori",
"OR_ADD_EXISTING": "Oppure scegline uno esistente",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} sarà rimosso dall'album</p><p>Tutte le foto da essi aggiunte verranno rimosse dall'album</p>",
"add_viewers": "Aggiungi visualizzatori",
"change_permission_to_viewer": "<p>{{selectedEmail}} non sarà in grado di aggiungere altre foto all'album</p><p>Essi saranno comunque in grado di rimuovere le foto aggiunte da loro</p>",
"change_permission_to_collaborator": "{{selectedEmail}} potrà aggiungere foto all'album",
"change_permission_title": "Cambiare i permessi?",
"confirm_convert_to_viewer": "Sì, converti in visualizzatore",
"confirm_convert_to_collaborator": "Sì, converti in collaboratore",
"manage": "Gestisci",
"added_as": "Aggiunto come",
"collaborator_hint": "I collaboratori possono aggiungere foto e video all'album condiviso",
"remove_participant": "Rimuovi partecipante",
"remove_participant_title": "Rimuovere?",
"remove_participant_message": "<p>{{selectedEmail}} sarà rimosso dall'album</p><p>Tutte le foto da essi aggiunte verranno rimosse dall'album</p>",
"confirm_remove": "Sì, rimuovi",
"owner": "Proprietario",
"collaborators": "Collaboratori",
"viewers": "Visualizzatori",
"add_more": "Aggiungi altri",
"or_add_existing": "Oppure scegline uno esistente",
"NOT_FOUND": "404 - non trovato",
"link_expired": "Link scaduto",
"link_expired_message": "",
"MANAGE_LINK": "Gestisci link",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "Consenti download",
"PUBLIC_COLLECT": "Consenti l'aggiunta di foto",
"LINK_DEVICE_LIMIT": "Limite dispositivi",
"NO_DEVICE_LIMIT": "Nessuno",
"LINK_EXPIRY": "Scadenza link",
"manage_link": "Gestisci link",
"link_request_limit_exceeded": "",
"allow_downloads": "Consenti download",
"allow_adding_photos": "Consenti l'aggiunta di foto",
"allow_adding_photos_hint": "Permetti alle persone con il link di aggiungere foto all'album condiviso.",
"device_limit": "Limite dispositivi",
"none": "Nessuno",
"link_expiry": "Scadenza link",
"never": "Mai",
"after_time": {
"hour": "Dopo un'ora",
"day": "Dopo un giorno",
"week": "Dopo una settimana",
"month": "Dopo un mese",
"year": "Dopo un anno"
},
"copy_link": "Copia link",
"done": "Fatto",
"share_link_section_title": "O condividi un link",
"remove_link": "Rimuovi link",
"create_public_link": "Crea link pubblico",
"public_link_created": "Link pubblick creato",
"public_link_enabled": "Link pubblico attivato",
"collect_photos": "Seleziona foto",
"disable_file_download": "Disabilita download",
"disable_file_download_message": "<p>Sei sicuro di voler disattivare il pulsante di download per i file?</p><p>I visualizzatori possono ancora fare screenshot o salvare una copia delle foto utilizzando strumenti esterni.</p>",
"shared_using": "Condiviso utilizzando <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Dopo un'ora",
"day": "Dopo un giorno",
"week": "Dopo una settimana",
"month": "Dopo un mese",
"year": "Dopo un anno"
},
"copy_link": "Copia link",
"done": "Fatto",
"LINK_SHARE_TITLE": "O condividi un link",
"REMOVE_LINK": "Rimuovi link",
"CREATE_PUBLIC_SHARING": "Crea link pubblico",
"public_link_created": "Link pubblick creato",
"PUBLIC_LINK_ENABLED": "Link pubblico attivato",
"COLLECT_PHOTOS": "Seleziona foto",
"PUBLIC_COLLECT_SUBTEXT": "Permetti alle persone con il link di aggiungere foto all'album condiviso.",
"STOP_EXPORT": "Stop",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> elementi sincronizzati",
"MIGRATING_EXPORT": "Preparazione...",

File diff suppressed because it is too large Load Diff

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "백업 완료"
},
"FILE_NOT_UPLOADED_LIST": "아래 파일들은 업로드 되지 않았습니다",
"INITIAL_LOAD_DELAY_WARNING": "처음 로딩시 다소 시간이 걸릴 수 있습니다",
"USER_DOES_NOT_EXIST": "죄송합니다. 해당 이메일을 사용하는 사용자를 찾을 수 없습니다",
"initial_load_delay_warning": "처음 로딩시 다소 시간이 걸릴 수 있습니다",
"no_account": "계정이 없습니다",
"existing_account": "이미 계정이 있습니다",
"create": "만들기",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "Atsarginės kopijos kūrimas baigtas"
},
"FILE_NOT_UPLOADED_LIST": "Toliau nurodyti failai nebuvo įkelti",
"INITIAL_LOAD_DELAY_WARNING": "Pirmasis įkėlimas gali šiek tiek užtrukti",
"USER_DOES_NOT_EXIST": "Atsiprašome, nepavyko rasti naudotojo su šiuo el. paštu.",
"initial_load_delay_warning": "Pirmasis įkėlimas gali šiek tiek užtrukti",
"no_account": "Neturiu paskyros",
"existing_account": "Jau turiu paskyrą",
"create": "Kurti",
@ -202,10 +201,11 @@
"delete_photos": "Ištrinti nuotraukas",
"keep_photos": "Laikyti nuotraukas",
"share_album": "Bendrinti albumą",
"SHARE_WITH_SELF": "Ups, negalite bendrinti su savimi.",
"ALREADY_SHARED": "Ups, jūs jau bendrinate tai su {{email}}.",
"SHARING_BAD_REQUEST_ERROR": "Neleidžiama bendrinti albumo.",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Bendrinimas išjungtas nemokamoms paskyroms.",
"sharing_with_self": "Negalite bendrinti su savimi.",
"sharing_already_shared": "Jūs jau bendrinate tai su {{email}}.",
"sharing_album_not_allowed": "Neleidžiama bendrinti albumo.",
"sharing_disabled_for_free_accounts": "Bendrinimas išjungtas nemokamoms paskyroms.",
"sharing_user_does_not_exist": "Nepavyko rasti naudotojo su šiuo el. paštu.",
"search": "Ieškoti",
"search_results": "Paieškos rezultatai",
"no_results": "Rezultatų nerasta.",
@ -362,43 +362,59 @@
"caption_character_limit": "Ne daugiau kaip 5000 simbolių",
"sharing_details": "Bendrinimo išsami informacija",
"modify_sharing": "Modifikuoti bendrinimą",
"ADD_COLLABORATORS": "Pridėti bendradarbių",
"ADD_NEW_EMAIL": "Pridėti naują el. paštą",
"add_collaborators": "Pridėti bendradarbių",
"add_new_email": "Pridėti naują el. paštą",
"shared_with_people_count_zero": "Bendrinti su konkrečiais asmenimis",
"shared_with_people_count_one": "Bendrinta su asmeniu",
"shared_with_people_count": "Bendrinta su {{count, number}} asmenimis (-ų)",
"participants_count_zero": "Nėra dalyvių",
"participants_count_one": "Dalyvis",
"participants_count": "{count, number} dalyviai (-ų)",
"ADD_VIEWERS": "Pridėti žiūrėtojus",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} negalės pridėti daugiau nuotraukų į albumą.</p><p>Jie vis tiek galės pašalinti savo pridėtas nuotraukas</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} galės pridėti nuotraukų į albumą",
"CONVERT_TO_VIEWER": "Taip, keisti į žiūrėtoją",
"CONVERT_TO_COLLABORATOR": "Taip, keisti į bendradarbį",
"CHANGE_PERMISSION": "Keisti leidimą?",
"REMOVE_PARTICIPANT": "Pašalinti?",
"CONFIRM_REMOVE": "Taip, pašalinti",
"MANAGE": "Tvarkyti",
"ADDED_AS": "Pridėta kaip",
"COLLABORATOR_RIGHTS": "Bendradarbiai gali pridėti nuotraukų ir vaizdo įrašų į bendrintą albumą",
"REMOVE_PARTICIPANT_HEAD": "Pašalinti dalyvį",
"OWNER": "Savininkas",
"COLLABORATORS": "Bendradarbiai",
"ADD_MORE": "Pridėti daugiau",
"VIEWERS": "Žiūrėtojai",
"OR_ADD_EXISTING": "Arba pasirinkite esamą",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} bus pašalintas iš albumo.</p><p>Visos jų pridėtos nuotraukos taip pat bus pašalintos iš albumo</p>",
"add_viewers": "Pridėti žiūrėtojus",
"change_permission_to_viewer": "<p>{{selectedEmail}} negalės pridėti daugiau nuotraukų į albumą.</p><p>Jie vis tiek galės pašalinti savo pridėtas nuotraukas</p>",
"change_permission_to_collaborator": "{{selectedEmail}} galės pridėti nuotraukų į albumą",
"change_permission_title": "Keisti leidimą?",
"confirm_convert_to_viewer": "Taip, keisti į žiūrėtoją",
"confirm_convert_to_collaborator": "Taip, keisti į bendradarbį",
"manage": "Tvarkyti",
"added_as": "Pridėta kaip",
"collaborator_hint": "Bendradarbiai gali pridėti nuotraukų ir vaizdo įrašų į bendrintą albumą",
"remove_participant": "Pašalinti dalyvį",
"remove_participant_title": "Pašalinti?",
"remove_participant_message": "<p>{{selectedEmail}} bus pašalintas iš albumo.</p><p>Visos jų pridėtos nuotraukos taip pat bus pašalintos iš albumo</p>",
"confirm_remove": "Taip, pašalinti",
"owner": "Savininkas",
"collaborators": "Bendradarbiai",
"viewers": "Žiūrėtojai",
"add_more": "Pridėti daugiau",
"or_add_existing": "Arba pasirinkite esamą",
"NOT_FOUND": "404 nerasta.",
"link_expired": "Nuoroda nebegalioja",
"link_expired_message": "Ši nuoroda nebegalioja arba yra išjungta.",
"MANAGE_LINK": "Tvarkyti nuorodą",
"LINK_TOO_MANY_REQUESTS": "Šis albumas buvo peržiūrėtas per daugelyje įrenginių.",
"FILE_DOWNLOAD": "Leisti atsisiuntimus",
"PUBLIC_COLLECT": "Leisti pridėti nuotraukų",
"LINK_DEVICE_LIMIT": "Įrenginių riba",
"NO_DEVICE_LIMIT": "Jokio",
"LINK_EXPIRY": "Nuorodos galiojimo laikas",
"manage_link": "Tvarkyti nuorodą",
"link_request_limit_exceeded": "Šis albumas buvo peržiūrėtas per daugelyje įrenginių.",
"allow_downloads": "Leisti atsisiuntimus",
"allow_adding_photos": "Leisti pridėti nuotraukų",
"allow_adding_photos_hint": "Leiskite nuorodą turintiems asmenims taip pat pridėti nuotraukų į bendrinamą albumą.",
"device_limit": "Įrenginių riba",
"none": "Jokio",
"link_expiry": "Nuorodos galiojimo laikas",
"never": "Niekada",
"after_time": {
"hour": "Po valandos",
"day": "Po dienos",
"week": "Po savaitės",
"month": "Po mėnesio",
"year": "Po metų"
},
"copy_link": "Kopijuoti nuorodą",
"done": "Atlikta",
"share_link_section_title": "Arba bendrinkite nuorodą",
"remove_link": "Pašalinti nuorodą",
"create_public_link": "Kurti viešą nuorodą",
"public_link_created": "Sukurta vieša nuoroda",
"public_link_enabled": "Įjungta viešoji nuoroda",
"collect_photos": "Rinkti nuotraukas",
"disable_file_download": "Išjungti atsisiuntimą",
"disable_file_download_message": "<p>Ar tikrai norite išjungti failų atsisiuntimo mygtuką?</p><p>Žiūrėtojai vis tiek gali daryti ekrano kopijas arba išsaugoti nuotraukų kopijas naudojant išorinius įrankius.</p>",
"shared_using": "Bendrinta naudojant <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Po valandos",
"day": "Po dienos",
"week": "Po savaitės",
"month": "Po mėnesio",
"year": "Po metų"
},
"copy_link": "Kopijuoti nuorodą",
"done": "Atlikta",
"LINK_SHARE_TITLE": "Arba bendrinkite nuorodą",
"REMOVE_LINK": "Pašalinti nuorodą",
"CREATE_PUBLIC_SHARING": "Kurti viešą nuorodą",
"public_link_created": "Sukurta vieša nuoroda",
"PUBLIC_LINK_ENABLED": "Įjungta viešoji nuoroda",
"COLLECT_PHOTOS": "Rinkti nuotraukas",
"PUBLIC_COLLECT_SUBTEXT": "Leiskite nuorodą turintiems asmenims taip pat pridėti nuotraukų į bendrinamą albumą.",
"STOP_EXPORT": "Stabdyti",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> sinchronizuoti elementai",
"MIGRATING_EXPORT": "Ruošiama...",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "Back-up voltooid"
},
"FILE_NOT_UPLOADED_LIST": "De volgende bestanden zijn niet geüpload",
"INITIAL_LOAD_DELAY_WARNING": "Eerste keer laden kan enige tijd duren",
"USER_DOES_NOT_EXIST": "Sorry, we konden geen account met dat e-mailadres vinden",
"initial_load_delay_warning": "Eerste keer laden kan enige tijd duren",
"no_account": "Heb nog geen account",
"existing_account": "Heb al een account",
"create": "Creëren",
@ -202,10 +201,11 @@
"delete_photos": "Foto's verwijderen",
"keep_photos": "Foto's behouden",
"share_album": "Album delen",
"SHARE_WITH_SELF": "Oeps, je kunt niet met jezelf delen",
"ALREADY_SHARED": "Oeps, je deelt dit al met {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Album delen niet toegestaan",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Delen is uitgeschakeld voor gratis accounts",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Album delen niet toegestaan",
"sharing_disabled_for_free_accounts": "Delen is uitgeschakeld voor gratis accounts",
"sharing_user_does_not_exist": "",
"search": "Zoeken",
"search_results": "Zoekresultaten",
"no_results": "Geen resultaten gevonden",
@ -362,43 +362,59 @@
"caption_character_limit": "5000 tekens max",
"sharing_details": "Delen van informatie",
"modify_sharing": "Delen wijzigen",
"ADD_COLLABORATORS": "Samenwerker toevoegen",
"ADD_NEW_EMAIL": "Nieuw e-mailadres toevoegen",
"add_collaborators": "Samenwerker toevoegen",
"add_new_email": "Nieuw e-mailadres toevoegen",
"shared_with_people_count_zero": "Delen met specifieke mensen",
"shared_with_people_count_one": "Gedeeld met 1 persoon",
"shared_with_people_count": "Gedeeld met {{count, number}} mensen",
"participants_count_zero": "Geen deelnemers",
"participants_count_one": "1 deelnemer",
"participants_count": "{{count, number}} deelnemers",
"ADD_VIEWERS": "Voeg kijkers toe",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} zullen geen foto's meer kunnen toevoegen aan dit album</p><p>Ze zullen nog steeds bestaande foto's kunnen verwijderen die door hen zijn toegevoegd</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} zal foto's aan het album kunnen toevoegen",
"CONVERT_TO_VIEWER": "Ja, converteren naar kijker",
"CONVERT_TO_COLLABORATOR": "Ja, converteren naar samenwerker",
"CHANGE_PERMISSION": "Rechten aanpassen?",
"REMOVE_PARTICIPANT": "Verwijderen?",
"CONFIRM_REMOVE": "Ja, verwijderen",
"MANAGE": "Beheren",
"ADDED_AS": "Toegevoegd als",
"COLLABORATOR_RIGHTS": "Samenwerkers kunnen foto's en video's toevoegen aan het gedeelde album",
"REMOVE_PARTICIPANT_HEAD": "Deelnemer verwijderen",
"OWNER": "Eigenaar",
"COLLABORATORS": "Samenwerker",
"ADD_MORE": "Meer toevoegen",
"VIEWERS": "Kijkers",
"OR_ADD_EXISTING": "Of kies een bestaande",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} zullen worden verwijderd uit het gedeelde album</p><p>Alle door hen toegevoegde foto's worden ook uit het album verwijderd</p>",
"add_viewers": "Voeg kijkers toe",
"change_permission_to_viewer": "<p>{{selectedEmail}} zullen geen foto's meer kunnen toevoegen aan dit album</p><p>Ze zullen nog steeds bestaande foto's kunnen verwijderen die door hen zijn toegevoegd</p>",
"change_permission_to_collaborator": "{{selectedEmail}} zal foto's aan het album kunnen toevoegen",
"change_permission_title": "Rechten aanpassen?",
"confirm_convert_to_viewer": "Ja, converteren naar kijker",
"confirm_convert_to_collaborator": "Ja, converteren naar samenwerker",
"manage": "Beheren",
"added_as": "Toegevoegd als",
"collaborator_hint": "Samenwerkers kunnen foto's en video's toevoegen aan het gedeelde album",
"remove_participant": "Deelnemer verwijderen",
"remove_participant_title": "Verwijderen?",
"remove_participant_message": "<p>{{selectedEmail}} zullen worden verwijderd uit het gedeelde album</p><p>Alle door hen toegevoegde foto's worden ook uit het album verwijderd</p>",
"confirm_remove": "Ja, verwijderen",
"owner": "Eigenaar",
"collaborators": "Samenwerker",
"viewers": "Kijkers",
"add_more": "Meer toevoegen",
"or_add_existing": "Of kies een bestaande",
"NOT_FOUND": "404 - niet gevonden",
"link_expired": "Link verlopen",
"link_expired_message": "Deze link is verlopen of gedeactiveerd",
"MANAGE_LINK": "Link beheren",
"LINK_TOO_MANY_REQUESTS": "Dit album is op te veel apparaten bekeken",
"FILE_DOWNLOAD": "Downloads toestaan",
"PUBLIC_COLLECT": "Foto's toevoegen toestaan",
"LINK_DEVICE_LIMIT": "Apparaat limiet",
"NO_DEVICE_LIMIT": "Geen",
"LINK_EXPIRY": "Vervaldatum link",
"manage_link": "Link beheren",
"link_request_limit_exceeded": "Dit album is op te veel apparaten bekeken",
"allow_downloads": "Downloads toestaan",
"allow_adding_photos": "Foto's toevoegen toestaan",
"allow_adding_photos_hint": "Sta toe dat mensen met de link ook foto's kunnen toevoegen aan het gedeelde album.",
"device_limit": "Apparaat limiet",
"none": "Geen",
"link_expiry": "Vervaldatum link",
"never": "Nooit",
"after_time": {
"hour": "Na één uur",
"day": "Na één dag",
"week": "Na één week",
"month": "Na één maand",
"year": "Na één jaar"
},
"copy_link": "Link kopiëren",
"done": "Voltooid",
"share_link_section_title": "Of deel een link",
"remove_link": "Link verwijderen",
"create_public_link": "Maak publieke link",
"public_link_created": "Publieke link aangemaakt",
"public_link_enabled": "Publieke link ingeschakeld",
"collect_photos": "Foto's verzamelen",
"disable_file_download": "Download uitschakelen",
"disable_file_download_message": "<p>Weet u zeker dat u de downloadknop voor bestanden wilt uitschakelen?</p><p>Kijkers kunnen nog steeds screenshots maken of een kopie van uw foto's opslaan met behulp van externe hulpmiddelen.</p>",
"shared_using": "Gedeeld via <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Na één uur",
"day": "Na één dag",
"week": "Na één week",
"month": "Na één maand",
"year": "Na één jaar"
},
"copy_link": "Link kopiëren",
"done": "Voltooid",
"LINK_SHARE_TITLE": "Of deel een link",
"REMOVE_LINK": "Link verwijderen",
"CREATE_PUBLIC_SHARING": "Maak publieke link",
"public_link_created": "Publieke link aangemaakt",
"PUBLIC_LINK_ENABLED": "Publieke link ingeschakeld",
"COLLECT_PHOTOS": "Foto's verzamelen",
"PUBLIC_COLLECT_SUBTEXT": "Sta toe dat mensen met de link ook foto's kunnen toevoegen aan het gedeelde album.",
"STOP_EXPORT": "Stoppen",
"EXPORT_PROGRESS": "<a>{{progress.success}} / {{progress.total}}</a> bestanden geëxporteerd",
"MIGRATING_EXPORT": "Voorbereiden...",

View File

@ -66,8 +66,7 @@
"5": "Kopia zapasowa zakończona"
},
"FILE_NOT_UPLOADED_LIST": "Następujące pliki nie zostały przesłane",
"INITIAL_LOAD_DELAY_WARNING": "Pierwsze ładowanie może zająć trochę czasu",
"USER_DOES_NOT_EXIST": "Przepraszamy, nie można znaleźć użytkownika z tym adresem e-mail",
"initial_load_delay_warning": "Pierwsze ładowanie może zająć trochę czasu",
"no_account": "Nie mam konta",
"existing_account": "Posiadam już konto",
"create": "Utwórz",
@ -202,10 +201,11 @@
"delete_photos": "Usuń zdjęcia",
"keep_photos": "Zachowaj zdjęcia",
"share_album": "Udostępnij album",
"SHARE_WITH_SELF": "Ups, nie możesz udostępnić samemu/samej sobie",
"ALREADY_SHARED": "Ups, już to udostępniasz z {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Udostępnianie albumu nie jest dozwolone",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Udostępnianie jest wyłączone dla darmowych kont",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Udostępnianie albumu nie jest dozwolone",
"sharing_disabled_for_free_accounts": "Udostępnianie jest wyłączone dla darmowych kont",
"sharing_user_does_not_exist": "",
"search": "Szukaj",
"search_results": "Wyniki wyszukiwania",
"no_results": "Nie znaleziono wyników",
@ -221,9 +221,9 @@
"terms_and_conditions": "Akceptuję <a>warunki korzystania z usługi</a> i <b>politykę prywatności</b>",
"people": "Ludzie",
"indexing_scheduled": "Indeksowanie jest zaplanowane...",
"indexing_photos": "",
"indexing_fetching": "",
"indexing_people": "",
"indexing_photos": "Aktualizowanie indeksów...",
"indexing_fetching": "Synchronizowanie indeksów...",
"indexing_people": "Synchronizowanie osób...",
"syncing_wait": "Synchronizowanie...",
"people_empty_too_few": "Ludzie będą tutaj wyświetlani, gdy będzie wystarczająca ilość zdjęć danej osoby",
"unnamed_person": "Osoba bez nazwy",
@ -362,43 +362,59 @@
"caption_character_limit": "Maksymalnie 5000 znaków",
"sharing_details": "Udostępnianie szczegółów",
"modify_sharing": "Modyfikuj udostępnianie",
"ADD_COLLABORATORS": "Dodaj współuczestników",
"ADD_NEW_EMAIL": "Dodaj nowy adres e-mail",
"add_collaborators": "Dodaj współuczestników",
"add_new_email": "Dodaj nowy adres e-mail",
"shared_with_people_count_zero": "Podziel się z określonymi osobami",
"shared_with_people_count_one": "Udostępnione z jedną osobą",
"shared_with_people_count": "Udostępnione z {{count, number}} osobami",
"participants_count_zero": "Brak uczestników",
"participants_count_one": "1 uczestnik",
"participants_count": "{{count, number}} uczestników",
"ADD_VIEWERS": "Dodaj widzów",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} nie będzie mógł dodać więcej zdjęć do tego albumu.</p><p>Nadal będą mogli usuwać istniejące zdjęcia, które dodali</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} będzie mógł dodawać zdjęcia do albumu",
"CONVERT_TO_VIEWER": "Tak, konwertuj na widza",
"CONVERT_TO_COLLABORATOR": "Tak, konwertuj na współuczestnika",
"CHANGE_PERMISSION": "Zmienić uprawnienie?",
"REMOVE_PARTICIPANT": "Usunąć?",
"CONFIRM_REMOVE": "Tak, usuń",
"MANAGE": "Zarządzaj",
"ADDED_AS": "Dodano jako",
"COLLABORATOR_RIGHTS": "Współuczestnicy mogą dodawać zdjęcia i wideo do udostępnionego albumu",
"REMOVE_PARTICIPANT_HEAD": "Usuń uczestnika",
"OWNER": "Właściciel",
"COLLABORATORS": "Współuczestnicy",
"ADD_MORE": "Dodaj więcej",
"VIEWERS": "Widzowie",
"OR_ADD_EXISTING": "Lub wybierz istniejący",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} zostanie usunięty z albumu</p><p>Wszelkie dodane przez nich zdjęcia zostaną usunięte z albumu</p>",
"add_viewers": "Dodaj widzów",
"change_permission_to_viewer": "<p>{{selectedEmail}} nie będzie mógł dodać więcej zdjęć do tego albumu.</p><p>Nadal będą mogli usuwać istniejące zdjęcia, które dodali</p>",
"change_permission_to_collaborator": "{{selectedEmail}} będzie mógł dodawać zdjęcia do albumu",
"change_permission_title": "Zmienić uprawnienie?",
"confirm_convert_to_viewer": "Tak, konwertuj na widza",
"confirm_convert_to_collaborator": "Tak, konwertuj na współuczestnika",
"manage": "Zarządzaj",
"added_as": "Dodano jako",
"collaborator_hint": "Współuczestnicy mogą dodawać zdjęcia i wideo do udostępnionego albumu",
"remove_participant": "Usuń uczestnika",
"remove_participant_title": "Usunąć?",
"remove_participant_message": "<p>{{selectedEmail}} zostanie usunięty z albumu</p><p>Wszelkie dodane przez nich zdjęcia zostaną usunięte z albumu</p>",
"confirm_remove": "Tak, usuń",
"owner": "Właściciel",
"collaborators": "Współuczestnicy",
"viewers": "Widzowie",
"add_more": "Dodaj więcej",
"or_add_existing": "Lub wybierz istniejący",
"NOT_FOUND": "404 - nie znaleziono",
"link_expired": "Link wygasł",
"link_expired_message": "Ten link wygasł lub został wyłączony",
"MANAGE_LINK": "Zarządzaj linkiem",
"LINK_TOO_MANY_REQUESTS": "Ten album został wyświetlony na zbyt wielu urządzeniach",
"FILE_DOWNLOAD": "Zezwól na pobieranie",
"PUBLIC_COLLECT": "Pozwól na dodawanie zdjęć",
"LINK_DEVICE_LIMIT": "Limit urządzeń",
"NO_DEVICE_LIMIT": "Brak",
"LINK_EXPIRY": "Wygaśnięcie linku",
"manage_link": "Zarządzaj linkiem",
"link_request_limit_exceeded": "Ten album został wyświetlony na zbyt wielu urządzeniach",
"allow_downloads": "Zezwól na pobieranie",
"allow_adding_photos": "Pozwól na dodawanie zdjęć",
"allow_adding_photos_hint": "Pozwól osobom z linkiem na dodawanie zdjęć do udostępnionego albumu.",
"device_limit": "Limit urządzeń",
"none": "Brak",
"link_expiry": "Wygaśnięcie linku",
"never": "Nigdy",
"after_time": {
"hour": "Po godzinie",
"day": "Po 1 dniu",
"week": "Po 1 tygodniu",
"month": "Po 1 miesiącu",
"year": "Po 1 roku"
},
"copy_link": "Skopiuj link",
"done": "Gotowe",
"share_link_section_title": "Lub udostępnij link",
"remove_link": "Usuń link",
"create_public_link": "Utwórz publiczny link",
"public_link_created": "Publiczny link utworzony",
"public_link_enabled": "Publiczny link włączony",
"collect_photos": "Zbierz zdjęcia",
"disable_file_download": "Wyłącz pobieranie",
"disable_file_download_message": "<p>Czy na pewno chcesz wyłączyć przycisk pobierania plików?</p><p>Widzowie nadal mogą robić zrzuty ekranu lub zapisać kopię zdjęć za pomocą narzędzi zewnętrznych.</p>",
"shared_using": "Udostępnione za pomocą <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Po godzinie",
"day": "Po 1 dniu",
"week": "Po 1 tygodniu",
"month": "Po 1 miesiącu",
"year": "Po 1 roku"
},
"copy_link": "Skopiuj link",
"done": "Gotowe",
"LINK_SHARE_TITLE": "Lub udostępnij link",
"REMOVE_LINK": "Usuń link",
"CREATE_PUBLIC_SHARING": "Utwórz publiczny link",
"public_link_created": "Publiczny link utworzony",
"PUBLIC_LINK_ENABLED": "Publiczny link włączony",
"COLLECT_PHOTOS": "Zbierz zdjęcia",
"PUBLIC_COLLECT_SUBTEXT": "Pozwól osobom z linkiem na dodawanie zdjęć do udostępnionego albumu.",
"STOP_EXPORT": "Zatrzymaj",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> elementy zsynchronizowane",
"MIGRATING_EXPORT": "Przygotowywanie...",

View File

@ -66,8 +66,7 @@
"5": "Cópia de segurança concluído"
},
"FILE_NOT_UPLOADED_LIST": "Os seguintes arquivos não foram enviados",
"INITIAL_LOAD_DELAY_WARNING": "O primeiro carregamento pode levar algum tempo",
"USER_DOES_NOT_EXIST": "Não foi possível encontrar usuários com este e-mail",
"initial_load_delay_warning": "Ao carregar pela primeira vez talvez possa levar algum tempo",
"no_account": "Não possui uma conta",
"existing_account": "Já possui uma conta",
"create": "Criar",
@ -202,10 +201,11 @@
"delete_photos": "Excluir fotos",
"keep_photos": "Manter fotos",
"share_album": "Compartilhar álbum",
"SHARE_WITH_SELF": "Opa! Você não pode compartilhar consigo mesmo",
"ALREADY_SHARED": "Opa! Você já está compartilhando isso com {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Não permitido compartilhar álbum",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "A compartilhação está desativada para contas grátis",
"sharing_with_self": "Não é possível compartilhar consigo mesmo",
"sharing_already_shared": "Você já está compartilhando isso com {{email}}",
"sharing_album_not_allowed": "Não permitido compartilhar álbum",
"sharing_disabled_for_free_accounts": "O compartilhamento está desativado para contas grátis",
"sharing_user_does_not_exist": "Não foi possível encontrar um usuário com aquele e-mail",
"search": "Buscar",
"search_results": "Resultados da busca",
"no_results": "Nenhum resultado encontrado",
@ -326,7 +326,7 @@
"unarchive": "Desarquivar",
"unarchive_album": "Desarquivar álbum",
"hide_collection": "Ocultar álbum",
"unhide_collection": "Reexibir álbum",
"unhide_collection": "Desocultar álbum",
"move": "Mover",
"add": "Adicionar",
"remove": "Remover",
@ -337,13 +337,13 @@
"trash_file_message": "O arquivo será removido de todos os álbuns e movido à lixeira.",
"delete_permanently": "Excluir permanentemente",
"restore": "Restaurar",
"empty_trash": "Esvaziar a lixeira",
"empty_trash_title": "Esvaziar a lixeira?",
"empty_trash_message": "Estes arquivos serão excluídos permanentemente da sua conta do ente.",
"leave_album": "Sair do álbum",
"leave_shared_album_title": "Sair do álbum compartilhado?",
"leave_shared_album_message": "Você deixará o álbum e ele deixará de ser visível para você.",
"leave_shared_album": "Sim, sair",
"empty_trash": "Esvaziar lixeira",
"empty_trash_title": "Esvaziar lixeira?",
"empty_trash_message": "Os arquivos selecionados serão excluídos permanentemente da sua conta Ente.",
"leave_album": "Deixar álbum",
"leave_shared_album_title": "Deixar álbum compartilhado?",
"leave_shared_album_message": "Ao deixar o álbum, ele parará de ser visível para você",
"leave_shared_album": "Sim, deixar",
"confirm_remove_message": "Os itens selecionados serão removidos deste álbum. Os itens em que estão apenas neste álbum serão movidos para \"Não categorizados\".",
"confirm_remove_incl_others_message": "Alguns dos itens que você está removendo foram adicionados por outras pessoas, e você perderá acesso a eles.",
"oldest": "Mais antigo",
@ -362,43 +362,59 @@
"caption_character_limit": "Máximo de 5.000 caracteres",
"sharing_details": "Detalhes de compartilhamento",
"modify_sharing": "Modificar compartilhamento",
"ADD_COLLABORATORS": "Adicionar colaboradores",
"ADD_NEW_EMAIL": "Adicionar um novo email",
"add_collaborators": "Adicionar colaboradores",
"add_new_email": "Adicionar um novo e-mail",
"shared_with_people_count_zero": "Compartilhar com pessoas específicas",
"shared_with_people_count_one": "Compartilhado com 1 pessoa",
"shared_with_people_count": "Compartilhado com {{count, number}} pessoas",
"participants_count_zero": "Nenhum participante",
"participants_count_one": "1 participante",
"participants_count": "{{count, number}} participantes",
"ADD_VIEWERS": "Adicionar visualizações",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} Não poderá adicionar mais fotos a este álbum<p><p>Eles ainda poderão remover as fotos existentes adicionadas por eles<p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} poderá adicionar fotos ao álbum",
"CONVERT_TO_VIEWER": "Sim, converter para visualizador",
"CONVERT_TO_COLLABORATOR": "Sim, converter para colaborador",
"CHANGE_PERMISSION": "Alterar permissões?",
"REMOVE_PARTICIPANT": "Remover?",
"CONFIRM_REMOVE": "Sim, remover",
"MANAGE": "Gerenciar",
"ADDED_AS": "Adicionado como",
"COLLABORATOR_RIGHTS": "Os colaboradores podem adicionar fotos e vídeos ao álbum compartilhado",
"REMOVE_PARTICIPANT_HEAD": "Remover participante",
"OWNER": "Proprietário",
"COLLABORATORS": "Colaboradores",
"ADD_MORE": "Adicionar mais",
"VIEWERS": "Visualizações",
"OR_ADD_EXISTING": "Ou escolha um existente",
"REMOVE_PARTICIPANT_MESSAGE": "</p>{{selectedEmail}} será removido deste álbum compartilhado</p><p>Quaisquer fotos adicionadas por eles também serão removidas do álbum</p>",
"add_viewers": "Adicionar visualizadores",
"change_permission_to_viewer": "<p>{{selectedEmail}} não poderá adicionar mais fotos a este álbum<p><p>Eles ainda poderão remover as fotos existentes adicionadas por eles<p>",
"change_permission_to_collaborator": "{{selectedEmail}} poderá adicionar fotos ao álbum",
"change_permission_title": "Alterar permissões?",
"confirm_convert_to_viewer": "Sim, converter para visualizador",
"confirm_convert_to_collaborator": "Sim, converter para colaborador",
"manage": "Gerenciar",
"added_as": "Adicionado como",
"collaborator_hint": "Os colaboradores podem adicionar fotos e vídeos ao álbum compartilhado",
"remove_participant": "Remover participante",
"remove_participant_title": "Remover?",
"remove_participant_message": "</p>{{selectedEmail}} será removido deste álbum compartilhado</p><p>Quaisquer fotos adicionadas por eles também serão removidas do álbum</p>",
"confirm_remove": "Sim, remover",
"owner": "proprietário",
"collaborators": "Colaboradores",
"viewers": "Visualizadores",
"add_more": "Adicionar mais",
"or_add_existing": "Ou escolher existente",
"NOT_FOUND": "404 Página não encontrada",
"link_expired": "Link expirado",
"link_expired_message": "Este link expirou-se ou foi desativado",
"MANAGE_LINK": "Gerenciar link",
"LINK_TOO_MANY_REQUESTS": "Este álbum foi visualizado em muitos dispositivos",
"FILE_DOWNLOAD": "Permitir downloads",
"PUBLIC_COLLECT": "Permitir adicionar fotos",
"LINK_DEVICE_LIMIT": "Limite de dispositivos",
"NO_DEVICE_LIMIT": "Nenhum",
"LINK_EXPIRY": "Expiração do link",
"manage_link": "Gerenciar link",
"link_request_limit_exceeded": "Este álbum foi visualizado em muitos dispositivos",
"allow_downloads": "Permitir baixar",
"allow_adding_photos": "Permitir adicionar fotos",
"allow_adding_photos_hint": "Permita que as pessoas com o link também adicionem fotos ao álbum compartilhado.",
"device_limit": "Limite de dispositivos",
"none": "Nenhum",
"link_expiry": "Expiração do link",
"never": "Nunca",
"after_time": {
"hour": "Após uma hora",
"day": "Após um dia",
"week": "Após uma semana",
"month": "Após um mês",
"year": "Após um ano"
},
"copy_link": "Copiar link",
"done": "Concluído",
"share_link_section_title": "Ou compartilhar link",
"remove_link": "Remover link",
"create_public_link": "Criar link público",
"public_link_created": "Link público criado",
"public_link_enabled": "Link público ativado",
"collect_photos": "Coletar fotos",
"disable_file_download": "Desativar transferência",
"disable_file_download_message": "<p>Você tem certeza que quer desativar o botão de transferência para os arquivos?</p><p>Os visualizadores podem tirar capturas de tela ou salvar uma cópia da sua foto usando ferramentas externas.</p>",
"shared_using": "Compartilhado usando <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Após uma hora",
"day": "Após um dia",
"week": "Após uma semana",
"month": "Após um mês",
"year": "Após um ano"
},
"copy_link": "Copiar link",
"done": "Concluído",
"LINK_SHARE_TITLE": "Ou compartilhe um link",
"REMOVE_LINK": "Remover link",
"CREATE_PUBLIC_SHARING": "Criar link público",
"public_link_created": "Link público criado",
"PUBLIC_LINK_ENABLED": "Link público ativado",
"COLLECT_PHOTOS": "Coletar fotos",
"PUBLIC_COLLECT_SUBTEXT": "Permita que as pessoas com o link também adicionem fotos ao álbum compartilhado.",
"STOP_EXPORT": "Parar",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> itens sincronizados",
"MIGRATING_EXPORT": "Preparando...",

View File

@ -66,8 +66,7 @@
"5": "Backup concluído"
},
"FILE_NOT_UPLOADED_LIST": "Os seguintes arquivos não foram enviados",
"INITIAL_LOAD_DELAY_WARNING": "O primeiro carregamento pode demorar algum tempo",
"USER_DOES_NOT_EXIST": "Desculpe, não foi possível encontrar um utilizador com esse e-mail",
"initial_load_delay_warning": "O primeiro carregamento pode demorar algum tempo",
"no_account": "Não possui uma conta",
"existing_account": "Já possui uma conta",
"create": "Criar",
@ -202,10 +201,11 @@
"delete_photos": "Apagar fotos",
"keep_photos": "Manter fotos",
"share_album": "Partilhar Álbum",
"SHARE_WITH_SELF": "Não podes partilhar contigo mesmo",
"ALREADY_SHARED": "Já está a partilhar isto com o {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Álbum compartilhado não permitido",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "A partilha está desactivada para contas gratuitas",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Álbum compartilhado não permitido",
"sharing_disabled_for_free_accounts": "A partilha está desactivada para contas gratuitas",
"sharing_user_does_not_exist": "",
"search": "Pesquisar",
"search_results": "Resultados de pesquisa",
"no_results": "Nenhum resultado encontrado",
@ -362,43 +362,59 @@
"caption_character_limit": "5000 caracteres no máximo",
"sharing_details": "Detalhes de compartilhamento",
"modify_sharing": "Modificar compartilhamento",
"ADD_COLLABORATORS": "Adicionar colaboradores",
"ADD_NEW_EMAIL": "Adicionar um novo email",
"add_collaborators": "Adicionar colaboradores",
"add_new_email": "Adicionar um novo email",
"shared_with_people_count_zero": "Partilhar com pessoas específicas",
"shared_with_people_count_one": "Partilhado com 1 pessoa",
"shared_with_people_count": "Partilhado com {{count, number}} pessoas",
"participants_count_zero": "Nenhum participante",
"participants_count_one": "1 participante",
"participants_count": "{{count, number}} participantes",
"ADD_VIEWERS": "Adicionar visualizações",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} não poderá adicionar mais fotografias ao álbum</p><p>Ainda poderão remover fotografias adicionadas por eles</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} poderá adicionar fotografias ao álbum",
"CONVERT_TO_VIEWER": "Sim, converter para visualizador",
"CONVERT_TO_COLLABORATOR": "Sim, converter para colaborador",
"CHANGE_PERMISSION": "Alterar permissões?",
"REMOVE_PARTICIPANT": "Remover?",
"CONFIRM_REMOVE": "Sim, remover",
"MANAGE": "Gerenciar",
"ADDED_AS": "Adicionado como",
"COLLABORATOR_RIGHTS": "Os colaboradores podem adicionar fotografias e vídeos ao álbum partilhado",
"REMOVE_PARTICIPANT_HEAD": "Remover participante",
"OWNER": "Proprietário",
"COLLABORATORS": "Colaboradores",
"ADD_MORE": "Adicionar mais",
"VIEWERS": "Visualizadores",
"OR_ADD_EXISTING": "Ou escolher um já existente",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} será removido do álbum</p><p>Quaisquer fotografias adicionadas por ele também serão removidas do álbum</p>",
"add_viewers": "Adicionar visualizações",
"change_permission_to_viewer": "<p>{{selectedEmail}} não poderá adicionar mais fotografias ao álbum</p><p>Ainda poderão remover fotografias adicionadas por eles</p>",
"change_permission_to_collaborator": "{{selectedEmail}} poderá adicionar fotografias ao álbum",
"change_permission_title": "Alterar permissões?",
"confirm_convert_to_viewer": "Sim, converter para visualizador",
"confirm_convert_to_collaborator": "Sim, converter para colaborador",
"manage": "Gerenciar",
"added_as": "Adicionado como",
"collaborator_hint": "Os colaboradores podem adicionar fotografias e vídeos ao álbum partilhado",
"remove_participant": "Remover participante",
"remove_participant_title": "Remover?",
"remove_participant_message": "<p>{{selectedEmail}} será removido do álbum</p><p>Quaisquer fotografias adicionadas por ele também serão removidas do álbum</p>",
"confirm_remove": "Sim, remover",
"owner": "Proprietário",
"collaborators": "Colaboradores",
"viewers": "Visualizadores",
"add_more": "Adicionar mais",
"or_add_existing": "Ou escolher um já existente",
"NOT_FOUND": "404 Página não encontrada",
"link_expired": "Link expirado",
"link_expired_message": "Este link expirou ou foi desativado",
"MANAGE_LINK": "Gerir link",
"LINK_TOO_MANY_REQUESTS": "Este álbum foi visualizado em muitos dispositivos",
"FILE_DOWNLOAD": "Permitir downloads",
"PUBLIC_COLLECT": "Permitir adicionar fotos",
"LINK_DEVICE_LIMIT": "Limite de dispositivos",
"NO_DEVICE_LIMIT": "Nenhum",
"LINK_EXPIRY": "Link expirado",
"manage_link": "Gerir link",
"link_request_limit_exceeded": "Este álbum foi visualizado em muitos dispositivos",
"allow_downloads": "Permitir downloads",
"allow_adding_photos": "Permitir adicionar fotos",
"allow_adding_photos_hint": "Permitir que as pessoas com a ligação também adicionem fotos ao álbum partilhado.",
"device_limit": "Limite de dispositivos",
"none": "Nenhum",
"link_expiry": "Link expirado",
"never": "Nunca",
"after_time": {
"hour": "Após uma hora",
"day": "Após um dia",
"week": "Após uma semana",
"month": "Após um mês",
"year": "Após um ano"
},
"copy_link": "Copiar link",
"done": "Concluído",
"share_link_section_title": "Ou partilhar uma link",
"remove_link": "Remover link",
"create_public_link": "Criar link público",
"public_link_created": "Link público criado",
"public_link_enabled": "Link público ativado",
"collect_photos": "Recolher fotos",
"disable_file_download": "Desativar download",
"disable_file_download_message": "<p>Tem a certeza de que pretende desativar o botão de transferência de ficheiros? </p><p>Os espectadores podem ainda tirar capturas de ecrã ou guardar uma cópia das suas fotografias utilizando ferramentas externas.</p>",
"shared_using": "Partilhado utilizando <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Após uma hora",
"day": "Após um dia",
"week": "Após uma semana",
"month": "Após um mês",
"year": "Após um ano"
},
"copy_link": "Copiar link",
"done": "Concluído",
"LINK_SHARE_TITLE": "Ou partilhar uma link",
"REMOVE_LINK": "Remover link",
"CREATE_PUBLIC_SHARING": "Criar link público",
"public_link_created": "Link público criado",
"PUBLIC_LINK_ENABLED": "Link público ativado",
"COLLECT_PHOTOS": "Recolher fotos",
"PUBLIC_COLLECT_SUBTEXT": "Permitir que as pessoas com a ligação também adicionem fotos ao álbum partilhado.",
"STOP_EXPORT": "Parar",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> itens sincronizados",
"MIGRATING_EXPORT": "Preparar...",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "Резервное копирование завершено"
},
"FILE_NOT_UPLOADED_LIST": "Следующие файлы не были загружены",
"INITIAL_LOAD_DELAY_WARNING": "Первая загрузка может занять некоторое время",
"USER_DOES_NOT_EXIST": "Пользователь с таким email не найден",
"initial_load_delay_warning": "Первая загрузка может занять некоторое время",
"no_account": "У меня нет учетной записи",
"existing_account": "Уже есть аккаунт",
"create": "Создать",
@ -202,10 +201,11 @@
"delete_photos": "Удалить фото",
"keep_photos": "Оставить фото",
"share_album": "Поделиться альбомом",
"SHARE_WITH_SELF": "Ой, Вы не можете поделиться с самим собой",
"ALREADY_SHARED": "Упс, Вы уже делились этим с {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Делиться альбомом запрещено",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Совместное использование отключено для бесплатных аккаунтов",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Делиться альбомом запрещено",
"sharing_disabled_for_free_accounts": "Совместное использование отключено для бесплатных аккаунтов",
"sharing_user_does_not_exist": "",
"search": "Поиск",
"search_results": "Результаты поиска",
"no_results": "Ничего не найдено",
@ -362,43 +362,59 @@
"caption_character_limit": "не более 5000 символов",
"sharing_details": "Обмен подробностями",
"modify_sharing": "Изменить общий доступ",
"ADD_COLLABORATORS": "Добавление соавторов",
"ADD_NEW_EMAIL": "Добавить новый email адрес",
"add_collaborators": "Добавление соавторов",
"add_new_email": "Добавить новый email адрес",
"shared_with_people_count_zero": "Делитесь с конкретными людьми",
"shared_with_people_count_one": "Совместно с 1 человеком",
"shared_with_people_count": "Поделился с {{count, number}} люди",
"participants_count_zero": "Нет участников",
"participants_count_one": "1 участник",
"participants_count": "{{count, number}} участники",
"ADD_VIEWERS": "Добавить зрителей",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} они не смогут добавить больше фотографий в альбом</p><p>Они по-прежнему смогут удалять добавленные ими фотографии</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} сможете добавлять фотографии в альбом",
"CONVERT_TO_VIEWER": "Да, преобразовать в программу просмотра",
"CONVERT_TO_COLLABORATOR": "Да, преобразовать в соавтора",
"CHANGE_PERMISSION": "Изменить разрешение?",
"REMOVE_PARTICIPANT": "Удалить?",
"CONFIRM_REMOVE": "Да, удалить",
"MANAGE": "Управлять",
"ADDED_AS": "Добавлено как",
"COLLABORATOR_RIGHTS": "Участники совместной работы могут добавлять фотографии и видео в общий альбом",
"REMOVE_PARTICIPANT_HEAD": "Удалить участника",
"OWNER": "Владелец",
"COLLABORATORS": "Коллаборационисты",
"ADD_MORE": "Добавить еще",
"VIEWERS": "Зрителей",
"OR_ADD_EXISTING": "Или выберите уже существующий вариант",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} будут удалены из альбома</p><p>Все добавленные ими фотографии также будут удалены из альбома</p>",
"add_viewers": "Добавить зрителей",
"change_permission_to_viewer": "<p>{{selectedEmail}} они не смогут добавить больше фотографий в альбом</p><p>Они по-прежнему смогут удалять добавленные ими фотографии</p>",
"change_permission_to_collaborator": "{{selectedEmail}} сможете добавлять фотографии в альбом",
"change_permission_title": "Изменить разрешение?",
"confirm_convert_to_viewer": "Да, преобразовать в программу просмотра",
"confirm_convert_to_collaborator": "Да, преобразовать в соавтора",
"manage": "Управлять",
"added_as": "Добавлено как",
"collaborator_hint": "Участники совместной работы могут добавлять фотографии и видео в общий альбом",
"remove_participant": "Удалить участника",
"remove_participant_title": "Удалить?",
"remove_participant_message": "<p>{{selectedEmail}} будут удалены из альбома</p><p>Все добавленные ими фотографии также будут удалены из альбома</p>",
"confirm_remove": "Да, удалить",
"owner": "Владелец",
"collaborators": "Коллаборационисты",
"viewers": "Зрителей",
"add_more": "Добавить еще",
"or_add_existing": "Или выберите уже существующий вариант",
"NOT_FOUND": "404 - не найден",
"link_expired": "Срок действия ссылки истек",
"link_expired_message": "Срок действия этой ссылки либо истек, либо она была отключена",
"MANAGE_LINK": "Управление ссылкой",
"LINK_TOO_MANY_REQUESTS": "Извините, этот альбом был просмотрен на слишком большом количестве устройств",
"FILE_DOWNLOAD": "Разрешить загрузку",
"PUBLIC_COLLECT": "Разрешить добавление фотографий",
"LINK_DEVICE_LIMIT": "Предел устройства",
"NO_DEVICE_LIMIT": "Никто",
"LINK_EXPIRY": "Истечение срока действия ссылки",
"manage_link": "Управление ссылкой",
"link_request_limit_exceeded": "Извините, этот альбом был просмотрен на слишком большом количестве устройств",
"allow_downloads": "Разрешить загрузку",
"allow_adding_photos": "Разрешить добавление фотографий",
"allow_adding_photos_hint": "Разрешите пользователям, у которых есть ссылка, также добавлять фотографии в общий альбом.",
"device_limit": "Предел устройства",
"none": "Никто",
"link_expiry": "Истечение срока действия ссылки",
"never": "Никогда",
"after_time": {
"hour": "Через час",
"day": "Через день",
"week": "Через неделю",
"month": "Через месяц",
"year": "Через год"
},
"copy_link": "Скопировать ссылку",
"done": "Сделано",
"share_link_section_title": "Или поделитесь ссылкой",
"remove_link": "Удалить ссылку",
"create_public_link": "Создать общедоступную ссылку",
"public_link_created": "Создана общедоступная ссылка",
"public_link_enabled": "Включена общедоступная ссылка",
"collect_photos": "Собирайте фотографии",
"disable_file_download": "Отключить загрузку",
"disable_file_download_message": "<p>Вы уверены, что хотите отключить кнопку загрузки файлов?</p><p>Зрители по-прежнему могут делать скриншоты или сохранять копии ваших фотографий с помощью внешних инструментов.</p>",
"shared_using": "Совместное использование <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "Гб",
"tb": "Терабайт"
},
"after_time": {
"hour": "Через час",
"day": "Через день",
"week": "Через неделю",
"month": "Через месяц",
"year": "Через год"
},
"copy_link": "Скопировать ссылку",
"done": "Сделано",
"LINK_SHARE_TITLE": "Или поделитесь ссылкой",
"REMOVE_LINK": "Удалить ссылку",
"CREATE_PUBLIC_SHARING": "Создать общедоступную ссылку",
"public_link_created": "Создана общедоступная ссылка",
"PUBLIC_LINK_ENABLED": "Включена общедоступная ссылка",
"COLLECT_PHOTOS": "Собирайте фотографии",
"PUBLIC_COLLECT_SUBTEXT": "Разрешите пользователям, у которых есть ссылка, также добавлять фотографии в общий альбом.",
"STOP_EXPORT": "Остановка",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> синхронизированные элементы",
"MIGRATING_EXPORT": "Подготовка...",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "Säkerhetskopiering slutförd"
},
"FILE_NOT_UPLOADED_LIST": "Följande filer laddades ej upp",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "Tyvärr, kunde inte hitta en användare med den e-postadressen",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "Skapa",
@ -202,10 +201,11 @@
"delete_photos": "Radera foton",
"keep_photos": "Behåll foton",
"share_album": "Dela album",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "Sök",
"search_results": "Sökresultat",
"no_results": "Inga resultat hittades",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "Delas med 1 person",
"shared_with_people_count": "",
"participants_count_zero": "Inga deltagare",
"participants_count_one": "1 deltagare",
"participants_count": "{{count, number}} deltagare",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "Hantera",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "Hantera",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "Hantera länk",
"LINK_TOO_MANY_REQUESTS": "Detta album har visats på för många enheter",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "Enhetsgräns",
"NO_DEVICE_LIMIT": "Ingen",
"LINK_EXPIRY": "",
"manage_link": "Hantera länk",
"link_request_limit_exceeded": "Detta album har visats på för många enheter",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "Enhetsgräns",
"none": "Ingen",
"link_expiry": "",
"never": "Aldrig",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "Kopiera länk",
"done": "Klar",
"share_link_section_title": "Eller dela en länk",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "Inaktivera nedladdning",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "Kopiera länk",
"done": "Klar",
"LINK_SHARE_TITLE": "Eller dela en länk",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "Fotoğrafları sil",
"keep_photos": "Fotoğrafları sakla",
"share_album": "Albümü paylaş",
"SHARE_WITH_SELF": "Oops, bunu kendinle paylaşamazsın",
"ALREADY_SHARED": "Oops, bunu zaten {{email}} ile paylaşıyorsun",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -66,8 +66,7 @@
"5": "Резервне копіювання завершено"
},
"FILE_NOT_UPLOADED_LIST": "Наступні файли не були вивантаженні",
"INITIAL_LOAD_DELAY_WARNING": "Перше завантаження може зайняти деякий час",
"USER_DOES_NOT_EXIST": "Не вдалося знайти користувача з такою поштовою адресою",
"initial_load_delay_warning": "Перше завантаження може зайняти деякий час",
"no_account": "Не маєте облікового запису",
"existing_account": "Уже маєте обліковий запис",
"create": "Створити",
@ -202,10 +201,11 @@
"delete_photos": "Видалити фото",
"keep_photos": "Залишити фото",
"share_album": "Поділитися альбомом",
"SHARE_WITH_SELF": "Упс, ви не можете поділитися із собою",
"ALREADY_SHARED": "Упс, ви вже ділитеся цим з {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Заборонено ділитися альбомом",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Спільний доступ вимкнено для безплатних облікових записів",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Заборонено ділитися альбомом",
"sharing_disabled_for_free_accounts": "Спільний доступ вимкнено для безплатних облікових записів",
"sharing_user_does_not_exist": "",
"search": "Пошук",
"search_results": "Результати пошуку",
"no_results": "Нічого не знайдено",
@ -362,43 +362,59 @@
"caption_character_limit": "Не більше 5000 символів",
"sharing_details": "Подробиці про спільний доступ",
"modify_sharing": "Змінити спільний доступ",
"ADD_COLLABORATORS": "Додати співавторів",
"ADD_NEW_EMAIL": "Додати нову пошту",
"add_collaborators": "Додати співавторів",
"add_new_email": "Додати нову пошту",
"shared_with_people_count_zero": "Поділитися з конкретними людьми",
"shared_with_people_count_one": "Спільний доступ з 1 особою",
"shared_with_people_count": "Спільний доступ з {{count, number}} людьми",
"participants_count_zero": "Немає учасників",
"participants_count_one": "1 учасник",
"participants_count": "{{count, number}} учасників",
"ADD_VIEWERS": "Додати глядачів",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} не зможуть додати більше фотографій до альбому</p><p>Вони все ще зможуть видаляти додані ними фотографії</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} зможуть додавати фотографії до альбому",
"CONVERT_TO_VIEWER": "Так, перетворити в глядача",
"CONVERT_TO_COLLABORATOR": "Так, перетворити в співавтора",
"CHANGE_PERMISSION": "Змінити дозвіл?",
"REMOVE_PARTICIPANT": "Видалити?",
"CONFIRM_REMOVE": "Так, видалити",
"MANAGE": "Керування",
"ADDED_AS": "Додано як",
"COLLABORATOR_RIGHTS": "Співавтори можуть додавати фотографії та відео до спільного альбому",
"REMOVE_PARTICIPANT_HEAD": "Видалити учасника",
"OWNER": "Власник",
"COLLABORATORS": "Співавтори",
"ADD_MORE": "Додати більше",
"VIEWERS": "Глядачі",
"OR_ADD_EXISTING": "Або виберіть наявний",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} було видалено з альбому</p><p>Будь-які фото, додані ними, будуть також видалені з альбому</p>",
"add_viewers": "Додати глядачів",
"change_permission_to_viewer": "<p>{{selectedEmail}} не зможуть додати більше фотографій до альбому</p><p>Вони все ще зможуть видаляти додані ними фотографії</p>",
"change_permission_to_collaborator": "{{selectedEmail}} зможуть додавати фотографії до альбому",
"change_permission_title": "Змінити дозвіл?",
"confirm_convert_to_viewer": "Так, перетворити в глядача",
"confirm_convert_to_collaborator": "Так, перетворити в співавтора",
"manage": "Керування",
"added_as": "Додано як",
"collaborator_hint": "Співавтори можуть додавати фотографії та відео до спільного альбому",
"remove_participant": "Видалити учасника",
"remove_participant_title": "Видалити?",
"remove_participant_message": "<p>{{selectedEmail}} було видалено з альбому</p><p>Будь-які фото, додані ними, будуть також видалені з альбому</p>",
"confirm_remove": "Так, видалити",
"owner": "Власник",
"collaborators": "Співавтори",
"viewers": "Глядачі",
"add_more": "Додати більше",
"or_add_existing": "Або виберіть наявний",
"NOT_FOUND": "404: не знайдено",
"link_expired": "Термін дії посилання закінчився",
"link_expired_message": "Термін дії цього посилання закінчився або його було вимкнено",
"MANAGE_LINK": "Керувати посиланням",
"LINK_TOO_MANY_REQUESTS": "Цей альбом було переглянуто на занадто багатьох пристроях",
"FILE_DOWNLOAD": "Дозволити завантаження",
"PUBLIC_COLLECT": "Дозволити додавати фотографії",
"LINK_DEVICE_LIMIT": "Досягнуто ліміту пристрою",
"NO_DEVICE_LIMIT": "Немає",
"LINK_EXPIRY": "Термін дії посилання закінчився",
"manage_link": "Керувати посиланням",
"link_request_limit_exceeded": "Цей альбом було переглянуто на занадто багатьох пристроях",
"allow_downloads": "Дозволити завантаження",
"allow_adding_photos": "Дозволити додавати фотографії",
"allow_adding_photos_hint": "Дозволити людям з посиланням також додавати фотографії до спільного альбому.",
"device_limit": "Досягнуто ліміту пристрою",
"none": "Немає",
"link_expiry": "Термін дії посилання закінчився",
"never": "Ніколи",
"after_time": {
"hour": "Через 1 годину",
"day": "Через 1 день",
"week": "Через 1 тиждень",
"month": "Через 1 місяць",
"year": "Через 1 рік"
},
"copy_link": "Копіювати посилання",
"done": "Виконано",
"share_link_section_title": "Або поділіться посиланням",
"remove_link": "Вилучити посилання",
"create_public_link": "Створити публічне посилання",
"public_link_created": "Публічне посилання створено",
"public_link_enabled": "Публічне посилання увімкнено",
"collect_photos": "Зібрати фотографії",
"disable_file_download": "Вимкнути завантаження",
"disable_file_download_message": "<p>Ви впевнені, що хочете вимкнути кнопку завантаження для файлів?</p><p>Глядачі все ще можуть робити знімки екрана або зберігати копії ваших фотографій за допомогою зовнішніх інструментів.</p>",
"shared_using": "Спільний доступ через <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "ГБ",
"tb": "ТБ"
},
"after_time": {
"hour": "Через 1 годину",
"day": "Через 1 день",
"week": "Через 1 тиждень",
"month": "Через 1 місяць",
"year": "Через 1 рік"
},
"copy_link": "Копіювати посилання",
"done": "Виконано",
"LINK_SHARE_TITLE": "Або поділіться посиланням",
"REMOVE_LINK": "Вилучити посилання",
"CREATE_PUBLIC_SHARING": "Створити публічне посилання",
"public_link_created": "Публічне посилання створено",
"PUBLIC_LINK_ENABLED": "Публічне посилання увімкнено",
"COLLECT_PHOTOS": "Зібрати фотографії",
"PUBLIC_COLLECT_SUBTEXT": "Дозволити людям з посиланням також додавати фотографії до спільного альбому.",
"STOP_EXPORT": "Зупинити",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> елементів синхронізовано",
"MIGRATING_EXPORT": "Підготування...",

View File

@ -66,8 +66,7 @@
"5": "Sao lưu hoàn tất"
},
"FILE_NOT_UPLOADED_LIST": "Các tệp sau không được tải lên",
"INITIAL_LOAD_DELAY_WARNING": "Tải lần đầu có thể mất một chút thời gian",
"USER_DOES_NOT_EXIST": "Xin lỗi, không tìm thấy người dùng với email đó",
"initial_load_delay_warning": "Tải lần đầu có thể mất một chút thời gian",
"no_account": "Không có tài khoản",
"existing_account": "Đã có tài khoản",
"create": "Tạo",
@ -202,10 +201,11 @@
"delete_photos": "Xóa ảnh",
"keep_photos": "Giữ ảnh",
"share_album": "Chia sẻ album",
"SHARE_WITH_SELF": "Ôi, bạn không thể chia sẻ với chính mình",
"ALREADY_SHARED": "Ôi, bạn đã chia sẻ điều này với {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Chia sẻ album không được phép",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Chia sẻ bị vô hiệu hóa cho các tài khoản miễn phí",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "Chia sẻ album không được phép",
"sharing_disabled_for_free_accounts": "Chia sẻ bị vô hiệu hóa cho các tài khoản miễn phí",
"sharing_user_does_not_exist": "",
"search": "Tìm kiếm",
"search_results": "Kết quả tìm kiếm",
"no_results": "Không tìm thấy kết quả",
@ -362,43 +362,59 @@
"caption_character_limit": "Tối đa 5000 ký tự",
"sharing_details": "Chi tiết chia sẻ",
"modify_sharing": "Chỉnh sửa chia sẻ",
"ADD_COLLABORATORS": "Thêm cộng tác viên",
"ADD_NEW_EMAIL": "Thêm một email mới",
"add_collaborators": "Thêm cộng tác viên",
"add_new_email": "Thêm một email mới",
"shared_with_people_count_zero": "Chia sẻ với người cụ thể",
"shared_with_people_count_one": "Chia sẻ với 1 người",
"shared_with_people_count": "Chia sẻ với {{count, number}} người",
"participants_count_zero": "Không có người tham gia",
"participants_count_one": "1 người tham gia",
"participants_count": "{{count, number}} người tham gia",
"ADD_VIEWERS": "Thêm người xem",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} sẽ không thể thêm nhiều ảnh hơn vào album</p><p>Họ vẫn có thể xóa ảnh đã thêm bởi họ</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} sẽ có thể thêm ảnh vào album",
"CONVERT_TO_VIEWER": "Có, chuyển thành người xem",
"CONVERT_TO_COLLABORATOR": "Có, chuyển thành cộng tác viên",
"CHANGE_PERMISSION": "Thay đổi quyền?",
"REMOVE_PARTICIPANT": "Xóa?",
"CONFIRM_REMOVE": "Có, xóa",
"MANAGE": "Quản lý",
"ADDED_AS": "Đã thêm như",
"COLLABORATOR_RIGHTS": "Cộng tác viên có thể thêm ảnh và video vào album chia sẻ",
"REMOVE_PARTICIPANT_HEAD": "Xóa người tham gia",
"OWNER": "Chủ sở hữu",
"COLLABORATORS": "Cộng tác viên",
"ADD_MORE": "Thêm nhiều hơn",
"VIEWERS": "Người xem",
"OR_ADD_EXISTING": "Hoặc chọn một cái có sẵn",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} sẽ bị xóa khỏi album</p><p>Các ảnh đã thêm bởi họ cũng sẽ bị xóa khỏi album</p>",
"add_viewers": "Thêm người xem",
"change_permission_to_viewer": "<p>{{selectedEmail}} sẽ không thể thêm nhiều ảnh hơn vào album</p><p>Họ vẫn có thể xóa ảnh đã thêm bởi họ</p>",
"change_permission_to_collaborator": "{{selectedEmail}} sẽ có thể thêm ảnh vào album",
"change_permission_title": "Thay đổi quyền?",
"confirm_convert_to_viewer": "Có, chuyển thành người xem",
"confirm_convert_to_collaborator": "Có, chuyển thành cộng tác viên",
"manage": "Quản lý",
"added_as": "Đã thêm như",
"collaborator_hint": "Cộng tác viên có thể thêm ảnh và video vào album chia sẻ",
"remove_participant": "Xóa người tham gia",
"remove_participant_title": "Xóa?",
"remove_participant_message": "<p>{{selectedEmail}} sẽ bị xóa khỏi album</p><p>Các ảnh đã thêm bởi họ cũng sẽ bị xóa khỏi album</p>",
"confirm_remove": "Có, xóa",
"owner": "Chủ sở hữu",
"collaborators": "Cộng tác viên",
"viewers": "Người xem",
"add_more": "Thêm nhiều hơn",
"or_add_existing": "Hoặc chọn một cái có sẵn",
"NOT_FOUND": "404 - không tìm thấy",
"link_expired": "Liên kết đã hết hạn",
"link_expired_message": "Liên kết này đã hết hạn hoặc đã bị vô hiệu hóa",
"MANAGE_LINK": "Quản lý liên kết",
"LINK_TOO_MANY_REQUESTS": "Album này đã được xem trên quá nhiều thiết bị",
"FILE_DOWNLOAD": "Cho phép tải xuống",
"PUBLIC_COLLECT": "Cho phép thêm ảnh",
"LINK_DEVICE_LIMIT": "Giới hạn thiết bị",
"NO_DEVICE_LIMIT": "Không",
"LINK_EXPIRY": "Hết hạn liên kết",
"manage_link": "Quản lý liên kết",
"link_request_limit_exceeded": "Album này đã được xem trên quá nhiều thiết bị",
"allow_downloads": "Cho phép tải xuống",
"allow_adding_photos": "Cho phép thêm ảnh",
"allow_adding_photos_hint": "Cho phép người có liên kết cũng thêm ảnh vào album chia sẻ.",
"device_limit": "Giới hạn thiết bị",
"none": "Không",
"link_expiry": "Hết hạn liên kết",
"never": "Không bao giờ",
"after_time": {
"hour": "Sau một giờ",
"day": "Sau một ngày",
"week": "Sau một tuần",
"month": "Sau một tháng",
"year": "Sau một năm"
},
"copy_link": "Sao chép liên kết",
"done": "Xong",
"share_link_section_title": "Hoặc chia sẻ một liên kết",
"remove_link": "Xóa liên kết",
"create_public_link": "Tạo liên kết công khai",
"public_link_created": "Liên kết công khai đã được tạo",
"public_link_enabled": "Liên kết công khai đã được bật",
"collect_photos": "Thu thập ảnh",
"disable_file_download": "Vô hiệu hóa tải xuống",
"disable_file_download_message": "<p>Bạn có chắc chắn muốn vô hiệu hóa nút tải xuống cho các tệp không?</p><p>Người xem vẫn có thể chụp ảnh màn hình hoặc lưu bản sao của ảnh của bạn bằng các công cụ bên ngoài.</p>",
"shared_using": "Chia sẻ bằng <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "Sau một giờ",
"day": "Sau một ngày",
"week": "Sau một tuần",
"month": "Sau một tháng",
"year": "Sau một năm"
},
"copy_link": "Sao chép liên kết",
"done": "Xong",
"LINK_SHARE_TITLE": "Hoặc chia sẻ một liên kết",
"REMOVE_LINK": "Xóa liên kết",
"CREATE_PUBLIC_SHARING": "Tạo liên kết công khai",
"public_link_created": "Liên kết công khai đã được tạo",
"PUBLIC_LINK_ENABLED": "Liên kết công khai đã được bật",
"COLLECT_PHOTOS": "Thu thập ảnh",
"PUBLIC_COLLECT_SUBTEXT": "Cho phép người có liên kết cũng thêm ảnh vào album chia sẻ.",
"STOP_EXPORT": "Dừng",
"EXPORT_PROGRESS": "<a>{{progress.success, number}} / {{progress.total, number}}</a> mục đã đồng bộ",
"MIGRATING_EXPORT": "Đang chuẩn bị...",

View File

@ -66,8 +66,7 @@
"5": "备份完成"
},
"FILE_NOT_UPLOADED_LIST": "以下文件未上传",
"INITIAL_LOAD_DELAY_WARNING": "第一次加载可能需要一些时间",
"USER_DOES_NOT_EXIST": "抱歉,找不到使用该电子邮件的用户",
"initial_load_delay_warning": "第一次加载可能需要一些时间",
"no_account": "没有账号",
"existing_account": "已有账号",
"create": "创建",
@ -202,10 +201,11 @@
"delete_photos": "删除照片",
"keep_photos": "保留照片",
"share_album": "分享相册",
"SHARE_WITH_SELF": "哎呀,您不能与自己分享",
"ALREADY_SHARED": "哎呀,您已经和 {{email}} 分享了",
"SHARING_BAD_REQUEST_ERROR": "不允许分享相册",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "免费账户禁用共享",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "不允许分享相册",
"sharing_disabled_for_free_accounts": "免费账户禁用共享",
"sharing_user_does_not_exist": "",
"search": "搜索",
"search_results": "搜索结果",
"no_results": "未找到任何结果",
@ -362,43 +362,59 @@
"caption_character_limit": "5000个字符上限",
"sharing_details": "共享的详细信息",
"modify_sharing": "更改共享",
"ADD_COLLABORATORS": "添加协作者",
"ADD_NEW_EMAIL": "添加新的电子邮件",
"add_collaborators": "添加协作者",
"add_new_email": "添加新的电子邮件",
"shared_with_people_count_zero": "与特定人员分享",
"shared_with_people_count_one": "已与1个人共享",
"shared_with_people_count": "已与 {count, number} 个人共享",
"participants_count_zero": "暂无参与者",
"participants_count_one": "1 名参与者",
"participants_count": "{{count, number}} 名参与者",
"ADD_VIEWERS": "添加查看者",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} 将无法向相册添加更多照片</p><p>他们仍然可以删除他们添加的照片</p>",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "{{selectedEmail}} 将能够将照片添加到相册",
"CONVERT_TO_VIEWER": "是的,转换为查看者",
"CONVERT_TO_COLLABORATOR": "是,转换为协作者",
"CHANGE_PERMISSION": "要修改权限吗?",
"REMOVE_PARTICIPANT": "要移除吗?",
"CONFIRM_REMOVE": "是,移除",
"MANAGE": "管理",
"ADDED_AS": "已添加为",
"COLLABORATOR_RIGHTS": "协作者可以将照片和视频添加到共享相册中",
"REMOVE_PARTICIPANT_HEAD": "移除参与者",
"OWNER": "所有者",
"COLLABORATORS": "协作者",
"ADD_MORE": "添加更多",
"VIEWERS": "查看者",
"OR_ADD_EXISTING": "或选择一个现有的",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} 将从相册中删除</p><p>他们添加的所有照片也将从相册中删除</p>",
"add_viewers": "添加查看者",
"change_permission_to_viewer": "<p>{{selectedEmail}} 将无法向相册添加更多照片</p><p>他们仍然可以删除他们添加的照片</p>",
"change_permission_to_collaborator": "{{selectedEmail}} 将能够将照片添加到相册",
"change_permission_title": "要修改权限吗?",
"confirm_convert_to_viewer": "是的,转换为查看者",
"confirm_convert_to_collaborator": "是,转换为协作者",
"manage": "管理",
"added_as": "已添加为",
"collaborator_hint": "协作者可以将照片和视频添加到共享相册中",
"remove_participant": "移除参与者",
"remove_participant_title": "要移除吗?",
"remove_participant_message": "<p>{{selectedEmail}} 将从相册中删除</p><p>他们添加的所有照片也将从相册中删除</p>",
"confirm_remove": "是,移除",
"owner": "所有者",
"collaborators": "协作者",
"viewers": "查看者",
"add_more": "添加更多",
"or_add_existing": "或选择一个现有的",
"NOT_FOUND": "404 - 未找到",
"link_expired": "链接已过期",
"link_expired_message": "此链接已过期或被禁用",
"MANAGE_LINK": "管理链接",
"LINK_TOO_MANY_REQUESTS": "已在过多设备上查看过此相册",
"FILE_DOWNLOAD": "允许下载",
"PUBLIC_COLLECT": "允许添加照片",
"LINK_DEVICE_LIMIT": "设备限制",
"NO_DEVICE_LIMIT": "无",
"LINK_EXPIRY": "链接过期",
"manage_link": "管理链接",
"link_request_limit_exceeded": "已在过多设备上查看过此相册",
"allow_downloads": "允许下载",
"allow_adding_photos": "允许添加照片",
"allow_adding_photos_hint": "允许具有链接的人也将照片添加到共享相册。",
"device_limit": "设备限制",
"none": "无",
"link_expiry": "链接过期",
"never": "永不",
"after_time": {
"hour": "1小时后",
"day": "一天后",
"week": "一周后",
"month": "一个月后",
"year": "一年后"
},
"copy_link": "复制链接",
"done": "已完成",
"share_link_section_title": "或共享一个链接",
"remove_link": "移除链接",
"create_public_link": "创建公开链接",
"public_link_created": "公开链接已创建",
"public_link_enabled": "公开链接已启用",
"collect_photos": "收集照片",
"disable_file_download": "禁止下载",
"disable_file_download_message": "<p>您确定要禁用文件下载按钮吗?</p><p>观看者仍然可以使用外部工具进行屏幕截图或保存您的照片副本。</p>",
"shared_using": "分享方式 <a>{{url}}</a>",
@ -511,22 +527,6 @@
"gb": "GB",
"tb": "TB"
},
"after_time": {
"hour": "1小时后",
"day": "一天后",
"week": "一周后",
"month": "一个月后",
"year": "一年后"
},
"copy_link": "复制链接",
"done": "已完成",
"LINK_SHARE_TITLE": "或共享一个链接",
"REMOVE_LINK": "移除链接",
"CREATE_PUBLIC_SHARING": "创建公开链接",
"public_link_created": "公开链接已创建",
"PUBLIC_LINK_ENABLED": "公开链接已启用",
"COLLECT_PHOTOS": "收集照片",
"PUBLIC_COLLECT_SUBTEXT": "允许具有链接的人也将照片添加到共享相册。",
"STOP_EXPORT": "停止",
"EXPORT_PROGRESS": "<a>{{progress.success}} / {{progress.total}}</a> 个文件已导出",
"MIGRATING_EXPORT": "准备中...",

View File

@ -66,8 +66,7 @@
"5": ""
},
"FILE_NOT_UPLOADED_LIST": "",
"INITIAL_LOAD_DELAY_WARNING": "",
"USER_DOES_NOT_EXIST": "",
"initial_load_delay_warning": "",
"no_account": "",
"existing_account": "",
"create": "",
@ -202,10 +201,11 @@
"delete_photos": "",
"keep_photos": "",
"share_album": "",
"SHARE_WITH_SELF": "",
"ALREADY_SHARED": "",
"SHARING_BAD_REQUEST_ERROR": "",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
"sharing_with_self": "",
"sharing_already_shared": "",
"sharing_album_not_allowed": "",
"sharing_disabled_for_free_accounts": "",
"sharing_user_does_not_exist": "",
"search": "",
"search_results": "",
"no_results": "",
@ -362,43 +362,59 @@
"caption_character_limit": "",
"sharing_details": "",
"modify_sharing": "",
"ADD_COLLABORATORS": "",
"ADD_NEW_EMAIL": "",
"add_collaborators": "",
"add_new_email": "",
"shared_with_people_count_zero": "",
"shared_with_people_count_one": "",
"shared_with_people_count": "",
"participants_count_zero": "",
"participants_count_one": "",
"participants_count": "",
"ADD_VIEWERS": "",
"CHANGE_PERMISSIONS_TO_VIEWER": "",
"CHANGE_PERMISSIONS_TO_COLLABORATOR": "",
"CONVERT_TO_VIEWER": "",
"CONVERT_TO_COLLABORATOR": "",
"CHANGE_PERMISSION": "",
"REMOVE_PARTICIPANT": "",
"CONFIRM_REMOVE": "",
"MANAGE": "",
"ADDED_AS": "",
"COLLABORATOR_RIGHTS": "",
"REMOVE_PARTICIPANT_HEAD": "",
"OWNER": "",
"COLLABORATORS": "",
"ADD_MORE": "",
"VIEWERS": "",
"OR_ADD_EXISTING": "",
"REMOVE_PARTICIPANT_MESSAGE": "",
"add_viewers": "",
"change_permission_to_viewer": "",
"change_permission_to_collaborator": "",
"change_permission_title": "",
"confirm_convert_to_viewer": "",
"confirm_convert_to_collaborator": "",
"manage": "",
"added_as": "",
"collaborator_hint": "",
"remove_participant": "",
"remove_participant_title": "",
"remove_participant_message": "",
"confirm_remove": "",
"owner": "",
"collaborators": "",
"viewers": "",
"add_more": "",
"or_add_existing": "",
"NOT_FOUND": "",
"link_expired": "",
"link_expired_message": "",
"MANAGE_LINK": "",
"LINK_TOO_MANY_REQUESTS": "",
"FILE_DOWNLOAD": "",
"PUBLIC_COLLECT": "",
"LINK_DEVICE_LIMIT": "",
"NO_DEVICE_LIMIT": "",
"LINK_EXPIRY": "",
"manage_link": "",
"link_request_limit_exceeded": "",
"allow_downloads": "",
"allow_adding_photos": "",
"allow_adding_photos_hint": "",
"device_limit": "",
"none": "",
"link_expiry": "",
"never": "",
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"share_link_section_title": "",
"remove_link": "",
"create_public_link": "",
"public_link_created": "",
"public_link_enabled": "",
"collect_photos": "",
"disable_file_download": "",
"disable_file_download_message": "",
"shared_using": "",
@ -511,22 +527,6 @@
"gb": "",
"tb": ""
},
"after_time": {
"hour": "",
"day": "",
"week": "",
"month": "",
"year": ""
},
"copy_link": "",
"done": "",
"LINK_SHARE_TITLE": "",
"REMOVE_LINK": "",
"CREATE_PUBLIC_SHARING": "",
"public_link_created": "",
"PUBLIC_LINK_ENABLED": "",
"COLLECT_PHOTOS": "",
"PUBLIC_COLLECT_SUBTEXT": "",
"STOP_EXPORT": "",
"EXPORT_PROGRESS": "",
"MIGRATING_EXPORT": "",

View File

@ -309,8 +309,8 @@ export interface Electron {
* {@link dataOrPathOrZipItem}.
*
* This executes the command using a FFmpeg executable we bundle with our
* desktop app. We also have a wasm FFmpeg wasm implementation that we use
* when running on the web, which has a sibling function with the same
* desktop app. We also have a Wasm FFmpeg implementation that we use when
* running on the web, which has a sibling function with the same
* parameters. See [Note:FFmpeg in Electron].
*
* @param command An array of strings, each representing one positional

View File

@ -20,7 +20,7 @@ import {
import { ffmpegExecWeb } from "./web";
/**
* Generate a thumbnail for the given video using a wasm FFmpeg running in a web
* Generate a thumbnail for the given video using a Wasm FFmpeg running in a web
* worker.
*
* This function is called during upload, when we need to generate thumbnails
@ -94,7 +94,7 @@ const makeGenThumbnailCommand = (seekTime: number) => [
*
* When we're running in the context of our desktop app _and_ we're passed a
* file path , this uses the native FFmpeg bundled with our desktop app.
* Otherwise it uses a wasm build of FFmpeg running in a web worker.
* Otherwise it uses a Wasm build of FFmpeg running in a web worker.
*
* This function is called during upload, when we need to extract the metadata
* of videos that the user is uploading.
@ -270,7 +270,7 @@ const convertToMP4Native = async (electron: Electron, blob: Blob) => {
};
/**
* Generate a preview variant of for the given video using a wasm FFmpeg running
* Generate a preview variant of for the given video using a Wasm FFmpeg running
* in a web worker.
*
* See: [Note: Preview variant of videos].

View File

@ -30,11 +30,13 @@ const createFFmpeg = async () => {
};
/**
* Run the given FFmpeg command using a wasm FFmpeg running in a web worker.
* Run the given FFmpeg command using a Wasm FFmpeg running in a web worker.
*
* This is a sibling of {@link ffmpegExec} exposed by the desktop app in `ipc.ts`.
* As a rough ballpark, currently the native FFmpeg integration in the desktop
* app is 10-20x faster than the wasm one. See: [Note: FFmpeg in Electron].
* This is a sibling of {@link ffmpegExec} exposed by the desktop app in
* `ipc.ts`. As a rough ballpark, currently the native FFmpeg integration in the
* desktop app is 10-20x faster than the Wasm one.
*
* See: [Note: FFmpeg in Electron].
*
* @param command The FFmpeg command to execute.
*

View File

@ -29,7 +29,7 @@ import { detectFileTypeInfo } from "./detect-type";
* desktop app can natively convert to a JPEG (using ffmpeg), do that and
* return the resultant JPEG blob.
*
* 4. If this is an HEIC file, use our (WASM) HEIC converter and return the
* 4. If this is an HEIC file, use our (Wasm) HEIC converter and return the
* resultant JPEG blob.
*
* 5. Otherwise return the original (with the MIME type if we were able to
@ -124,7 +124,7 @@ const nativeConvertToJPEG = async (imageBlob: Blob) => {
*
* - Otherwise try to convert using FFmpeg. This conversion always happens on
* the desktop app, but in the browser the conversion only happens for short
* videos since the WASM FFmpeg implementation is much slower. There is also a
* videos since the Wasm FFmpeg implementation is much slower. There is also a
* flag to force this conversion regardless.
*/
export const playableVideoBlob = async (

View File

@ -1,4 +1,5 @@
import { sharedCryptoWorker } from "@/base/crypto";
import { dateFromEpochMicroseconds } from "@/base/date";
import log from "@/base/log";
import { type Metadata, ItemVisibility } from "./file-metadata";
@ -172,7 +173,15 @@ export interface EnteFile
* But its presence is not guaranteed.
*/
pubMagicMetadata?: FilePublicMagicMetadata;
/**
* `true` if this file is in trash (i.e. it has been deleted by the user,
* and will be permanently deleted after 30 days of being moved to trash).
*/
isTrashed?: boolean;
/**
* If this is a file in trash, then {@link deleteBy} contains the epoch
* microseconds when this file will be permanently deleted.
*/
deleteBy?: number;
/**
* The base64 representation of the decrypted encryption key associated with
@ -285,6 +294,16 @@ export const fileLogID = (file: EnteFile) =>
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
`file ${file.metadata.title ?? "-"} (${file.id})`;
/**
* Return the date when the file will be deleted permanently. Only valid for
* files that are in the user's trash.
*
* This is a convenience wrapper over the {@link deleteBy} property of a file,
* converting that epoch microsecond value into a JavaScript date.
*/
export const enteFileDeletionDate = (file: EnteFile) =>
dateFromEpochMicroseconds(file.deleteBy);
export async function decryptFile(
file: EncryptedEnteFile,
collectionKey: string,

View File

@ -4,7 +4,7 @@ import type { HEICConvertWorker } from "./heic-convert.worker";
/**
* Convert a HEIC image to a JPEG.
*
* Behind the scenes, it uses a web worker to do the conversion using a WASM
* Behind the scenes, it uses a web worker to do the conversion using a Wasm
* HEIC conversion package.
*
* @param heicBlob The HEIC blob to convert.

View File

@ -1,3 +1,4 @@
import { SpaceBetweenFlex } from "@/base/components/containers";
import type { ButtonishProps } from "@/base/components/mui";
import { FocusVisibleButton } from "@/base/components/mui/FocusVisibleButton";
import {
@ -5,6 +6,7 @@ import {
genericRetriableErrorDialogAttributes,
} from "@/base/components/utils/dialog";
import type { ModalVisibilityProps } from "@/base/components/utils/modal";
import { wipTheme } from "@/base/components/utils/theme";
import log from "@/base/log";
import { useUserDetailsSnapshot } from "@/new/photos/components/utils/use-snapshot";
import { useWrapAsyncOperation } from "@/new/photos/components/utils/use-wrap-async";
@ -34,10 +36,6 @@ import {
import { useAppContext } from "@/new/photos/types/context";
import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units";
import { openURL } from "@/new/photos/utils/web";
import {
FlexWrapper,
SpaceBetweenFlex,
} from "@ente/shared/components/Container";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import CloseIcon from "@mui/icons-material/Close";
@ -87,6 +85,17 @@ export const PlanSelector: React.FC<PlanSelectorProps> = ({
[theme.breakpoints.down(360)]: { p: 0 },
}),
},
// [Note: Backdrop variant blur]
//
// What we wish for is creating a variant of Backdrop that
// instead of specifying the backdrop filter each time. But as
// of MUI v6.4, the TypeScript definition for Backdrop does not
// contain a variant, causing tsc to show an error when we try
// to specify a variant.
//
// Since the styling is trivial and used only infrequently, for
// now we copy paste it. If it gets needed more often, we can
// also make it into a palette var.
backdrop: {
sx: { backdropFilter: "blur(30px) opacity(95%)" },
},
@ -576,10 +585,23 @@ const PlanRow: React.FC<PlanRowProps> = ({ plan, onPlanSelect, disabled }) => {
);
};
const PlanRowContainer = styled(FlexWrapper)(() => ({
background:
"linear-gradient(268.22deg, rgba(256, 256, 256, 0.08) -3.72%, rgba(256, 256, 256, 0) 85.73%)",
}));
const PlanRowContainer = styled("div")(({ theme }) =>
wipTheme
? {
display: "flex",
background:
"linear-gradient(270deg, transparent, rgba(0 0 0 / 0.02), transparent)",
...theme.applyStyles("dark", {
background:
"linear-gradient(270deg, rgba(255 255 255 / 0.08) -3.72%, transparent 85.73%)",
}),
}
: {
display: "flex",
background:
"linear-gradient(270deg, rgba(255 255 255 / 0.08) -3.72%, transparent 85.73%)",
},
);
const PlanStorage = styled("div")`
flex: 1;

View File

@ -1,3 +1,4 @@
import { Overlay } from "@/base/components/containers";
import { downloadManager } from "@/gallery/services/download";
import { type EnteFile } from "@/media/file";
import {
@ -99,12 +100,12 @@ export const ItemCard: React.FC<React.PropsWithChildren<ItemCardProps>> = ({
* A generic "base" tile, meant to be used (after setting dimensions) as the
* {@link TileComponent} provided to an {@link ItemCard}.
*
* Use {@link ItemTileOverlay} (usually via one of its presets) to overlay
* content on top of the tile.
* Use {@link Overlay} (usually via one of its presets) to overlay content on
* top of the tile.
*/
const BaseTile = styled("div")`
display: flex;
/* Act as container for the absolutely positioned ItemTileOverlays. */
/* Act as container for the absolutely positioned 'Overlay's. */
position: relative;
border-radius: 4px;
overflow: hidden;
@ -133,6 +134,7 @@ export const PreviewItemTile = styled(BaseTile)`
export const BarItemTile = styled(BaseTile)`
width: 90px;
height: 64px;
color: white;
`;
/**
@ -155,7 +157,7 @@ export const BaseTileButton = styled(UnstyledButton)`
/* Rest of this is mostly verbatim from BaseTile ... */
display: flex;
/* Act as container for the absolutely positioned ItemTileOverlays. */
/* Act as container for the absolutely positioned 'Overlay's. */
position: relative;
border-radius: 4px;
overflow: hidden;
@ -177,24 +179,10 @@ export const LargeTileButton = styled(BaseTileButton)`
`;
/**
* An empty overlay on top of the nearest relative positioned ancestor.
*
* This is meant to be used in tandem with a derivate of {@link BaseTile} or
* {@link BaseTileButton}.
* An {@link Overlay} suitable for hosting textual content at the top left of
* small and medium sized tiles.
*/
export const ItemTileOverlay = styled("div")`
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
`;
/**
* An {@link ItemTileOverlay} suitable for hosting textual content at the top
* left of small and medium sized tiles.
*/
export const TileTextOverlay = styled(ItemTileOverlay)`
export const TileTextOverlay = styled(Overlay)`
padding: 4px;
background: linear-gradient(
0deg,
@ -207,7 +195,7 @@ export const TileTextOverlay = styled(ItemTileOverlay)`
* A variation of {@link TileTextOverlay} for use with larger tiles like the
* {@link CollectionTile}.
*/
export const LargeTileTextOverlay = styled(ItemTileOverlay)`
export const LargeTileTextOverlay = styled(Overlay)`
padding: 8px;
background: linear-gradient(
0deg,
@ -219,7 +207,7 @@ export const LargeTileTextOverlay = styled(ItemTileOverlay)`
/**
* A container for "+", suitable for use with a {@link LargeTileTextOverlay}.
*/
export const LargeTilePlusOverlay = styled(ItemTileOverlay)(
export const LargeTilePlusOverlay = styled(Overlay)(
({ theme }) => `
display: flex;
justify-content: center;
@ -230,13 +218,15 @@ export const LargeTilePlusOverlay = styled(ItemTileOverlay)(
);
/**
* An {@link ItemTileOverlay} suitable for holding the collection name shown
* atop the tiles in the duplicates listing.
* An {@link Overlay} suitable for showing text at the bottom center of the
* tile. Used by the tiles in trash (for showing the days until deletion) and
* duplicate listing (for showing the collection name).
*/
export const DuplicateTileTextOverlay = styled(ItemTileOverlay)`
export const TileBottomTextOverlay = styled(Overlay)`
display: flex;
justify-content: center;
align-items: flex-end;
padding: 4px;
background: linear-gradient(transparent 50%, rgba(0, 0, 0, 0.7));
padding: 6px;
background: linear-gradient(transparent 30%, 80%, rgba(0 0 0 / 0.7));
color: white;
`;

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