From 97052a8b1eb31bd48a1c96ec9d896031ce67e85b Mon Sep 17 00:00:00 2001
From: Arthur Norat <norat.arthur@gmail.com>
Date: Wed, 19 Mar 2025 18:15:17 -0300
Subject: [PATCH 1/2] Add kids mode toggle to settings view

---
 Podfile.lock                                  |   2 +-
 .../iOS/Settings.bundle/en.lproj/Root.strings |   3 +++
 .../Settings.bundle/pt-BR.lproj/Root.strings  | Bin 19596 -> 19808 bytes
 Sources/Headers/VLCConstants.h                |   2 ++
 Sources/Settings/Model/SettingsSection.swift  |   8 ++++++++
 5 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Podfile.lock b/Podfile.lock
index 30aed5be3..a195ec749 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -205,4 +205,4 @@ SPEC CHECKSUMS:
 
 PODFILE CHECKSUM: 65a7fa9ee482022fade614219df0522c6399aafe
 
-COCOAPODS: 1.15.2
+COCOAPODS: 1.16.2
diff --git a/Resources/iOS/Settings.bundle/en.lproj/Root.strings b/Resources/iOS/Settings.bundle/en.lproj/Root.strings
index 533c90bd7..1bfd2257b 100644
--- a/Resources/iOS/Settings.bundle/en.lproj/Root.strings
+++ b/Resources/iOS/Settings.bundle/en.lproj/Root.strings
@@ -171,3 +171,6 @@
 
 "SETTINGS_RESET" = "Reset the settings";
 "SETTINGS_RESET_TITLE" = "Reset";
