sgHardReset

This commit is contained in:
Kylmakalle 2025-03-23 00:45:26 +02:00
parent 0e29d0cf17
commit a3f000e896
5 changed files with 147 additions and 2 deletions

View File

@ -3,6 +3,7 @@ import Foundation
import SGLogging
private let dbResetKey = "sg_db_reset"
private let dbHardResetKey = "sg_db_hard_reset"
public func sgDBResetIfNeeded(databasePath: String, present: ((UIViewController) -> ())?) {
guard UserDefaults.standard.bool(forKey: dbResetKey) else {
@ -45,3 +46,117 @@ public func sgDBResetIfNeeded(databasePath: String, present: ((UIViewController)
// let semaphore = DispatchSemaphore(value: 0)
// semaphore.wait()
}
public func sgHardReset(dataPath: String, present: ((UIViewController) -> ())?) {
let startAlert = UIAlertController(
title: "ATTENTION",
message: "Confirm HARD RESET?",
preferredStyle: .alert
)
startAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
exit(0)
})
startAlert.addAction(UIAlertAction(title: "RESET", style: .destructive) { _ in
let ensureAlert = UIAlertController(
title: "⚠️ ATTENTION ⚠️",
message: "ARE YOU SURE you want to make a HARD RESET?",
preferredStyle: .alert
)
ensureAlert.addAction(UIAlertAction(title: "Cancel", style: .default) { _ in
exit(0)
})
ensureAlert.addAction(UIAlertAction(title: "RESET NOW", style: .destructive) { _ in
NSLog("[SG.DBReset] Hard reset with system settings")
let alert = UIAlertController(
title: "Hard reset.\nPlease wait...",
message: nil,
preferredStyle: .alert
)
ensureAlert.dismiss(animated: false) {
present?(alert)
}
do {
let fileManager = FileManager.default
let contents = try fileManager.contentsOfDirectory(atPath: dataPath)
// Filter directories that match our criteria
let accountDirectories = contents.compactMap { filename in
let fullPath = (dataPath as NSString).appendingPathComponent(filename)
var isDirectory: ObjCBool = false
if fileManager.fileExists(atPath: fullPath, isDirectory: &isDirectory), isDirectory.boolValue {
if filename.hasPrefix("account-") || filename == "accounts-metadata" {
return fullPath
}
}
return nil
}
NSLog("[SG.DBReset] Found \(accountDirectories.count) account dirs...")
var deletedPostboxCount = 0
for accountDir in accountDirectories {
let accountName = (accountDir as NSString).lastPathComponent
let postboxPath = (accountDir as NSString).appendingPathComponent("postbox")
var isPostboxDir: ObjCBool = false
if fileManager.fileExists(atPath: postboxPath, isDirectory: &isPostboxDir), isPostboxDir.boolValue {
// Delete postbox/db
let dbPath = (postboxPath as NSString).appendingPathComponent("db")
var isDbDir: ObjCBool = false
if fileManager.fileExists(atPath: dbPath, isDirectory: &isDbDir), isDbDir.boolValue {
NSLog("[SG.DBReset] Trying to delete postbox/db in: \(accountName)")
try fileManager.removeItem(atPath: dbPath)
NSLog("[SG.DBReset] OK. Deleted postbox/db directory in: \(accountName)")
}
// Delete postbox/media
let mediaPath = (postboxPath as NSString).appendingPathComponent("media")
var isMediaDir: ObjCBool = false
if fileManager.fileExists(atPath: mediaPath, isDirectory: &isMediaDir), isMediaDir.boolValue {
NSLog("[SG.DBReset] Trying to delete postbox/media in: \(accountName)")
try fileManager.removeItem(atPath: mediaPath)
NSLog("[SG.DBReset] OK. Deleted postbox/media directory in: \(accountName)")
}
deletedPostboxCount += 1
}
}
NSLog("[SG.DBReset] Done. Hard Reset completed")
let successAlert = UIAlertController(
title: "Hard reset completed",
message: nil,
preferredStyle: .alert
)
successAlert.addAction(UIAlertAction(title: "Restart App", style: .cancel) { _ in
exit(0)
})
alert.dismiss(animated: false) {
present?(successAlert)
}
} catch {
NSLog("[SG.DBReset] ERROR. Hard reset failed: \(error)")
let failAlert = UIAlertController(
title: "ERROR. Hard reset failed",
message: "\(error)",
preferredStyle: .alert
)
alert.dismiss(animated: false) {
present?(failAlert)
}
}
})
ensureAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
exit(0)
})
present?(ensureAlert)
})
present?(startAlert)
UserDefaults.standard.set(false, forKey: dbHardResetKey)
}

View File

@ -24,6 +24,24 @@
<key>DefaultValue</key>
<false/>
</dict>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>FooterText</key>
<string>HardReset.Notice</string>
<key>Title</key>
<string>HardReset.Title</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>HardReset.Toggle</string>
<key>Key</key>
<string>sg_db_hard_reset</string>
<key>DefaultValue</key>
<false/>
</dict>
</array>
</dict>
</plist>

View File

@ -1,5 +1,8 @@
/* A single strings file, whose title is specified in your preferences schema. The strings files provide the localized content to display to the user for each of your preferences. */
"Reset.Title" = "TROUBLESHOOTING";
"Reset.Toggle" = "Reset caches on next launch";
"Reset.Toggle" = "Reset metadata";
"Reset.Notice" = "Use in case you're stuck and can't open the app. This WILL NOT logout your accounts, but all secret chats will be lost.";
"HardReset.Title" = "";
"HardReset.Toggle" = "Reset all";
"HardReset.Notice" = "Clears metadata, cached messages and media for all accounts. This should not logout your accounts, but proceed at YOUR OWN RISK. All secret chats will be lost.";

View File

@ -1,3 +1,6 @@
"Reset.Title" = "РЕШЕНИЕ ПРОБЛЕМ";
"Reset.Toggle" = "Сбросить кэш при следующем запуске";
"Reset.Toggle" = "Сбросить метаданные";
"Reset.Notice" = "Используйте, если приложение вылетает или не загружается. Эта опция НЕ СБРАСЫВАЕТ ваши аккаунты, но удалит все секретные чаты.";
"HardReset.Title" = "";
"HardReset.Toggle" = "Сбросить всё";
"HardReset.Notice" = "Сбрасывает метаданные, кэшированные сообщения и медиа для всех аккаунтов. Эта опция не должна разлогинить ваши аккаунты, но используйте её на СВОЙ СТРАХ И РИСК. Все секретные чаты удалятся.";

View File

@ -605,6 +605,12 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
}
let rootPath = rootPathForBasePath(appGroupUrl.path)
// MARK: Swiftgram
if UserDefaults.standard.bool(forKey: "sg_db_hard_reset") {
self.window?.makeKeyAndVisible()
sgHardReset(dataPath: rootPath, present: self.mainWindow?.presentNative)
return true
}
performAppGroupUpgrades(appGroupPath: appGroupUrl.path, rootPath: rootPath)
let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId)