fix(privacy): Finish shows what it would take in, and takes in exactly that (ADR 0019)

The final reading of 22 Oct found that Finish's question said only how
many edits of each kind there were, so the person couldn't see content the
instance planted, and that taking them in sealed whatever was unsigned when
it ran, answers included without being counted. The dialog now lists each
edit with its kind and what it says (answers too), and taking them in seals
exactly the rows listed, each only while it still says what was shown; one
that came or changed after the list stays locked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-22 11:34:42 +02:00
commit c9c6533afc
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
5 changed files with 434 additions and 243 deletions

View file

@ -2078,20 +2078,17 @@
"@publishTagsSent": {"placeholders": {"names": {"type": "String"}}},
"publishTagsSentNone": "Es gehen keine Tags mit.",
"privacyAdoptTitle": "Unsignierte Änderungen übernehmen?",
"privacyAdoptBody": "Während es privat gemacht wurde, hat ein Gerät ohne deine Schlüssel es geändert: {parts}. Übernommen, werden sie als deine versiegelt; sonst bleiben sie gesperrt, wie alles, was die Instanz geschrieben haben könnte.",
"@privacyAdoptBody": {"placeholders": {"parts": {"type": "String"}}},
"privacyAdoptTake": "Übernehmen",
"privacyAdoptLeave": "Gesperrt lassen",
"privacyEditsCards": "{count, plural, =1{1 Karteikarte} other{{count} Karteikarten}}",
"@privacyEditsCards": {"placeholders": {"count": {"type": "int"}}},
"privacyEditsNotes": "{count, plural, =1{1 Notiz} other{{count} Notizen}}",
"@privacyEditsNotes": {"placeholders": {"count": {"type": "int"}}},
"privacyEditsPaths": "{count, plural, =1{1 Änderung an Lernpfaden} other{{count} Änderungen an Lernpfaden}}",
"@privacyEditsPaths": {"placeholders": {"count": {"type": "int"}}},
"privacyEditsPdfs": "{count, plural, =1{1 PDF} other{{count} PDFs}}",
"@privacyEditsPdfs": {"placeholders": {"count": {"type": "int"}}},
"privacyEditsStudysets": "{count, plural, =1{1 Lernset} other{{count} Lernsets}}",
"@privacyEditsStudysets": {"placeholders": {"count": {"type": "int"}}},
"privacyAdoptListBody": "Während es privat gemacht wurde, wurde das hier ohne deine Schlüssel geschrieben: von einem Gerät, das sie nicht hatte, oder von der Instanz. Übernommen, werden genau diese als deine versiegelt; gelassen, bleiben sie gesperrt.",
"privacyEditCard": "Karteikarte",
"privacyEditNote": "Notiz",
"privacyEditPath": "Lernpfad",
"privacyEditStep": "Schritt",
"privacyEditPdf": "PDF",
"privacyEditStudyset": "Lernset",
"privacyEditAnswer": "Antwort",
"privacyEditNoText": "(kein Text)",
"studysetLockedTitle": "Gesperrt",
"studysetLockedBody": "Dieses Lernset ist privat, und sein Schlüssel öffnet sich auf diesem Gerät nicht: Es wurde mit Schlüsseln verschlüsselt, die dein Konto nicht mehr hat. Es lässt sich nur noch löschen.",
"studysetVisibilityPartly": "Privat, teils lesbar",

View file

