Repository: streetcomplete/StreetComplete (language: kotlin)

Issue:
#surveyme in last Note comment should show the Note (even if there are no preceding comments)
Back in https://github.com/streetcomplete/StreetComplete/issues/2641 (via https://github.com/streetcomplete/StreetComplete/commit/b3ad39b2130dabdf0db2132dabeb3eaaa2ad48c4), it was made that `#surveyme` tag in the last comment would always (unless manually hidden by the user) result in showing the OSM Note, even if that comment was created by the same user which is using the app.

In SC 60.0 it works *mostly*,  i.e. if that comment is any ***but*** the first one.

I don't think that is intentional (I see no logic for that, nor do the comments seem to indicate the reason for such strange behaviour). 
If the user's **last comment** contains a marker indicating the survey is required and we want to display the note in that case (as we do), then it **_should not matter how many comments preceded that last one_** (0 or more).

**How to Reproduce**
1) add a comment to existing note with just text `test`; and note gets hidden - OK
2) add a comment to existing note with text `#surveyme test`; and note remains displayed - OK
3) create a new note with text `#surveyme test` -- note gets hidden - BAD

**Expected Behavior**
- in step (3), note should remain displayed just as in does in (2), as the last message indicates the survey is required.

**Versions affected**
SC 60.0, Android 14


Discussion hints:
This behaviour is coordinated by

https://github.com/streetcomplete/StreetComplete/blob/45a51eb3260babab935c1a56e7e23c4679be581a/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestController.kt#L191-L223

more specifically

https://github.com/streetcomplete/StreetComplete/blob/45a51eb3260babab935c1a56e7e23c4679be581a/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestController.kt#L207

This hides a note that is created from (a) within SC, (b) by yourself and (c) has no replies, just like your test (3), no matter if #surveyme is contained or not.

A note I created via osm.org and downloaded the data in SC after that correctly shows the note, even though #surveyme is the first comment:

