Merge remote-tracking branch 'origin/main' into remote_db
This commit is contained in:
@@ -142,6 +142,7 @@ export const sidebar = [
|
||||
text: "Video streaming",
|
||||
link: "/photos/faq/video-streaming",
|
||||
},
|
||||
{ text: "Misc", link: "/photos/faq/misc" },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
20
docs/docs/photos/faq/misc.md
Normal file
20
docs/docs/photos/faq/misc.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: Miscellaneous general FAQ
|
||||
description: Unsorted frequently asked questions about Ente Photos
|
||||
---
|
||||
|
||||
# Miscellaneous FAQ
|
||||
|
||||
## Exif Description
|
||||
|
||||
Ente will try to read as much information from Exif when the image is uploaded,
|
||||
but after that, only the fields which have been parsed into Ente can be
|
||||
searched.
|
||||
|
||||
The app still show all the fields in the raw Exif data in the file info panel
|
||||
when someone taps on the "View all Exif" option, but otherwise the app is
|
||||
unaware of these fields.
|
||||
|
||||
In particular, for the description associated with a photo, the exact logic to
|
||||
determine the description from the Exif when uploading the image can be seen
|
||||
[in this part of the code](https://github.com/ente-io/ente/blob/0dcb185744da469848b41b668fe4b647226b6fe2/web/packages/gallery/services/exif.ts#L609-L620).
|
||||
@@ -101,11 +101,13 @@ class HomeWidgetService {
|
||||
|
||||
await setData(key, path);
|
||||
|
||||
final subText = await SmartMemoriesService.getDateFormattedLocale(
|
||||
creationTime: ogFile.creationTime!,
|
||||
);
|
||||
|
||||
final data = {
|
||||
"title": title,
|
||||
"subText": SmartMemoriesService.getDateFormatted(
|
||||
creationTime: ogFile.creationTime!,
|
||||
),
|
||||
"subText": subText,
|
||||
"generatedId": ogFile.generatedID!,
|
||||
};
|
||||
if (Platform.isIOS) {
|
||||
|
||||
16
mobile/lib/services/language_service.dart
Normal file
16
mobile/lib/services/language_service.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/l10n/l10n.dart";
|
||||
|
||||
class LanguageService {
|
||||
static Future<S> get s async {
|
||||
try {
|
||||
return S.current;
|
||||
} catch (_) {}
|
||||
|
||||
final local = await getLocale();
|
||||
|
||||
final s = await S.load(local!);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,10 @@ class MemoryHomeWidgetService {
|
||||
}
|
||||
|
||||
await _memoryForceRefreshLock.synchronized(() async {
|
||||
final result = await hasAnyBlockers();
|
||||
if (result) {
|
||||
return;
|
||||
}
|
||||
final isTotalEmpty = await _checkIfTotalEmpty();
|
||||
forceFetchNewMemories ??= await getForceFetchCondition(isTotalEmpty);
|
||||
|
||||
@@ -138,13 +142,11 @@ class MemoryHomeWidgetService {
|
||||
return {};
|
||||
}
|
||||
|
||||
// flatten the memories to a list of files and take first 50
|
||||
final files = memories.take(50).toList().asMap().map(
|
||||
(k, v) => MapEntry(
|
||||
v.title,
|
||||
v.memories.map((e) => e.file),
|
||||
),
|
||||
);
|
||||
final files = Map.fromEntries(
|
||||
memories.map((m) {
|
||||
return MapEntry(m.title, m.memories.map((e) => e.file).toList());
|
||||
}).take(50),
|
||||
);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
@@ -1257,7 +1257,7 @@ class SearchService {
|
||||
searchResults.add(
|
||||
GenericSearchResult(
|
||||
ResultType.event,
|
||||
memory.title,
|
||||
memory.title + "(I)",
|
||||
files,
|
||||
hierarchicalSearchFilter: TopLevelGenericFilter(
|
||||
filterName: memory.title,
|
||||
|
||||
@@ -13,7 +13,6 @@ import "package:photos/core/constants.dart";
|
||||
import "package:photos/db/memories_db.dart";
|
||||
import "package:photos/db/ml/db.dart";
|
||||
import "package:photos/extensions/stop_watch.dart";
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/l10n/l10n.dart";
|
||||
import "package:photos/models/base_location.dart";
|
||||
import "package:photos/models/file/file.dart";
|
||||
@@ -31,6 +30,7 @@ import "package:photos/models/ml/face/face_with_embedding.dart";
|
||||
import "package:photos/models/ml/face/person.dart";
|
||||
import "package:photos/models/ml/vector.dart";
|
||||
import "package:photos/service_locator.dart";
|
||||
import "package:photos/services/language_service.dart";
|
||||
import "package:photos/services/location_service.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/person/person_service.dart";
|
||||
import "package:photos/services/machine_learning/ml_computer.dart";
|
||||
@@ -119,7 +119,8 @@ class SmartMemoriesService {
|
||||
|
||||
final local = await getLocale();
|
||||
final languageCode = local?.languageCode ?? "en";
|
||||
final s = await S.load(local!);
|
||||
final s = await LanguageService.s;
|
||||
|
||||
_logger.finest('get locale and S $t');
|
||||
|
||||
_logger.finest('all data fetched $t at ${DateTime.now()}, to computer');
|
||||
@@ -315,6 +316,15 @@ class SmartMemoriesService {
|
||||
final seenTimes = await _memoriesDB.getSeenTimes();
|
||||
final fillerMemories =
|
||||
await _getFillerResults(allFiles, now, seenTimes: seenTimes);
|
||||
|
||||
final local = await getLocale();
|
||||
final languageCode = local?.languageCode ?? "en";
|
||||
final s = await LanguageService.s;
|
||||
|
||||
_logger.finest('get locale and S');
|
||||
for (final memory in fillerMemories) {
|
||||
memory.title = memory.createTitle(s, languageCode);
|
||||
}
|
||||
return fillerMemories;
|
||||
}
|
||||
|
||||
@@ -1534,12 +1544,26 @@ class SmartMemoriesService {
|
||||
return memoryResults;
|
||||
}
|
||||
|
||||
static Future<String> getDateFormattedLocale({
|
||||
required int creationTime,
|
||||
}) async {
|
||||
final locale = await getLocale();
|
||||
|
||||
return getDateFormatted(
|
||||
creationTime: creationTime,
|
||||
languageCode: locale!.languageCode,
|
||||
);
|
||||
}
|
||||
|
||||
static String getDateFormatted({
|
||||
required int creationTime,
|
||||
BuildContext? context,
|
||||
String? languageCode,
|
||||
}) {
|
||||
return DateFormat.yMMMd(
|
||||
context != null ? Localizations.localeOf(context).languageCode : "en",
|
||||
context != null
|
||||
? Localizations.localeOf(context).languageCode
|
||||
: languageCode ?? "en",
|
||||
).format(
|
||||
DateTime.fromMicrosecondsSinceEpoch(creationTime),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter/scheduler.dart";
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/models/memories/memory.dart";
|
||||
import "package:photos/theme/colors.dart";
|
||||
import "package:photos/theme/effects.dart";
|
||||
@@ -19,7 +18,7 @@ class MemoryCoverWidget extends StatefulWidget {
|
||||
static const aspectRatio = 0.68;
|
||||
static const horizontalPadding = 2.5;
|
||||
final double maxScaleOffsetX;
|
||||
final String? title;
|
||||
final String title;
|
||||
|
||||
const MemoryCoverWidget({
|
||||
required this.memories,
|
||||
@@ -28,7 +27,7 @@ class MemoryCoverWidget extends StatefulWidget {
|
||||
required this.maxHeight,
|
||||
required this.maxWidth,
|
||||
required this.maxScaleOffsetX,
|
||||
this.title,
|
||||
required this.title,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -47,11 +46,8 @@ class _MemoryCoverWidgetState extends State<MemoryCoverWidget> {
|
||||
|
||||
final widthOfScreen = MediaQuery.sizeOf(context).width;
|
||||
final index = _getNextMemoryIndex();
|
||||
final title = widget.title != null
|
||||
? widget.title! == "filler"
|
||||
? _getTitle(widget.memories[index])
|
||||
: widget.title!
|
||||
: _getTitle(widget.memories[index]);
|
||||
final title = widget.title;
|
||||
|
||||
final memory = widget.memories[index];
|
||||
final isSeen = memory.isSeen();
|
||||
final brightness =
|
||||
@@ -246,11 +242,4 @@ class _MemoryCoverWidgetState extends State<MemoryCoverWidget> {
|
||||
}
|
||||
return lastSeenIndex + 1;
|
||||
}
|
||||
|
||||
String _getTitle(Memory memory) {
|
||||
final present = DateTime.now();
|
||||
final then = DateTime.fromMicrosecondsSinceEpoch(memory.file.creationTime!);
|
||||
final diffInYears = present.year - then.year;
|
||||
return S.of(context).yearsAgo(diffInYears);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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: 1.0.0+1030
|
||||
version: 1.0.0+1031
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
|
||||
@@ -73,6 +73,8 @@ services:
|
||||
|
||||
configs:
|
||||
credentials_yaml:
|
||||
# You'll need to recreate the containers (docker compose down && docker
|
||||
# compose up) when changing this inline config for the changes to apply.
|
||||
content: |
|
||||
db:
|
||||
host: postgres
|
||||
|
||||
@@ -91,7 +91,13 @@ docker compose down
|
||||
```
|
||||
|
||||
Apart from this `my-ente` directory, the script does not install anything else
|
||||
on your system. All persistent data is saved in volumes managed by Docker.
|
||||
on your system. Settings and credentials are saved in `my-ente`, while other
|
||||
persistent data is saved in volumes managed by Docker.
|
||||
|
||||
> [!IMPORTANT]
|
||||
>
|
||||
> The `museum.yaml` contains your (unique) autogenerated museum, DB and S3
|
||||
> credentials, without which the data on your volumes will not be accessible.
|
||||
|
||||
> [!CAUTION]
|
||||
>
|
||||
|
||||
@@ -827,8 +827,10 @@ export const FileViewer: React.FC<FileViewerProps> = ({
|
||||
}, [handleClose, files]);
|
||||
|
||||
useEffect(() => {
|
||||
psRef.current?.refreshCurrentSlideFavoriteButtonIfNeeded();
|
||||
}, [favoriteFileIDs, pendingFavoriteUpdates]);
|
||||
if (open) {
|
||||
psRef.current?.refreshCurrentSlideFavoriteButtonIfNeeded();
|
||||
}
|
||||
}, [favoriteFileIDs, pendingFavoriteUpdates, open]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
@@ -840,7 +842,9 @@ export const FileViewer: React.FC<FileViewerProps> = ({
|
||||
disableDownload,
|
||||
haveUser,
|
||||
delegate: delegateRef.current!,
|
||||
onClose: handleClose,
|
||||
onClose: () => {
|
||||
if (psRef.current) handleClose();
|
||||
},
|
||||
onAnnotate: handleAnnotate,
|
||||
onViewInfo: handleViewInfo,
|
||||
onDownload: handleDownloadBarAction,
|
||||
|
||||
Reference in New Issue
Block a user