mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Web app improvements
This commit is contained in:
parent
e4cfa80981
commit
c0bb57c850
@ -268,6 +268,7 @@ public class AttachmentController: ViewController {
|
|||||||
self.container.canHaveKeyboardFocus = true
|
self.container.canHaveKeyboardFocus = true
|
||||||
self.panel = AttachmentPanel(context: controller.context, chatLocation: controller.chatLocation, updatedPresentationData: controller.updatedPresentationData)
|
self.panel = AttachmentPanel(context: controller.context, chatLocation: controller.chatLocation, updatedPresentationData: controller.updatedPresentationData)
|
||||||
self.panel.fromMenu = controller.fromMenu
|
self.panel.fromMenu = controller.fromMenu
|
||||||
|
self.panel.isStandalone = controller.isStandalone
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
@ -636,7 +637,10 @@ public class AttachmentController: ViewController {
|
|||||||
|
|
||||||
var containerLayout = layout
|
var containerLayout = layout
|
||||||
let containerRect: CGRect
|
let containerRect: CGRect
|
||||||
|
var isCompact = true
|
||||||
if case .regular = layout.metrics.widthClass {
|
if case .regular = layout.metrics.widthClass {
|
||||||
|
isCompact = false
|
||||||
|
|
||||||
let availableHeight = layout.size.height - (layout.inputHeight ?? 0.0) - 60.0
|
let availableHeight = layout.size.height - (layout.inputHeight ?? 0.0) - 60.0
|
||||||
|
|
||||||
let size = CGSize(width: 390.0, height: min(620.0, availableHeight))
|
let size = CGSize(width: 390.0, height: min(620.0, availableHeight))
|
||||||
@ -645,17 +649,28 @@ public class AttachmentController: ViewController {
|
|||||||
let masterWidth = min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0))
|
let masterWidth = min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0))
|
||||||
let position: CGPoint = CGPoint(x: masterWidth - 174.0, y: layout.size.height - size.height - insets.bottom - 40.0)
|
let position: CGPoint = CGPoint(x: masterWidth - 174.0, y: layout.size.height - size.height - insets.bottom - 40.0)
|
||||||
|
|
||||||
containerRect = CGRect(origin: position, size: size)
|
if controller.isStandalone {
|
||||||
|
var containerY = floorToScreenPixels((layout.size.height - size.height) / 2.0)
|
||||||
|
if let inputHeight = layout.inputHeight, inputHeight > 88.0 {
|
||||||
|
containerY = layout.size.height - inputHeight - size.height - 80.0
|
||||||
|
}
|
||||||
|
containerRect = CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - size.width) / 2.0), y: containerY), size: size)
|
||||||
|
} else {
|
||||||
|
containerRect = CGRect(origin: position, size: size)
|
||||||
|
}
|
||||||
containerLayout.size = containerRect.size
|
containerLayout.size = containerRect.size
|
||||||
containerLayout.intrinsicInsets.bottom = 12.0
|
containerLayout.intrinsicInsets.bottom = 12.0
|
||||||
containerLayout.inputHeight = nil
|
containerLayout.inputHeight = nil
|
||||||
|
|
||||||
if self.wrapperNode.view.mask == nil {
|
if controller.isStandalone {
|
||||||
|
self.wrapperNode.cornerRadius = 10.0
|
||||||
|
} else if self.wrapperNode.view.mask == nil {
|
||||||
let maskView = UIImageView()
|
let maskView = UIImageView()
|
||||||
maskView.image = generateMaskImage()
|
maskView.image = generateMaskImage()
|
||||||
maskView.contentMode = .scaleToFill
|
maskView.contentMode = .scaleToFill
|
||||||
self.wrapperNode.view.mask = maskView
|
self.wrapperNode.view.mask = maskView
|
||||||
}
|
}
|
||||||
|
|
||||||
if let maskView = self.wrapperNode.view.mask {
|
if let maskView = self.wrapperNode.view.mask {
|
||||||
transition.updateFrame(view: maskView, frame: CGRect(origin: CGPoint(), size: size))
|
transition.updateFrame(view: maskView, frame: CGRect(origin: CGPoint(), size: size))
|
||||||
}
|
}
|
||||||
@ -697,7 +712,7 @@ public class AttachmentController: ViewController {
|
|||||||
if fromMenu && !hasButton, let inputContainerHeight = self.inputContainerHeight {
|
if fromMenu && !hasButton, let inputContainerHeight = self.inputContainerHeight {
|
||||||
panelHeight = inputContainerHeight
|
panelHeight = inputContainerHeight
|
||||||
}
|
}
|
||||||
if hasPanel || hasButton || fromMenu {
|
if hasPanel || hasButton || (fromMenu && isCompact) {
|
||||||
containerInsets.bottom = panelHeight
|
containerInsets.bottom = panelHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,13 +731,13 @@ public class AttachmentController: ViewController {
|
|||||||
panelTransition = .animated(duration: 0.25, curve: .easeInOut)
|
panelTransition = .animated(duration: 0.25, curve: .easeInOut)
|
||||||
}
|
}
|
||||||
var panelY = containerRect.height - panelHeight
|
var panelY = containerRect.height - panelHeight
|
||||||
if fromMenu {
|
if fromMenu && isCompact {
|
||||||
panelY = layout.size.height - panelHeight
|
panelY = layout.size.height - panelHeight
|
||||||
} else if !hasPanel && !hasButton {
|
} else if !hasPanel && !hasButton {
|
||||||
panelY = containerRect.height
|
panelY = containerRect.height
|
||||||
}
|
}
|
||||||
|
|
||||||
if fromMenu {
|
if fromMenu && isCompact {
|
||||||
if hasButton {
|
if hasButton {
|
||||||
self.panel.isHidden = false
|
self.panel.isHidden = false
|
||||||
self.inputContainerNode?.isHidden = true
|
self.inputContainerNode?.isHidden = true
|
||||||
@ -735,7 +750,7 @@ public class AttachmentController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
panelTransition.updateFrame(node: self.panel, frame: CGRect(origin: CGPoint(x: 0.0, y: panelY), size: CGSize(width: containerRect.width, height: panelHeight)), completion: { [weak self] finished in
|
panelTransition.updateFrame(node: self.panel, frame: CGRect(origin: CGPoint(x: 0.0, y: panelY), size: CGSize(width: containerRect.width, height: panelHeight)), completion: { [weak self] finished in
|
||||||
if transitioning && finished {
|
if transitioning && finished, isCompact {
|
||||||
self?.panel.isHidden = !hasButton
|
self?.panel.isHidden = !hasButton
|
||||||
self?.inputContainerNode?.isHidden = hasButton
|
self?.inputContainerNode?.isHidden = hasButton
|
||||||
}
|
}
|
||||||
@ -765,7 +780,8 @@ public class AttachmentController: ViewController {
|
|||||||
|
|
||||||
if self.container.supernode == nil, !controllers.isEmpty && self.container.isReady {
|
if self.container.supernode == nil, !controllers.isEmpty && self.container.isReady {
|
||||||
self.wrapperNode.addSubnode(self.container)
|
self.wrapperNode.addSubnode(self.container)
|
||||||
if controller.fromMenu {
|
|
||||||
|
if fromMenu, let _ = controller.getInputContainerNode() {
|
||||||
self.addSubnode(self.panel)
|
self.addSubnode(self.panel)
|
||||||
} else {
|
} else {
|
||||||
self.container.addSubnode(self.panel)
|
self.container.addSubnode(self.panel)
|
||||||
@ -814,6 +830,10 @@ public class AttachmentController: ViewController {
|
|||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate var isStandalone: Bool {
|
||||||
|
return self.buttons.contains(.standalone)
|
||||||
|
}
|
||||||
|
|
||||||
private var node: Node {
|
private var node: Node {
|
||||||
return self.displayNode as! Node
|
return self.displayNode as! Node
|
||||||
}
|
}
|
||||||
|
@ -482,6 +482,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
private var scrollLayout: (width: CGFloat, contentSize: CGSize)?
|
private var scrollLayout: (width: CGFloat, contentSize: CGSize)?
|
||||||
|
|
||||||
var fromMenu: Bool = false
|
var fromMenu: Bool = false
|
||||||
|
var isStandalone: Bool = false
|
||||||
|
|
||||||
var selectionChanged: (AttachmentButtonType) -> Bool = { _ in return false }
|
var selectionChanged: (AttachmentButtonType) -> Bool = { _ in return false }
|
||||||
var beganTextEditing: () -> Void = {}
|
var beganTextEditing: () -> Void = {}
|
||||||
@ -1090,9 +1091,16 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
let containerTransition: ContainedViewLayoutTransition
|
let containerTransition: ContainedViewLayoutTransition
|
||||||
let containerFrame: CGRect
|
let containerFrame: CGRect
|
||||||
if isButtonVisible {
|
if isButtonVisible {
|
||||||
let height: CGFloat
|
var height: CGFloat
|
||||||
if layout.intrinsicInsets.bottom > 0.0 && (layout.inputHeight ?? 0.0).isZero {
|
if layout.intrinsicInsets.bottom > 0.0 && (layout.inputHeight ?? 0.0).isZero {
|
||||||
height = bounds.height + 9.0
|
height = bounds.height + 9.0
|
||||||
|
if case .regular = layout.metrics.widthClass {
|
||||||
|
if self.isStandalone {
|
||||||
|
height -= 3.0
|
||||||
|
} else {
|
||||||
|
height += 6.0
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
height = bounds.height + 9.0 + 8.0
|
height = bounds.height + 9.0 + 8.0
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,8 @@ public final class AnimatedStickerComponent: Component {
|
|||||||
playbackMode = .loop
|
playbackMode = .loop
|
||||||
} else if component.isAnimating {
|
} else if component.isAnimating {
|
||||||
playbackMode = .once
|
playbackMode = .once
|
||||||
|
} else {
|
||||||
|
animationNode.autoplay = true
|
||||||
}
|
}
|
||||||
animationNode.setup(source: source, width: Int(component.size.width * component.animation.scale), height: Int(component.size.height * component.animation.scale), playbackMode: playbackMode, mode: .direct(cachePathPrefix: nil))
|
animationNode.setup(source: source, width: Int(component.size.width * component.animation.scale), height: Int(component.size.height * component.animation.scale), playbackMode: playbackMode, mode: .direct(cachePathPrefix: nil))
|
||||||
animationNode.visibility = self.isInHierarchy
|
animationNode.visibility = self.isInHierarchy
|
||||||
|
@ -2300,7 +2300,7 @@ public func svgIconImageFile(account: Account, fileReference: FileMediaReference
|
|||||||
|
|
||||||
if let fullSizePath = fullSizePath {
|
if let fullSizePath = fullSizePath {
|
||||||
if fullSizeComplete, let data = try? Data(contentsOf: URL(fileURLWithPath: fullSizePath)) {
|
if fullSizeComplete, let data = try? Data(contentsOf: URL(fileURLWithPath: fullSizePath)) {
|
||||||
fullSizeImage = drawSvgImage(data, CGSize.zero, .clear, .black, false)
|
fullSizeImage = drawSvgImage(data, stickToTop ? CGSize.zero : CGSize(width: 90.0, height: 90.0), .clear, .black, false)
|
||||||
if let image = fullSizeImage {
|
if let image = fullSizeImage {
|
||||||
fittedSize = image.size.aspectFitted(arguments.boundingSize)
|
fittedSize = image.size.aspectFitted(arguments.boundingSize)
|
||||||
}
|
}
|
||||||
|
@ -2931,6 +2931,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
case .speak:
|
case .speak:
|
||||||
let _ = speakText(text.string)
|
let _ = speakText(text.string)
|
||||||
case .translate:
|
case .translate:
|
||||||
|
strongSelf.chatDisplayNode.dismissInput()
|
||||||
|
|
||||||
let _ = (context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.translationSettings])
|
let _ = (context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.translationSettings])
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> deliverOnMainQueue).start(next: { sharedData in
|
|> deliverOnMainQueue).start(next: { sharedData in
|
||||||
@ -3364,7 +3366,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, openUrl: { [weak self] url in
|
let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, openUrl: { [weak self] url in
|
||||||
self?.openUrl(url, concealed: true, forceExternal: true)
|
self?.openUrl(url, concealed: true, forceExternal: true)
|
||||||
}, getInputContainerNode: { [weak self] in
|
}, getInputContainerNode: { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self, let layout = strongSelf.validLayout, case .compact = layout.metrics.widthClass {
|
||||||
return (strongSelf.chatDisplayNode.getWindowInputAccessoryHeight(), strongSelf.chatDisplayNode.inputPanelContainerNode, {
|
return (strongSelf.chatDisplayNode.getWindowInputAccessoryHeight(), strongSelf.chatDisplayNode.inputPanelContainerNode, {
|
||||||
return strongSelf.chatDisplayNode.textInputPanelNode?.makeAttachmentMenuTransition(accessoryPanelNode: nil)
|
return strongSelf.chatDisplayNode.textInputPanelNode?.makeAttachmentMenuTransition(accessoryPanelNode: nil)
|
||||||
})
|
})
|
||||||
|
@ -55,10 +55,12 @@ private final class PlayPauseIconNode: ManagedAnimationNode {
|
|||||||
|
|
||||||
final class PlayPauseIconComponent: Component {
|
final class PlayPauseIconComponent: Component {
|
||||||
let state: PlayPauseIconNodeState
|
let state: PlayPauseIconNodeState
|
||||||
|
let tintColor: UIColor?
|
||||||
let size: CGSize
|
let size: CGSize
|
||||||
|
|
||||||
init(state: PlayPauseIconNodeState, size: CGSize) {
|
init(state: PlayPauseIconNodeState, tintColor: UIColor?, size: CGSize) {
|
||||||
self.state = state
|
self.state = state
|
||||||
|
self.tintColor = tintColor
|
||||||
self.size = size
|
self.size = size
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +68,9 @@ final class PlayPauseIconComponent: Component {
|
|||||||
if lhs.state != rhs.state {
|
if lhs.state != rhs.state {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.tintColor != rhs.tintColor {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.size != rhs.size {
|
if lhs.size != rhs.size {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -94,6 +99,8 @@ final class PlayPauseIconComponent: Component {
|
|||||||
|
|
||||||
self.animationNode.enqueueState(component.state, animated: true)
|
self.animationNode.enqueueState(component.state, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.animationNode.customColor = component.tintColor
|
||||||
|
|
||||||
let animationSize = component.size
|
let animationSize = component.size
|
||||||
let size = CGSize(width: min(animationSize.width, availableSize.width), height: min(animationSize.height, availableSize.height))
|
let size = CGSize(width: min(animationSize.width, availableSize.width), height: min(animationSize.height, availableSize.height))
|
||||||
|
@ -15,11 +15,10 @@ import MultilineTextComponent
|
|||||||
import BundleIconComponent
|
import BundleIconComponent
|
||||||
import UndoUI
|
import UndoUI
|
||||||
|
|
||||||
private func generateExpandBackground(size: CGSize) -> UIImage {
|
private func generateExpandBackground(size: CGSize, color: UIColor) -> UIImage {
|
||||||
return generateImage(size, rotatedContext: { size, context in
|
return generateImage(size, rotatedContext: { size, context in
|
||||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
|
|
||||||
let color = UIColor.white
|
|
||||||
var locations: [CGFloat] = [0.0, 1.0]
|
var locations: [CGFloat] = [0.0, 1.0]
|
||||||
let colors: [CGColor] = [color.withAlphaComponent(0.0).cgColor, color.cgColor]
|
let colors: [CGColor] = [color.withAlphaComponent(0.0).cgColor, color.cgColor]
|
||||||
|
|
||||||
@ -88,7 +87,7 @@ private final class TranslateScreenComponent: CombinedComponent {
|
|||||||
private var speechHolder: SpeechSynthesizerHolder?
|
private var speechHolder: SpeechSynthesizerHolder?
|
||||||
fileprivate var availableSpeakLanguages: Set<String>
|
fileprivate var availableSpeakLanguages: Set<String>
|
||||||
|
|
||||||
fileprivate var moreBackgroundImage: (CGSize, UIImage)?
|
fileprivate var moreBackgroundImage: (CGSize, UIImage, UIColor)?
|
||||||
|
|
||||||
init(context: AccountContext, fromLanguage: String?, text: String, toLanguage: String, expand: @escaping () -> Void) {
|
init(context: AccountContext, fromLanguage: String?, text: String, toLanguage: String, expand: @escaping () -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
@ -115,6 +114,7 @@ private final class TranslateScreenComponent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
self.speechHolder?.stop()
|
||||||
self.translationDisposable.dispose()
|
self.translationDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,6 +346,7 @@ private final class TranslateScreenComponent: CombinedComponent {
|
|||||||
))),
|
))),
|
||||||
AnyComponentWithIdentity(id: "a", component: AnyComponent(PlayPauseIconComponent(
|
AnyComponentWithIdentity(id: "a", component: AnyComponent(PlayPauseIconComponent(
|
||||||
state: state.isSpeakingOriginalText ? .pause : .play,
|
state: state.isSpeakingOriginalText ? .pause : .play,
|
||||||
|
tintColor: theme.list.itemCheckColors.foregroundColor,
|
||||||
size: CGSize(width: 18.0, height: 18.0)
|
size: CGSize(width: 18.0, height: 18.0)
|
||||||
))),
|
))),
|
||||||
])),
|
])),
|
||||||
@ -381,14 +382,15 @@ private final class TranslateScreenComponent: CombinedComponent {
|
|||||||
|
|
||||||
let originalMoreBackgroundSize = CGSize(width: originalMoreButton.size.width + 50.0, height: originalMoreButton.size.height)
|
let originalMoreBackgroundSize = CGSize(width: originalMoreButton.size.width + 50.0, height: originalMoreButton.size.height)
|
||||||
let originalMoreBackgroundImage: UIImage
|
let originalMoreBackgroundImage: UIImage
|
||||||
if let (size, image) = state.moreBackgroundImage, size == originalMoreBackgroundSize {
|
let backgroundColor = theme.list.itemBlocksBackgroundColor
|
||||||
|
if let (size, image, color) = state.moreBackgroundImage, size == originalMoreBackgroundSize && color == backgroundColor {
|
||||||
originalMoreBackgroundImage = image
|
originalMoreBackgroundImage = image
|
||||||
} else {
|
} else {
|
||||||
originalMoreBackgroundImage = generateExpandBackground(size: originalMoreBackgroundSize)
|
originalMoreBackgroundImage = generateExpandBackground(size: originalMoreBackgroundSize, color: backgroundColor)
|
||||||
state.moreBackgroundImage = (originalMoreBackgroundSize, originalMoreBackgroundImage)
|
state.moreBackgroundImage = (originalMoreBackgroundSize, originalMoreBackgroundImage, backgroundColor)
|
||||||
}
|
}
|
||||||
let originalMoreBackground = originalMoreBackground.update(
|
let originalMoreBackground = originalMoreBackground.update(
|
||||||
component: Image(image: originalMoreBackgroundImage, tintColor: theme.list.itemBlocksBackgroundColor),
|
component: Image(image: originalMoreBackgroundImage, tintColor: backgroundColor),
|
||||||
availableSize: originalMoreBackgroundSize,
|
availableSize: originalMoreBackgroundSize,
|
||||||
transition: .immediate
|
transition: .immediate
|
||||||
)
|
)
|
||||||
@ -426,6 +428,7 @@ private final class TranslateScreenComponent: CombinedComponent {
|
|||||||
))),
|
))),
|
||||||
AnyComponentWithIdentity(id: "a", component: AnyComponent(PlayPauseIconComponent(
|
AnyComponentWithIdentity(id: "a", component: AnyComponent(PlayPauseIconComponent(
|
||||||
state: state.isSpeakingTranslatedText ? .pause : .play,
|
state: state.isSpeakingTranslatedText ? .pause : .play,
|
||||||
|
tintColor: theme.list.itemCheckColors.foregroundColor,
|
||||||
size: CGSize(width: 18.0, height: 18.0)
|
size: CGSize(width: 18.0, height: 18.0)
|
||||||
))),
|
))),
|
||||||
])),
|
])),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user