![image](https://github.com/user-attachments/assets/80b67d33-3606-4f6a-8577-ca70c496b664)

So, it would need to be discussed, whether the exclusion of notes from oneself within the app without replies should be hidden no matter what, or, if surveyme should "override" that behaviour.
IMHO, I can live with the behaviour as is.
Thanks for the investigation!
I'd agree that the current behavior is as intended. The reason is stated in the comment:

newly created notes by user should not be shown if it was both created in this app and has no replies yet
> So, it would need to be discussed, whether the exclusion of notes from oneself within the app without replies should be hidden no matter what, or, if surveyme should "override" that behaviour.

I see no reason why we should exclude them? `#surveyme` (especially if it has no following comments) clearly indicates that on-site survey is needed (And since the note was left in SC, also indicates that it cannot be surveyed on the ground **at that moment**, e.g. because being outside of opening hours or other limitations).

Original note creator can do that on-ground survey as well as any other on-the ground mapper (and probably better, as they obviously have active interest in that being solved, or they wouldn't create the note in the first place).

> newly created notes by user should not be shown if it was both created in this app and has no replies yet

Yes, but that is pre-surveyme behaviour, and should be overriden by `#surveyme`?
 
Same as we regularly don't show the note if it was last commented by current user -- but that check ***is*** currently being overriden by `#surveyme` (and the same logic why it is overriden in case when it is second or third comment, should apply when it is a first comment).
Hmm, okay, but if `#surveyme` in the starter post when posted by yourself in this app should not lead to it being hidden for you, it means that if you create a note with this text, immediately a quest pin will appear that asks you if you can contribute anything to that note. Usually, when one writes a note, it isn't immediately visible again for the user that created it.

Pull request: OsmNoteQuestController: surveyme override and regex test update
Resolves #6052.

* Restructured exclusion of notes that get overridden by #surveyme
* Added RegexOption.DOT_MATCHES_ALL to function NoteComment.containsSurveyRequiredMarker: #surveyme wasn't found at the end of the text added by the user, because SC add "\n\nvia StreetComplete <x.y>" to the text

Test command: ./gradlew :app:testDebugUnitTest --tests "de.westnordost.streetcomplete.data.osmnotes.notequests.OsmNoteQuestControllerTest"

Fix patch:
diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestController.kt b/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestController.kt
index ad4fadbd8c7..4894f5b6b80 100644
--- a/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestController.kt
+++ b/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestController.kt
@@ -196,16 +196,22 @@ private fun Note.shouldShowAsQuest(
     // don't show notes hidden by user
     if (id in blockedNoteIds) return false
 
-    // don't show notes where user replied last unless he wrote a survey required marker
-    if (comments.last().isReplyFromUser(userId)
+    /*
+        We usually don't show notes where either the user is the last responder, or the
+        note was created with the app and has no replies.
+        If the most recent comment contains "#surveyme", we want to show the note regardless.
+        See https://github.com/streetcomplete/StreetComplete/issues/6052#issuecomment-2567163451
+     */
+    if (
+        (
+            comments.last().isReplyFromUser(userId) ||
+            (probablyCreatedByUserInThisApp(userId) && !hasReplies)
+        )
         && !comments.last().containsSurveyRequiredMarker()
     ) {
         return false
     }
 
-    // newly created notes by user should not be shown if it was both created in this app and has no replies yet
-    if (probablyCreatedByUserInThisApp(userId) && !hasReplies) return false
-
     /*
         many notes are created to report problems on the map that cannot be resolved
         through an on-site survey.
@@ -250,7 +256,7 @@ private fun Note.containsSurveyRequiredMarker(): Boolean =
     comments.any { it.containsSurveyRequiredMarker() }
 
 private fun NoteComment.containsSurveyRequiredMarker(): Boolean =
-    text?.matches(".*#surveyme.*".toRegex()) == true
+    text?.contains("#surveyme", ignoreCase = true) == true
 
 private fun Note.probablyCreatedByUserInThisApp(userId: Long): Boolean {
     val firstComment = comments.first()


Test patch:
diff --git a/app/src/test/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestControllerTest.kt b/app/src/test/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestControllerTest.kt
index 5b347b3a33a..9200a73b9d3 100644
--- a/app/src/test/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestControllerTest.kt
+++ b/app/src/test/java/de/westnordost/streetcomplete/data/osmnotes/notequests/OsmNoteQuestControllerTest.kt
@@ -175,6 +175,33 @@ class OsmNoteQuestControllerTest {
         assertNotNull(ctrl.getVisible(1))
     }
 
+    @Test fun `get note quest created in app without comments and without survey required marker returns null`() {
+        on(noteSource.get(1)).thenReturn(note(comments = listOf(
+            comment(text = "this is a non-question test note\n\nCreated via StreetComplete 60.1", user = User(id = 100, "Blaubär")),
+        )))
+        on(userDataSource.userId).thenReturn(1)
+
+        assertNull(ctrl.getVisible(1))
+    }
+
+    @Test fun `get note quest created in app without comments and with survey required marker returns non-null`() {
+        on(noteSource.get(1)).thenReturn(note(comments = listOf(
+            comment(text = "this is a non-question test note #surveyme\n\nCreated via StreetComplete 60.1", user = User(id = 100, "Blaubär")),
+        )))
+        on(userDataSource.userId).thenReturn(1)
+
+        assertNotNull(ctrl.getVisible(1))
+    }
+
+    @Test fun `get note quest created in app without comments and with survey required marker (ignore case) returns non-null`() {
+        on(noteSource.get(1)).thenReturn(note(comments = listOf(
+            comment(text = "this is a non-question test note #SurVEyMe\n\nCreated via StreetComplete 60.1", user = User(id = 100, "Blaubär")),
+        )))
+        on(userDataSource.userId).thenReturn(1)
+
+        assertNotNull(ctrl.getVisible(1))
+    }
+
     @Test fun `get quest not phrased as question returns null`() {
         on(noteSource.get(1)).thenReturn(note(comments = listOf(
             comment(text = "test")