Fix ShowRepostToStory in system share sheet

This commit is contained in:
Kylmakalle 2025-07-10 17:07:03 +03:00
parent 2ddba21088
commit c24962bd60
10 changed files with 113 additions and 64 deletions

View File

@ -1,6 +1,6 @@
import Foundation import Foundation
let fallbackBaseBundleId: String = "app.swiftgram.ios" public let FALLBACK_BASE_BUNDLE_ID: String = "app.swiftgram.ios"
public func sgAppGroupIdentifier() -> String { public func sgAppGroupIdentifier() -> String {
let baseBundleId: String let baseBundleId: String
@ -9,13 +9,13 @@ public func sgAppGroupIdentifier() -> String {
if let lastDotRange: Range<String.Index> = bundleId.range(of: ".", options: [.backwards]) { if let lastDotRange: Range<String.Index> = bundleId.range(of: ".", options: [.backwards]) {
baseBundleId = String(bundleId[..<lastDotRange.lowerBound]) baseBundleId = String(bundleId[..<lastDotRange.lowerBound])
} else { } else {
baseBundleId = fallbackBaseBundleId baseBundleId = FALLBACK_BASE_BUNDLE_ID
} }
} else { } else {
baseBundleId = bundleId baseBundleId = bundleId
} }
} else { } else {
baseBundleId = fallbackBaseBundleId baseBundleId = FALLBACK_BASE_BUNDLE_ID
} }
let result: String = "group.\(baseBundleId)" let result: String = "group.\(baseBundleId)"

View File

