mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-05 11:00:54 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
fd8b7bb597
@ -351,7 +351,7 @@ public func generateGradientTintedImage(image: UIImage?, colors: [UIColor]) -> U
|
|||||||
let t = CGFloat(i) / CGFloat(colors.count - 1)
|
let t = CGFloat(i) / CGFloat(colors.count - 1)
|
||||||
locations.append(t)
|
locations.append(t)
|
||||||
}
|
}
|
||||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace
|
||||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||||
|
|
||||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: imageRect.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions())
|
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: imageRect.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions())
|
||||||
@ -381,7 +381,7 @@ public func generateGradientImage(size: CGSize, colors: [UIColor], locations: [C
|
|||||||
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
||||||
if let context = UIGraphicsGetCurrentContext() {
|
if let context = UIGraphicsGetCurrentContext() {
|
||||||
let gradientColors = colors.map { $0.cgColor } as CFArray
|
let gradientColors = colors.map { $0.cgColor } as CFArray
|
||||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace
|
||||||
|
|
||||||
var locations = locations
|
var locations = locations
|
||||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||||
@ -403,7 +403,7 @@ public func generateGradientFilledCircleImage(diameter: CGFloat, colors: NSArray
|
|||||||
context.clip()
|
context.clip()
|
||||||
|
|
||||||
var locations: [CGFloat] = [0.0, 1.0]
|
var locations: [CGFloat] = [0.0, 1.0]
|
||||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace
|
||||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: &locations)!
|
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: &locations)!
|
||||||
|
|
||||||
context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: bounds.size.height), options: CGGradientDrawingOptions())
|
context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: bounds.size.height), options: CGGradientDrawingOptions())
|
||||||
|
@ -1190,6 +1190,7 @@ open class NavigationBar: ASDisplayNode {
|
|||||||
|
|
||||||
self.badgeNode.updateTheme(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor)
|
self.badgeNode.updateTheme(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor)
|
||||||
|
|
||||||
|
self.updateLeftButton(animated: false)
|
||||||
self.requestLayout()
|
self.requestLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ private final class MediaGroupsGridAlbumItemNode : ListViewItemNode {
|
|||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
super.didLoad()
|
super.didLoad()
|
||||||
|
|
||||||
self.imageNode.cornerRadius = 10.0
|
self.imageNode.cornerRadius = 5.0
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
self.imageNode.layer.cornerCurve = .continuous
|
self.imageNode.layer.cornerCurve = .continuous
|
||||||
}
|
}
|
||||||
@ -221,11 +221,11 @@ private func preparedTransition(action: @escaping (PHAssetCollection) -> Void, f
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class MediaGroupsAlbumGridItem: ListViewItem {
|
final class MediaGroupsAlbumGridItem: ListViewItem {
|
||||||
let presentationData: ItemListPresentationData
|
let presentationData: PresentationData
|
||||||
let collections: [PHAssetCollection]
|
let collections: [PHAssetCollection]
|
||||||
let action: (PHAssetCollection) -> Void
|
let action: (PHAssetCollection) -> Void
|
||||||
|
|
||||||
public init(presentationData: ItemListPresentationData, collections: [PHAssetCollection], action: @escaping (PHAssetCollection) -> Void) {
|
public init(presentationData: PresentationData, collections: [PHAssetCollection], action: @escaping (PHAssetCollection) -> Void) {
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
self.collections = collections
|
self.collections = collections
|
||||||
self.action = action
|
self.action = action
|
||||||
@ -347,7 +347,8 @@ private class MediaGroupsAlbumGridItemNode: ListViewItemNode {
|
|||||||
firstItem = result.firstObject
|
firstItem = result.firstObject
|
||||||
}
|
}
|
||||||
if let firstItem = firstItem {
|
if let firstItem = firstItem {
|
||||||
entries.append(MediaGroupsGridAlbumEntry(theme: item.presentationData.theme, index: index, collection: collection, firstItem: firstItem, count: presentationStringsFormattedNumber(Int32(result.count))))
|
let count = presentationStringsFormattedNumber(Int32(result.count), item.presentationData.dateTimeFormat.groupingSeparator)
|
||||||
|
entries.append(MediaGroupsGridAlbumEntry(theme: item.presentationData.theme, index: index, collection: collection, firstItem: firstItem, count: count))
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ private enum MediaGroupsEntry: Comparable, Identifiable {
|
|||||||
case let .albumsHeader(_, text), let .smartAlbumsHeader(_, text):
|
case let .albumsHeader(_, text), let .smartAlbumsHeader(_, text):
|
||||||
return MediaGroupsHeaderItem(presentationData: ItemListPresentationData(presentationData), title: text)
|
return MediaGroupsHeaderItem(presentationData: ItemListPresentationData(presentationData), title: text)
|
||||||
case let .albums(_, collections):
|
case let .albums(_, collections):
|
||||||
return MediaGroupsAlbumGridItem(presentationData: ItemListPresentationData(presentationData), collections: collections, action: { collection in
|
return MediaGroupsAlbumGridItem(presentationData: presentationData, collections: collections, action: { collection in
|
||||||
openGroup(collection)
|
openGroup(collection)
|
||||||
})
|
})
|
||||||
case let .smartAlbum(_, _, collection, count):
|
case let .smartAlbum(_, _, collection, count):
|
||||||
|
@ -612,7 +612,18 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updatePresentationData(_ presentationData: PresentationData) {
|
func updatePresentationData(_ presentationData: PresentationData) {
|
||||||
|
let stringsUpdated = self.presentationData.strings !== presentationData.strings
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
|
|
||||||
|
if stringsUpdated {
|
||||||
|
if let snapshotView = self.view.snapshotView(afterScreenUpdates: false) {
|
||||||
|
self.view.addSubview(snapshotView)
|
||||||
|
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||||
|
snapshotView?.removeFromSuperview()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.presentationDataValue.set(.single(presentationData))
|
self.presentationDataValue.set(.single(presentationData))
|
||||||
self.backgroundColor = presentationData.theme.list.blocksBackgroundColor
|
self.backgroundColor = presentationData.theme.list.blocksBackgroundColor
|
||||||
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.list.blocksBackgroundColor, direction: true)
|
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.list.blocksBackgroundColor, direction: true)
|
||||||
|
@ -319,6 +319,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||||||
|
|
||||||
let launchIconSize = CGSize(width: 99.0, height: 99.0)
|
let launchIconSize = CGSize(width: 99.0, height: 99.0)
|
||||||
let launchIconView = UIImageView(image: UIImage(bundleImageName: "Components/LaunchLogo"))
|
let launchIconView = UIImageView(image: UIImage(bundleImageName: "Components/LaunchLogo"))
|
||||||
|
launchIconView.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin, .flexibleBottomMargin]
|
||||||
launchIconView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((hostView.containerView.frame.width - launchIconSize.width) / 2.0), y: floorToScreenPixels((hostView.containerView.frame.height - launchIconSize.height) / 2.0)), size: launchIconSize)
|
launchIconView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((hostView.containerView.frame.width - launchIconSize.width) / 2.0), y: floorToScreenPixels((hostView.containerView.frame.height - launchIconSize.height) / 2.0)), size: launchIconSize)
|
||||||
hostView.containerView.addSubview(launchIconView)
|
hostView.containerView.addSubview(launchIconView)
|
||||||
|
|
||||||
|
@ -735,7 +735,7 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func update(presentationData: PresentationData, constrainedWidth: CGFloat, maxHeight: CGFloat, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) -> (cleanSize: CGSize, apparentHeight: CGFloat) {
|
func update(presentationData: PresentationData, constrainedWidth: CGFloat, maxHeight: CGFloat, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) -> (cleanSize: CGSize, apparentHeight: CGFloat) {
|
||||||
let constrainedSize = CGSize(width: min(260.0, constrainedWidth), height: min(604.0, maxHeight))
|
let constrainedSize = CGSize(width: min(220.0, constrainedWidth), height: min(604.0, maxHeight))
|
||||||
|
|
||||||
var topContentHeight: CGFloat = 0.0
|
var topContentHeight: CGFloat = 0.0
|
||||||
if let backButtonNode = self.backButtonNode {
|
if let backButtonNode = self.backButtonNode {
|
||||||
|
@ -9,6 +9,7 @@ import TelegramAudio
|
|||||||
import AccountContext
|
import AccountContext
|
||||||
import TelegramUniversalVideoContent
|
import TelegramUniversalVideoContent
|
||||||
import DeviceProximity
|
import DeviceProximity
|
||||||
|
import RaiseToListen
|
||||||
|
|
||||||
private enum SharedMediaPlaybackItem: Equatable {
|
private enum SharedMediaPlaybackItem: Equatable {
|
||||||
case audio(MediaPlayer)
|
case audio(MediaPlayer)
|
||||||
@ -120,7 +121,9 @@ final class SharedMediaPlayer {
|
|||||||
|
|
||||||
private var playbackRate: AudioPlaybackRate
|
private var playbackRate: AudioPlaybackRate
|
||||||
|
|
||||||
private var proximityManagerIndex: Int?
|
//private var proximityManagerIndex: Int?
|
||||||
|
private var raiseToListen: RaiseToListenManager?
|
||||||
|
|
||||||
private let controlPlaybackWithProximity: Bool
|
private let controlPlaybackWithProximity: Bool
|
||||||
private var forceAudioToSpeaker = false
|
private var forceAudioToSpeaker = false
|
||||||
|
|
||||||
@ -346,9 +349,10 @@ final class SharedMediaPlayer {
|
|||||||
} else {
|
} else {
|
||||||
strongSelf.playbackStateValue.set(.single(nil))
|
strongSelf.playbackStateValue.set(.single(nil))
|
||||||
if !state.loading {
|
if !state.loading {
|
||||||
if let proximityManagerIndex = strongSelf.proximityManagerIndex {
|
strongSelf.raiseToListen = nil
|
||||||
DeviceProximityManager.shared().remove(proximityManagerIndex)
|
// if let proximityManagerIndex = strongSelf.proximityManagerIndex {
|
||||||
}
|
// DeviceProximityManager.shared().remove(proximityManagerIndex)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,18 +366,44 @@ final class SharedMediaPlayer {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if controlPlaybackWithProximity {
|
if controlPlaybackWithProximity {
|
||||||
self.proximityManagerIndex = DeviceProximityManager.shared().add { [weak self] value in
|
self.raiseToListen = RaiseToListenManager(shouldActivate: {
|
||||||
let forceAudioToSpeaker = !value
|
return true
|
||||||
if let strongSelf = self, strongSelf.forceAudioToSpeaker != forceAudioToSpeaker {
|
}, activate: { [weak self] in
|
||||||
strongSelf.forceAudioToSpeaker = forceAudioToSpeaker
|
if let strongSelf = self {
|
||||||
strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker)
|
let forceAudioToSpeaker = false
|
||||||
if !forceAudioToSpeaker {
|
if strongSelf.forceAudioToSpeaker != forceAudioToSpeaker {
|
||||||
strongSelf.control(.playback(.play))
|
strongSelf.forceAudioToSpeaker = forceAudioToSpeaker
|
||||||
} else {
|
strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker)
|
||||||
strongSelf.control(.playback(.pause))
|
if !forceAudioToSpeaker {
|
||||||
|
strongSelf.control(.playback(.play))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, deactivate: { [weak self] in
|
||||||
|
if let strongSelf = self {
|
||||||
|
let forceAudioToSpeaker = true
|
||||||
|
if strongSelf.forceAudioToSpeaker != forceAudioToSpeaker {
|
||||||
|
strongSelf.forceAudioToSpeaker = forceAudioToSpeaker
|
||||||
|
strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker)
|
||||||
|
if forceAudioToSpeaker {
|
||||||
|
strongSelf.control(.playback(.pause))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
self.raiseToListen?.enabled = true
|
||||||
|
// self.proximityManagerIndex = DeviceProximityManager.shared().add { [weak self] value in
|
||||||
|
// let forceAudioToSpeaker = !value
|
||||||
|
// if let strongSelf = self, strongSelf.forceAudioToSpeaker != forceAudioToSpeaker {
|
||||||
|
// strongSelf.forceAudioToSpeaker = forceAudioToSpeaker
|
||||||
|
// strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker)
|
||||||
|
// if !forceAudioToSpeaker {
|
||||||
|
// strongSelf.control(.playback(.play))
|
||||||
|
// } else {
|
||||||
|
// strongSelf.control(.playback(.pause))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,9 +414,9 @@ final class SharedMediaPlayer {
|
|||||||
self.playbackStateValueDisposable?.dispose()
|
self.playbackStateValueDisposable?.dispose()
|
||||||
self.prefetchDisposable.dispose()
|
self.prefetchDisposable.dispose()
|
||||||
|
|
||||||
if let proximityManagerIndex = self.proximityManagerIndex {
|
// if let proximityManagerIndex = self.proximityManagerIndex {
|
||||||
DeviceProximityManager.shared().remove(proximityManagerIndex)
|
// DeviceProximityManager.shared().remove(proximityManagerIndex)
|
||||||
}
|
// }
|
||||||
|
|
||||||
if let playbackItem = self.playbackItem {
|
if let playbackItem = self.playbackItem {
|
||||||
switch playbackItem {
|
switch playbackItem {
|
||||||
|
@ -222,14 +222,24 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id)
|
|||||||
let hypotheses = languageRecognizer.languageHypotheses(withMaximum: 4)
|
let hypotheses = languageRecognizer.languageHypotheses(withMaximum: 4)
|
||||||
languageRecognizer.reset()
|
languageRecognizer.reset()
|
||||||
|
|
||||||
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains($0.key.rawValue) }.sorted(by: { $0.value > $1.value })
|
func normalize(_ code: String) -> String {
|
||||||
if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) {
|
if code.contains("-") {
|
||||||
let fromLang = language.key.rawValue
|
return code.components(separatedBy: "-").first ?? code
|
||||||
|
} else if code == "nb" {
|
||||||
|
return "no"
|
||||||
|
} else {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains(normalize($0.key.rawValue)) }.sorted(by: { $0.value > $1.value })
|
||||||
|
if let language = filteredLanguages.first {
|
||||||
|
let fromLang = normalize(language.key.rawValue)
|
||||||
fromLangs[fromLang] = (fromLangs[fromLang] ?? 0) + message.text.count
|
fromLangs[fromLang] = (fromLangs[fromLang] ?? 0) + message.text.count
|
||||||
count += 1
|
count += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if count >= 10 {
|
if count >= 16 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,6 @@ public var supportedTranslationLanguages = [
|
|||||||
"ca",
|
"ca",
|
||||||
"ceb",
|
"ceb",
|
||||||
"zh",
|
"zh",
|
||||||
// "zh-Hant",
|
|
||||||
// "zh-CN", "zh"
|
|
||||||
// "zh-TW"
|
|
||||||
"co",
|
"co",
|
||||||
"hr",
|
"hr",
|
||||||
"cs",
|
"cs",
|
||||||
@ -168,9 +165,20 @@ public func canTranslateText(context: AccountContext, text: String, showTranslat
|
|||||||
supportedTranslationLanguages = ["uk", "ru"]
|
supportedTranslationLanguages = ["uk", "ru"]
|
||||||
}
|
}
|
||||||
|
|
||||||
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains($0.key.rawValue) }.sorted(by: { $0.value > $1.value })
|
func normalize(_ code: String) -> String {
|
||||||
if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) {
|
if code.contains("-") {
|
||||||
return (!dontTranslateLanguages.contains(language.key.rawValue), language.key.rawValue)
|
return code.components(separatedBy: "-").first ?? code
|
||||||
|
} else if code == "nb" {
|
||||||
|
return "no"
|
||||||
|
} else {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains(normalize($0.key.rawValue)) }.sorted(by: { $0.value > $1.value })
|
||||||
|
if let language = filteredLanguages.first {
|
||||||
|
let languageCode = normalize(language.key.rawValue)
|
||||||
|
return (!dontTranslateLanguages.contains(languageCode), languageCode)
|
||||||
} else {
|
} else {
|
||||||
return (false, nil)
|
return (false, nil)
|
||||||
}
|
}
|
||||||
|
@ -245,9 +245,9 @@ class WebSearchControllerNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.segmentedContainerNode)
|
self.addSubnode(self.segmentedContainerNode)
|
||||||
self.segmentedContainerNode.addSubnode(self.segmentedBackgroundNode)
|
self.segmentedContainerNode.addSubnode(self.segmentedBackgroundNode)
|
||||||
self.segmentedContainerNode.addSubnode(self.segmentedSeparatorNode)
|
self.segmentedContainerNode.addSubnode(self.segmentedSeparatorNode)
|
||||||
if case .media = mode {
|
// if case .media = mode {
|
||||||
self.segmentedContainerNode.addSubnode(self.segmentedControlNode)
|
// self.segmentedContainerNode.addSubnode(self.segmentedControlNode)
|
||||||
}
|
// }
|
||||||
if !attachment {
|
if !attachment {
|
||||||
self.addSubnode(self.toolbarBackgroundNode)
|
self.addSubnode(self.toolbarBackgroundNode)
|
||||||
self.addSubnode(self.toolbarSeparatorNode)
|
self.addSubnode(self.toolbarSeparatorNode)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user