Merge remote-tracking branch 'origin/main' into remote_db

This commit is contained in:
Neeraj Gupta
2025-03-22 15:17:42 +05:30
12 changed files with 100 additions and 34 deletions

View File

@@ -142,6 +142,7 @@ export const sidebar = [
text: "Video streaming",
link: "/photos/faq/video-streaming",
},
{ text: "Misc", link: "/photos/faq/misc" },
],
},
{

View 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).

View File

@@ -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) {

View 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;
}
}

View File

@@ -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;
}

View File

@@ -1257,7 +1257,7 @@ class SearchService {
searchResults.add(
GenericSearchResult(
ResultType.event,
memory.title,
memory.title + "(I)",
files,
hierarchicalSearchFilter: TopLevelGenericFilter(
filterName: memory.title,

View File

@@ -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),
);

View File

@@ -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);
}
}

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: 1.0.0+1030
version: 1.0.0+1031
publish_to: none
environment:

View File

@@ -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

View File

@@ -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]
>

View File

@@ -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,