@ -2444,20 +2444,17 @@
"@publishTagsSent": {"placeholders": {"names": {"type": "String"}}},
"publishTagsSentNone": "No tags go with it.",
"privacyAdoptTitle": "Take in edits nobody signed?",
"privacyAdoptBody": "While it was made private, a device without your keys changed it: {parts}. Taken in, they are sealed as yours; left, they stay locked, as anything the instance could have written.",
"@privacyAdoptBody": {"placeholders": {"parts": {"type": "String"}}},
"privacyAdoptTake": "Take them in",
"privacyAdoptLeave": "Leave them locked",
"privacyEditsCards": "{count, plural, =1{1 flashcard} other{{count} flashcards}}",
"@privacyEditsCards": {"placeholders": {"count": {"type": "int"}}},
"privacyEditsNotes": "{count, plural, =1{1 note} other{{count} notes}}",
"@privacyEditsNotes": {"placeholders": {"count": {"type": "int"}}},
"privacyEditsPaths": "{count, plural, =1{1 change to learning paths} other{{count} changes to learning paths}}",
"@privacyEditsPaths": {"placeholders": {"count": {"type": "int"}}},
"privacyEditsPdfs": "{count, plural, =1{1 PDF} other{{count} PDFs}}",
"@privacyEditsPdfs": {"placeholders": {"count": {"type": "int"}}},
"privacyEditsStudysets": "{count, plural, =1{1 studyset} other{{count} studysets}}",
"@privacyEditsStudysets": {"placeholders": {"count": {"type": "int"}}},
"privacyAdoptListBody": "While it was made private, these were written without your keys: by a device that didn't have them, or by the instance. Taken in, exactly these are sealed as yours; left, they stay locked.",
"privacyEditCard": "Flashcard",
"privacyEditNote": "Note",
"privacyEditPath": "Learning path",
"privacyEditStep": "Step",
"privacyEditPdf": "PDF",
"privacyEditStudyset": "Studyset",
"privacyEditAnswer": "Answer",
"privacyEditNoText": "(no text)",
"studysetLockedTitle": "Locked",
"studysetLockedBody": "This studyset is private, and its key doesn't open on this device: it was encrypted with keys your account no longer has. It can only be deleted.",
"studysetVisibilityPartly": "Private, partly readable",

View file

@ -12249,12 +12249,6 @@ abstract class AppLocalizations {
/// **'Take in edits nobody signed?'**
String get privacyAdoptTitle;
/// No description provided for @privacyAdoptBody.
///
/// In en, this message translates to:
/// **'While it was made private, a device without your keys changed it: {parts}. Taken in, they are sealed as yours; left, they stay locked, as anything the instance could have written.'**
String privacyAdoptBody(String parts);
/// No description provided for @privacyAdoptTake.
///
/// In en, this message translates to:
@ -12267,35 +12261,59 @@ abstract class AppLocalizations {
/// **'Leave them locked'**
String get privacyAdoptLeave;
/// No description provided for @privacyEditsCards.
/// No description provided for @privacyAdoptListBody.
///
/// In en, this message translates to:
/// **'{count, plural, =1{1 flashcard} other{{count} flashcards}}'**
String privacyEditsCards(int count);
/// **'While it was made private, these were written without your keys: by a device that didn\'t have them, or by the instance. Taken in, exactly these are sealed as yours; left, they stay locked.'**
String get privacyAdoptListBody;
/// No description provided for @privacyEditsNotes.
/// No description provided for @privacyEditCard.
///
/// In en, this message translates to:
/// **'{count, plural, =1{1 note} other{{count} notes}}'**
String privacyEditsNotes(int count);
/// **'Flashcard'**
String get privacyEditCard;
/// No description provided for @privacyEditsPaths.
/// No description provided for @privacyEditNote.
///
/// In en, this message translates to:
/// **'{count, plural, =1{1 change to learning paths} other{{count} changes to learning paths}}'**
String privacyEditsPaths(int count);
/// **'Note'**
String get privacyEditNote;
/// No description provided for @privacyEditsPdfs.
/// No description provided for @privacyEditPath.
///
/// In en, this message translates to:
/// **'{count, plural, =1{1 PDF} other{{count} PDFs}}'**
String privacyEditsPdfs(int count);
/// **'Learning path'**
String get privacyEditPath;
/// No description provided for @privacyEditsStudysets.
/// No description provided for @privacyEditStep.
///
/// In en, this message translates to:
/// **'{count, plural, =1{1 studyset} other{{count} studysets}}'**
String privacyEditsStudysets(int count);
/// **'Step'**
String get privacyEditStep;
/// No description provided for @privacyEditPdf.
///
/// In en, this message translates to:
/// **'PDF'**
String get privacyEditPdf;
/// No description provided for @privacyEditStudyset.
///
/// In en, this message translates to:
/// **'Studyset'**
String get privacyEditStudyset;
/// No description provided for @privacyEditAnswer.
///
/// In en, this message translates to:
/// **'Answer'**
String get privacyEditAnswer;
/// No description provided for @privacyEditNoText.
///
/// In en, this message translates to:
/// **'(no text)'**
String get privacyEditNoText;
/// No description provided for @studysetLockedTitle.
///

View file

@ -7766,11 +7766,6 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get privacyAdoptTitle => 'Unsignierte Änderungen übernehmen?';
@override
String privacyAdoptBody(String parts) {
return 'Während es privat gemacht wurde, hat ein Gerät ohne deine Schlüssel es geändert: $parts. Übernommen, werden sie als deine versiegelt; sonst bleiben sie gesperrt, wie alles, was die Instanz geschrieben haben könnte.';
}
@override
String get privacyAdoptTake => 'Übernehmen';
@ -7778,59 +7773,32 @@ class AppLocalizationsDe extends AppLocalizations {
String get privacyAdoptLeave => 'Gesperrt lassen';
@override
String privacyEditsCards(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten',
one: '1 Karteikarte',
);
return '$_temp0';
}
String get privacyAdoptListBody =>
'Während es privat gemacht wurde, wurde das hier ohne deine Schlüssel geschrieben: von einem Gerät, das sie nicht hatte, oder von der Instanz. Übernommen, werden genau diese als deine versiegelt; gelassen, bleiben sie gesperrt.';
@override
String privacyEditsNotes(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Notizen',
one: '1 Notiz',
);
return '$_temp0';
}
String get privacyEditCard => 'Karteikarte';
@override
String privacyEditsPaths(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Änderungen an Lernpfaden',
one: '1 Änderung an Lernpfaden',
);
return '$_temp0';
}
String get privacyEditNote => 'Notiz';
@override
String privacyEditsPdfs(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count PDFs',
one: '1 PDF',
);
return '$_temp0';
}
String get privacyEditPath => 'Lernpfad';
@override
String privacyEditsStudysets(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Lernsets',
one: '1 Lernset',
);
return '$_temp0';
}
String get privacyEditStep => 'Schritt';
@override
String get privacyEditPdf => 'PDF';
@override
String get privacyEditStudyset => 'Lernset';
@override
String get privacyEditAnswer => 'Antwort';
@override
String get privacyEditNoText => '(kein Text)';
@override
String get studysetLockedTitle => 'Gesperrt';

