From 1acf76b1a583119e3f1c44daca2e721443125e6d Mon Sep 17 00:00:00 2001
From: Robert Brands
Date: Fri, 22 Nov 2024 08:44:10 +0100
Subject: [PATCH] Incognito mode introduced (#146)
* Incognito mode for check-in: The name of the participant will not be displayed.
* Own name will be displayed in incognito mode
* Update news.md
* Update userguide.md
---------
Co-authored-by: Robert Brands (RiwaAdmin)
---
MeetUpFunctions/Constants.cs | 2 +-
.../MeetUpPlanner.Functions.csproj | 2 +-
MeetUpPlanner/Client/AppState.cs | 2 +
.../Client/MeetUpPlanner.Client.csproj | 2 +-
MeetUpPlanner/Client/Pages/About.razor | 8 ++--
MeetUpPlanner/Client/Pages/Calendar.razor | 40 ++++++++++---------
MeetUpPlanner/Client/Pages/Comment.razor | 2 +-
.../Client/Pages/Dataprotection.razor | 12 +++---
MeetUpPlanner/Client/Pages/Guests.razor | 16 +++++---
MeetUpPlanner/Client/Pages/Index.razor | 9 +++++
MeetUpPlanner/Client/Pages/Register.razor | 2 +
.../Client/Pages/RegisterOthers.razor | 7 +++-
MeetUpPlanner/Client/PermAppState.cs | 1 +
MeetUpPlanner/Client/Shared/MeetUp.razor | 6 ++-
MeetUpPlanner/Client/Shared/MeetUpCard.razor | 4 +-
.../Server/Controllers/UtilController.cs | 2 +-
.../Server/MeetUpPlanner.Server.csproj | 2 +-
MeetUpPlanner/Shared/ExtendedCalendarItem.cs | 21 +++++++---
MeetUpPlanner/Shared/Participant.cs | 2 +
docs/news.md | 4 ++
docs/userguide.md | 4 ++
21 files changed, 100 insertions(+), 50 deletions(-)
diff --git a/MeetUpFunctions/Constants.cs b/MeetUpFunctions/Constants.cs
index f7c4380..9226735 100644
--- a/MeetUpFunctions/Constants.cs
+++ b/MeetUpFunctions/Constants.cs
@@ -22,7 +22,7 @@ public static class Constants
public const string DEFAULT_DISCLAIMER = "Disclaimer";
public const string DEFAULT_GUEST_DISCLAIMER = "Guest Disclaimer";
- public const string VERSION = "2024-11-19";
+ public const string VERSION = "2024-11-21";
public const int ADMINOVERBOOKFACTOR = 1; // no overbooking any more, because not needed
public const int LOG_TTL = 30 * 24 * 3600; // 30 days TTL for Log items
diff --git a/MeetUpFunctions/MeetUpPlanner.Functions.csproj b/MeetUpFunctions/MeetUpPlanner.Functions.csproj
index c8e2297..94969a9 100644
--- a/MeetUpFunctions/MeetUpPlanner.Functions.csproj
+++ b/MeetUpFunctions/MeetUpPlanner.Functions.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/MeetUpPlanner/Client/AppState.cs b/MeetUpPlanner/Client/AppState.cs
index 47d1cb9..a72ebc9 100644
--- a/MeetUpPlanner/Client/AppState.cs
+++ b/MeetUpPlanner/Client/AppState.cs
@@ -58,6 +58,8 @@ public string DisplayName
public string PhoneMail { get; set; }
public Boolean NoAddressNeeded { get; set; } = false;
public bool SaveSettings { get; set; } = true;
+ // User prefers to hide his name in the list of participants of a meetup
+ public Boolean Incognito { get; set; } = false;
public ExtendedRoute RouteArg { get; set; }
public bool NotificationSubscriptionRequested { get; set; } = false;
diff --git a/MeetUpPlanner/Client/MeetUpPlanner.Client.csproj b/MeetUpPlanner/Client/MeetUpPlanner.Client.csproj
index 16f62a9..db9d49d 100644
--- a/MeetUpPlanner/Client/MeetUpPlanner.Client.csproj
+++ b/MeetUpPlanner/Client/MeetUpPlanner.Client.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/MeetUpPlanner/Client/Pages/About.razor b/MeetUpPlanner/Client/Pages/About.razor
index 28f26f1..9251745 100644
--- a/MeetUpPlanner/Client/Pages/About.razor
+++ b/MeetUpPlanner/Client/Pages/About.razor
@@ -8,7 +8,7 @@
- Diese kleine Anwendung habe ich ursprünglich in den "Corona"-Zeiten entwickelt, damit Radausfahrten so organisiert werden können, dass
+ Ursprünglich ist diese kleine Anwendung während der Covid-Pandemie entstanden, damit Radausfahrten so organisiert werden können, dass
die Teilnehmer sich registrieren können und alle Kontakte nachvollziehbar sind. Aber darüberhinaus hat sich der MeetUpPlanner als nützliches Tool
für die Verabredung von Ausfahrten oder anderen Aktivitäten bewährt.
@@ -23,12 +23,12 @@
Die Web-Anwendung ist "responsive", d.h. kann auf PC und SmartPhones mit allen modernen Browsern genutzt werden.
- Minimaler administrativer Aufwand: Alle Termine mit ihren Teilnehmern werden automatisch nach 4 Wochen gelöscht.
+ Minimaler administrativer Aufwand: Alle Termine mit ihren Teilnehmern werden automatisch nach einer konfigurierbaren Zeit gelöscht.
Es können "private" Termine erstellt werden. Normalerweise sind die Termine für alle, die das "Schlüsselwort" kennen, zugänglich und
einsehbar. Es ist aber auch möglich, Termine mit einem weiteren Schlüsselwort zu versehen, um den Termin nur für enge Freunde sichtbar
- und "buchbar" zu machen. Trotzdem bleibt die Nachverfolgbarkeit der Kontakte gegeben.
+ und "buchbar" zu machen.
Für die Anmeldung zu einem Termin/Ausfahrt ist die Angabe des Namens und der E-Mail-Adresse oder Telefonnummer notwendig. Diese Angaben
- werden ausschließlich zur Organisation der Termine benötigt (Einhaltung max. Teilnehmeranzahl) und für die Nachverfolgbarkeit im Falle
- einer Covid-19 Erkrankung. In diesem Fall können auf Anfrage alle Teilnehmer der letzten 4 Wochen, die mit der betreffenden Person im gleichen Termin
- waren, herausgegeben werden. Alle Termine werden ansonsten automatisch nach 4 Wochen gelöscht.
+ werden ausschließlich zur Organisation der Termine benötigt (Einhaltung max. Teilnehmeranzahl), ggf. für Rückfragen oder der Kontaktaufnahme nach Unfällen. Dazu werden
+ die Teilnehmerdaten für eine konfigurierbaren Zeitraum (max. 4 Wochen) gespeichert. Alle Termine mit Teilnehmerdaten werden ansonsten automatisch nach dem konfigurierten Zeitraum vollständig gelöscht.
Ansonsten erfolgt keine Verwendung oder Weitergabe der Daten.
Cookies
- Die Internetseiten verwenden teilweise so genannte Cookies. Cookies richten auf deinem Rechner keinen Schaden an und
+ Die Internetseiten verwenden teilweise sog.Cookies. Cookies richten auf deinem Rechner keinen Schaden an und
enthalten keine Viren. Cookies dienen dazu, unser Angebot nutzerfreundlicher, effektiver und sicherer zu machen.
Cookies sind kleine Textdateien, die auf deinem Rechner abgelegt werden und die dein Browser speichert.
@@ -25,8 +24,9 @@
automatisch gelöscht.
- Au0erdem kannst du bei der Eingabe des Namens und der Tel.-Nr/E-Mail-Adresse angeben, dass diese Angaben im Browser gespeichert werden.
- Das erspart die Eingabe beim nächsten Mal. Die Speicherung dieser Eingabehilfe erfolgt ausschließlich im Browser.
+ Außerdem kannst du bei der Eingabe des Namens und der Tel.-Nr/E-Mail-Adresse angeben, dass diese Angaben im Browser gespeichert werden.
+ Das erspart die Eingabe beim nächsten Mal. Die Speicherung dieser Eingabehilfe erfolgt ausschließlich im Browser. Erst bei der Anmeldung zu einem Termin werden deine
+ Kontaktdaten übertragen.
}
@@ -122,6 +122,7 @@
AppStateStore.FirstName = _guest.ParticipantFirstName;
AppStateStore.LastName = _guest.ParticipantLastName;
AppStateStore.PhoneMail = _guest.ParticipantAdressInfo;
+ AppStateStore.Incognito = _guest.IsIncognito;
if (AppStateStore.SaveSettings)
{
// Copy from app state to permanent storage
@@ -130,6 +131,7 @@
_permAppState.LastName = _guest.ParticipantLastName;
_permAppState.PhoneMail = _guest.ParticipantAdressInfo;
_permAppState.NoAddressNeeded = AppStateStore.NoAddressNeeded;
+ _permAppState.Incognito = _guest.IsIncognito;
await LocalStorage.SetItemAsync(PERM_STORAGE, _permAppState);
}
else
@@ -151,6 +153,7 @@
_guest.ParticipantFirstName = _permAppState.FirstName;
_guest.ParticipantLastName = _permAppState.LastName;
_guest.ParticipantAdressInfo = _permAppState.PhoneMail;
+ _guest.IsIncognito = _permAppState.Incognito;
AppStateStore.NoAddressNeeded = _permAppState.NoAddressNeeded;
// If someone has stored the settings before the disclaimer has already been accepted by user
UsageRightsAccepted = true;
@@ -252,6 +255,7 @@
_permAppState.FirstName = _guest.ParticipantFirstName;
_permAppState.LastName = _guest.ParticipantLastName;
_permAppState.PhoneMail = _guest.ParticipantAdressInfo;
+ _permAppState.Incognito = _guest.IsIncognito;
await LocalStorage.SetItemAsync(PERM_STORAGE, _permAppState);
}
else
diff --git a/MeetUpPlanner/Client/Pages/Index.razor b/MeetUpPlanner/Client/Pages/Index.razor
index 99c13db..05b03dc 100644
--- a/MeetUpPlanner/Client/Pages/Index.razor
+++ b/MeetUpPlanner/Client/Pages/Index.razor
@@ -73,6 +73,13 @@
Für die Nachverfolgbarkeit hier bitte deine Mail-Adresse oder Telefonnummer eingeben. Diese Info wird nicht in der allgemeinen Teilnehmerliste zu Ausfahrten angezeigt.
+
+
+
+
+
+ Dein Name wird in den Anmeldelisten der Termine nicht angezeigt. Du kannst dann allerdings auch nicht die Namen der anderen sehen für Termine, zu denen du inkognito angemeldet bist.
+
@@ -127,6 +134,7 @@
AppStateStore.PrivateKeyWord2 = permAppState.PrivateKeyWord2;
AppStateStore.PrivateKeyWord3 = permAppState.PrivateKeyWord3;
AppStateStore.NoAddressNeeded = permAppState.NoAddressNeeded;
+ AppStateStore.Incognito = permAppState.Incognito;
// If someone has stored the settings before the disclaimer has already been accepted by user
UsageRightsAccepted = true;
}
@@ -218,6 +226,7 @@
permAppState.PrivateKeyWord2 = AppStateStore.PrivateKeyWord2;
permAppState.PrivateKeyWord3 = AppStateStore.PrivateKeyWord3;
permAppState.NoAddressNeeded = AppStateStore.NoAddressNeeded;
+ permAppState.Incognito = AppStateStore.Incognito;
await localStorage.SetItemAsync("permAppState", permAppState);
}
else
diff --git a/MeetUpPlanner/Client/Pages/Register.razor b/MeetUpPlanner/Client/Pages/Register.razor
index 29ed720..12ad30b 100644
--- a/MeetUpPlanner/Client/Pages/Register.razor
+++ b/MeetUpPlanner/Client/Pages/Register.razor
@@ -91,6 +91,7 @@
_guest.ParticipantFirstName = permAppState.FirstName;
_guest.ParticipantLastName = permAppState.LastName;
_guest.ParticipantAdressInfo = permAppState.PhoneMail;
+ _guest.IsIncognito = permAppState.Incognito;
}
// Get client settings from server
PrepareHttpClient();
@@ -138,6 +139,7 @@
permAppState.FirstName = _guest.ParticipantFirstName;
permAppState.LastName = _guest.ParticipantLastName;
permAppState.PhoneMail = _guest.ParticipantAdressInfo;
+ permAppState.Incognito = _guest.IsIncognito;
await LocalStorage.SetItemAsync(PERM_STORAGE, permAppState);
}
else
diff --git a/MeetUpPlanner/Client/Pages/RegisterOthers.razor b/MeetUpPlanner/Client/Pages/RegisterOthers.razor
index 5359ec0..4bff066 100644
--- a/MeetUpPlanner/Client/Pages/RegisterOthers.razor
+++ b/MeetUpPlanner/Client/Pages/RegisterOthers.razor
@@ -7,7 +7,12 @@
@inject NotificationService notificationService
@using Newtonsoft.Json
-
+
diff --git a/MeetUpPlanner/Client/PermAppState.cs b/MeetUpPlanner/Client/PermAppState.cs
index 517439e..7871f2b 100644
--- a/MeetUpPlanner/Client/PermAppState.cs
+++ b/MeetUpPlanner/Client/PermAppState.cs
@@ -18,6 +18,7 @@ public class PermAppState
public string LastName { get; set; }
public string PhoneMail { get; set; }
public Boolean NoAddressNeeded { get; set; }
+ public Boolean Incognito { get; set; }
}
}
diff --git a/MeetUpPlanner/Client/Shared/MeetUp.razor b/MeetUpPlanner/Client/Shared/MeetUp.razor
index 7156602..9ec7d67 100644
--- a/MeetUpPlanner/Client/Shared/MeetUp.razor
+++ b/MeetUpPlanner/Client/Shared/MeetUp.razor
@@ -30,7 +30,7 @@
{
Min @CalendarItem.MinRegistrationsCount
}
- : @CalendarItem.HostDisplayName(NameDisplayLength)@((MarkupString)CalendarItem.ParticipantsDisplay(NameDisplayLength))
+ : @CalendarItem.HostDisplayName(NameDisplayLength)@((MarkupString)CalendarItem.ParticipantsDisplay(NameDisplayLength, FirstName, LastName))
}
else
{
@@ -58,4 +58,8 @@
public String AdditionalText { get; set; } = null;
[Parameter]
public int NameDisplayLength { get; set; } = 1;
+ [Parameter]
+ public String FirstName { get; set; } = "";
+ [Parameter]
+ public String LastName { get; set; } = "";
}
diff --git a/MeetUpPlanner/Client/Shared/MeetUpCard.razor b/MeetUpPlanner/Client/Shared/MeetUpCard.razor
index 43109d6..ec31049 100644
--- a/MeetUpPlanner/Client/Shared/MeetUpCard.razor
+++ b/MeetUpPlanner/Client/Shared/MeetUpCard.razor
@@ -84,11 +84,11 @@
{
Min @CalendarItem.MinRegistrationsCount
}
- : @CalendarItem.HostDisplayName(AppStateStore.ClientSettings.NameDisplayLength)@CalendarItem.ParticipantsDisplay(AppStateStore.ClientSettings.NameDisplayLength)
+ : @CalendarItem.HostDisplayName(AppStateStore.ClientSettings.NameDisplayLength)@CalendarItem.ParticipantsDisplay(AppStateStore.ClientSettings.NameDisplayLength, AppStateStore.FirstName, AppStateStore.LastName)
@if (0 < CalendarItem.WaitingListCounter)
{
- Warteliste (@CalendarItem.WaitingListCounter von @CalendarItem.MaxWaitingList): @CalendarItem.WaitingListDisplay(AppStateStore.ClientSettings.NameDisplayLength)
+ Warteliste (@CalendarItem.WaitingListCounter von @CalendarItem.MaxWaitingList): @CalendarItem.WaitingListDisplay(AppStateStore.ClientSettings.NameDisplayLength, AppStateStore.FirstName, AppStateStore.LastName)
}
}
else
diff --git a/MeetUpPlanner/Server/Controllers/UtilController.cs b/MeetUpPlanner/Server/Controllers/UtilController.cs
index 51751b2..9fc0d60 100644
--- a/MeetUpPlanner/Server/Controllers/UtilController.cs
+++ b/MeetUpPlanner/Server/Controllers/UtilController.cs
@@ -20,7 +20,7 @@ public class UtilController : ControllerBase
{
private readonly MeetUpFunctions _meetUpFunctions;
private readonly ILogger logger;
- const string serverVersion = "2024-11-19";
+ const string serverVersion = "2024-11-21";
string functionsVersion = "tbd";
public UtilController(ILogger logger, MeetUpFunctions meetUpFunctions)
diff --git a/MeetUpPlanner/Server/MeetUpPlanner.Server.csproj b/MeetUpPlanner/Server/MeetUpPlanner.Server.csproj
index f5d1b4f..cc2f757 100644
--- a/MeetUpPlanner/Server/MeetUpPlanner.Server.csproj
+++ b/MeetUpPlanner/Server/MeetUpPlanner.Server.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/MeetUpPlanner/Shared/ExtendedCalendarItem.cs b/MeetUpPlanner/Shared/ExtendedCalendarItem.cs
index f66d1ed..fc4ca49 100644
--- a/MeetUpPlanner/Shared/ExtendedCalendarItem.cs
+++ b/MeetUpPlanner/Shared/ExtendedCalendarItem.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
@@ -66,14 +67,16 @@ public ExtendedCalendarItem(CalendarItem calendarItem)
}
- public string ParticipantsDisplay(int nameDisplayLength)
+ public string ParticipantsDisplay(int nameDisplayLength, string firstName, string lastName)
{
StringBuilder sb = new StringBuilder(100);
int counter = WithoutHost ? 0 : 1;
int coGuideCounter = 0;
+ bool isCheckedInAsIncognito = IsCheckedInAsIncognito(firstName, lastName);
foreach (Participant participant in this.ParticipantsList)
{
if (participant.IsCoGuide) coGuideCounter++;
+ Boolean isOwnName = participant.ParticipantFirstName.Equals(firstName) && participant.ParticipantLastName.Equals(lastName);
if (!participant.IsWaiting)
{
if (counter > 0)
@@ -84,7 +87,7 @@ public string ParticipantsDisplay(int nameDisplayLength)
{
sb.Append("");
}
- sb.Append(participant.ParticipantDisplayName(nameDisplayLength));
+ sb.Append((isCheckedInAsIncognito && !isOwnName) ? "Inkognito" : participant.ParticipantDisplayName(nameDisplayLength));
if (participant.IsCoGuide && coGuideCounter <= this.MaxCoGuidesCount)
{
sb.Append("(Co-Guide)");
@@ -94,19 +97,21 @@ public string ParticipantsDisplay(int nameDisplayLength)
}
return sb.ToString();
}
- public string WaitingListDisplay(int nameDisplayLength)
+ public string WaitingListDisplay(int nameDisplayLength, string firstName, string lastName)
{
StringBuilder sb = new StringBuilder(100);
int counter = 0;
+ bool isCheckedInAsIncognito = IsCheckedInAsIncognito(firstName, lastName);
foreach (Participant participant in this.ParticipantsList)
{
+ Boolean isOwnName = participant.ParticipantFirstName.Equals(firstName) && participant.ParticipantLastName.Equals(lastName);
if (participant.IsWaiting)
{
if (counter > 0)
{
sb.Append(", ");
}
- sb.Append(participant.ParticipantDisplayName(nameDisplayLength));
+ sb.Append((isCheckedInAsIncognito && !isOwnName) ? "Inkognito" : participant.ParticipantDisplayName(nameDisplayLength));
++counter;
}
}
@@ -219,6 +224,12 @@ public Participant FindParticipant(string firstName, string lastName)
}
return participant;
}
+ public Boolean IsCheckedInAsIncognito(string firstName, string lastName)
+ {
+ Participant participant = FindParticipant(firstName, lastName);
+ Boolean result = (null != participant && participant.IsIncognito);
+ return result;
+ }
}
}
diff --git a/MeetUpPlanner/Shared/Participant.cs b/MeetUpPlanner/Shared/Participant.cs
index 6d1bf06..24e3a74 100644
--- a/MeetUpPlanner/Shared/Participant.cs
+++ b/MeetUpPlanner/Shared/Participant.cs
@@ -24,6 +24,8 @@ public class Participant : CosmosDBEntity
public DateTime CheckInDate { get; set; }
[JsonProperty(PropertyName = "isGuest")]
public Boolean IsGuest { get; set; } = false;
+ [JsonProperty(PropertyName = "isIncognito")]
+ public Boolean IsIncognito { get; set; } = false;
[JsonProperty(PropertyName = "isWaiting")]
public Boolean IsWaiting { get; set; } = false;
[JsonProperty(PropertyName = "isCoGuide")]
diff --git a/docs/news.md b/docs/news.md
index 07aea63..240d1a2 100644
--- a/docs/news.md
+++ b/docs/news.md
@@ -1,5 +1,9 @@
[https://www.meetupplanner.de](https://www.meetupplanner.de)
# Änderungshistorie zum MeetUpPlanner
+*21.11.2024*
+- Einführung des "Inkognitomodus" - man kann sich optional jetzt auch "inkognito" zu Terminen anmelden, d.h. der eigene Name wird in den Anmeldelisten nicht angezeigt. Genauere Beschreibung siehe Userguide.
+- Bugfixing diverser Serialisieungsfehler: "Akkordion"-Anhänge zu Terminen können jetzt wieder editiert werden, Kennzeichnung von Anmeldungen aus dem befreundeten Club.
+
*19.11.2024*
- Aktualisierung aller Komponenten (Blazor-Frontend, Web-Server Middle-Tier und Azure Functions) auf .NET 8 LTS, d.h. supported bis Mai 2026
- Auf der Startseite wird klarer gemacht, dass die Kontaktdaten erst bei der Anmeldung zu einer Ausfahrt gespeichert werden, bis dahin nur lokal im Browser
diff --git a/docs/userguide.md b/docs/userguide.md
index 2dcbf7e..a6629c0 100644
--- a/docs/userguide.md
+++ b/docs/userguide.md
@@ -7,6 +7,10 @@ Hier sollen die etwas versteckteren Features beschrieben werden.
## Features für alle Benutzer:innen
+
Inkognitomodus
+
+
Auf dem Startbildschirm direkt unter der Angabe der Kontaktdaten kann man den Inkognitomodus aktivieren. Wenn man sich dann für einen Termin anmeldet, wird der eigene Name in der Anmeldeliste nicht angezeigt, sondern durch "Inkognito" ersetzt. Man selbst sieht den eigenen Namen in der Anmeldeliste, alle anderen Namen werden unterdrückt, nach dem Motto: Wer anonym bleiben möchte, sollte dann auch nicht die Infos über die anderen erhalten. Der Name der Guides (auch Co-Guides) bleibt immer sichtbar. Außerdem kann der Organisator eines Termins die Namen sehen.
+
Preview An/Aus
Wenn man eine Ausfahrt erstellt und dabei einen Link zur Strecke hinzufügt - z.B. Komoot - kann man jetzt über den Button "Preview An/Aus" eine Preview für den Link abrufen. Dies funktioniert ähnlich wie bei Facebook, Twitter & Co: Die Webseite wird abgerufen und Informationen wie Titel, Beschreibung und Bild ausgelesen. Das Bild wird dann in der Ausfahrt oben dargestellt. Bei Komoot ist das z.B. typischerweise eine Kartenübersicht. Aber nicht immer: Hat man in der Komoot-Strecke ein oder mehrere "Highlights" aufgenomnmnen und sind diese mit Fotos angereichert, so wird als Bild für den Link das erste Foto und nicht die Karte verwendet. Da hilft nur auf Highlights in der Planung zu verzichten (so mache ich es sowieso) oder später hinzuzufügen.