@ -12,14 +12,14 @@ private func rootPathForBasePath(_ appGroupPath: String) -> String {
return appGroupPath + "/telegram-data" return appGroupPath + "/telegram-data"
} }
public final class SGLogger { public class SGLogger {
private let queue = Queue(name: "app.swiftgram.ios.log", qos: .utility) public let queue = Queue(name: "app.swiftgram.ios.log", qos: .utility)
private let maxLength: Int = 2 * 1024 * 1024 private let maxLength: Int = 2 * 1024 * 1024
private let maxShortLength: Int = 1 * 1024 * 1024 private let maxShortLength: Int = 1 * 1024 * 1024
private let maxFiles: Int = 20 private let maxFiles: Int = 20
private let rootPath: String public let rootPath: String
private let basePath: String public let basePath: String
private var file: (ManagedFile, Int)? private var file: (ManagedFile, Int)?
private var shortFile: (ManagedFile, Int)? private var shortFile: (ManagedFile, Int)?
@ -66,59 +66,6 @@ public final class SGLogger {
self.basePath = basePath self.basePath = basePath
} }
public func collectLogs(prefix: String? = nil) -> Signal<[(String, String)], NoError> {
return Signal { subscriber in
self.queue.async {
let logsPath: String
if let prefix = prefix {
logsPath = self.rootPath + prefix
} else {
logsPath = self.basePath
}
var result: [(Date, String, String)] = []
if let files = try? FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: logsPath), includingPropertiesForKeys: [URLResourceKey.creationDateKey], options: []) {
for url in files {
if url.lastPathComponent.hasPrefix("log-") {
if let creationDate = (try? url.resourceValues(forKeys: Set([.creationDateKey])))?.creationDate {
result.append((creationDate, url.lastPathComponent, url.path))
}
}
}
}
result.sort(by: { $0.0 < $1.0 })
subscriber.putNext(result.map { ($0.1, $0.2) })
subscriber.putCompletion()
}
return EmptyDisposable
}
}
public func collectLogs(basePath: String) -> Signal<[(String, String)], NoError> {
return Signal { subscriber in
self.queue.async {
let logsPath: String = basePath
var result: [(Date, String, String)] = []
if let files = try? FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: logsPath), includingPropertiesForKeys: [URLResourceKey.creationDateKey], options: []) {
for url in files {
if url.lastPathComponent.hasPrefix("log-") {
if let creationDate = (try? url.resourceValues(forKeys: Set([.creationDateKey])))?.creationDate {
result.append((creationDate, url.lastPathComponent, url.path))
}
}
}
}
result.sort(by: { $0.0 < $1.0 })
subscriber.putNext(result.map { ($0.1, $0.2) })
subscriber.putCompletion()
}
return EmptyDisposable
}
}
public func log(_ tag: String, _ what: @autoclosure () -> String) { public func log(_ tag: String, _ what: @autoclosure () -> String) {
if !self.logToFile && !self.logToConsole { if !self.logToFile && !self.logToConsole {
return return

View File

@ -0,0 +1,19 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "SGLoggingComposer",
module_name = "SGLoggingComposer",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//Swiftgram/SGLogging:SGLogging",
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
],
visibility = [
"//visibility:public",
],
)

View File

@ -0,0 +1,59 @@
import Foundation
import SGLogging
import SwiftSignalKit
extension SGLogger {
public func collectLogs(prefix: String? = nil) -> Signal<[(String, String)], NoError> {
return Signal { subscriber in
self.queue.async {
let logsPath: String
if let prefix = prefix {
logsPath = self.rootPath + prefix
} else {
logsPath = self.basePath
}
var result: [(Date, String, String)] = []
if let files = try? FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: logsPath), includingPropertiesForKeys: [URLResourceKey.creationDateKey], options: []) {
for url in files {
if url.lastPathComponent.hasPrefix("log-") {
if let creationDate = (try? url.resourceValues(forKeys: Set([.creationDateKey])))?.creationDate {
result.append((creationDate, url.lastPathComponent, url.path))
}
}
}
}
result.sort(by: { $0.0 < $1.0 })
subscriber.putNext(result.map { ($0.1, $0.2) })
subscriber.putCompletion()
}
return EmptyDisposable
}
}
public func collectLogs(basePath: String) -> Signal<[(String, String)], NoError> {
return Signal { subscriber in
self.queue.async {
let logsPath: String = basePath
var result: [(Date, String, String)] = []
if let files = try? FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: logsPath), includingPropertiesForKeys: [URLResourceKey.creationDateKey], options: []) {
for url in files {
if url.lastPathComponent.hasPrefix("log-") {
if let creationDate = (try? url.resourceValues(forKeys: Set([.creationDateKey])))?.creationDate {
result.append((creationDate, url.lastPathComponent, url.path))
}
}
}
}
result.sort(by: { $0.0 < $1.0 })
subscriber.putNext(result.map { ($0.1, $0.2) })
subscriber.putCompletion()
}
return EmptyDisposable
}
}
}

View File

