Move SSD download file selection to typed Kotlin

ober

05cdee55fd19dcc8ab2e63f4d80e620885bffe03

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index e739edf..2062fc6 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -3867,11 +3867,12 @@
                       (json-object-opt-json-array root "groups")))))))))
 
     (typed-kotlin-file "com/sfb/ssdreview/UiTextHelpers.kt"
+      (kotlin-imports (java io File))
       (typed-library (com sfb ssdreview)
         (export normalizeFiringArc normalizeLabel shouldReplaceGuessLabel
                 shouldReplaceBoxTypeLabel resolvedBoxTypeLabel
                 boxTypeFallbackName boxTypeLabelMatches defaultBoxTypeLabel
-                isGenericGuessLabel isSsdPdfName
+                isGenericGuessLabel isSsdPdfName shouldIncludeSsdPdfFile
                 sourceBaseName canonicalSourceName isUsefulGuessLabel isErrorStatus
                 formatActivityDuration groupDisplayLabel appendModeStatus
                 selectedGroupStatus sessionCountsStatus rotatedPageStatus
@@ -3932,6 +3933,11 @@
                 touchPointerOuterRadius touchPointerInnerRadius hitGroupPad)
         (type Int32)
         (type Float32)
+        (type File)
+        (extern (fileIsFile (file : File)) : Bool
+          (kotlin-member-get isFile))
+        (extern (fileName (file : File)) : String
+          (kotlin-member-get name))
         (extern (androidColorRgb (red : Int32)
                                  (green : Int32)
                                  (blue : Int32)) : Int32
@@ -4021,6 +4027,12 @@
           (let ((lower (string-lowercase name)))
             (and (string-ends-with? lower ".pdf")
                  (string-contains? lower "ssd"))))
+        (def (shouldIncludeSsdPdfFile (file : File)
+                                      (currentChoices : Int32)
+                                      (limit : Int32)) : Bool
+          (and (< currentChoices limit)
+               (and (fileIsFile file)
+                    (isSsdPdfName (fileName file)))))
         (def (sourceBaseName (value : String)) : String
           (string-lowercase
             (string-replace-regex
@@ -6597,11 +6609,11 @@
        "        try {"
        "            dir.walkTopDown()"
        "                .maxDepth(MAX_SSD_PDF_SCAN_DEPTH)"
-       "                .filter { it.isFile && isSsdPdfName(it.name) }"
-       "                .take(MAX_SSD_PDF_CHOICES)"
        "                .forEach { file ->"
-       "                    val label = ssdPdfDownloadFileLabel(file.relativeToOrSelf(dir).path)"
-       "                    choices.add(SsdPdfChoice(label, Uri.fromFile(file)))"
+       "                    if (shouldIncludeSsdPdfFile(file, choices.size, MAX_SSD_PDF_CHOICES)) {"
+       "                        val label = ssdPdfDownloadFileLabel(file.relativeToOrSelf(dir).path)"
+       "                        choices.add(SsdPdfChoice(label, Uri.fromFile(file)))"
+       "                    }"
        "                }"
        "        } catch (_: Exception) {"
        "        }"