+
+"SETTINGS_KIDSMODE_TOGGLE" = "Kids mode";
+"SETTINGS_KIDSMODE_SUBTITLE" = "Restrict some actions";
diff --git a/Resources/iOS/Settings.bundle/pt-BR.lproj/Root.strings b/Resources/iOS/Settings.bundle/pt-BR.lproj/Root.strings
index 38832c02ce9be7bc71aa79f05a889d12578ace9e..93da76f6f027c406f536653858cd266b370d51c0 100644
GIT binary patch
delta 162
zcmeB~$@pLv<Axre$qrItj@}HO3@!}8489EhK-!fdo*@LtatA^mAWw-wfx#Atm4Nd3
z3@JdYz>vw1$B@R52qa5@?3~FLnWg#BOqqO8NqF)H7A~_OhE#@Ppt>Tku5=(-1T-O$
cA%`KIp_CyP$SMZ&pEG;~t5jmJX5eA~0QyHEqyPW_

delta 9
QcmaDbi?L@W<Axp|02X}&DgXcg

diff --git a/Sources/Headers/VLCConstants.h b/Sources/Headers/VLCConstants.h
index c5d22a5b1..453e96286 100644
--- a/Sources/Headers/VLCConstants.h
+++ b/Sources/Headers/VLCConstants.h
@@ -185,6 +185,8 @@
 
 #define kVLCDonationAnonymousCustomerID @"kVLCDonationAnonymousCustomerID"
 
+#define kVLCSettingEnableKidsMode @"kVLCSettingEnableKidsMode"
+
 /* LEGACY KEYS, DO NOT USE IN NEW CODE */
 #define kVLCFTPServer @"ftp-server"
 #define kVLCFTPLogin @"ftp-login"
diff --git a/Sources/Settings/Model/SettingsSection.swift b/Sources/Settings/Model/SettingsSection.swift
index 5897ba3c2..4c210a700 100644
--- a/Sources/Settings/Model/SettingsSection.swift
+++ b/Sources/Settings/Model/SettingsSection.swift
@@ -175,6 +175,13 @@ enum MainOptions {
                      subtitle: Localizer.getSubtitle(for: k),
                      action: .showActionSheet(title: "SETTINGS_DARKTHEME", preferenceKey: k, hasInfo: false))
     }
+    
+    static var kidsMode: SettingsItem {
+        .init(title: "SETTINGS_KIDSMODE_TOGGLE",
+              subtitle: "SETTINGS_KIDSMODE_SUBTITLE",
+              action: .toggle(SettingsItem.Toggle(preferenceKey: kVLCSettingEnableKidsMode)),
+              isTitleEmphasized: false)
+    }
 
     static func section() -> SettingsSection? {
         var items = [privacy]
@@ -182,6 +189,7 @@ enum MainOptions {
         // visionOS uses a standard system appearance and doesn't have light/dark mode.
         items.append(appearance)
         #endif
+        items.append(kidsMode)
         return .init(title: nil, items: items)
     }
 }
-- 
GitLab


From ff83a3b3ddc98f281cb6cdb3c5a581b90420ab13 Mon Sep 17 00:00:00 2001
From: Arthur Norat <norat.arthur@gmail.com>
Date: Wed, 26 Mar 2025 17:35:53 -0300
Subject: [PATCH 2/2] Update toggle from Kids Mode to Parental Control and
 requires PIN to delete media and playlist item

---
 .../iOS/Settings.bundle/en.lproj/Root.strings |   4 +--
 .../Settings.bundle/pt-BR.lproj/Root.strings  | Bin 19808 -> 19980 bytes
 Sources/Headers/VLCConstants.h                |   2 +-
 .../Media Library/Editing/EditActions.swift   |  31 ++++++++++++++++--
 Sources/Settings/Model/SettingsSection.swift  |  11 +++----
 5 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/Resources/iOS/Settings.bundle/en.lproj/Root.strings b/Resources/iOS/Settings.bundle/en.lproj/Root.strings
index 1bfd2257b..3847352cd 100644
--- a/Resources/iOS/Settings.bundle/en.lproj/Root.strings
+++ b/Resources/iOS/Settings.bundle/en.lproj/Root.strings
@@ -172,5 +172,5 @@
 "SETTINGS_RESET" = "Reset the settings";
 "SETTINGS_RESET_TITLE" = "Reset";
 
-"SETTINGS_KIDSMODE_TOGGLE" = "Kids mode";
-"SETTINGS_KIDSMODE_SUBTITLE" = "Restrict some actions";
+"SETTINGS_PARENTAL_CONTROL_TOGGLE" = "Parental control";
+"SETTINGS_PARENTAL_CONTROL_SUBTITLE" = "When activated, files cannot be deleted or playlists modified without entering the pin";
diff --git a/Resources/iOS/Settings.bundle/pt-BR.lproj/Root.strings b/Resources/iOS/Settings.bundle/pt-BR.lproj/Root.strings
index 93da76f6f027c406f536653858cd266b370d51c0..20b42e7220179e85afce410df6c641bfd0b3c074 100644
GIT binary patch
delta 282
zcmaDbi?L@8<Ay~(lO4QSq=Oh-8T=SR7#taV7~&b68T`S#ARz5Cd83cy<U4#E;zbPk
z3^@#`3<?Y>Kvpr3E?`Jx$eeu9Q<fMr%mW!pf$H<Xx)p$|5{68MG9V2yO$TUNB0~{F
zAy5rS6k>iJ!()d0$<n&gIUsvWplU%j=K=Y-U>D>7MJs{s$^^Qo1njC@pzahPKMjbJ
i!Fm$G;>A!snLynjb`em%2xvw=*c_0k5`#4Z7XttSXFBBo

delta 138
zcmeB~!}wqp<Ay~({N4<n3@!}8489EhK-zWkK_5v;Uxs{!6d+b$$YjW4NMlF@k|jWP
z&g6^C(wI7wgeQMs;W7(iNM$Gnsw)EPN(YifKob%fav0JXN*Qv2tYR?#Im1`5N+kws
H1}+8wB{&~=

diff --git a/Sources/Headers/VLCConstants.h b/Sources/Headers/VLCConstants.h
index 453e96286..ebf2acc4d 100644
--- a/Sources/Headers/VLCConstants.h
+++ b/Sources/Headers/VLCConstants.h
@@ -185,7 +185,7 @@
 
 #define kVLCDonationAnonymousCustomerID @"kVLCDonationAnonymousCustomerID"
 
-#define kVLCSettingEnableKidsMode @"kVLCSettingEnableKidsMode"
+#define kVLCSettingParentalControl @"kVLCSettingParentalControl"
 
 /* LEGACY KEYS, DO NOT USE IN NEW CODE */
 #define kVLCFTPServer @"ftp-server"
diff --git a/Sources/Media Library/Editing/EditActions.swift b/Sources/Media Library/Editing/EditActions.swift
index 5fd1b8e53..cd4b99959 100644
--- a/Sources/Media Library/Editing/EditActions.swift	
+++ b/Sources/Media Library/Editing/EditActions.swift	
@@ -8,6 +8,8 @@
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
 
+import LocalAuthentication
+
 enum completionState {
     case inProgress
     case success
@@ -204,9 +206,21 @@ extension EditActions {
         let deleteButton = VLCAlertButton(title: NSLocalizedString("BUTTON_DELETE", comment: ""),
                                           style: .destructive,
                                           action: { [unowned self] action in
-            self.model.anyDelete(self.objects)
-            self.objects.removeAll()
-            self.completion?(.success)
+            if UserDefaults.standard.bool(forKey: kVLCSettingParentalControl) {
+                self.authenticateUser { success in
+                    if success {
+                        self.model.anyDelete(self.objects)
+                        self.objects.removeAll()
+                        self.completion?(.success)
+                    } else {
+                        self.completion?(.fail)
+                    }
+                }
+            } else {
+                self.model.anyDelete(self.objects)
+                self.objects.removeAll()
+                self.completion?(.success)
+            }
         })
 
         VLCAlertViewController.alertViewManager(title: title,
@@ -349,6 +363,17 @@ private extension EditActions {
         }
         return fileURLs
     }
+    
+    private func authenticateUser(completion: @escaping (Bool) -> Void) {
+        let coordinator = KeychainCoordinator.passcodeService
+        coordinator.validateSecret(
+            allowBiometricAuthentication: false, // no faceid for now
+            isCancellable: true
+        ) { success in
+            completion(success)
+        }
+    }
+
 
     // MARK: Media Groups
 
diff --git a/Sources/Settings/Model/SettingsSection.swift b/Sources/Settings/Model/SettingsSection.swift
index 4c210a700..a403d8261 100644
--- a/Sources/Settings/Model/SettingsSection.swift
+++ b/Sources/Settings/Model/SettingsSection.swift
@@ -176,11 +176,10 @@ enum MainOptions {
                      action: .showActionSheet(title: "SETTINGS_DARKTHEME", preferenceKey: k, hasInfo: false))
     }
     
-    static var kidsMode: SettingsItem {
-        .init(title: "SETTINGS_KIDSMODE_TOGGLE",
-              subtitle: "SETTINGS_KIDSMODE_SUBTITLE",
-              action: .toggle(SettingsItem.Toggle(preferenceKey: kVLCSettingEnableKidsMode)),
-              isTitleEmphasized: false)
+    static var parentalControl: SettingsItem {
+        .toggle(title: "SETTINGS_PARENTAL_CONTROL_TOGGLE",
+                subtitle: "SETTINGS_PARENTAL_CONTROL_SUBTITLE",
+                preferenceKey: kVLCSettingParentalControl)
     }
 
     static func section() -> SettingsSection? {
@@ -189,7 +188,7 @@ enum MainOptions {
         // visionOS uses a standard system appearance and doesn't have light/dark mode.
         items.append(appearance)
         #endif
-        items.append(kidsMode)
+        items.append(parentalControl)
         return .init(title: nil, items: items)
     }
 }
-- 
GitLab