mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Various improvements
This commit is contained in:
@@ -6,6 +6,7 @@ import Postbox
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import PresentationDataUtils
|
||||
import ItemListUI
|
||||
import AccountContext
|
||||
import OpenInExternalAppUI
|
||||
@@ -13,12 +14,15 @@ import ItemListPeerActionItem
|
||||
import UndoUI
|
||||
import WebKit
|
||||
import LinkPresentation
|
||||
import CoreServices
|
||||
import PersistentStringHash
|
||||
|
||||
private final class WebBrowserSettingsControllerArguments {
|
||||
let context: AccountContext
|
||||
let updateDefaultBrowser: (String?) -> Void
|
||||
let clearCookies: () -> Void
|
||||
let addException: () -> Void
|
||||
let removeException: (String) -> Void
|
||||
let clearExceptions: () -> Void
|
||||
|
||||
init(
|
||||
@@ -26,12 +30,14 @@ private final class WebBrowserSettingsControllerArguments {
|
||||
updateDefaultBrowser: @escaping (String?) -> Void,
|
||||
clearCookies: @escaping () -> Void,
|
||||
addException: @escaping () -> Void,
|
||||
removeException: @escaping (String) -> Void,
|
||||
clearExceptions: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.updateDefaultBrowser = updateDefaultBrowser
|
||||
self.clearCookies = clearCookies
|
||||
self.addException = addException
|
||||
self.removeException = removeException
|
||||
self.clearExceptions = clearExceptions
|
||||
}
|
||||
}
|
||||
@@ -66,7 +72,30 @@ private enum WebBrowserSettingsControllerEntry: ItemListNodeEntry {
|
||||
}
|
||||
}
|
||||
|
||||
var stableId: Int32 {
|
||||
var stableId: UInt64 {
|
||||
switch self {
|
||||
case .browserHeader:
|
||||
return 0
|
||||
case let .browser(_, _, _, _, _, index):
|
||||
return UInt64(1 + index)
|
||||
case .clearCookies:
|
||||
return 102
|
||||
case .clearCookiesInfo:
|
||||
return 103
|
||||
case .exceptionsHeader:
|
||||
return 104
|
||||
case .exceptionsAdd:
|
||||
return 105
|
||||
case let .exception(_, _, exception):
|
||||
return 2000 + exception.domain.persistentHashValue
|
||||
case .exceptionsClear:
|
||||
return 1000
|
||||
case .exceptionsInfo:
|
||||
return 1001
|
||||
}
|
||||
}
|
||||
|
||||
var sortId: Int32 {
|
||||
switch self {
|
||||
case .browserHeader:
|
||||
return 0
|
||||
@@ -149,7 +178,7 @@ private enum WebBrowserSettingsControllerEntry: ItemListNodeEntry {
|
||||
}
|
||||
|
||||
static func <(lhs: WebBrowserSettingsControllerEntry, rhs: WebBrowserSettingsControllerEntry) -> Bool {
|
||||
return lhs.stableId < rhs.stableId
|
||||
return lhs.sortId < rhs.sortId
|
||||
}
|
||||
|
||||
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
||||
@@ -170,7 +199,9 @@ private enum WebBrowserSettingsControllerEntry: ItemListNodeEntry {
|
||||
case let .exceptionsHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .exception(_, _, exception):
|
||||
return WebBrowserDomainExceptionItem(presentationData: presentationData, context: arguments.context, title: exception.title, label: exception.domain, sectionId: self.section, style: .blocks)
|
||||
return WebBrowserDomainExceptionItem(presentationData: presentationData, context: arguments.context, title: exception.title, label: exception.domain, icon: exception.icon, sectionId: self.section, style: .blocks, deleted: {
|
||||
arguments.removeException(exception.domain)
|
||||
})
|
||||
case let .exceptionsAdd(_, text):
|
||||
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.plusIconImage(presentationData.theme), title: text, sectionId: self.section, height: .generic, color: .accent, editing: false, action: {
|
||||
arguments.addException()
|
||||
@@ -207,7 +238,7 @@ private func webBrowserSettingsControllerEntries(context: AccountContext, presen
|
||||
entries.append(.exceptionsAdd(presentationData.theme, presentationData.strings.WebBrowser_Exceptions_AddException))
|
||||
|
||||
var exceptionIndex: Int32 = 0
|
||||
for exception in settings.exceptions {
|
||||
for exception in settings.exceptions.reversed() {
|
||||
entries.append(.exception(exceptionIndex, presentationData.theme, exception))
|
||||
exceptionIndex += 1
|
||||
}
|
||||
@@ -225,6 +256,7 @@ private func webBrowserSettingsControllerEntries(context: AccountContext, presen
|
||||
public func webBrowserSettingsController(context: AccountContext) -> ViewController {
|
||||
var clearCookiesImpl: (() -> Void)?
|
||||
var addExceptionImpl: (() -> Void)?
|
||||
var removeExceptionImpl: ((String) -> Void)?
|
||||
var clearExceptionsImpl: (() -> Void)?
|
||||
|
||||
let arguments = WebBrowserSettingsControllerArguments(
|
||||
@@ -240,6 +272,9 @@ public func webBrowserSettingsController(context: AccountContext) -> ViewControl
|
||||
addException: {
|
||||
addExceptionImpl?()
|
||||
},
|
||||
removeException: { domain in
|
||||
removeExceptionImpl?(domain)
|
||||
},
|
||||
clearExceptions: {
|
||||
clearExceptionsImpl?()
|
||||
}
|
||||
@@ -261,6 +296,9 @@ public func webBrowserSettingsController(context: AccountContext) -> ViewControl
|
||||
if previousSettings.defaultWebBrowser != settings.defaultWebBrowser {
|
||||
animateChanges = true
|
||||
}
|
||||
if previousSettings.exceptions.count != settings.exceptions.count {
|
||||
animateChanges = true
|
||||
}
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.WebBrowser_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||
@@ -290,9 +328,11 @@ public func webBrowserSettingsController(context: AccountContext) -> ViewControl
|
||||
}
|
||||
|
||||
addExceptionImpl = { [weak controller] in
|
||||
var dismissImpl: (() -> Void)?
|
||||
let linkController = webBrowserDomainController(context: context, apply: { url in
|
||||
if let url {
|
||||
let _ = fetchDomainExceptionInfo(url: url).startStandalone(next: { newException in
|
||||
let _ = (fetchDomainExceptionInfo(context: context, url: url)
|
||||
|> deliverOnMainQueue).startStandalone(next: { newException in
|
||||
let _ = updateWebBrowserSettingsInteractively(accountManager: context.sharedContext.accountManager, { currentSettings in
|
||||
var currentExceptions = currentSettings.exceptions
|
||||
for exception in currentExceptions {
|
||||
@@ -303,18 +343,44 @@ public func webBrowserSettingsController(context: AccountContext) -> ViewControl
|
||||
currentExceptions.append(newException)
|
||||
return currentSettings.withUpdatedExceptions(currentExceptions)
|
||||
}).start()
|
||||
dismissImpl?()
|
||||
})
|
||||
}
|
||||
})
|
||||
dismissImpl = { [weak linkController] in
|
||||
linkController?.view.endEditing(true)
|
||||
linkController?.dismissAnimated()
|
||||
}
|
||||
controller?.present(linkController, in: .window(.root))
|
||||
}
|
||||
|
||||
clearExceptionsImpl = {
|
||||
removeExceptionImpl = { domain in
|
||||
let _ = updateWebBrowserSettingsInteractively(accountManager: context.sharedContext.accountManager, { currentSettings in
|
||||
return currentSettings.withUpdatedExceptions([])
|
||||
let updatedExceptions = currentSettings.exceptions.filter { $0.domain != domain }
|
||||
return currentSettings.withUpdatedExceptions(updatedExceptions)
|
||||
}).start()
|
||||
}
|
||||
|
||||
clearExceptionsImpl = { [weak controller] in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let alertController = textAlertController(
|
||||
context: context,
|
||||
updatedPresentationData: nil,
|
||||
title: nil,
|
||||
text: presentationData.strings.WebBrowser_Exceptions_ClearConfirmation_Text,
|
||||
actions: [
|
||||
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}),
|
||||
TextAlertAction(type: .defaultAction, title: presentationData.strings.WebBrowser_Exceptions_ClearConfirmation_Clear, action: {
|
||||
let _ = updateWebBrowserSettingsInteractively(accountManager: context.sharedContext.accountManager, { currentSettings in
|
||||
return currentSettings.withUpdatedExceptions([])
|
||||
}).start()
|
||||
})
|
||||
]
|
||||
)
|
||||
controller?.present(alertController, in: .window(.root))
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
@@ -333,22 +399,59 @@ private func cleanDomain(url: String) -> (domain: String, fullUrl: String) {
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchDomainExceptionInfo(url: String) -> Signal<WebBrowserException, NoError> {
|
||||
private func fetchDomainExceptionInfo(context: AccountContext, url: String) -> Signal<WebBrowserException, NoError> {
|
||||
let (domain, domainUrl) = cleanDomain(url: url)
|
||||
if #available(iOS 13.0, *), let url = URL(string: domainUrl) {
|
||||
return Signal { subscriber in
|
||||
let metadataProvider = LPMetadataProvider()
|
||||
metadataProvider.shouldFetchSubresources = true
|
||||
metadataProvider.startFetchingMetadata(for: url, completionHandler: { metadata, _ in
|
||||
let title = metadata?.value(forKey: "_siteName") as? String ?? metadata?.title
|
||||
subscriber.putNext(WebBrowserException(domain: domain, title: title ?? domain))
|
||||
subscriber.putCompletion()
|
||||
let completeWithImage: (Data?) -> Void = { imageData in
|
||||
var image: TelegramMediaImage?
|
||||
if let imageData, let parsedImage = UIImage(data: imageData) {
|
||||
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
||||
context.account.postbox.mediaBox.storeResourceData(resource.id, data: imageData)
|
||||
image = TelegramMediaImage(
|
||||
imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)),
|
||||
representations: [
|
||||
TelegramMediaImageRepresentation(
|
||||
dimensions: PixelDimensions(width: Int32(parsedImage.size.width), height: Int32(parsedImage.size.height)),
|
||||
resource: resource,
|
||||
progressiveSizes: [],
|
||||
immediateThumbnailData: nil,
|
||||
hasVideo: false,
|
||||
isPersonal: false
|
||||
)
|
||||
],
|
||||
immediateThumbnailData: nil,
|
||||
reference: nil,
|
||||
partialReference: nil,
|
||||
flags: []
|
||||
)
|
||||
}
|
||||
|
||||
let title = metadata?.value(forKey: "_siteName") as? String ?? metadata?.title
|
||||
subscriber.putNext(WebBrowserException(domain: domain, title: title ?? domain, icon: image))
|
||||
subscriber.putCompletion()
|
||||
}
|
||||
|
||||
if let imageProvider = metadata?.iconProvider {
|
||||
imageProvider.loadFileRepresentation(forTypeIdentifier: kUTTypeImage as String, completionHandler: { imageUrl, _ in
|
||||
guard let imageUrl, let imageData = try? Data(contentsOf: imageUrl) else {
|
||||
completeWithImage(nil)
|
||||
return
|
||||
}
|
||||
completeWithImage(imageData)
|
||||
})
|
||||
} else {
|
||||
completeWithImage(nil)
|
||||
}
|
||||
})
|
||||
return ActionDisposable {
|
||||
metadataProvider.cancel()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .single(WebBrowserException(domain: domain, title: domain))
|
||||
return .single(WebBrowserException(domain: domain, title: domain, icon: nil))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user