@ -182,7 +182,7 @@ private func SGControllerEntries(presentationData: PresentationData, callListSet
entries.append(.toggle(id: id.count, section: .stories, settingName: .hideStories, value: SGSettings.hideStories, text: i18n("Settings.Stories.Hide", lang), enabled: true)) entries.append(.toggle(id: id.count, section: .stories, settingName: .hideStories, value: SGSettings.hideStories, text: i18n("Settings.Stories.Hide", lang), enabled: true))
entries.append(.toggle(id: id.count, section: .stories, settingName: .disableSwipeToRecordStory, value: SGSimpleSettings.shared.disableSwipeToRecordStory, text: i18n("Settings.Stories.DisableSwipeToRecord", lang), enabled: true)) entries.append(.toggle(id: id.count, section: .stories, settingName: .disableSwipeToRecordStory, value: SGSimpleSettings.shared.disableSwipeToRecordStory, text: i18n("Settings.Stories.DisableSwipeToRecord", lang), enabled: true))
entries.append(.toggle(id: id.count, section: .stories, settingName: .warnOnStoriesOpen, value: SGSettings.warnOnStoriesOpen, text: i18n("Settings.Stories.WarnBeforeView", lang), enabled: true)) entries.append(.toggle(id: id.count, section: .stories, settingName: .warnOnStoriesOpen, value: SGSettings.warnOnStoriesOpen, text: i18n("Settings.Stories.WarnBeforeView", lang), enabled: true))
entries.append(.toggle(id: id.count, section: .stories, settingName: .showRepostToStory, value: SGSimpleSettings.shared.showRepostToStory, text: presentationData.strings.Share_RepostToStory.replacingOccurrences(of: "\n", with: " "), enabled: true)) entries.append(.toggle(id: id.count, section: .stories, settingName: .showRepostToStory, value: SGSimpleSettings.shared.showRepostToStoryV2, text: presentationData.strings.Share_RepostToStory.replacingOccurrences(of: "\n", with: " "), enabled: true))
if SGSimpleSettings.shared.canUseStealthMode { if SGSimpleSettings.shared.canUseStealthMode {
entries.append(.toggle(id: id.count, section: .stories, settingName: .storyStealthMode, value: SGSimpleSettings.shared.storyStealthMode, text: presentationData.strings.Story_StealthMode_Title, enabled: true)) entries.append(.toggle(id: id.count, section: .stories, settingName: .storyStealthMode, value: SGSimpleSettings.shared.storyStealthMode, text: presentationData.strings.Story_StealthMode_Title, enabled: true))
entries.append(.notice(id: id.count, section: .stories, text: presentationData.strings.Story_StealthMode_ControlText)) entries.append(.notice(id: id.count, section: .stories, text: presentationData.strings.Story_StealthMode_ControlText))
@ -410,7 +410,7 @@ public func sgSettingsController(context: AccountContext/*, focusOnItemTag: Int?
case .hideReactions: case .hideReactions:
SGSimpleSettings.shared.hideReactions = value SGSimpleSettings.shared.hideReactions = value
case .showRepostToStory: case .showRepostToStory:
SGSimpleSettings.shared.showRepostToStory = value SGSimpleSettings.shared.showRepostToStoryV2 = value
case .contextShowSelectFromUser: case .contextShowSelectFromUser:
SGSimpleSettings.shared.contextShowSelectFromUser = value SGSimpleSettings.shared.contextShowSelectFromUser = value
case .contextShowSaveToCloud: case .contextShowSaveToCloud:

View File

@ -11,6 +11,7 @@ swift_library(
], ],
deps = [ deps = [
"//Swiftgram/SGAppGroupIdentifier:SGAppGroupIdentifier", "//Swiftgram/SGAppGroupIdentifier:SGAppGroupIdentifier",
"//Swiftgram/SGLogging:SGLogging",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -1,5 +1,6 @@
import Foundation import Foundation
import SGAppGroupIdentifier import SGAppGroupIdentifier
import SGLogging
let APP_GROUP_IDENTIFIER = sgAppGroupIdentifier() let APP_GROUP_IDENTIFIER = sgAppGroupIdentifier()
@ -9,6 +10,7 @@ public class SGSimpleSettings {
private init() { private init() {
setDefaultValues() setDefaultValues()
migrate()
preCacheValues() preCacheValues()
} }
@ -21,6 +23,19 @@ public class SGSimpleSettings {
} }
} }
private func migrate() {
let showRepostToStoryMigrationKey = "migrated_\(Keys.showRepostToStory.rawValue)"
if let groupUserDefaults = UserDefaults(suiteName: APP_GROUP_IDENTIFIER) {
if !groupUserDefaults.bool(forKey: showRepostToStoryMigrationKey) {
self.showRepostToStoryV2 = self.showRepostToStory
groupUserDefaults.set(true, forKey: showRepostToStoryMigrationKey)
SGLogger.shared.log("SGSimpleSettings", "Migrated showRepostToStory. \(self.showRepostToStory) -> \(self.showRepostToStoryV2)")
}
} else {
SGLogger.shared.log("SGSimpleSettings", "Unable to migrate showRepostToStory. Shared UserDefaults suite is not available for '\(APP_GROUP_IDENTIFIER)'.")
}
}
private func preCacheValues() { private func preCacheValues() {
// let dispatchGroup = DispatchGroup() // let dispatchGroup = DispatchGroup()
@ -82,6 +97,7 @@ public class SGSimpleSettings {
case outgoingLanguageTranslation case outgoingLanguageTranslation
case hideReactions case hideReactions
case showRepostToStory case showRepostToStory
case showRepostToStoryV2
case contextShowSelectFromUser case contextShowSelectFromUser
case contextShowSaveToCloud case contextShowSaveToCloud
case contextShowRestrict case contextShowRestrict
@ -272,7 +288,8 @@ public class SGSimpleSettings {
Keys.legacyNotificationsFix.rawValue: false, Keys.legacyNotificationsFix.rawValue: false,
Keys.pinnedMessageNotifications.rawValue: PinnedMessageNotificationsSettings.default.rawValue, Keys.pinnedMessageNotifications.rawValue: PinnedMessageNotificationsSettings.default.rawValue,
Keys.mentionsAndRepliesNotifications.rawValue: MentionsAndRepliesNotificationsSettings.default.rawValue, Keys.mentionsAndRepliesNotifications.rawValue: MentionsAndRepliesNotificationsSettings.default.rawValue,
Keys.status.rawValue: 1 Keys.status.rawValue: 1,
Keys.showRepostToStoryV2.rawValue: true,
] ]
@UserDefault(key: Keys.hidePhoneInSettings.rawValue) @UserDefault(key: Keys.hidePhoneInSettings.rawValue)
@ -327,9 +344,13 @@ public class SGSimpleSettings {
@UserDefault(key: Keys.hideReactions.rawValue) @UserDefault(key: Keys.hideReactions.rawValue)
public var hideReactions: Bool public var hideReactions: Bool
// @available(*, deprecated, message: "Use showRepostToStoryV2 instead")
@UserDefault(key: Keys.showRepostToStory.rawValue) @UserDefault(key: Keys.showRepostToStory.rawValue)
public var showRepostToStory: Bool public var showRepostToStory: Bool
@UserDefault(key: Keys.showRepostToStoryV2.rawValue, userDefaults: UserDefaults(suiteName: APP_GROUP_IDENTIFIER) ?? .standard)
public var showRepostToStoryV2: Bool
@UserDefault(key: Keys.contextShowRestrict.rawValue) @UserDefault(key: Keys.contextShowRestrict.rawValue)
public var contextShowRestrict: Bool public var contextShowRestrict: Bool

View File

@ -3,6 +3,7 @@ load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
sgdeps = [ sgdeps = [
"//Swiftgram/SGDebugUI:SGDebugUI", "//Swiftgram/SGDebugUI:SGDebugUI",
"//Swiftgram/SGLogging:SGLogging", "//Swiftgram/SGLogging:SGLogging",
"//Swiftgram/SGLoggingComposer:SGLoggingComposer",
"//Swiftgram/SGSimpleSettings:SGSimpleSettings" "//Swiftgram/SGSimpleSettings:SGSimpleSettings"
] ]

View File

@ -1,5 +1,6 @@
// MARK: Swiftgram // MARK: Swiftgram
import SGLogging import SGLogging
import SGLoggingComposer
import SGSimpleSettings import SGSimpleSettings
import SGDebugUI import SGDebugUI

View File

@ -164,7 +164,7 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
self.peersValue.set(.single(peers)) self.peersValue.set(.single(peers))
let canShareStory = controllerInteraction.shareStory != nil && SGSimpleSettings.shared.showRepostToStory let canShareStory = controllerInteraction.shareStory != nil && SGSimpleSettings.shared.showRepostToStoryV2
let items: Signal<[SharePeerEntry], NoError> = combineLatest(self.peersValue.get(), self.foundPeers.get(), self.tick.get(), self.themePromise.get()) let items: Signal<[SharePeerEntry], NoError> = combineLatest(self.peersValue.get(), self.foundPeers.get(), self.tick.get(), self.themePromise.get())
|> map { [weak controllerInteraction] initialPeers, foundPeers, _, theme -> [SharePeerEntry] in |> map { [weak controllerInteraction] initialPeers, foundPeers, _, theme -> [SharePeerEntry] in