mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Stickers Import Improvements
This commit is contained in:
parent
437cd445d1
commit
0c246e83b6
@ -6507,11 +6507,12 @@ Sorry for the inconvenience.";
|
||||
"ImportStickerPack.RemoveFromImport" = "Remove From Import";
|
||||
"ImportStickerPack.ChooseName" = "Choose Name";
|
||||
"ImportStickerPack.ChooseNameDescription" = "Please choose a name for your set.";
|
||||
"ImportStickerPack.NamePlaceholder" = "Name";
|
||||
"ImportStickerPack.GeneratingLink" = "generating link...";
|
||||
"ImportStickerPack.CheckingLink" = "checking availability...";
|
||||
"ImportStickerPack.ChooseLink" = "Choose Link";
|
||||
"ImportStickerPack.ChooseLinkDescription" = "You can use a-z, 0-9 and underscores.";
|
||||
"ImportStickerPack.LinkTaken" = "Sorry, this link is alreay taken.";
|
||||
"ImportStickerPack.LinkTaken" = "Sorry, this link is already taken.";
|
||||
"ImportStickerPack.LinkAvailable" = "Link is available.";
|
||||
"ImportStickerPack.ImportingStickers" = "Importing Stickers";
|
||||
"ImportStickerPack.Of" = "%1$@ of %2$@ Imported";
|
||||
|
@ -30,6 +30,7 @@ swift_library(
|
||||
"//submodules/UndoUI:UndoUI",
|
||||
"//submodules/ContextUI:ContextUI",
|
||||
"//submodules/RadialStatusNode:RadialStatusNode",
|
||||
"//submodules/StickerPackPreviewUI:StickerPackPreviewUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -74,7 +74,8 @@ public final class ImportStickerPackController: ViewController, StandalonePresen
|
||||
self.controllerNode.presentInGlobalOverlay = { [weak self] controller, arguments in
|
||||
self?.presentInGlobalOverlay(controller, with: arguments)
|
||||
}
|
||||
|
||||
self.controllerNode.navigationController = self.parentNavigationController
|
||||
|
||||
Queue.mainQueue().after(0.1) {
|
||||
self.controllerNode.updateStickerPack(self.stickerPack)
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import AccountContext
|
||||
import ContextUI
|
||||
import RadialStatusNode
|
||||
import UndoUI
|
||||
import StickerPackPreviewUI
|
||||
|
||||
private struct StickerPackPreviewGridEntry: Comparable, Identifiable {
|
||||
let index: Int
|
||||
@ -77,6 +78,8 @@ final class ImportStickerPackControllerNode: ViewControllerTracingNode, UIScroll
|
||||
|
||||
private var interaction: StickerPackPreviewInteraction!
|
||||
|
||||
weak var navigationController: NavigationController?
|
||||
|
||||
var present: ((ViewController, Any?) -> Void)?
|
||||
var presentInGlobalOverlay: ((ViewController, Any?) -> Void)?
|
||||
var dismiss: (() -> Void)?
|
||||
@ -583,7 +586,7 @@ final class ImportStickerPackControllerNode: ViewControllerTracingNode, UIScroll
|
||||
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||
}
|
||||
|
||||
self.disposable.set((self.context.engine.stickers.createStickerSet(title: title, shortName: shortName, stickers: stickers, thumbnail: thumbnailSticker, isAnimated: stickerPack.isAnimated)
|
||||
self.disposable.set((self.context.engine.stickers.createStickerSet(title: title, shortName: shortName, stickers: stickers, thumbnail: thumbnailSticker, isAnimated: stickerPack.isAnimated, software: stickerPack.software)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
if let strongSelf = self {
|
||||
if case let .complete(info, items) = status {
|
||||
@ -620,12 +623,19 @@ final class ImportStickerPackControllerNode: ViewControllerTracingNode, UIScroll
|
||||
|
||||
strongSelf.cancelButtonNode.isUserInteractionEnabled = false
|
||||
|
||||
let navigationController = strongSelf.navigationController
|
||||
let context = strongSelf.context
|
||||
|
||||
Queue.mainQueue().after(1.0) {
|
||||
var firstItem: StickerPackItem?
|
||||
if let firstStickerItem = firstStickerItem, let resource = firstStickerItem.resource as? TelegramMediaResource {
|
||||
firstItem = StickerPackItem(index: ItemCollectionItemIndex(index: 0, id: 0), file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: stickerPack.isAnimated ? "application/x-tgsticker": "image/png", size: nil, attributes: [.FileName(fileName: stickerPack.isAnimated ? "sticker.tgs" : "sticker.png"), .ImageSize(size: firstStickerItem.dimensions)]), indexKeys: [])
|
||||
}
|
||||
strongSelf.presentInGlobalOverlay?(UndoOverlayController(presentationData: strongSelf.presentationData, content: .stickersModified(title: strongSelf.presentationData.strings.StickerPackActionInfo_AddedTitle, text: strongSelf.presentationData.strings.StickerPackActionInfo_AddedText(info.title).0, undo: false, info: info, topItem: firstItem ?? items.first, context: strongSelf.context), elevatedLayout: false, action: { _ in return true}), nil)
|
||||
strongSelf.presentInGlobalOverlay?(UndoOverlayController(presentationData: strongSelf.presentationData, content: .stickersModified(title: strongSelf.presentationData.strings.StickerPackActionInfo_AddedTitle, text: strongSelf.presentationData.strings.StickerPackActionInfo_AddedText(info.title).0, undo: false, info: info, topItem: firstItem ?? items.first, context: strongSelf.context), elevatedLayout: false, action: { _ in
|
||||
(navigationController?.viewControllers.last as? ViewController)?.present(StickerPackScreen(context: context, mode: .settings, mainStickerPack: .id(id: info.id.id, accessHash: info.accessHash), stickerPacks: [], parentNavigationController: navigationController, actionPerformed: { _, _, _ in
|
||||
}), in: .window(.root))
|
||||
return true
|
||||
}), nil)
|
||||
strongSelf.cancel?()
|
||||
}
|
||||
} else if case let .progress(progress, count, total) = status {
|
||||
@ -645,7 +655,7 @@ final class ImportStickerPackControllerNode: ViewControllerTracingNode, UIScroll
|
||||
|
||||
@objc func installActionButtonPressed() {
|
||||
var proceedImpl: ((String, String?) -> Void)?
|
||||
let titleController = importStickerPackTitleController(context: self.context, title: self.presentationData.strings.ImportStickerPack_ChooseName, text: self.presentationData.strings.ImportStickerPack_ChooseNameDescription, placeholder: "", value: nil, maxLength: 128, apply: { [weak self] title in
|
||||
let titleController = importStickerPackTitleController(context: self.context, title: self.presentationData.strings.ImportStickerPack_ChooseName, text: self.presentationData.strings.ImportStickerPack_ChooseNameDescription, placeholder: self.presentationData.strings.ImportStickerPack_NamePlaceholder, value: nil, maxLength: 128, apply: { [weak self] title in
|
||||
if let strongSelf = self, let title = title {
|
||||
strongSelf.shortNameSuggestionDisposable.set((strongSelf.context.engine.stickers.getStickerSetShortNameSuggestion(title: title)
|
||||
|> deliverOnMainQueue).start(next: { suggestedShortName in
|
||||
|
@ -12,18 +12,28 @@ import UrlEscaping
|
||||
import ActivityIndicator
|
||||
|
||||
private class TextField: UITextField, UIScrollViewDelegate {
|
||||
let placeholderLabel: ImmediateTextNode
|
||||
var placeholderString: NSAttributedString? {
|
||||
didSet {
|
||||
self.placeholderLabel.attributedText = self.placeholderString
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func updatePrefixWidth(_ prefixWidth: CGFloat) {
|
||||
let previousPrefixWidth = self.prefixWidth
|
||||
guard previousPrefixWidth != prefixWidth else {
|
||||
return
|
||||
}
|
||||
self.prefixWidth = prefixWidth
|
||||
let leftOffset = prefixWidth
|
||||
if let scrollView = self.scrollView {
|
||||
if scrollView.contentInset.left != leftOffset {
|
||||
scrollView.contentInset = UIEdgeInsets(top: 0.0, left: leftOffset, bottom: 0.0, right: 0.0)
|
||||
if scrollView.contentInset.left != prefixWidth {
|
||||
scrollView.contentInset = UIEdgeInsets(top: 0.0, left: prefixWidth, bottom: 0.0, right: 0.0)
|
||||
}
|
||||
if leftOffset.isZero {
|
||||
if prefixWidth.isZero {
|
||||
scrollView.contentOffset = CGPoint()
|
||||
} else if self.prefixWidth != previousPrefixWidth {
|
||||
scrollView.contentOffset = CGPoint(x: -leftOffset, y: 0.0)
|
||||
} else if prefixWidth != previousPrefixWidth {
|
||||
scrollView.contentOffset = CGPoint(x: -prefixWidth, y: 0.0)
|
||||
}
|
||||
self.updatePrefixPosition(transition: .immediate)
|
||||
}
|
||||
@ -45,10 +55,17 @@ private class TextField: UITextField, UIScrollViewDelegate {
|
||||
self.prefixLabel.displaysAsynchronously = false
|
||||
self.prefixLabel.maximumNumberOfLines = 1
|
||||
self.prefixLabel.truncationMode = .byTruncatingTail
|
||||
|
||||
self.placeholderLabel = ImmediateTextNode()
|
||||
self.placeholderLabel.isUserInteractionEnabled = false
|
||||
self.placeholderLabel.displaysAsynchronously = false
|
||||
self.placeholderLabel.maximumNumberOfLines = 1
|
||||
self.placeholderLabel.truncationMode = .byTruncatingTail
|
||||
|
||||
super.init(frame: CGRect())
|
||||
|
||||
self.addSubnode(self.prefixLabel)
|
||||
self.addSubnode(self.placeholderLabel)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
@ -88,6 +105,17 @@ private class TextField: UITextField, UIScrollViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func selectWhole() {
|
||||
guard let scrollView = self.scrollView else {
|
||||
return
|
||||
}
|
||||
// if scrollView.contentSize.width > scrollView.frame.width - scrollView.contentInset.left {
|
||||
// scrollView.contentOffset = CGPoint(x: -scrollView.contentInset.left + scrollView.contentSize.width - (scrollView.frame.width - scrollView.contentInset.left), y: 0.0)
|
||||
// self.updatePrefixPosition()
|
||||
// }
|
||||
self.selectAll(nil)
|
||||
}
|
||||
|
||||
var fixAutoScroll: CGPoint?
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if let fixAutoScroll = self.fixAutoScroll {
|
||||
@ -164,13 +192,10 @@ private class TextField: UITextField, UIScrollViewDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
var placeholderOffset: CGFloat = 0.0
|
||||
if #available(iOS 14.0, *) {
|
||||
placeholderOffset = 1.0
|
||||
} else {
|
||||
}
|
||||
|
||||
let textRect = self.textRect(forBounds: bounds)
|
||||
|
||||
let labelSize = self.placeholderLabel.updateLayout(textRect.size)
|
||||
self.placeholderLabel.frame = CGRect(origin: CGPoint(x: textRect.minX, y: floorToScreenPixels((bounds.height - labelSize.height) / 2.0)), size: labelSize)
|
||||
|
||||
let prefixSize = self.prefixLabel.updateLayout(CGSize(width: floor(bounds.size.width * 0.7), height: bounds.size.height))
|
||||
let prefixBounds = bounds.insetBy(dx: 4.0, dy: 4.0)
|
||||
@ -182,7 +207,6 @@ private class TextField: UITextField, UIScrollViewDelegate {
|
||||
private final class ImportStickerPackTitleInputFieldNode: ASDisplayNode, UITextFieldDelegate {
|
||||
private var theme: PresentationTheme
|
||||
private let backgroundNode: ASImageNode
|
||||
// private let textInputNode: EditableTextNode
|
||||
private let textInputNode: TextField
|
||||
private let clearButton: HighlightableButtonNode
|
||||
|
||||
@ -199,6 +223,7 @@ private final class ImportStickerPackTitleInputFieldNode: ASDisplayNode, UITextF
|
||||
}
|
||||
set {
|
||||
self.textInputNode.attributedText = NSAttributedString(string: newValue, font: Font.regular(14.0), textColor: self.theme.actionSheet.inputTextColor)
|
||||
self.textInputNode.placeholderLabel.isHidden = !newValue.isEmpty
|
||||
if self.textInputNode.isFirstResponder {
|
||||
self.clearButton.isHidden = newValue.isEmpty
|
||||
} else {
|
||||
@ -234,6 +259,7 @@ private final class ImportStickerPackTitleInputFieldNode: ASDisplayNode, UITextF
|
||||
self.textInputNode.font = Font.regular(14.0)
|
||||
self.textInputNode.typingAttributes = [NSAttributedString.Key.font: Font.regular(14.0), NSAttributedString.Key.foregroundColor: theme.actionSheet.inputTextColor]
|
||||
self.textInputNode.clipsToBounds = true
|
||||
self.textInputNode.placeholderString = NSAttributedString(string: placeholder, font: Font.regular(14.0), textColor: theme.actionSheet.secondaryTextColor)
|
||||
// self.textInputNode.textContainerInset = UIEdgeInsets(top: self.inputInsets.top, left: 0.0, bottom: self.inputInsets.bottom, right: 0.0)
|
||||
self.textInputNode.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||
self.textInputNode.keyboardType = keyboardType
|
||||
@ -265,7 +291,7 @@ private final class ImportStickerPackTitleInputFieldNode: ASDisplayNode, UITextF
|
||||
}
|
||||
|
||||
func selectAll() {
|
||||
self.textInputNode.selectAll(nil)
|
||||
self.textInputNode.selectWhole()
|
||||
}
|
||||
|
||||
func updateTheme(_ theme: PresentationTheme) {
|
||||
@ -287,7 +313,7 @@ private final class ImportStickerPackTitleInputFieldNode: ASDisplayNode, UITextF
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: backgroundInsets.left, y: backgroundInsets.top), size: CGSize(width: width - backgroundInsets.left - backgroundInsets.right, height: panelHeight - backgroundInsets.top - backgroundInsets.bottom))
|
||||
transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame)
|
||||
|
||||
transition.updateFrame(view: self.textInputNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + inputInsets.left, y: backgroundFrame.minY), size: CGSize(width: backgroundFrame.size.width - inputInsets.left - inputInsets.right - 20.0, height: backgroundFrame.size.height)))
|
||||
transition.updateFrame(view: self.textInputNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + inputInsets.left, y: backgroundFrame.minY), size: CGSize(width: backgroundFrame.size.width - inputInsets.left - inputInsets.right - 22.0, height: backgroundFrame.size.height)))
|
||||
|
||||
if let image = self.clearButton.image(for: []) {
|
||||
transition.updateFrame(node: self.clearButton, frame: CGRect(origin: CGPoint(x: backgroundFrame.maxX - 8.0 - image.size.width, y: backgroundFrame.minY + floor((backgroundFrame.size.height - image.size.height) / 2.0)), size: image.size))
|
||||
@ -315,7 +341,8 @@ private final class ImportStickerPackTitleInputFieldNode: ASDisplayNode, UITextF
|
||||
func textFieldDidUpdateText(_ text: String) {
|
||||
self.updateTextNodeText(animated: true)
|
||||
self.textChanged?(text)
|
||||
self.clearButton.isHidden = (text).isEmpty
|
||||
self.clearButton.isHidden = text.isEmpty
|
||||
self.textInputNode.placeholderLabel.isHidden = !text.isEmpty
|
||||
}
|
||||
|
||||
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
|
@ -6316,9 +6316,9 @@ public extension Api {
|
||||
}
|
||||
}
|
||||
public struct stickers {
|
||||
public static func createStickerSet(flags: Int32, userId: Api.InputUser, title: String, shortName: String, thumb: Api.InputDocument?, stickers: [Api.InputStickerSetItem]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.StickerSet>) {
|
||||
public static func createStickerSet(flags: Int32, userId: Api.InputUser, title: String, shortName: String, thumb: Api.InputDocument?, stickers: [Api.InputStickerSetItem], software: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.StickerSet>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-251435136)
|
||||
buffer.appendInt32(-1876841625)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
userId.serialize(buffer, true)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
@ -6329,7 +6329,8 @@ public extension Api {
|
||||
for item in stickers {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
return (FunctionDescription(name: "stickers.createStickerSet", parameters: [("flags", flags), ("userId", userId), ("title", title), ("shortName", shortName), ("thumb", thumb), ("stickers", stickers)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.StickerSet? in
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(software!, buffer: buffer, boxed: false)}
|
||||
return (FunctionDescription(name: "stickers.createStickerSet", parameters: [("flags", flags), ("userId", userId), ("title", title), ("shortName", shortName), ("thumb", thumb), ("stickers", stickers), ("software", software)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.StickerSet? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.messages.StickerSet?
|
||||
if let signature = reader.readInt32() {
|
||||
|
@ -95,7 +95,7 @@ public enum CreateStickerSetStatus {
|
||||
case complete(StickerPackCollectionInfo, [ItemCollectionItem])
|
||||
}
|
||||
|
||||
func _internal_createStickerSet(account: Account, title: String, shortName: String, stickers: [ImportSticker], thumbnail: ImportSticker?, isAnimated: Bool) -> Signal<CreateStickerSetStatus, CreateStickerSetError> {
|
||||
func _internal_createStickerSet(account: Account, title: String, shortName: String, stickers: [ImportSticker], thumbnail: ImportSticker?, isAnimated: Bool, software: String?) -> Signal<CreateStickerSetStatus, CreateStickerSetError> {
|
||||
return account.postbox.loadedPeerWithId(account.peerId)
|
||||
|> castError(CreateStickerSetError.self)
|
||||
|> mapToSignal { peer -> Signal<CreateStickerSetStatus, CreateStickerSetError> in
|
||||
@ -140,7 +140,10 @@ func _internal_createStickerSet(account: Account, title: String, shortName: Stri
|
||||
flags |= (1 << 2)
|
||||
thumbnailDocument = .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data()))
|
||||
}
|
||||
return account.network.request(Api.functions.stickers.createStickerSet(flags: flags, userId: inputUser, title: title, shortName: shortName, thumb: thumbnailDocument, stickers: inputStickers))
|
||||
if let software = software, !software.isEmpty {
|
||||
flags |= (1 << 3)
|
||||
}
|
||||
return account.network.request(Api.functions.stickers.createStickerSet(flags: flags, userId: inputUser, title: title, shortName: shortName, thumb: thumbnailDocument, stickers: inputStickers, software: software))
|
||||
|> mapError { error -> CreateStickerSetError in
|
||||
return .generic
|
||||
}
|
||||
|
@ -80,7 +80,9 @@ func _internal_removeStickerPacksInteractively(postbox: Postbox, ids: [ItemColle
|
||||
let items = transaction.getItemCollectionItems(collectionId: id)
|
||||
|
||||
addSynchronizeInstalledStickerPacksOperation(transaction: transaction, namespace: namespace, content: content, noDelay: false)
|
||||
transaction.removeItemCollection(collectionId: id)
|
||||
for id in ids {
|
||||
transaction.removeItemCollection(collectionId: id)
|
||||
}
|
||||
return index.flatMap { ($0, items) }
|
||||
} else {
|
||||
return nil
|
||||
|
@ -70,8 +70,8 @@ public extension TelegramEngine {
|
||||
return _internal_stickerPacksAttachedToMedia(account: self.account, media: media)
|
||||
}
|
||||
|
||||
public func createStickerSet(title: String, shortName: String, stickers: [ImportSticker], thumbnail: ImportSticker?, isAnimated: Bool) -> Signal<CreateStickerSetStatus, CreateStickerSetError> {
|
||||
return _internal_createStickerSet(account: self.account, title: title, shortName: shortName, stickers: stickers, thumbnail: thumbnail, isAnimated: isAnimated)
|
||||
public func createStickerSet(title: String, shortName: String, stickers: [ImportSticker], thumbnail: ImportSticker?, isAnimated: Bool, software: String?) -> Signal<CreateStickerSetStatus, CreateStickerSetError> {
|
||||
return _internal_createStickerSet(account: self.account, title: title, shortName: shortName, stickers: stickers, thumbnail: thumbnail, isAnimated: isAnimated, software: software)
|
||||
}
|
||||
|
||||
public func getStickerSetShortNameSuggestion(title: String) -> Signal<String?, NoError> {
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user