View file

@ -7693,11 +7693,6 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get privacyAdoptTitle => 'Take in edits nobody signed?';
@override
String privacyAdoptBody(String parts) {
return 'While it was made private, a device without your keys changed it: $parts. Taken in, they are sealed as yours; left, they stay locked, as anything the instance could have written.';
}
@override
String get privacyAdoptTake => 'Take them in';
@ -7705,59 +7700,32 @@ class AppLocalizationsEn extends AppLocalizations {
String get privacyAdoptLeave => 'Leave them locked';
@override
String privacyEditsCards(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count flashcards',
one: '1 flashcard',
);
return '$_temp0';
}
String get privacyAdoptListBody =>
'While it was made private, these were written without your keys: by a device that didn\'t have them, or by the instance. Taken in, exactly these are sealed as yours; left, they stay locked.';
@override
String privacyEditsNotes(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count notes',
one: '1 note',
);
return '$_temp0';
}
String get privacyEditCard => 'Flashcard';
@override
String privacyEditsPaths(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count changes to learning paths',
one: '1 change to learning paths',
);
return '$_temp0';
}
String get privacyEditNote => 'Note';
@override
String privacyEditsPdfs(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count PDFs',
one: '1 PDF',
);
return '$_temp0';
}
String get privacyEditPath => 'Learning path';
@override
String privacyEditsStudysets(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count studysets',
one: '1 studyset',
);
return '$_temp0';
}
String get privacyEditStep => 'Step';
@override
String get privacyEditPdf => 'PDF';
@override
String get privacyEditStudyset => 'Studyset';
@override
String get privacyEditAnswer => 'Answer';
@override
String get privacyEditNoText => '(no text)';
@override
String get studysetLockedTitle => 'Locked';